mirror of https://github.com/facebook/rocksdb.git
Update upper_bound_offset when reseek changes iterate_upper_bound dynamically (#11775)
Summary: Update the logic in FilePrefetchBuffer to update `upper_bound_offset_` during reseek. During Reseek, `iterate_upper_bound` can be changed dynamically. So added an API to update that in FilePrefetchBuffer. Added unit test to confirm the behavior. Pull Request resolved: https://github.com/facebook/rocksdb/pull/11775 Test Plan: - Check stress tests in case there is any failure after this diff. - make crash_test -j32 with auto_readahead_size=1 passed locally Reviewed By: anand1976 Differential Revision: D48815177 Pulled By: akankshamahajan15 fbshipit-source-id: 5f44fbb3af06c86a1c38f139c5fa4543891837f4
This commit is contained in:
parent
e1fd348b92
commit
1e2fd343bb
|
@ -279,6 +279,11 @@ class FilePrefetchBuffer {
|
||||||
// Callback function passed to underlying FS in case of asynchronous reads.
|
// Callback function passed to underlying FS in case of asynchronous reads.
|
||||||
void PrefetchAsyncCallback(const FSReadRequest& req, void* cb_arg);
|
void PrefetchAsyncCallback(const FSReadRequest& req, void* cb_arg);
|
||||||
|
|
||||||
|
void ResetUpperBoundOffset(uint64_t upper_bound_offset) {
|
||||||
|
upper_bound_offset_ = upper_bound_offset;
|
||||||
|
readahead_size_ = initial_auto_readahead_size_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Calculates roundoff offset and length to be prefetched based on alignment
|
// Calculates roundoff offset and length to be prefetched based on alignment
|
||||||
// and data present in buffer_. It also allocates new buffer or refit tail if
|
// and data present in buffer_. It also allocates new buffer or refit tail if
|
||||||
|
@ -321,7 +326,6 @@ class FilePrefetchBuffer {
|
||||||
void ResetValues() {
|
void ResetValues() {
|
||||||
num_file_reads_ = 1;
|
num_file_reads_ = 1;
|
||||||
readahead_size_ = initial_auto_readahead_size_;
|
readahead_size_ = initial_auto_readahead_size_;
|
||||||
upper_bound_offset_ = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called in case of implicit auto prefetching.
|
// Called in case of implicit auto prefetching.
|
||||||
|
|
|
@ -2082,6 +2082,7 @@ TEST_P(PrefetchTest, IterReadAheadSizeWithUpperBound) {
|
||||||
|
|
||||||
int buff_count_with_tuning = 0, buff_count_without_tuning = 0;
|
int buff_count_with_tuning = 0, buff_count_without_tuning = 0;
|
||||||
int keys_with_tuning = 0, keys_without_tuning = 0;
|
int keys_with_tuning = 0, keys_without_tuning = 0;
|
||||||
|
int reseek_keys_with_tuning = 0, reseek_keys_without_tuning = 0;
|
||||||
buff_prefetch_count = 0;
|
buff_prefetch_count = 0;
|
||||||
|
|
||||||
SyncPoint::GetInstance()->SetCallBack(
|
SyncPoint::GetInstance()->SetCallBack(
|
||||||
|
@ -2102,48 +2103,92 @@ TEST_P(PrefetchTest, IterReadAheadSizeWithUpperBound) {
|
||||||
ropts.async_io = true;
|
ropts.async_io = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Slice ub = Slice("my_key_uuu");
|
|
||||||
ropts.iterate_upper_bound = &ub;
|
|
||||||
Slice seek_key = Slice("my_key_aaa");
|
|
||||||
|
|
||||||
// With tuning readahead_size.
|
// With tuning readahead_size.
|
||||||
{
|
{
|
||||||
ASSERT_OK(options.statistics->Reset());
|
ASSERT_OK(options.statistics->Reset());
|
||||||
|
Slice ub = Slice("my_key_uuu");
|
||||||
|
Slice* ub_ptr = &ub;
|
||||||
|
ropts.iterate_upper_bound = ub_ptr;
|
||||||
ropts.auto_readahead_size = true;
|
ropts.auto_readahead_size = true;
|
||||||
|
|
||||||
auto iter = std::unique_ptr<Iterator>(db_->NewIterator(ropts));
|
auto iter = std::unique_ptr<Iterator>(db_->NewIterator(ropts));
|
||||||
|
|
||||||
iter->Seek(seek_key);
|
// Seek.
|
||||||
|
{
|
||||||
|
Slice seek_key = Slice("my_key_aaa");
|
||||||
|
iter->Seek(seek_key);
|
||||||
|
|
||||||
while (iter->Valid()) {
|
while (iter->Valid()) {
|
||||||
keys_with_tuning++;
|
keys_with_tuning++;
|
||||||
iter->Next();
|
iter->Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t readahead_trimmed =
|
||||||
|
options.statistics->getAndResetTickerCount(READAHEAD_TRIMMED);
|
||||||
|
ASSERT_GT(readahead_trimmed, 0);
|
||||||
|
buff_count_with_tuning = buff_prefetch_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t readhahead_trimmed =
|
// Reseek with new upper_bound_iterator.
|
||||||
options.statistics->getAndResetTickerCount(READAHEAD_TRIMMED);
|
{
|
||||||
ASSERT_GT(readhahead_trimmed, 0);
|
ub = Slice("my_key_y");
|
||||||
buff_count_with_tuning = buff_prefetch_count;
|
Slice reseek_key = Slice("my_key_v");
|
||||||
|
iter->Seek(reseek_key);
|
||||||
|
|
||||||
|
while (iter->Valid()) {
|
||||||
|
iter->Next();
|
||||||
|
reseek_keys_with_tuning++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t readahead_trimmed =
|
||||||
|
options.statistics->getAndResetTickerCount(READAHEAD_TRIMMED);
|
||||||
|
ASSERT_GT(readahead_trimmed, 0);
|
||||||
|
ASSERT_GT(reseek_keys_with_tuning, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Without tuning readahead_size
|
// Without tuning readahead_size
|
||||||
{
|
{
|
||||||
|
Slice ub = Slice("my_key_uuu");
|
||||||
|
Slice* ub_ptr = &ub;
|
||||||
|
ropts.iterate_upper_bound = ub_ptr;
|
||||||
buff_prefetch_count = 0;
|
buff_prefetch_count = 0;
|
||||||
ASSERT_OK(options.statistics->Reset());
|
ASSERT_OK(options.statistics->Reset());
|
||||||
ropts.auto_readahead_size = false;
|
ropts.auto_readahead_size = false;
|
||||||
|
|
||||||
auto iter = std::unique_ptr<Iterator>(db_->NewIterator(ropts));
|
auto iter = std::unique_ptr<Iterator>(db_->NewIterator(ropts));
|
||||||
|
|
||||||
iter->Seek(seek_key);
|
// Seek.
|
||||||
|
{
|
||||||
|
Slice seek_key = Slice("my_key_aaa");
|
||||||
|
iter->Seek(seek_key);
|
||||||
|
|
||||||
while (iter->Valid()) {
|
while (iter->Valid()) {
|
||||||
keys_without_tuning++;
|
keys_without_tuning++;
|
||||||
iter->Next();
|
iter->Next();
|
||||||
|
}
|
||||||
|
buff_count_without_tuning = buff_prefetch_count;
|
||||||
|
uint64_t readahead_trimmed =
|
||||||
|
options.statistics->getAndResetTickerCount(READAHEAD_TRIMMED);
|
||||||
|
ASSERT_EQ(readahead_trimmed, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reseek with new upper_bound_iterator.
|
||||||
|
{
|
||||||
|
ub = Slice("my_key_y");
|
||||||
|
Slice reseek_key = Slice("my_key_v");
|
||||||
|
iter->Seek(reseek_key);
|
||||||
|
|
||||||
|
while (iter->Valid()) {
|
||||||
|
iter->Next();
|
||||||
|
reseek_keys_without_tuning++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t readahead_trimmed =
|
||||||
|
options.statistics->getAndResetTickerCount(READAHEAD_TRIMMED);
|
||||||
|
ASSERT_EQ(readahead_trimmed, 0);
|
||||||
|
ASSERT_GT(reseek_keys_without_tuning, 0);
|
||||||
}
|
}
|
||||||
buff_count_without_tuning = buff_prefetch_count;
|
|
||||||
uint64_t readhahead_trimmed =
|
|
||||||
options.statistics->getAndResetTickerCount(READAHEAD_TRIMMED);
|
|
||||||
ASSERT_EQ(readhahead_trimmed, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -2159,6 +2204,8 @@ TEST_P(PrefetchTest, IterReadAheadSizeWithUpperBound) {
|
||||||
ASSERT_GT(buff_count_with_tuning, 0);
|
ASSERT_GT(buff_count_with_tuning, 0);
|
||||||
// No of keys should be equal.
|
// No of keys should be equal.
|
||||||
ASSERT_EQ(keys_without_tuning, keys_with_tuning);
|
ASSERT_EQ(keys_without_tuning, keys_with_tuning);
|
||||||
|
// No of keys after reseek with new upper bound should be equal.
|
||||||
|
ASSERT_EQ(reseek_keys_without_tuning, reseek_keys_with_tuning);
|
||||||
}
|
}
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,11 @@ class BlockPrefetcher {
|
||||||
|
|
||||||
void SetUpperBoundOffset(uint64_t upper_bound_offset) {
|
void SetUpperBoundOffset(uint64_t upper_bound_offset) {
|
||||||
upper_bound_offset_ = upper_bound_offset;
|
upper_bound_offset_ = upper_bound_offset;
|
||||||
|
if (prefetch_buffer() != nullptr) {
|
||||||
|
// Upper bound can be changed on reseek. So update that in
|
||||||
|
// FilePrefetchBuffer.
|
||||||
|
prefetch_buffer()->ResetUpperBoundOffset(upper_bound_offset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
* When auto_readahead_size is enabled, update readahead upper bound during readahead trimming when reseek changes iterate_upper_bound dynamically.
|
Loading…
Reference in New Issue