|
|
@ -47,8 +47,8 @@ class ExternSSTFileLinkFailFallbackTest |
|
|
|
: DBTestBase("/external_sst_file_test", /*env_do_fsync=*/true), |
|
|
|
: DBTestBase("/external_sst_file_test", /*env_do_fsync=*/true), |
|
|
|
test_env_(new ExternalSSTTestEnv(env_, true)) { |
|
|
|
test_env_(new ExternalSSTTestEnv(env_, true)) { |
|
|
|
sst_files_dir_ = dbname_ + "/sst_files/"; |
|
|
|
sst_files_dir_ = dbname_ + "/sst_files/"; |
|
|
|
DestroyDir(env_, sst_files_dir_); |
|
|
|
EXPECT_EQ(DestroyDir(env_, sst_files_dir_), Status::OK()); |
|
|
|
env_->CreateDir(sst_files_dir_); |
|
|
|
EXPECT_EQ(env_->CreateDir(sst_files_dir_), Status::OK()); |
|
|
|
options_ = CurrentOptions(); |
|
|
|
options_ = CurrentOptions(); |
|
|
|
options_.disable_auto_compactions = true; |
|
|
|
options_.disable_auto_compactions = true; |
|
|
|
options_.env = test_env_; |
|
|
|
options_.env = test_env_; |
|
|
@ -79,8 +79,8 @@ class ExternalSSTFileTest |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void DestroyAndRecreateExternalSSTFilesDir() { |
|
|
|
void DestroyAndRecreateExternalSSTFilesDir() { |
|
|
|
DestroyDir(env_, sst_files_dir_); |
|
|
|
ASSERT_OK(DestroyDir(env_, sst_files_dir_)); |
|
|
|
env_->CreateDir(sst_files_dir_); |
|
|
|
ASSERT_OK(env_->CreateDir(sst_files_dir_)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Status GenerateOneExternalFile( |
|
|
|
Status GenerateOneExternalFile( |
|
|
@ -116,7 +116,7 @@ class ExternalSSTFileTest |
|
|
|
for (const auto& entry : data) { |
|
|
|
for (const auto& entry : data) { |
|
|
|
s = sst_file_writer.Put(entry.first, entry.second); |
|
|
|
s = sst_file_writer.Put(entry.first, entry.second); |
|
|
|
if (!s.ok()) { |
|
|
|
if (!s.ok()) { |
|
|
|
sst_file_writer.Finish(); |
|
|
|
sst_file_writer.Finish().PermitUncheckedError(); |
|
|
|
return s; |
|
|
|
return s; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -171,7 +171,7 @@ class ExternalSSTFileTest |
|
|
|
for (auto& entry : data) { |
|
|
|
for (auto& entry : data) { |
|
|
|
s = sst_file_writer.Put(entry.first, entry.second); |
|
|
|
s = sst_file_writer.Put(entry.first, entry.second); |
|
|
|
if (!s.ok()) { |
|
|
|
if (!s.ok()) { |
|
|
|
sst_file_writer.Finish(); |
|
|
|
sst_file_writer.Finish().PermitUncheckedError(); |
|
|
|
return s; |
|
|
|
return s; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -213,11 +213,10 @@ class ExternalSSTFileTest |
|
|
|
size_t num_cfs = column_families.size(); |
|
|
|
size_t num_cfs = column_families.size(); |
|
|
|
assert(ifos.size() == num_cfs); |
|
|
|
assert(ifos.size() == num_cfs); |
|
|
|
assert(data.size() == num_cfs); |
|
|
|
assert(data.size() == num_cfs); |
|
|
|
Status s; |
|
|
|
|
|
|
|
std::vector<IngestExternalFileArg> args(num_cfs); |
|
|
|
std::vector<IngestExternalFileArg> args(num_cfs); |
|
|
|
for (size_t i = 0; i != num_cfs; ++i) { |
|
|
|
for (size_t i = 0; i != num_cfs; ++i) { |
|
|
|
std::string external_file_path; |
|
|
|
std::string external_file_path; |
|
|
|
s = GenerateOneExternalFile( |
|
|
|
Status s = GenerateOneExternalFile( |
|
|
|
options, column_families[i], data[i], file_id, sort_data, |
|
|
|
options, column_families[i], data[i], file_id, sort_data, |
|
|
|
&external_file_path, |
|
|
|
&external_file_path, |
|
|
|
true_data.size() == num_cfs ? &true_data[i] : nullptr); |
|
|
|
true_data.size() == num_cfs ? &true_data[i] : nullptr); |
|
|
@ -230,8 +229,7 @@ class ExternalSSTFileTest |
|
|
|
args[i].external_files.push_back(external_file_path); |
|
|
|
args[i].external_files.push_back(external_file_path); |
|
|
|
args[i].options = ifos[i]; |
|
|
|
args[i].options = ifos[i]; |
|
|
|
} |
|
|
|
} |
|
|
|
s = db_->IngestExternalFiles(args); |
|
|
|
return db_->IngestExternalFiles(args); |
|
|
|
return s; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Status GenerateAndAddExternalFile( |
|
|
|
Status GenerateAndAddExternalFile( |
|
|
@ -282,7 +280,9 @@ class ExternalSSTFileTest |
|
|
|
return db_->IngestExternalFile(files, opts); |
|
|
|
return db_->IngestExternalFile(files, opts); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
~ExternalSSTFileTest() override { DestroyDir(env_, sst_files_dir_); } |
|
|
|
~ExternalSSTFileTest() override { |
|
|
|
|
|
|
|
DestroyDir(env_, sst_files_dir_).PermitUncheckedError(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
protected: |
|
|
|
int last_file_id_ = 0; |
|
|
|
int last_file_id_ = 0; |
|
|
@ -305,8 +305,7 @@ TEST_F(ExternalSSTFileTest, Basic) { |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
} |
|
|
|
} |
|
|
|
ExternalSstFileInfo file1_info; |
|
|
|
ExternalSstFileInfo file1_info; |
|
|
|
Status s = sst_file_writer.Finish(&file1_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&file1_info)); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Current file size should be non-zero after success write.
|
|
|
|
// Current file size should be non-zero after success write.
|
|
|
|
ASSERT_GT(sst_file_writer.FileSize(), 0); |
|
|
|
ASSERT_GT(sst_file_writer.FileSize(), 0); |
|
|
@ -319,8 +318,7 @@ TEST_F(ExternalSSTFileTest, Basic) { |
|
|
|
ASSERT_EQ(file1_info.smallest_range_del_key, ""); |
|
|
|
ASSERT_EQ(file1_info.smallest_range_del_key, ""); |
|
|
|
ASSERT_EQ(file1_info.largest_range_del_key, ""); |
|
|
|
ASSERT_EQ(file1_info.largest_range_del_key, ""); |
|
|
|
// sst_file_writer already finished, cannot add this value
|
|
|
|
// sst_file_writer already finished, cannot add this value
|
|
|
|
s = sst_file_writer.Put(Key(100), "bad_val"); |
|
|
|
ASSERT_NOK(sst_file_writer.Put(Key(100), "bad_val")); |
|
|
|
ASSERT_FALSE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// file2.sst (100 => 199)
|
|
|
|
// file2.sst (100 => 199)
|
|
|
|
std::string file2 = sst_files_dir_ + "file2.sst"; |
|
|
|
std::string file2 = sst_files_dir_ + "file2.sst"; |
|
|
@ -329,11 +327,9 @@ TEST_F(ExternalSSTFileTest, Basic) { |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
} |
|
|
|
} |
|
|
|
// Cannot add this key because it's not after last added key
|
|
|
|
// Cannot add this key because it's not after last added key
|
|
|
|
s = sst_file_writer.Put(Key(99), "bad_val"); |
|
|
|
ASSERT_NOK(sst_file_writer.Put(Key(99), "bad_val")); |
|
|
|
ASSERT_FALSE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ExternalSstFileInfo file2_info; |
|
|
|
ExternalSstFileInfo file2_info; |
|
|
|
s = sst_file_writer.Finish(&file2_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&file2_info)); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(file2_info.file_path, file2); |
|
|
|
ASSERT_EQ(file2_info.file_path, file2); |
|
|
|
ASSERT_EQ(file2_info.num_entries, 100); |
|
|
|
ASSERT_EQ(file2_info.num_entries, 100); |
|
|
|
ASSERT_EQ(file2_info.smallest_key, Key(100)); |
|
|
|
ASSERT_EQ(file2_info.smallest_key, Key(100)); |
|
|
@ -347,9 +343,8 @@ TEST_F(ExternalSSTFileTest, Basic) { |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val_overlap")); |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val_overlap")); |
|
|
|
} |
|
|
|
} |
|
|
|
ExternalSstFileInfo file3_info; |
|
|
|
ExternalSstFileInfo file3_info; |
|
|
|
s = sst_file_writer.Finish(&file3_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&file3_info)); |
|
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
// Current file size should be non-zero after success finish.
|
|
|
|
// Current file size should be non-zero after success finish.
|
|
|
|
ASSERT_GT(sst_file_writer.FileSize(), 0); |
|
|
|
ASSERT_GT(sst_file_writer.FileSize(), 0); |
|
|
|
ASSERT_EQ(file3_info.file_path, file3); |
|
|
|
ASSERT_EQ(file3_info.file_path, file3); |
|
|
@ -365,8 +360,7 @@ TEST_F(ExternalSSTFileTest, Basic) { |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val_overlap")); |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val_overlap")); |
|
|
|
} |
|
|
|
} |
|
|
|
ExternalSstFileInfo file4_info; |
|
|
|
ExternalSstFileInfo file4_info; |
|
|
|
s = sst_file_writer.Finish(&file4_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&file4_info)); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(file4_info.file_path, file4); |
|
|
|
ASSERT_EQ(file4_info.file_path, file4); |
|
|
|
ASSERT_EQ(file4_info.num_entries, 10); |
|
|
|
ASSERT_EQ(file4_info.num_entries, 10); |
|
|
|
ASSERT_EQ(file4_info.smallest_key, Key(30)); |
|
|
|
ASSERT_EQ(file4_info.smallest_key, Key(30)); |
|
|
@ -379,8 +373,7 @@ TEST_F(ExternalSSTFileTest, Basic) { |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
} |
|
|
|
} |
|
|
|
ExternalSstFileInfo file5_info; |
|
|
|
ExternalSstFileInfo file5_info; |
|
|
|
s = sst_file_writer.Finish(&file5_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&file5_info)); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(file5_info.file_path, file5); |
|
|
|
ASSERT_EQ(file5_info.file_path, file5); |
|
|
|
ASSERT_EQ(file5_info.num_entries, 100); |
|
|
|
ASSERT_EQ(file5_info.num_entries, 100); |
|
|
|
ASSERT_EQ(file5_info.smallest_key, Key(400)); |
|
|
|
ASSERT_EQ(file5_info.smallest_key, Key(400)); |
|
|
@ -389,10 +382,9 @@ TEST_F(ExternalSSTFileTest, Basic) { |
|
|
|
// file6.sst (delete 400 => 500)
|
|
|
|
// file6.sst (delete 400 => 500)
|
|
|
|
std::string file6 = sst_files_dir_ + "file6.sst"; |
|
|
|
std::string file6 = sst_files_dir_ + "file6.sst"; |
|
|
|
ASSERT_OK(sst_file_writer.Open(file6)); |
|
|
|
ASSERT_OK(sst_file_writer.Open(file6)); |
|
|
|
sst_file_writer.DeleteRange(Key(400), Key(500)); |
|
|
|
ASSERT_OK(sst_file_writer.DeleteRange(Key(400), Key(500))); |
|
|
|
ExternalSstFileInfo file6_info; |
|
|
|
ExternalSstFileInfo file6_info; |
|
|
|
s = sst_file_writer.Finish(&file6_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&file6_info)); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(file6_info.file_path, file6); |
|
|
|
ASSERT_EQ(file6_info.file_path, file6); |
|
|
|
ASSERT_EQ(file6_info.num_entries, 0); |
|
|
|
ASSERT_EQ(file6_info.num_entries, 0); |
|
|
|
ASSERT_EQ(file6_info.smallest_key, ""); |
|
|
|
ASSERT_EQ(file6_info.smallest_key, ""); |
|
|
@ -404,17 +396,16 @@ TEST_F(ExternalSSTFileTest, Basic) { |
|
|
|
// file7.sst (delete 500 => 570, put 520 => 599 divisible by 2)
|
|
|
|
// file7.sst (delete 500 => 570, put 520 => 599 divisible by 2)
|
|
|
|
std::string file7 = sst_files_dir_ + "file7.sst"; |
|
|
|
std::string file7 = sst_files_dir_ + "file7.sst"; |
|
|
|
ASSERT_OK(sst_file_writer.Open(file7)); |
|
|
|
ASSERT_OK(sst_file_writer.Open(file7)); |
|
|
|
sst_file_writer.DeleteRange(Key(500), Key(550)); |
|
|
|
ASSERT_OK(sst_file_writer.DeleteRange(Key(500), Key(550))); |
|
|
|
for (int k = 520; k < 560; k += 2) { |
|
|
|
for (int k = 520; k < 560; k += 2) { |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
} |
|
|
|
} |
|
|
|
sst_file_writer.DeleteRange(Key(525), Key(575)); |
|
|
|
ASSERT_OK(sst_file_writer.DeleteRange(Key(525), Key(575))); |
|
|
|
for (int k = 560; k < 600; k += 2) { |
|
|
|
for (int k = 560; k < 600; k += 2) { |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
} |
|
|
|
} |
|
|
|
ExternalSstFileInfo file7_info; |
|
|
|
ExternalSstFileInfo file7_info; |
|
|
|
s = sst_file_writer.Finish(&file7_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&file7_info)); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(file7_info.file_path, file7); |
|
|
|
ASSERT_EQ(file7_info.file_path, file7); |
|
|
|
ASSERT_EQ(file7_info.num_entries, 40); |
|
|
|
ASSERT_EQ(file7_info.num_entries, 40); |
|
|
|
ASSERT_EQ(file7_info.smallest_key, Key(520)); |
|
|
|
ASSERT_EQ(file7_info.smallest_key, Key(520)); |
|
|
@ -426,10 +417,9 @@ TEST_F(ExternalSSTFileTest, Basic) { |
|
|
|
// file8.sst (delete 600 => 700)
|
|
|
|
// file8.sst (delete 600 => 700)
|
|
|
|
std::string file8 = sst_files_dir_ + "file8.sst"; |
|
|
|
std::string file8 = sst_files_dir_ + "file8.sst"; |
|
|
|
ASSERT_OK(sst_file_writer.Open(file8)); |
|
|
|
ASSERT_OK(sst_file_writer.Open(file8)); |
|
|
|
sst_file_writer.DeleteRange(Key(600), Key(700)); |
|
|
|
ASSERT_OK(sst_file_writer.DeleteRange(Key(600), Key(700))); |
|
|
|
ExternalSstFileInfo file8_info; |
|
|
|
ExternalSstFileInfo file8_info; |
|
|
|
s = sst_file_writer.Finish(&file8_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&file8_info)); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(file8_info.file_path, file8); |
|
|
|
ASSERT_EQ(file8_info.file_path, file8); |
|
|
|
ASSERT_EQ(file8_info.num_entries, 0); |
|
|
|
ASSERT_EQ(file8_info.num_entries, 0); |
|
|
|
ASSERT_EQ(file8_info.smallest_key, ""); |
|
|
|
ASSERT_EQ(file8_info.smallest_key, ""); |
|
|
@ -441,13 +431,11 @@ TEST_F(ExternalSSTFileTest, Basic) { |
|
|
|
// Cannot create an empty sst file
|
|
|
|
// Cannot create an empty sst file
|
|
|
|
std::string file_empty = sst_files_dir_ + "file_empty.sst"; |
|
|
|
std::string file_empty = sst_files_dir_ + "file_empty.sst"; |
|
|
|
ExternalSstFileInfo file_empty_info; |
|
|
|
ExternalSstFileInfo file_empty_info; |
|
|
|
s = sst_file_writer.Finish(&file_empty_info); |
|
|
|
ASSERT_NOK(sst_file_writer.Finish(&file_empty_info)); |
|
|
|
ASSERT_NOK(s); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DestroyAndReopen(options); |
|
|
|
DestroyAndReopen(options); |
|
|
|
// Add file using file path
|
|
|
|
// Add file using file path
|
|
|
|
s = DeprecatedAddFile({file1}); |
|
|
|
ASSERT_OK(DeprecatedAddFile({file1})); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(db_->GetLatestSequenceNumber(), 0U); |
|
|
|
ASSERT_EQ(db_->GetLatestSequenceNumber(), 0U); |
|
|
|
for (int k = 0; k < 100; k++) { |
|
|
|
for (int k = 0; k < 100; k++) { |
|
|
|
ASSERT_EQ(Get(Key(k)), Key(k) + "_val"); |
|
|
|
ASSERT_EQ(Get(Key(k)), Key(k) + "_val"); |
|
|
@ -468,12 +456,10 @@ TEST_F(ExternalSSTFileTest, Basic) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// This file has overlapping values with the existing data
|
|
|
|
// This file has overlapping values with the existing data
|
|
|
|
s = DeprecatedAddFile({file3}); |
|
|
|
ASSERT_NOK(DeprecatedAddFile({file3})); |
|
|
|
ASSERT_FALSE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This file has overlapping values with the existing data
|
|
|
|
// This file has overlapping values with the existing data
|
|
|
|
s = DeprecatedAddFile({file4}); |
|
|
|
ASSERT_NOK(DeprecatedAddFile({file4})); |
|
|
|
ASSERT_FALSE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Overwrite values of keys divisible by 5
|
|
|
|
// Overwrite values of keys divisible by 5
|
|
|
|
for (int k = 0; k < 200; k += 5) { |
|
|
|
for (int k = 0; k < 200; k += 5) { |
|
|
@ -485,8 +471,7 @@ TEST_F(ExternalSSTFileTest, Basic) { |
|
|
|
ASSERT_OK(DeprecatedAddFile({file5})); |
|
|
|
ASSERT_OK(DeprecatedAddFile({file5})); |
|
|
|
|
|
|
|
|
|
|
|
// This file has overlapping values with the existing data
|
|
|
|
// This file has overlapping values with the existing data
|
|
|
|
s = DeprecatedAddFile({file6}); |
|
|
|
ASSERT_NOK(DeprecatedAddFile({file6})); |
|
|
|
ASSERT_FALSE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Key range of file7 (500 => 598) don't overlap with any keys in DB
|
|
|
|
// Key range of file7 (500 => 598) don't overlap with any keys in DB
|
|
|
|
ASSERT_OK(DeprecatedAddFile({file7})); |
|
|
|
ASSERT_OK(DeprecatedAddFile({file7})); |
|
|
@ -614,15 +599,13 @@ TEST_F(ExternalSSTFileTest, AddList) { |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
} |
|
|
|
} |
|
|
|
ExternalSstFileInfo file1_info; |
|
|
|
ExternalSstFileInfo file1_info; |
|
|
|
Status s = sst_file_writer.Finish(&file1_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&file1_info)); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(file1_info.file_path, file1); |
|
|
|
ASSERT_EQ(file1_info.file_path, file1); |
|
|
|
ASSERT_EQ(file1_info.num_entries, 100); |
|
|
|
ASSERT_EQ(file1_info.num_entries, 100); |
|
|
|
ASSERT_EQ(file1_info.smallest_key, Key(0)); |
|
|
|
ASSERT_EQ(file1_info.smallest_key, Key(0)); |
|
|
|
ASSERT_EQ(file1_info.largest_key, Key(99)); |
|
|
|
ASSERT_EQ(file1_info.largest_key, Key(99)); |
|
|
|
// sst_file_writer already finished, cannot add this value
|
|
|
|
// sst_file_writer already finished, cannot add this value
|
|
|
|
s = sst_file_writer.Put(Key(100), "bad_val"); |
|
|
|
ASSERT_NOK(sst_file_writer.Put(Key(100), "bad_val")); |
|
|
|
ASSERT_FALSE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// file2.sst (100 => 199)
|
|
|
|
// file2.sst (100 => 199)
|
|
|
|
std::string file2 = sst_files_dir_ + "file2.sst"; |
|
|
|
std::string file2 = sst_files_dir_ + "file2.sst"; |
|
|
@ -631,11 +614,9 @@ TEST_F(ExternalSSTFileTest, AddList) { |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
} |
|
|
|
} |
|
|
|
// Cannot add this key because it's not after last added key
|
|
|
|
// Cannot add this key because it's not after last added key
|
|
|
|
s = sst_file_writer.Put(Key(99), "bad_val"); |
|
|
|
ASSERT_NOK(sst_file_writer.Put(Key(99), "bad_val")); |
|
|
|
ASSERT_FALSE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ExternalSstFileInfo file2_info; |
|
|
|
ExternalSstFileInfo file2_info; |
|
|
|
s = sst_file_writer.Finish(&file2_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&file2_info)); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(file2_info.file_path, file2); |
|
|
|
ASSERT_EQ(file2_info.file_path, file2); |
|
|
|
ASSERT_EQ(file2_info.num_entries, 100); |
|
|
|
ASSERT_EQ(file2_info.num_entries, 100); |
|
|
|
ASSERT_EQ(file2_info.smallest_key, Key(100)); |
|
|
|
ASSERT_EQ(file2_info.smallest_key, Key(100)); |
|
|
@ -649,8 +630,7 @@ TEST_F(ExternalSSTFileTest, AddList) { |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val_overlap")); |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val_overlap")); |
|
|
|
} |
|
|
|
} |
|
|
|
ExternalSstFileInfo file3_info; |
|
|
|
ExternalSstFileInfo file3_info; |
|
|
|
s = sst_file_writer.Finish(&file3_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&file3_info)); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(file3_info.file_path, file3); |
|
|
|
ASSERT_EQ(file3_info.file_path, file3); |
|
|
|
ASSERT_EQ(file3_info.num_entries, 5); |
|
|
|
ASSERT_EQ(file3_info.num_entries, 5); |
|
|
|
ASSERT_EQ(file3_info.smallest_key, Key(195)); |
|
|
|
ASSERT_EQ(file3_info.smallest_key, Key(195)); |
|
|
@ -664,8 +644,7 @@ TEST_F(ExternalSSTFileTest, AddList) { |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val_overlap")); |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val_overlap")); |
|
|
|
} |
|
|
|
} |
|
|
|
ExternalSstFileInfo file4_info; |
|
|
|
ExternalSstFileInfo file4_info; |
|
|
|
s = sst_file_writer.Finish(&file4_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&file4_info)); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(file4_info.file_path, file4); |
|
|
|
ASSERT_EQ(file4_info.file_path, file4); |
|
|
|
ASSERT_EQ(file4_info.num_entries, 10); |
|
|
|
ASSERT_EQ(file4_info.num_entries, 10); |
|
|
|
ASSERT_EQ(file4_info.smallest_key, Key(30)); |
|
|
|
ASSERT_EQ(file4_info.smallest_key, Key(30)); |
|
|
@ -678,8 +657,7 @@ TEST_F(ExternalSSTFileTest, AddList) { |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
} |
|
|
|
} |
|
|
|
ExternalSstFileInfo file5_info; |
|
|
|
ExternalSstFileInfo file5_info; |
|
|
|
s = sst_file_writer.Finish(&file5_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&file5_info)); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(file5_info.file_path, file5); |
|
|
|
ASSERT_EQ(file5_info.file_path, file5); |
|
|
|
ASSERT_EQ(file5_info.num_entries, 100); |
|
|
|
ASSERT_EQ(file5_info.num_entries, 100); |
|
|
|
ASSERT_EQ(file5_info.smallest_key, Key(200)); |
|
|
|
ASSERT_EQ(file5_info.smallest_key, Key(200)); |
|
|
@ -691,8 +669,7 @@ TEST_F(ExternalSSTFileTest, AddList) { |
|
|
|
ASSERT_OK(sst_file_writer.DeleteRange(Key(0), Key(75))); |
|
|
|
ASSERT_OK(sst_file_writer.DeleteRange(Key(0), Key(75))); |
|
|
|
ASSERT_OK(sst_file_writer.DeleteRange(Key(25), Key(100))); |
|
|
|
ASSERT_OK(sst_file_writer.DeleteRange(Key(25), Key(100))); |
|
|
|
ExternalSstFileInfo file6_info; |
|
|
|
ExternalSstFileInfo file6_info; |
|
|
|
s = sst_file_writer.Finish(&file6_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&file6_info)); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(file6_info.file_path, file6); |
|
|
|
ASSERT_EQ(file6_info.file_path, file6); |
|
|
|
ASSERT_EQ(file6_info.num_entries, 0); |
|
|
|
ASSERT_EQ(file6_info.num_entries, 0); |
|
|
|
ASSERT_EQ(file6_info.smallest_key, ""); |
|
|
|
ASSERT_EQ(file6_info.smallest_key, ""); |
|
|
@ -706,8 +683,7 @@ TEST_F(ExternalSSTFileTest, AddList) { |
|
|
|
ASSERT_OK(sst_file_writer.Open(file7)); |
|
|
|
ASSERT_OK(sst_file_writer.Open(file7)); |
|
|
|
ASSERT_OK(sst_file_writer.DeleteRange(Key(99), Key(201))); |
|
|
|
ASSERT_OK(sst_file_writer.DeleteRange(Key(99), Key(201))); |
|
|
|
ExternalSstFileInfo file7_info; |
|
|
|
ExternalSstFileInfo file7_info; |
|
|
|
s = sst_file_writer.Finish(&file7_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&file7_info)); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(file7_info.file_path, file7); |
|
|
|
ASSERT_EQ(file7_info.file_path, file7); |
|
|
|
ASSERT_EQ(file7_info.num_entries, 0); |
|
|
|
ASSERT_EQ(file7_info.num_entries, 0); |
|
|
|
ASSERT_EQ(file7_info.smallest_key, ""); |
|
|
|
ASSERT_EQ(file7_info.smallest_key, ""); |
|
|
@ -727,17 +703,13 @@ TEST_F(ExternalSSTFileTest, AddList) { |
|
|
|
DestroyAndReopen(options); |
|
|
|
DestroyAndReopen(options); |
|
|
|
|
|
|
|
|
|
|
|
// These lists of files have key ranges that overlap with each other
|
|
|
|
// These lists of files have key ranges that overlap with each other
|
|
|
|
s = DeprecatedAddFile(file_list1); |
|
|
|
ASSERT_NOK(DeprecatedAddFile(file_list1)); |
|
|
|
ASSERT_FALSE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
// Both of the following overlap on the range deletion tombstone.
|
|
|
|
// Both of the following overlap on the range deletion tombstone.
|
|
|
|
s = DeprecatedAddFile(file_list4); |
|
|
|
ASSERT_NOK(DeprecatedAddFile(file_list4)); |
|
|
|
ASSERT_FALSE(s.ok()) << s.ToString(); |
|
|
|
ASSERT_NOK(DeprecatedAddFile(file_list5)); |
|
|
|
s = DeprecatedAddFile(file_list5); |
|
|
|
|
|
|
|
ASSERT_FALSE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Add files using file path list
|
|
|
|
// Add files using file path list
|
|
|
|
s = DeprecatedAddFile(file_list0); |
|
|
|
ASSERT_OK(DeprecatedAddFile(file_list0)); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(db_->GetLatestSequenceNumber(), 0U); |
|
|
|
ASSERT_EQ(db_->GetLatestSequenceNumber(), 0U); |
|
|
|
for (int k = 0; k < 200; k++) { |
|
|
|
for (int k = 0; k < 200; k++) { |
|
|
|
ASSERT_EQ(Get(Key(k)), Key(k) + "_val"); |
|
|
|
ASSERT_EQ(Get(Key(k)), Key(k) + "_val"); |
|
|
@ -778,8 +750,7 @@ TEST_F(ExternalSSTFileTest, AddList) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// This file list has overlapping values with the existing data
|
|
|
|
// This file list has overlapping values with the existing data
|
|
|
|
s = DeprecatedAddFile(file_list3); |
|
|
|
ASSERT_NOK(DeprecatedAddFile(file_list3)); |
|
|
|
ASSERT_FALSE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Overwrite values of keys divisible by 5
|
|
|
|
// Overwrite values of keys divisible by 5
|
|
|
|
for (int k = 0; k < 200; k += 5) { |
|
|
|
for (int k = 0; k < 200; k += 5) { |
|
|
@ -847,16 +818,14 @@ TEST_F(ExternalSSTFileTest, AddListAtomicity) { |
|
|
|
for (int k = i * 100; k < (i + 1) * 100; k++) { |
|
|
|
for (int k = i * 100; k < (i + 1) * 100; k++) { |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
} |
|
|
|
} |
|
|
|
Status s = sst_file_writer.Finish(&files_info[i]); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&files_info[i])); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(files_info[i].file_path, files[i]); |
|
|
|
ASSERT_EQ(files_info[i].file_path, files[i]); |
|
|
|
ASSERT_EQ(files_info[i].num_entries, 100); |
|
|
|
ASSERT_EQ(files_info[i].num_entries, 100); |
|
|
|
ASSERT_EQ(files_info[i].smallest_key, Key(i * 100)); |
|
|
|
ASSERT_EQ(files_info[i].smallest_key, Key(i * 100)); |
|
|
|
ASSERT_EQ(files_info[i].largest_key, Key((i + 1) * 100 - 1)); |
|
|
|
ASSERT_EQ(files_info[i].largest_key, Key((i + 1) * 100 - 1)); |
|
|
|
} |
|
|
|
} |
|
|
|
files.push_back(sst_files_dir_ + "file" + std::to_string(n) + ".sst"); |
|
|
|
files.push_back(sst_files_dir_ + "file" + std::to_string(n) + ".sst"); |
|
|
|
auto s = DeprecatedAddFile(files); |
|
|
|
ASSERT_NOK(DeprecatedAddFile(files)); |
|
|
|
ASSERT_NOK(s) << s.ToString(); |
|
|
|
|
|
|
|
for (int k = 0; k < n * 100; k++) { |
|
|
|
for (int k = 0; k < n * 100; k++) { |
|
|
|
ASSERT_EQ("NOT_FOUND", Get(Key(k))); |
|
|
|
ASSERT_EQ("NOT_FOUND", Get(Key(k))); |
|
|
|
} |
|
|
|
} |
|
|
@ -878,17 +847,14 @@ TEST_F(ExternalSSTFileTest, PurgeObsoleteFilesBug) { |
|
|
|
|
|
|
|
|
|
|
|
// file1.sst (0 => 500)
|
|
|
|
// file1.sst (0 => 500)
|
|
|
|
std::string sst_file_path = sst_files_dir_ + "file1.sst"; |
|
|
|
std::string sst_file_path = sst_files_dir_ + "file1.sst"; |
|
|
|
Status s = sst_file_writer.Open(sst_file_path); |
|
|
|
ASSERT_OK(sst_file_writer.Open(sst_file_path)); |
|
|
|
ASSERT_OK(s); |
|
|
|
|
|
|
|
for (int i = 0; i < 500; i++) { |
|
|
|
for (int i = 0; i < 500; i++) { |
|
|
|
std::string k = Key(i); |
|
|
|
std::string k = Key(i); |
|
|
|
s = sst_file_writer.Put(k, k + "_val"); |
|
|
|
ASSERT_OK(sst_file_writer.Put(k, k + "_val")); |
|
|
|
ASSERT_OK(s); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ExternalSstFileInfo sst_file_info; |
|
|
|
ExternalSstFileInfo sst_file_info; |
|
|
|
s = sst_file_writer.Finish(&sst_file_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&sst_file_info)); |
|
|
|
ASSERT_OK(s); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
options.delete_obsolete_files_period_micros = 0; |
|
|
|
options.delete_obsolete_files_period_micros = 0; |
|
|
|
options.disable_auto_compactions = true; |
|
|
|
options.disable_auto_compactions = true; |
|
|
@ -900,12 +866,11 @@ TEST_F(ExternalSSTFileTest, PurgeObsoleteFilesBug) { |
|
|
|
ASSERT_OK(Flush()); |
|
|
|
ASSERT_OK(Flush()); |
|
|
|
ASSERT_OK(Put("aaa", "xxx")); |
|
|
|
ASSERT_OK(Put("aaa", "xxx")); |
|
|
|
ASSERT_OK(Flush()); |
|
|
|
ASSERT_OK(Flush()); |
|
|
|
db_->CompactRange(CompactRangeOptions(), nullptr, nullptr); |
|
|
|
ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr)); |
|
|
|
}); |
|
|
|
}); |
|
|
|
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing(); |
|
|
|
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing(); |
|
|
|
|
|
|
|
|
|
|
|
s = DeprecatedAddFile({sst_file_path}); |
|
|
|
ASSERT_OK(DeprecatedAddFile({sst_file_path})); |
|
|
|
ASSERT_OK(s); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 500; i++) { |
|
|
|
for (int i = 0; i < 500; i++) { |
|
|
|
std::string k = Key(i); |
|
|
|
std::string k = Key(i); |
|
|
@ -928,8 +893,7 @@ TEST_F(ExternalSSTFileTest, SkipSnapshot) { |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
} |
|
|
|
} |
|
|
|
ExternalSstFileInfo file1_info; |
|
|
|
ExternalSstFileInfo file1_info; |
|
|
|
Status s = sst_file_writer.Finish(&file1_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&file1_info)); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(file1_info.file_path, file1); |
|
|
|
ASSERT_EQ(file1_info.file_path, file1); |
|
|
|
ASSERT_EQ(file1_info.num_entries, 100); |
|
|
|
ASSERT_EQ(file1_info.num_entries, 100); |
|
|
|
ASSERT_EQ(file1_info.smallest_key, Key(0)); |
|
|
|
ASSERT_EQ(file1_info.smallest_key, Key(0)); |
|
|
@ -942,8 +906,7 @@ TEST_F(ExternalSSTFileTest, SkipSnapshot) { |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
} |
|
|
|
} |
|
|
|
ExternalSstFileInfo file2_info; |
|
|
|
ExternalSstFileInfo file2_info; |
|
|
|
s = sst_file_writer.Finish(&file2_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&file2_info)); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(file2_info.file_path, file2); |
|
|
|
ASSERT_EQ(file2_info.file_path, file2); |
|
|
|
ASSERT_EQ(file2_info.num_entries, 200); |
|
|
|
ASSERT_EQ(file2_info.num_entries, 200); |
|
|
|
ASSERT_EQ(file2_info.smallest_key, Key(100)); |
|
|
|
ASSERT_EQ(file2_info.smallest_key, Key(100)); |
|
|
@ -972,8 +935,7 @@ TEST_F(ExternalSSTFileTest, SkipSnapshot) { |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val")); |
|
|
|
} |
|
|
|
} |
|
|
|
ExternalSstFileInfo file3_info; |
|
|
|
ExternalSstFileInfo file3_info; |
|
|
|
s = sst_file_writer.Finish(&file3_info); |
|
|
|
ASSERT_OK(sst_file_writer.Finish(&file3_info)); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
ASSERT_EQ(file3_info.file_path, file3); |
|
|
|
ASSERT_EQ(file3_info.file_path, file3); |
|
|
|
ASSERT_EQ(file3_info.num_entries, 100); |
|
|
|
ASSERT_EQ(file3_info.num_entries, 100); |
|
|
|
ASSERT_EQ(file3_info.smallest_key, Key(300)); |
|
|
|
ASSERT_EQ(file3_info.smallest_key, Key(300)); |
|
|
@ -1019,8 +981,7 @@ TEST_F(ExternalSSTFileTest, MultiThreaded) { |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k))); |
|
|
|
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k))); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Status s = sst_file_writer.Finish(); |
|
|
|
ASSERT_OK(sst_file_writer.Finish()); |
|
|
|
ASSERT_TRUE(s.ok()) << s.ToString(); |
|
|
|
|
|
|
|
}; |
|
|
|
}; |
|
|
|
// Write num_files files in parallel
|
|
|
|
// Write num_files files in parallel
|
|
|
|
std::vector<port::Thread> sst_writer_threads; |
|
|
|
std::vector<port::Thread> sst_writer_threads; |
|
|
@ -1082,8 +1043,7 @@ TEST_F(ExternalSSTFileTest, MultiThreaded) { |
|
|
|
// Overwrite values of keys divisible by 100
|
|
|
|
// Overwrite values of keys divisible by 100
|
|
|
|
for (int k = 0; k < num_files * keys_per_file; k += 100) { |
|
|
|
for (int k = 0; k < num_files * keys_per_file; k += 100) { |
|
|
|
std::string key = Key(k); |
|
|
|
std::string key = Key(k); |
|
|
|
Status s = Put(key, key + "_new"); |
|
|
|
ASSERT_OK(Put(key, key + "_new")); |
|
|
|
ASSERT_TRUE(s.ok()); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 2; i++) { |
|
|
|
for (int i = 0; i < 2; i++) { |
|
|
@ -1167,7 +1127,8 @@ TEST_F(ExternalSSTFileTest, OverlappingRanges) { |
|
|
|
|
|
|
|
|
|
|
|
// Generate the file containing the range
|
|
|
|
// Generate the file containing the range
|
|
|
|
std::string file_name = sst_files_dir_ + env_->GenerateUniqueId(); |
|
|
|
std::string file_name = sst_files_dir_ + env_->GenerateUniqueId(); |
|
|
|
ASSERT_OK(sst_file_writer.Open(file_name)); |
|
|
|
s = sst_file_writer.Open(file_name); |
|
|
|
|
|
|
|
ASSERT_OK(s); |
|
|
|
for (int k = range_start; k <= range_end; k++) { |
|
|
|
for (int k = range_start; k <= range_end; k++) { |
|
|
|
s = sst_file_writer.Put(Key(k), range_val); |
|
|
|
s = sst_file_writer.Put(Key(k), range_val); |
|
|
|
ASSERT_OK(s); |
|
|
|
ASSERT_OK(s); |
|
|
@ -1212,10 +1173,10 @@ TEST_F(ExternalSSTFileTest, OverlappingRanges) { |
|
|
|
|
|
|
|
|
|
|
|
// Flush / Compact the DB
|
|
|
|
// Flush / Compact the DB
|
|
|
|
if (i && i % 50 == 0) { |
|
|
|
if (i && i % 50 == 0) { |
|
|
|
Flush(); |
|
|
|
ASSERT_OK(Flush()); |
|
|
|
} |
|
|
|
} |
|
|
|
if (i && i % 75 == 0) { |
|
|
|
if (i && i % 75 == 0) { |
|
|
|
db_->CompactRange(CompactRangeOptions(), nullptr, nullptr); |
|
|
|
ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1293,7 +1254,7 @@ TEST_P(ExternalSSTFileTest, PickedLevel) { |
|
|
|
// Hold compaction from finishing
|
|
|
|
// Hold compaction from finishing
|
|
|
|
TEST_SYNC_POINT("ExternalSSTFileTest::PickedLevel:2"); |
|
|
|
TEST_SYNC_POINT("ExternalSSTFileTest::PickedLevel:2"); |
|
|
|
|
|
|
|
|
|
|
|
dbfull()->TEST_WaitForCompact(); |
|
|
|
ASSERT_OK(dbfull()->TEST_WaitForCompact()); |
|
|
|
EXPECT_EQ(FilesPerLevel(), "1,1,1,2"); |
|
|
|
EXPECT_EQ(FilesPerLevel(), "1,1,1,2"); |
|
|
|
|
|
|
|
|
|
|
|
size_t kcnt = 0; |
|
|
|
size_t kcnt = 0; |
|
|
@ -1380,7 +1341,7 @@ TEST_F(ExternalSSTFileTest, PickedLevelBug) { |
|
|
|
ASSERT_OK(bg_addfile_status); |
|
|
|
ASSERT_OK(bg_addfile_status); |
|
|
|
ASSERT_OK(bg_compact_status); |
|
|
|
ASSERT_OK(bg_compact_status); |
|
|
|
|
|
|
|
|
|
|
|
dbfull()->TEST_WaitForCompact(); |
|
|
|
ASSERT_OK(dbfull()->TEST_WaitForCompact()); |
|
|
|
|
|
|
|
|
|
|
|
int total_keys = 0; |
|
|
|
int total_keys = 0; |
|
|
|
Iterator* iter = db_->NewIterator(ReadOptions()); |
|
|
|
Iterator* iter = db_->NewIterator(ReadOptions()); |
|
|
@ -1417,7 +1378,7 @@ TEST_F(ExternalSSTFileTest, IngestNonExistingFile) { |
|
|
|
|
|
|
|
|
|
|
|
// After full compaction, there should be only 1 file.
|
|
|
|
// After full compaction, there should be only 1 file.
|
|
|
|
std::vector<std::string> files; |
|
|
|
std::vector<std::string> files; |
|
|
|
env_->GetChildren(dbname_, &files); |
|
|
|
ASSERT_OK(env_->GetChildren(dbname_, &files)); |
|
|
|
int num_sst_files = 0; |
|
|
|
int num_sst_files = 0; |
|
|
|
for (auto& f : files) { |
|
|
|
for (auto& f : files) { |
|
|
|
uint64_t number; |
|
|
|
uint64_t number; |
|
|
@ -1539,7 +1500,7 @@ TEST_F(ExternalSSTFileTest, PickedLevelDynamic) { |
|
|
|
TEST_SYNC_POINT("ExternalSSTFileTest::PickedLevelDynamic:2"); |
|
|
|
TEST_SYNC_POINT("ExternalSSTFileTest::PickedLevelDynamic:2"); |
|
|
|
|
|
|
|
|
|
|
|
// Output of the compaction will go to L3
|
|
|
|
// Output of the compaction will go to L3
|
|
|
|
dbfull()->TEST_WaitForCompact(); |
|
|
|
ASSERT_OK(dbfull()->TEST_WaitForCompact()); |
|
|
|
EXPECT_EQ(FilesPerLevel(), "1,0,0,2"); |
|
|
|
EXPECT_EQ(FilesPerLevel(), "1,0,0,2"); |
|
|
|
|
|
|
|
|
|
|
|
Close(); |
|
|
|
Close(); |
|
|
@ -1681,7 +1642,7 @@ TEST_F(ExternalSSTFileTest, AddFileTrivialMoveBug) { |
|
|
|
cro.exclusive_manual_compaction = false; |
|
|
|
cro.exclusive_manual_compaction = false; |
|
|
|
ASSERT_OK(db_->CompactRange(cro, nullptr, nullptr)); |
|
|
|
ASSERT_OK(db_->CompactRange(cro, nullptr, nullptr)); |
|
|
|
|
|
|
|
|
|
|
|
dbfull()->TEST_WaitForCompact(); |
|
|
|
ASSERT_OK(dbfull()->TEST_WaitForCompact()); |
|
|
|
|
|
|
|
|
|
|
|
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing(); |
|
|
|
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing(); |
|
|
|
} |
|
|
|
} |
|
|
@ -1733,9 +1694,9 @@ TEST_F(ExternalSSTFileTest, WithUnorderedWrite) { |
|
|
|
Options options = CurrentOptions(); |
|
|
|
Options options = CurrentOptions(); |
|
|
|
options.unordered_write = true; |
|
|
|
options.unordered_write = true; |
|
|
|
DestroyAndReopen(options); |
|
|
|
DestroyAndReopen(options); |
|
|
|
Put("foo", "v1"); |
|
|
|
ASSERT_OK(Put("foo", "v1")); |
|
|
|
SyncPoint::GetInstance()->EnableProcessing(); |
|
|
|
SyncPoint::GetInstance()->EnableProcessing(); |
|
|
|
port::Thread writer([&]() { Put("bar", "v2"); }); |
|
|
|
port::Thread writer([&]() { ASSERT_OK(Put("bar", "v2")); }); |
|
|
|
|
|
|
|
|
|
|
|
TEST_SYNC_POINT("ExternalSSTFileTest::WithUnorderedWrite:WaitWriteWAL"); |
|
|
|
TEST_SYNC_POINT("ExternalSSTFileTest::WithUnorderedWrite:WaitWriteWAL"); |
|
|
|
ASSERT_OK(GenerateAndAddExternalFile(options, {{"bar", "v3"}}, -1, |
|
|
|
ASSERT_OK(GenerateAndAddExternalFile(options, {{"bar", "v3"}}, -1, |
|
|
@ -1784,7 +1745,7 @@ TEST_P(ExternalSSTFileTest, IngestFileWithGlobalSeqnoRandomized) { |
|
|
|
} |
|
|
|
} |
|
|
|
size_t kcnt = 0; |
|
|
|
size_t kcnt = 0; |
|
|
|
VerifyDBFromMap(true_data, &kcnt, false); |
|
|
|
VerifyDBFromMap(true_data, &kcnt, false); |
|
|
|
db_->CompactRange(CompactRangeOptions(), nullptr, nullptr); |
|
|
|
ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr)); |
|
|
|
VerifyDBFromMap(true_data, &kcnt, false); |
|
|
|
VerifyDBFromMap(true_data, &kcnt, false); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -1868,8 +1829,8 @@ TEST_P(ExternalSSTFileTest, IngestFileWithGlobalSeqnoMemtableFlush) { |
|
|
|
ASSERT_OK(Put(Key(k), "memtable")); |
|
|
|
ASSERT_OK(Put(Key(k), "memtable")); |
|
|
|
true_data[Key(k)] = "memtable"; |
|
|
|
true_data[Key(k)] = "memtable"; |
|
|
|
} |
|
|
|
} |
|
|
|
db_->GetIntProperty(DB::Properties::kNumEntriesActiveMemTable, |
|
|
|
ASSERT_TRUE(db_->GetIntProperty(DB::Properties::kNumEntriesActiveMemTable, |
|
|
|
&entries_in_memtable); |
|
|
|
&entries_in_memtable)); |
|
|
|
ASSERT_GE(entries_in_memtable, 1); |
|
|
|
ASSERT_GE(entries_in_memtable, 1); |
|
|
|
|
|
|
|
|
|
|
|
bool write_global_seqno = std::get<0>(GetParam()); |
|
|
|
bool write_global_seqno = std::get<0>(GetParam()); |
|
|
@ -1878,40 +1839,40 @@ TEST_P(ExternalSSTFileTest, IngestFileWithGlobalSeqnoMemtableFlush) { |
|
|
|
ASSERT_OK(GenerateAndAddExternalFile( |
|
|
|
ASSERT_OK(GenerateAndAddExternalFile( |
|
|
|
options, {90, 100, 110}, -1, true, write_global_seqno, |
|
|
|
options, {90, 100, 110}, -1, true, write_global_seqno, |
|
|
|
verify_checksums_before_ingest, false, false, &true_data)); |
|
|
|
verify_checksums_before_ingest, false, false, &true_data)); |
|
|
|
db_->GetIntProperty(DB::Properties::kNumEntriesActiveMemTable, |
|
|
|
ASSERT_TRUE(db_->GetIntProperty(DB::Properties::kNumEntriesActiveMemTable, |
|
|
|
&entries_in_memtable); |
|
|
|
&entries_in_memtable)); |
|
|
|
ASSERT_GE(entries_in_memtable, 1); |
|
|
|
ASSERT_GE(entries_in_memtable, 1); |
|
|
|
|
|
|
|
|
|
|
|
// This file will flush the memtable
|
|
|
|
// This file will flush the memtable
|
|
|
|
ASSERT_OK(GenerateAndAddExternalFile( |
|
|
|
ASSERT_OK(GenerateAndAddExternalFile( |
|
|
|
options, {19, 20, 21}, -1, true, write_global_seqno, |
|
|
|
options, {19, 20, 21}, -1, true, write_global_seqno, |
|
|
|
verify_checksums_before_ingest, false, false, &true_data)); |
|
|
|
verify_checksums_before_ingest, false, false, &true_data)); |
|
|
|
db_->GetIntProperty(DB::Properties::kNumEntriesActiveMemTable, |
|
|
|
ASSERT_TRUE(db_->GetIntProperty(DB::Properties::kNumEntriesActiveMemTable, |
|
|
|
&entries_in_memtable); |
|
|
|
&entries_in_memtable)); |
|
|
|
ASSERT_EQ(entries_in_memtable, 0); |
|
|
|
ASSERT_EQ(entries_in_memtable, 0); |
|
|
|
|
|
|
|
|
|
|
|
for (int k : {200, 201, 205, 206}) { |
|
|
|
for (int k : {200, 201, 205, 206}) { |
|
|
|
ASSERT_OK(Put(Key(k), "memtable")); |
|
|
|
ASSERT_OK(Put(Key(k), "memtable")); |
|
|
|
true_data[Key(k)] = "memtable"; |
|
|
|
true_data[Key(k)] = "memtable"; |
|
|
|
} |
|
|
|
} |
|
|
|
db_->GetIntProperty(DB::Properties::kNumEntriesActiveMemTable, |
|
|
|
ASSERT_TRUE(db_->GetIntProperty(DB::Properties::kNumEntriesActiveMemTable, |
|
|
|
&entries_in_memtable); |
|
|
|
&entries_in_memtable)); |
|
|
|
ASSERT_GE(entries_in_memtable, 1); |
|
|
|
ASSERT_GE(entries_in_memtable, 1); |
|
|
|
|
|
|
|
|
|
|
|
// No need for flush, this file keys fit between the memtable keys
|
|
|
|
// No need for flush, this file keys fit between the memtable keys
|
|
|
|
ASSERT_OK(GenerateAndAddExternalFile( |
|
|
|
ASSERT_OK(GenerateAndAddExternalFile( |
|
|
|
options, {202, 203, 204}, -1, true, write_global_seqno, |
|
|
|
options, {202, 203, 204}, -1, true, write_global_seqno, |
|
|
|
verify_checksums_before_ingest, false, false, &true_data)); |
|
|
|
verify_checksums_before_ingest, false, false, &true_data)); |
|
|
|
db_->GetIntProperty(DB::Properties::kNumEntriesActiveMemTable, |
|
|
|
ASSERT_TRUE(db_->GetIntProperty(DB::Properties::kNumEntriesActiveMemTable, |
|
|
|
&entries_in_memtable); |
|
|
|
&entries_in_memtable)); |
|
|
|
ASSERT_GE(entries_in_memtable, 1); |
|
|
|
ASSERT_GE(entries_in_memtable, 1); |
|
|
|
|
|
|
|
|
|
|
|
// This file will flush the memtable
|
|
|
|
// This file will flush the memtable
|
|
|
|
ASSERT_OK(GenerateAndAddExternalFile( |
|
|
|
ASSERT_OK(GenerateAndAddExternalFile( |
|
|
|
options, {206, 207}, -1, true, write_global_seqno, |
|
|
|
options, {206, 207}, -1, true, write_global_seqno, |
|
|
|
verify_checksums_before_ingest, false, false, &true_data)); |
|
|
|
verify_checksums_before_ingest, false, false, &true_data)); |
|
|
|
db_->GetIntProperty(DB::Properties::kNumEntriesActiveMemTable, |
|
|
|
ASSERT_TRUE(db_->GetIntProperty(DB::Properties::kNumEntriesActiveMemTable, |
|
|
|
&entries_in_memtable); |
|
|
|
&entries_in_memtable)); |
|
|
|
ASSERT_EQ(entries_in_memtable, 0); |
|
|
|
ASSERT_EQ(entries_in_memtable, 0); |
|
|
|
|
|
|
|
|
|
|
|
size_t kcnt = 0; |
|
|
|
size_t kcnt = 0; |
|
|
@ -2309,7 +2270,7 @@ TEST_P(ExternalSSTFileTest, IngestBehind) { |
|
|
|
ASSERT_OK(Put(Key(i), "memtable")); |
|
|
|
ASSERT_OK(Put(Key(i), "memtable")); |
|
|
|
true_data[Key(i)] = "memtable"; |
|
|
|
true_data[Key(i)] = "memtable"; |
|
|
|
} |
|
|
|
} |
|
|
|
db_->CompactRange(CompactRangeOptions(), nullptr, nullptr); |
|
|
|
ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr)); |
|
|
|
// Universal picker should go at second from the bottom level
|
|
|
|
// Universal picker should go at second from the bottom level
|
|
|
|
ASSERT_EQ("0,1", FilesPerLevel()); |
|
|
|
ASSERT_EQ("0,1", FilesPerLevel()); |
|
|
|
ASSERT_OK(GenerateAndAddExternalFile( |
|
|
|
ASSERT_OK(GenerateAndAddExternalFile( |
|
|
@ -2323,7 +2284,7 @@ TEST_P(ExternalSSTFileTest, IngestBehind) { |
|
|
|
verify_checksums_before_ingest, true /*ingest_behind*/, |
|
|
|
verify_checksums_before_ingest, true /*ingest_behind*/, |
|
|
|
false /*sort_data*/, &true_data)); |
|
|
|
false /*sort_data*/, &true_data)); |
|
|
|
ASSERT_EQ("0,1,1", FilesPerLevel()); |
|
|
|
ASSERT_EQ("0,1,1", FilesPerLevel()); |
|
|
|
db_->CompactRange(CompactRangeOptions(), nullptr, nullptr); |
|
|
|
ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr)); |
|
|
|
// bottom level should be empty
|
|
|
|
// bottom level should be empty
|
|
|
|
ASSERT_EQ("0,1", FilesPerLevel()); |
|
|
|
ASSERT_EQ("0,1", FilesPerLevel()); |
|
|
|
|
|
|
|
|
|
|
@ -2471,9 +2432,8 @@ TEST_P(ExternalSSTFileTest, IngestFilesIntoMultipleColumnFamilies_Success) { |
|
|
|
// Resize the true_data vector upon construction to avoid re-alloc
|
|
|
|
// Resize the true_data vector upon construction to avoid re-alloc
|
|
|
|
std::vector<std::map<std::string, std::string>> true_data( |
|
|
|
std::vector<std::map<std::string, std::string>> true_data( |
|
|
|
column_families.size()); |
|
|
|
column_families.size()); |
|
|
|
Status s = GenerateAndAddExternalFiles(options, column_families, ifos, data, |
|
|
|
ASSERT_OK(GenerateAndAddExternalFiles(options, column_families, ifos, data, |
|
|
|
-1, true, true_data); |
|
|
|
-1, true, true_data)); |
|
|
|
ASSERT_OK(s); |
|
|
|
|
|
|
|
Close(); |
|
|
|
Close(); |
|
|
|
ReopenWithColumnFamilies({kDefaultColumnFamilyName, "pikachu", "eevee"}, |
|
|
|
ReopenWithColumnFamilies({kDefaultColumnFamilyName, "pikachu", "eevee"}, |
|
|
|
options); |
|
|
|
options); |
|
|
@ -2654,9 +2614,8 @@ TEST_P(ExternalSSTFileTest, IngestFilesIntoMultipleColumnFamilies_PrepareFail) { |
|
|
|
std::vector<std::map<std::string, std::string>> true_data( |
|
|
|
std::vector<std::map<std::string, std::string>> true_data( |
|
|
|
column_families.size()); |
|
|
|
column_families.size()); |
|
|
|
port::Thread ingest_thread([&]() { |
|
|
|
port::Thread ingest_thread([&]() { |
|
|
|
Status s = GenerateAndAddExternalFiles(options, column_families, ifos, data, |
|
|
|
ASSERT_NOK(GenerateAndAddExternalFiles(options, column_families, ifos, data, |
|
|
|
-1, true, true_data); |
|
|
|
-1, true, true_data)); |
|
|
|
ASSERT_NOK(s); |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
TEST_SYNC_POINT( |
|
|
|
TEST_SYNC_POINT( |
|
|
|
"ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_PrepareFail:" |
|
|
|
"ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_PrepareFail:" |
|
|
@ -2724,9 +2683,8 @@ TEST_P(ExternalSSTFileTest, IngestFilesIntoMultipleColumnFamilies_CommitFail) { |
|
|
|
std::vector<std::map<std::string, std::string>> true_data( |
|
|
|
std::vector<std::map<std::string, std::string>> true_data( |
|
|
|
column_families.size()); |
|
|
|
column_families.size()); |
|
|
|
port::Thread ingest_thread([&]() { |
|
|
|
port::Thread ingest_thread([&]() { |
|
|
|
Status s = GenerateAndAddExternalFiles(options, column_families, ifos, data, |
|
|
|
ASSERT_NOK(GenerateAndAddExternalFiles(options, column_families, ifos, data, |
|
|
|
-1, true, true_data); |
|
|
|
-1, true, true_data)); |
|
|
|
ASSERT_NOK(s); |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
TEST_SYNC_POINT( |
|
|
|
TEST_SYNC_POINT( |
|
|
|
"ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_CommitFail:" |
|
|
|
"ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_CommitFail:" |
|
|
@ -2799,9 +2757,8 @@ TEST_P(ExternalSSTFileTest, |
|
|
|
std::vector<std::map<std::string, std::string>> true_data( |
|
|
|
std::vector<std::map<std::string, std::string>> true_data( |
|
|
|
column_families.size()); |
|
|
|
column_families.size()); |
|
|
|
port::Thread ingest_thread([&]() { |
|
|
|
port::Thread ingest_thread([&]() { |
|
|
|
Status s = GenerateAndAddExternalFiles(options, column_families, ifos, data, |
|
|
|
ASSERT_NOK(GenerateAndAddExternalFiles(options, column_families, ifos, data, |
|
|
|
-1, true, true_data); |
|
|
|
-1, true, true_data)); |
|
|
|
ASSERT_NOK(s); |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
TEST_SYNC_POINT( |
|
|
|
TEST_SYNC_POINT( |
|
|
|
"ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_" |
|
|
|
"ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_" |
|
|
@ -2812,7 +2769,7 @@ TEST_P(ExternalSSTFileTest, |
|
|
|
"PartialManifestWriteFail:1"); |
|
|
|
"PartialManifestWriteFail:1"); |
|
|
|
ingest_thread.join(); |
|
|
|
ingest_thread.join(); |
|
|
|
|
|
|
|
|
|
|
|
fault_injection_env->DropUnsyncedFileData(); |
|
|
|
ASSERT_OK(fault_injection_env->DropUnsyncedFileData()); |
|
|
|
fault_injection_env->SetFilesystemActive(true); |
|
|
|
fault_injection_env->SetFilesystemActive(true); |
|
|
|
Close(); |
|
|
|
Close(); |
|
|
|
ReopenWithColumnFamilies({kDefaultColumnFamilyName, "pikachu", "eevee"}, |
|
|
|
ReopenWithColumnFamilies({kDefaultColumnFamilyName, "pikachu", "eevee"}, |
|
|
@ -2847,7 +2804,7 @@ TEST_P(ExternalSSTFileTest, IngestFilesTriggerFlushingWithTwoWriteQueue) { |
|
|
|
// sure that it won't enter the 2nd writer queue for the second time.
|
|
|
|
// sure that it won't enter the 2nd writer queue for the second time.
|
|
|
|
std::vector<std::pair<std::string, std::string>> data; |
|
|
|
std::vector<std::pair<std::string, std::string>> data; |
|
|
|
data.push_back(std::make_pair("1001", "v2")); |
|
|
|
data.push_back(std::make_pair("1001", "v2")); |
|
|
|
GenerateAndAddExternalFile(options, data); |
|
|
|
ASSERT_OK(GenerateAndAddExternalFile(options, data, -1, true)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
TEST_P(ExternalSSTFileTest, DeltaEncodingWhileGlobalSeqnoPresent) { |
|
|
|
TEST_P(ExternalSSTFileTest, DeltaEncodingWhileGlobalSeqnoPresent) { |
|
|
|