const Options& options, bool* expect_bloom_not_match)
: PlainTableReader(options, std::move(file), storage_options, icomparator,
file_size, bloom_bits_per_key, hash_table_ratio,
- index_sparseness, table_properties),
+ index_sparseness, table_properties, 2 * 1024 * 1024),
expect_bloom_not_match_(expect_bloom_not_match) {
Status s = PopulateIndex(const_cast<TableProperties*>(table_properties));
ASSERT_TRUE(s.ok());
class TestPlainTableFactory : public PlainTableFactory {
public:
explicit TestPlainTableFactory(bool* expect_bloom_not_match,
- uint32_t user_key_len =
- kPlainTableVariableLength,
- int bloom_bits_per_key = 0,
- double hash_table_ratio = 0.75,
- size_t index_sparseness = 16)
+ uint32_t user_key_len, int bloom_bits_per_key,
+ double hash_table_ratio,
+ size_t index_sparseness,
+ size_t huge_page_tlb_size)
: PlainTableFactory(user_key_len, user_key_len, hash_table_ratio,
- hash_table_ratio),
+ index_sparseness, huge_page_tlb_size),
bloom_bits_per_key_(bloom_bits_per_key),
hash_table_ratio_(hash_table_ratio),
index_sparseness_(index_sparseness),
};
TEST(PlainTableDBTest, Flush) {
- for (int bloom_bits = 0; bloom_bits <= 117; bloom_bits += 117) {
- for (int total_order = 0; total_order <= 1; total_order++) {
- Options options = CurrentOptions();
- options.create_if_missing = true;
- // Set only one bucket to force bucket conflict.
- // Test index interval for the same prefix to be 1, 2 and 4
- if (total_order) {
- options.table_factory.reset(
- NewTotalOrderPlainTableFactory(16, bloom_bits, 2));
- } else {
- options.table_factory.reset(NewPlainTableFactory(16, bloom_bits));
+ for (size_t huge_page_tlb_size = 0; huge_page_tlb_size <= 2 * 1024 * 1024;
+ huge_page_tlb_size += 2 * 1024 * 1024) {
+ for (int bloom_bits = 0; bloom_bits <= 117; bloom_bits += 117) {
+ for (int total_order = 0; total_order <= 1; total_order++) {
+ Options options = CurrentOptions();
+ options.create_if_missing = true;
+ // Set only one bucket to force bucket conflict.
+ // Test index interval for the same prefix to be 1, 2 and 4
+ if (total_order) {
+ options.table_factory.reset(NewTotalOrderPlainTableFactory(
+ 16, bloom_bits, 2, huge_page_tlb_size));
+ } else {
+ options.table_factory.reset(NewPlainTableFactory(
+ 16, bloom_bits, 0.75, 16, huge_page_tlb_size));
+ }
+ DestroyAndReopen(&options);
+
+ ASSERT_OK(Put("1000000000000foo", "v1"));
+ ASSERT_OK(Put("0000000000000bar", "v2"));
+ ASSERT_OK(Put("1000000000000foo", "v3"));
+ dbfull()->TEST_FlushMemTable();
+
+ TablePropertiesCollection ptc;
+ reinterpret_cast<DB*>(dbfull())->GetPropertiesOfAllTables(&ptc);
+ ASSERT_EQ(1U, ptc.size());
+ auto row = ptc.begin();
+ auto tp = row->second;
+ ASSERT_EQ(total_order ? "4" : "12", (tp->user_collected_properties).at(
+ "plain_table_hash_table_size"));
+ ASSERT_EQ(total_order ? "9" : "0", (tp->user_collected_properties).at(
+ "plain_table_sub_index_size"));
+
+ ASSERT_EQ("v3", Get("1000000000000foo"));
+ ASSERT_EQ("v2", Get("0000000000000bar"));
}
- DestroyAndReopen(&options);
-
- ASSERT_OK(Put("1000000000000foo", "v1"));
- ASSERT_OK(Put("0000000000000bar", "v2"));
- ASSERT_OK(Put("1000000000000foo", "v3"));
- dbfull()->TEST_FlushMemTable();
-
- TablePropertiesCollection ptc;
- reinterpret_cast<DB*>(dbfull())->GetPropertiesOfAllTables(&ptc);
- ASSERT_EQ(1U, ptc.size());
- auto row = ptc.begin();
- auto tp = row->second;
- ASSERT_EQ(
- total_order ? "4" : "12",
- (tp->user_collected_properties).at("plain_table_hash_table_size"));
- ASSERT_EQ(
- total_order ? "9" : "0",
- (tp->user_collected_properties).at("plain_table_sub_index_size"));
-
- ASSERT_EQ("v3", Get("1000000000000foo"));
- ASSERT_EQ("v2", Get("0000000000000bar"));
}
}
}
TEST(PlainTableDBTest, Flush2) {
- for (int bloom_bits = 0; bloom_bits <= 117; bloom_bits += 117) {
- for (int total_order = 0; total_order <= 1; total_order++) {
- bool expect_bloom_not_match = false;
- Options options = CurrentOptions();
- options.create_if_missing = true;
- // Set only one bucket to force bucket conflict.
- // Test index interval for the same prefix to be 1, 2 and 4
- if (total_order) {
- options.prefix_extractor = nullptr;
- options.table_factory.reset(new TestPlainTableFactory(
- &expect_bloom_not_match, 16, bloom_bits, 0, 2));
- } else {
- options.table_factory.reset(
- new TestPlainTableFactory(&expect_bloom_not_match, 16, bloom_bits));
- }
- DestroyAndReopen(&options);
- ASSERT_OK(Put("0000000000000bar", "b"));
- ASSERT_OK(Put("1000000000000foo", "v1"));
- dbfull()->TEST_FlushMemTable();
-
- ASSERT_OK(Put("1000000000000foo", "v2"));
- dbfull()->TEST_FlushMemTable();
- ASSERT_EQ("v2", Get("1000000000000foo"));
-
- ASSERT_OK(Put("0000000000000eee", "v3"));
- dbfull()->TEST_FlushMemTable();
- ASSERT_EQ("v3", Get("0000000000000eee"));
-
- ASSERT_OK(Delete("0000000000000bar"));
- dbfull()->TEST_FlushMemTable();
- ASSERT_EQ("NOT_FOUND", Get("0000000000000bar"));
-
- ASSERT_OK(Put("0000000000000eee", "v5"));
- ASSERT_OK(Put("9000000000000eee", "v5"));
- dbfull()->TEST_FlushMemTable();
- ASSERT_EQ("v5", Get("0000000000000eee"));
-
- // Test Bloom Filter
- if (bloom_bits > 0) {
- // Neither key nor value should exist.
- expect_bloom_not_match = true;
- ASSERT_EQ("NOT_FOUND", Get("5_not00000000bar"));
-
- // Key doesn't exist any more but prefix exists.
+ for (size_t huge_page_tlb_size = 0; huge_page_tlb_size <= 2 * 1024 * 1024;
+ huge_page_tlb_size += 2 * 1024 * 1024) {
+ for (int bloom_bits = 0; bloom_bits <= 117; bloom_bits += 117) {
+ for (int total_order = 0; total_order <= 1; total_order++) {
+ bool expect_bloom_not_match = false;
+ Options options = CurrentOptions();
+ options.create_if_missing = true;
+ // Set only one bucket to force bucket conflict.
+ // Test index interval for the same prefix to be 1, 2 and 4
if (total_order) {
- ASSERT_EQ("NOT_FOUND", Get("1000000000000not"));
- ASSERT_EQ("NOT_FOUND", Get("0000000000000not"));
+ options.prefix_extractor = nullptr;
+ options.table_factory.reset(
+ new TestPlainTableFactory(&expect_bloom_not_match, 16, bloom_bits,
+ 0, 2, huge_page_tlb_size));
+ } else {
+ options.table_factory.reset(
+ new TestPlainTableFactory(&expect_bloom_not_match, 16, bloom_bits,
+ 0.75, 16, huge_page_tlb_size));
+ }
+ DestroyAndReopen(&options);
+ ASSERT_OK(Put("0000000000000bar", "b"));
+ ASSERT_OK(Put("1000000000000foo", "v1"));
+ dbfull()->TEST_FlushMemTable();
+
+ ASSERT_OK(Put("1000000000000foo", "v2"));
+ dbfull()->TEST_FlushMemTable();
+ ASSERT_EQ("v2", Get("1000000000000foo"));
+
+ ASSERT_OK(Put("0000000000000eee", "v3"));
+ dbfull()->TEST_FlushMemTable();
+ ASSERT_EQ("v3", Get("0000000000000eee"));
+
+ ASSERT_OK(Delete("0000000000000bar"));
+ dbfull()->TEST_FlushMemTable();
+ ASSERT_EQ("NOT_FOUND", Get("0000000000000bar"));
+
+ ASSERT_OK(Put("0000000000000eee", "v5"));
+ ASSERT_OK(Put("9000000000000eee", "v5"));
+ dbfull()->TEST_FlushMemTable();
+ ASSERT_EQ("v5", Get("0000000000000eee"));
+
+ // Test Bloom Filter
+ if (bloom_bits > 0) {
+ // Neither key nor value should exist.
+ expect_bloom_not_match = true;
+ ASSERT_EQ("NOT_FOUND", Get("5_not00000000bar"));
+
+ // Key doesn't exist any more but prefix exists.
+ if (total_order) {
+ ASSERT_EQ("NOT_FOUND", Get("1000000000000not"));
+ ASSERT_EQ("NOT_FOUND", Get("0000000000000not"));
+ }
+ expect_bloom_not_match = false;
}
- expect_bloom_not_match = false;
}
}
}
}
TEST(PlainTableDBTest, Iterator) {
- for (int bloom_bits = 0; bloom_bits <= 117; bloom_bits += 117) {
- for (int total_order = 0; total_order <= 1; total_order++) {
- bool expect_bloom_not_match = false;
- Options options = CurrentOptions();
- options.create_if_missing = true;
- // Set only one bucket to force bucket conflict.
- // Test index interval for the same prefix to be 1, 2 and 4
- if (total_order) {
- options.prefix_extractor = nullptr;
- options.table_factory.reset(new TestPlainTableFactory(
- &expect_bloom_not_match, 16, bloom_bits, 0, 2));
- } else {
- options.table_factory.reset(
- new TestPlainTableFactory(&expect_bloom_not_match, 16, bloom_bits));
- }
- DestroyAndReopen(&options);
-
- ASSERT_OK(Put("1000000000foo002", "v_2"));
- ASSERT_OK(Put("0000000000000bar", "random"));
- ASSERT_OK(Put("1000000000foo001", "v1"));
- ASSERT_OK(Put("3000000000000bar", "bar_v"));
- ASSERT_OK(Put("1000000000foo003", "v__3"));
- ASSERT_OK(Put("1000000000foo004", "v__4"));
- ASSERT_OK(Put("1000000000foo005", "v__5"));
- ASSERT_OK(Put("1000000000foo007", "v__7"));
- ASSERT_OK(Put("1000000000foo008", "v__8"));
- dbfull()->TEST_FlushMemTable();
- ASSERT_EQ("v1", Get("1000000000foo001"));
- ASSERT_EQ("v__3", Get("1000000000foo003"));
- Iterator* iter = dbfull()->NewIterator(ReadOptions());
- iter->Seek("1000000000foo000");
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("1000000000foo001", iter->key().ToString());
- ASSERT_EQ("v1", iter->value().ToString());
-
- iter->Next();
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("1000000000foo002", iter->key().ToString());
- ASSERT_EQ("v_2", iter->value().ToString());
+ for (size_t huge_page_tlb_size = 0; huge_page_tlb_size <= 2 * 1024 * 1024;
+ huge_page_tlb_size += 2 * 1024 * 1024) {
+ for (int bloom_bits = 0; bloom_bits <= 117; bloom_bits += 117) {
+ for (int total_order = 0; total_order <= 1; total_order++) {
+ bool expect_bloom_not_match = false;
+ Options options = CurrentOptions();
+ options.create_if_missing = true;
+ // Set only one bucket to force bucket conflict.
+ // Test index interval for the same prefix to be 1, 2 and 4
+ if (total_order) {
+ options.prefix_extractor = nullptr;
+ options.table_factory.reset(
+ new TestPlainTableFactory(&expect_bloom_not_match, 16, bloom_bits,
+ 0, 2, huge_page_tlb_size));
+ } else {
+ options.table_factory.reset(
+ new TestPlainTableFactory(&expect_bloom_not_match, 16, bloom_bits,
+ 0.75, 16, huge_page_tlb_size));
+ }
+ DestroyAndReopen(&options);
+
+ ASSERT_OK(Put("1000000000foo002", "v_2"));
+ ASSERT_OK(Put("0000000000000bar", "random"));
+ ASSERT_OK(Put("1000000000foo001", "v1"));
+ ASSERT_OK(Put("3000000000000bar", "bar_v"));
+ ASSERT_OK(Put("1000000000foo003", "v__3"));
+ ASSERT_OK(Put("1000000000foo004", "v__4"));
+ ASSERT_OK(Put("1000000000foo005", "v__5"));
+ ASSERT_OK(Put("1000000000foo007", "v__7"));
+ ASSERT_OK(Put("1000000000foo008", "v__8"));
+ dbfull()->TEST_FlushMemTable();
+ ASSERT_EQ("v1", Get("1000000000foo001"));
+ ASSERT_EQ("v__3", Get("1000000000foo003"));
+ Iterator* iter = dbfull()->NewIterator(ReadOptions());
+ iter->Seek("1000000000foo000");
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("1000000000foo001", iter->key().ToString());
+ ASSERT_EQ("v1", iter->value().ToString());
- iter->Next();
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("1000000000foo003", iter->key().ToString());
- ASSERT_EQ("v__3", iter->value().ToString());
+ iter->Next();
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("1000000000foo002", iter->key().ToString());
+ ASSERT_EQ("v_2", iter->value().ToString());
- iter->Next();
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("1000000000foo004", iter->key().ToString());
- ASSERT_EQ("v__4", iter->value().ToString());
+ iter->Next();
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("1000000000foo003", iter->key().ToString());
+ ASSERT_EQ("v__3", iter->value().ToString());
- iter->Seek("3000000000000bar");
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("3000000000000bar", iter->key().ToString());
- ASSERT_EQ("bar_v", iter->value().ToString());
+ iter->Next();
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("1000000000foo004", iter->key().ToString());
+ ASSERT_EQ("v__4", iter->value().ToString());
- iter->Seek("1000000000foo000");
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("1000000000foo001", iter->key().ToString());
- ASSERT_EQ("v1", iter->value().ToString());
+ iter->Seek("3000000000000bar");
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("3000000000000bar", iter->key().ToString());
+ ASSERT_EQ("bar_v", iter->value().ToString());
- iter->Seek("1000000000foo005");
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("1000000000foo005", iter->key().ToString());
- ASSERT_EQ("v__5", iter->value().ToString());
+ iter->Seek("1000000000foo000");
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("1000000000foo001", iter->key().ToString());
+ ASSERT_EQ("v1", iter->value().ToString());
- iter->Seek("1000000000foo006");
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("1000000000foo007", iter->key().ToString());
- ASSERT_EQ("v__7", iter->value().ToString());
+ iter->Seek("1000000000foo005");
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("1000000000foo005", iter->key().ToString());
+ ASSERT_EQ("v__5", iter->value().ToString());
- iter->Seek("1000000000foo008");
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("1000000000foo008", iter->key().ToString());
- ASSERT_EQ("v__8", iter->value().ToString());
+ iter->Seek("1000000000foo006");
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("1000000000foo007", iter->key().ToString());
+ ASSERT_EQ("v__7", iter->value().ToString());
- if (total_order == 0) {
- iter->Seek("1000000000foo009");
+ iter->Seek("1000000000foo008");
ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("3000000000000bar", iter->key().ToString());
- }
+ ASSERT_EQ("1000000000foo008", iter->key().ToString());
+ ASSERT_EQ("v__8", iter->value().ToString());
- // Test Bloom Filter
- if (bloom_bits > 0) {
- if (!total_order) {
- // Neither key nor value should exist.
- expect_bloom_not_match = true;
- iter->Seek("2not000000000bar");
- ASSERT_TRUE(!iter->Valid());
- ASSERT_EQ("NOT_FOUND", Get("2not000000000bar"));
- expect_bloom_not_match = false;
- } else {
- expect_bloom_not_match = true;
- ASSERT_EQ("NOT_FOUND", Get("2not000000000bar"));
- expect_bloom_not_match = false;
+ if (total_order == 0) {
+ iter->Seek("1000000000foo009");
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("3000000000000bar", iter->key().ToString());
}
- }
- delete iter;
+ // Test Bloom Filter
+ if (bloom_bits > 0) {
+ if (!total_order) {
+ // Neither key nor value should exist.
+ expect_bloom_not_match = true;
+ iter->Seek("2not000000000bar");
+ ASSERT_TRUE(!iter->Valid());
+ ASSERT_EQ("NOT_FOUND", Get("2not000000000bar"));
+ expect_bloom_not_match = false;
+ } else {
+ expect_bloom_not_match = true;
+ ASSERT_EQ("NOT_FOUND", Get("2not000000000bar"));
+ expect_bloom_not_match = false;
+ }
+ }
+
+ delete iter;
+ }
}
}
}
}
TEST(PlainTableDBTest, HashBucketConflict) {
- for (unsigned char i = 1; i <= 3; i++) {
- Options options = CurrentOptions();
- options.create_if_missing = true;
- // Set only one bucket to force bucket conflict.
- // Test index interval for the same prefix to be 1, 2 and 4
- options.table_factory.reset(NewTotalOrderPlainTableFactory(16, 0, 2 ^ i));
- DestroyAndReopen(&options);
- ASSERT_OK(Put("5000000000000fo0", "v1"));
- ASSERT_OK(Put("5000000000000fo1", "v2"));
- ASSERT_OK(Put("5000000000000fo2", "v"));
- ASSERT_OK(Put("2000000000000fo0", "v3"));
- ASSERT_OK(Put("2000000000000fo1", "v4"));
- ASSERT_OK(Put("2000000000000fo2", "v"));
- ASSERT_OK(Put("2000000000000fo3", "v"));
-
- dbfull()->TEST_FlushMemTable();
-
- ASSERT_EQ("v1", Get("5000000000000fo0"));
- ASSERT_EQ("v2", Get("5000000000000fo1"));
- ASSERT_EQ("v3", Get("2000000000000fo0"));
- ASSERT_EQ("v4", Get("2000000000000fo1"));
-
- ASSERT_EQ("NOT_FOUND", Get("5000000000000bar"));
- ASSERT_EQ("NOT_FOUND", Get("2000000000000bar"));
- ASSERT_EQ("NOT_FOUND", Get("5000000000000fo8"));
- ASSERT_EQ("NOT_FOUND", Get("2000000000000fo8"));
-
- ReadOptions ro;
- Iterator* iter = dbfull()->NewIterator(ro);
-
- iter->Seek("5000000000000fo0");
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("5000000000000fo0", iter->key().ToString());
- iter->Next();
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("5000000000000fo1", iter->key().ToString());
+ for (size_t huge_page_tlb_size = 0; huge_page_tlb_size <= 2 * 1024 * 1024;
+ huge_page_tlb_size += 2 * 1024 * 1024) {
+ for (unsigned char i = 1; i <= 3; i++) {
+ Options options = CurrentOptions();
+ options.create_if_missing = true;
+ // Set only one bucket to force bucket conflict.
+ // Test index interval for the same prefix to be 1, 2 and 4
+ options.table_factory.reset(
+ NewTotalOrderPlainTableFactory(16, 0, 2 ^ i, huge_page_tlb_size));
+ DestroyAndReopen(&options);
+ ASSERT_OK(Put("5000000000000fo0", "v1"));
+ ASSERT_OK(Put("5000000000000fo1", "v2"));
+ ASSERT_OK(Put("5000000000000fo2", "v"));
+ ASSERT_OK(Put("2000000000000fo0", "v3"));
+ ASSERT_OK(Put("2000000000000fo1", "v4"));
+ ASSERT_OK(Put("2000000000000fo2", "v"));
+ ASSERT_OK(Put("2000000000000fo3", "v"));
- iter->Seek("5000000000000fo1");
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("5000000000000fo1", iter->key().ToString());
+ dbfull()->TEST_FlushMemTable();
- iter->Seek("2000000000000fo0");
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("2000000000000fo0", iter->key().ToString());
- iter->Next();
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("2000000000000fo1", iter->key().ToString());
+ ASSERT_EQ("v1", Get("5000000000000fo0"));
+ ASSERT_EQ("v2", Get("5000000000000fo1"));
+ ASSERT_EQ("v3", Get("2000000000000fo0"));
+ ASSERT_EQ("v4", Get("2000000000000fo1"));
- iter->Seek("2000000000000fo1");
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("2000000000000fo1", iter->key().ToString());
+ ASSERT_EQ("NOT_FOUND", Get("5000000000000bar"));
+ ASSERT_EQ("NOT_FOUND", Get("2000000000000bar"));
+ ASSERT_EQ("NOT_FOUND", Get("5000000000000fo8"));
+ ASSERT_EQ("NOT_FOUND", Get("2000000000000fo8"));
- iter->Seek("2000000000000bar");
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("2000000000000fo0", iter->key().ToString());
+ ReadOptions ro;
+ Iterator* iter = dbfull()->NewIterator(ro);
- iter->Seek("5000000000000bar");
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("5000000000000fo0", iter->key().ToString());
+ iter->Seek("5000000000000fo0");
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("5000000000000fo0", iter->key().ToString());
+ iter->Next();
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("5000000000000fo1", iter->key().ToString());
+
+ iter->Seek("5000000000000fo1");
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("5000000000000fo1", iter->key().ToString());
- iter->Seek("2000000000000fo8");
- ASSERT_TRUE(!iter->Valid() ||
- options.comparator->Compare(iter->key(), "20000001") > 0);
+ iter->Seek("2000000000000fo0");
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("2000000000000fo0", iter->key().ToString());
+ iter->Next();
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("2000000000000fo1", iter->key().ToString());
+
+ iter->Seek("2000000000000fo1");
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("2000000000000fo1", iter->key().ToString());
+
+ iter->Seek("2000000000000bar");
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("2000000000000fo0", iter->key().ToString());
+
+ iter->Seek("5000000000000bar");
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("5000000000000fo0", iter->key().ToString());
- iter->Seek("5000000000000fo8");
- ASSERT_TRUE(!iter->Valid());
+ iter->Seek("2000000000000fo8");
+ ASSERT_TRUE(!iter->Valid() ||
+ options.comparator->Compare(iter->key(), "20000001") > 0);
- iter->Seek("1000000000000fo2");
- ASSERT_TRUE(!iter->Valid());
+ iter->Seek("5000000000000fo8");
+ ASSERT_TRUE(!iter->Valid());
- iter->Seek("3000000000000fo2");
- ASSERT_TRUE(!iter->Valid());
+ iter->Seek("1000000000000fo2");
+ ASSERT_TRUE(!iter->Valid());
- iter->Seek("8000000000000fo2");
- ASSERT_TRUE(!iter->Valid());
+ iter->Seek("3000000000000fo2");
+ ASSERT_TRUE(!iter->Valid());
- delete iter;
+ iter->Seek("8000000000000fo2");
+ ASSERT_TRUE(!iter->Valid());
+
+ delete iter;
+ }
}
}
TEST(PlainTableDBTest, HashBucketConflictReverseSuffixComparator) {
- for (unsigned char i = 1; i <= 3; i++) {
- Options options = CurrentOptions();
- options.create_if_missing = true;
- SimpleSuffixReverseComparator comp;
- options.comparator = ∁
- // Set only one bucket to force bucket conflict.
- // Test index interval for the same prefix to be 1, 2 and 4
- options.table_factory.reset(NewTotalOrderPlainTableFactory(16, 0, 2 ^ i));
- DestroyAndReopen(&options);
- ASSERT_OK(Put("5000000000000fo0", "v1"));
- ASSERT_OK(Put("5000000000000fo1", "v2"));
- ASSERT_OK(Put("5000000000000fo2", "v"));
- ASSERT_OK(Put("2000000000000fo0", "v3"));
- ASSERT_OK(Put("2000000000000fo1", "v4"));
- ASSERT_OK(Put("2000000000000fo2", "v"));
- ASSERT_OK(Put("2000000000000fo3", "v"));
-
- dbfull()->TEST_FlushMemTable();
-
- ASSERT_EQ("v1", Get("5000000000000fo0"));
- ASSERT_EQ("v2", Get("5000000000000fo1"));
- ASSERT_EQ("v3", Get("2000000000000fo0"));
- ASSERT_EQ("v4", Get("2000000000000fo1"));
-
- ASSERT_EQ("NOT_FOUND", Get("5000000000000bar"));
- ASSERT_EQ("NOT_FOUND", Get("2000000000000bar"));
- ASSERT_EQ("NOT_FOUND", Get("5000000000000fo8"));
- ASSERT_EQ("NOT_FOUND", Get("2000000000000fo8"));
-
- ReadOptions ro;
- Iterator* iter = dbfull()->NewIterator(ro);
-
- iter->Seek("5000000000000fo1");
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("5000000000000fo1", iter->key().ToString());
- iter->Next();
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("5000000000000fo0", iter->key().ToString());
+ for (size_t huge_page_tlb_size = 0; huge_page_tlb_size <= 2 * 1024 * 1024;
+ huge_page_tlb_size += 2 * 1024 * 1024) {
+ for (unsigned char i = 1; i <= 3; i++) {
+ Options options = CurrentOptions();
+ options.create_if_missing = true;
+ SimpleSuffixReverseComparator comp;
+ options.comparator = ∁
+ // Set only one bucket to force bucket conflict.
+ // Test index interval for the same prefix to be 1, 2 and 4
+ options.table_factory.reset(
+ NewTotalOrderPlainTableFactory(16, 0, 2 ^ i, huge_page_tlb_size));
+ DestroyAndReopen(&options);
+ ASSERT_OK(Put("5000000000000fo0", "v1"));
+ ASSERT_OK(Put("5000000000000fo1", "v2"));
+ ASSERT_OK(Put("5000000000000fo2", "v"));
+ ASSERT_OK(Put("2000000000000fo0", "v3"));
+ ASSERT_OK(Put("2000000000000fo1", "v4"));
+ ASSERT_OK(Put("2000000000000fo2", "v"));
+ ASSERT_OK(Put("2000000000000fo3", "v"));
- iter->Seek("5000000000000fo1");
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("5000000000000fo1", iter->key().ToString());
+ dbfull()->TEST_FlushMemTable();
- iter->Seek("2000000000000fo1");
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("2000000000000fo1", iter->key().ToString());
- iter->Next();
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("2000000000000fo0", iter->key().ToString());
+ ASSERT_EQ("v1", Get("5000000000000fo0"));
+ ASSERT_EQ("v2", Get("5000000000000fo1"));
+ ASSERT_EQ("v3", Get("2000000000000fo0"));
+ ASSERT_EQ("v4", Get("2000000000000fo1"));
- iter->Seek("2000000000000fo1");
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("2000000000000fo1", iter->key().ToString());
+ ASSERT_EQ("NOT_FOUND", Get("5000000000000bar"));
+ ASSERT_EQ("NOT_FOUND", Get("2000000000000bar"));
+ ASSERT_EQ("NOT_FOUND", Get("5000000000000fo8"));
+ ASSERT_EQ("NOT_FOUND", Get("2000000000000fo8"));
- iter->Seek("2000000000000var");
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("2000000000000fo3", iter->key().ToString());
+ ReadOptions ro;
+ Iterator* iter = dbfull()->NewIterator(ro);
- iter->Seek("5000000000000var");
- ASSERT_TRUE(iter->Valid());
- ASSERT_EQ("5000000000000fo2", iter->key().ToString());
+ iter->Seek("5000000000000fo1");
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("5000000000000fo1", iter->key().ToString());
+ iter->Next();
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("5000000000000fo0", iter->key().ToString());
+
+ iter->Seek("5000000000000fo1");
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("5000000000000fo1", iter->key().ToString());
+
+ iter->Seek("2000000000000fo1");
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("2000000000000fo1", iter->key().ToString());
+ iter->Next();
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("2000000000000fo0", iter->key().ToString());
- std::string seek_key = "2000000000000bar";
- iter->Seek(seek_key);
- ASSERT_TRUE(!iter->Valid() ||
- options.prefix_extractor->Transform(iter->key()) !=
- options.prefix_extractor->Transform(seek_key));
+ iter->Seek("2000000000000fo1");
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("2000000000000fo1", iter->key().ToString());
- iter->Seek("1000000000000fo2");
- ASSERT_TRUE(!iter->Valid());
+ iter->Seek("2000000000000var");
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("2000000000000fo3", iter->key().ToString());
+
+ iter->Seek("5000000000000var");
+ ASSERT_TRUE(iter->Valid());
+ ASSERT_EQ("5000000000000fo2", iter->key().ToString());
- iter->Seek("3000000000000fo2");
- ASSERT_TRUE(!iter->Valid());
+ std::string seek_key = "2000000000000bar";
+ iter->Seek(seek_key);
+ ASSERT_TRUE(!iter->Valid() ||
+ options.prefix_extractor->Transform(iter->key()) !=
+ options.prefix_extractor->Transform(seek_key));
- iter->Seek("8000000000000fo2");
- ASSERT_TRUE(!iter->Valid());
+ iter->Seek("1000000000000fo2");
+ ASSERT_TRUE(!iter->Valid());
- delete iter;
+ iter->Seek("3000000000000fo2");
+ ASSERT_TRUE(!iter->Valid());
+
+ iter->Seek("8000000000000fo2");
+ ASSERT_TRUE(!iter->Valid());
+
+ delete iter;
+ }
}
}