Skip to content

Moving predictor to WorkingArea to make it thread safe #13706

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 104 commits into from

Conversation

shubhajeet
Copy link
Contributor

Summary:

We need to move the Predictor to WorkingArea so that it is local to each thread and thus is thread safe.

Test Plan:

It should pass the test case written in ./compression_test.

shubhajeet added 30 commits May 28, 2025 16:25
Summary:
Added compiler options in the stress test. Need to verify it is correct.
Need to verify ldb is correct.
@shubhajeet shubhajeet requested review from hx235 and pdillinger June 17, 2025 18:42
@@ -33,6 +33,20 @@ class CompressionRejectionProbabilityPredictor {
size_t window_size_;
};

class AutoSkipCompressionContext : public Compressor::WorkingArea {
public:
explicit AutoSkipCompressionContext(Compressor::ManagedWorkingArea&& wa)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can call this AutoSkipWorkingArea

if (prediction <= kProbabilityCutOff) {
// decide to compress
return CompressBlockAndRecord(uncompressed_data, compressed_output,
out_compression_type, wa);
} else {
// decide to bypass compression
// bypassed compression
Copy link
Contributor

@hx235 hx235 Jun 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like you accidentally reversed some good fix such as this comment. Make sure to check other places too

// Predict rejection probability using a moving window approach
// This class is not thread safe
// Predicts Rejection Probability using previous using past data of certain
// window size
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another accidental revert?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure this PR is rebased on the upstream main after it includes all your previous fixes to auto skip. This is to not accidentally revert your changes.

Copy link
Contributor

@hx235 hx235 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will leave @pdillinger for the final pass. For quick pass, overall design looks right to me except for some small stuff

@@ -65,27 +65,44 @@ Status AutoSkipCompressorWrapper::CompressBlock(
return CompressBlockAndRecord(uncompressed_data, compressed_output,
out_compression_type, wa);
} else {
auto prediction = predictor_->Predict();
auto predictor_ptr =
static_cast<AutoSkipCompressionContext*>(wa->get())->predictor;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you look at the API commend on CompressBlock,

  // The working area is optional and used to optimize repeated compression by
  // a single thread. ManagedWorkingArea is provided rather than just
  // WorkingArea so that it can be used only if the `owner` matches expectation.
  // This could be useful for a Compressor wrapping more than one alternative
  // underlying Compressor.

Specifically, the working area should only be used if the owner matches expectations. See BuiltinCompressorV2::CompressBlock checking owner() for example.

Also the working area is optional. It is typically provided by the RocksDB table builder but not guaranteed in general.

Copy link
Contributor Author

@shubhajeet shubhajeet Jun 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pdillinger If the working area is not provided or a working area with wrong owner is provided, does it mean they are not using AutoSkip? Since the predictor is in the working area, we don't have access to any prediction.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think it is OK to provide degraded functionality (always attempt compression) if the WorkingArea is not provided. I might reconsider the exact contract for this in the future.

Some detail: Right now the compressed secondary cache can't efficiently provide a working area because we cannot predict which threads might access the cache, and how many times they might access it. It is perhaps unlikely that AutoSkip would be used with the compressed secondary cache, but it's possible.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The owner() check part is still outstanding also.

Compressor::ManagedWorkingArea AutoSkipCompressorWrapper::ObtainWorkingArea() {
auto wrap_wa = wrapped_->ObtainWorkingArea();
return ManagedWorkingArea(
static_cast<WorkingArea*>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static_cast should be unnecessary

Status AutoSkipCompressorWrapper::CompressBlockAndRecord(
Slice uncompressed_data, std::string* compressed_output,
CompressionType* out_compression_type, ManagedWorkingArea* wa) {
auto wrap_wa =
&(static_cast<AutoSkipCompressionContext*>(wa->get())->wrapped);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't this function take AutoSkipCompressionContext instead of WorkingArea to avoid so many casts?

@facebook-github-bot
Copy link
Contributor

@shubhajeet has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@shubhajeet has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@shubhajeet has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

Copy link
Contributor

@pdillinger pdillinger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very close. Resolve the WorkingArea extra checks needed

@@ -62,14 +62,18 @@ Status AutoSkipCompressorWrapper::CompressBlock(
"AutoSkipCompressorWrapper::CompressBlock::exploitOrExplore",
&exploration);
if (exploration) {
auto autoskip_wa = static_cast<AutoSkipWorkingArea*>(wa->get());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still have three ugly static_cast<AutoSkipWorkingArea*> where I believe one should be sufficient.

@@ -65,27 +65,44 @@ Status AutoSkipCompressorWrapper::CompressBlock(
return CompressBlockAndRecord(uncompressed_data, compressed_output,
out_compression_type, wa);
} else {
auto prediction = predictor_->Predict();
auto predictor_ptr =
static_cast<AutoSkipCompressionContext*>(wa->get())->predictor;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The owner() check part is still outstanding also.

@facebook-github-bot
Copy link
Contributor

@shubhajeet has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@shubhajeet has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@shubhajeet has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@shubhajeet has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@shubhajeet shubhajeet self-assigned this Jun 17, 2025
@shubhajeet shubhajeet requested a review from pdillinger June 17, 2025 23:52
Copy link
Contributor

@pdillinger pdillinger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks!

@facebook-github-bot
Copy link
Contributor

@shubhajeet merged this pull request in 34d8f03.

@hx235 hx235 mentioned this pull request Jun 18, 2025
@shubhajeet shubhajeet deleted the working_area branch June 26, 2025 21:52
SoujanyaPonnapalli pushed a commit to tyler-griggs/rocksdb that referenced this pull request Jul 20, 2025
Summary:
**Summary:**

We need to move the Predictor to WorkingArea so that it is local to each thread and thus is thread safe.

Pull Request resolved: facebook#13706

Test Plan: It should pass the test case written in ./compression_test.

Reviewed By: pdillinger

Differential Revision: D76836846

Pulled By: shubhajeet

fbshipit-source-id: 0d0170baf65f4bb95ba107fec77151e66b8a4449
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants