@@ -299,7 +299,7 @@ TEST_F(BasicKVTest, SameKeyInsertRemoveMultiTimes) {
299
299
btree = res.value ();
300
300
});
301
301
302
- // insert 100 key-values to the btree
302
+ // insert 1000 key-values to the btree
303
303
size_t numKVs (1000 );
304
304
std::vector<std::pair<std::string, std::string>> kvToTest;
305
305
for (size_t i = 0 ; i < numKVs; ++i) {
@@ -342,4 +342,72 @@ TEST_F(BasicKVTest, SameKeyInsertRemoveMultiTimes) {
342
342
mStore ->ExecSync (0 , [&]() { EXPECT_EQ (btree->CountEntries (), numKVs); });
343
343
}
344
344
345
+ TEST_F (BasicKVTest, PrefixLookup) {
346
+ storage::btree::BasicKV* btree;
347
+ mStore ->ExecSync (0 , [&]() {
348
+ auto res = mStore ->CreateBasicKV (genBtreeName (" _tree1" ));
349
+ ASSERT_TRUE (res);
350
+ ASSERT_NE (res.value (), nullptr );
351
+ btree = res.value ();
352
+ });
353
+ // callback function
354
+ std::vector<std::tuple<std::string, std::string>> copiedKeyValue;
355
+ auto copyKeyAndValueOut = [&](Slice key, Slice val) {
356
+ copiedKeyValue.emplace_back (key.ToString (), val.ToString ());
357
+ };
358
+
359
+ {
360
+ // not found valid prefix key
361
+ std::string prefixString (" key_" );
362
+ auto prefixKey = Slice (prefixString);
363
+ EXPECT_EQ (btree->PrefixLookup (prefixKey, copyKeyAndValueOut), OpCode::kNotFound );
364
+ }
365
+
366
+ {
367
+ // insert key and value
368
+ size_t numKVs (10 );
369
+ std::vector<std::pair<std::string, std::string>> kvToTest;
370
+ for (size_t i = 0 ; i < numKVs; ++i) {
371
+ std::string key (" key_" + std::string (10 , ' x' ) + std::to_string (i));
372
+ std::string val (" val_" + std::string (100 , ' x' ) + std::to_string (i));
373
+ mStore ->ExecSync (0 , [&]() { EXPECT_EQ (btree->Insert (key, val), OpCode::kOK ); });
374
+ kvToTest.emplace_back (std::move (key), std::move (val));
375
+ }
376
+
377
+ // prefix lookup the full set
378
+ auto prefixString (" key_" + std::string (10 , ' x' ));
379
+ auto prefixKey = Slice (prefixString);
380
+ EXPECT_EQ (btree->PrefixLookup (prefixKey, copyKeyAndValueOut), OpCode::kOK );
381
+ EXPECT_EQ (copiedKeyValue.size (), kvToTest.size ());
382
+ for (size_t i = 0 ; i < copiedKeyValue.size (); i++) {
383
+ const auto & [key, expectedVal] = kvToTest[i];
384
+ const auto & [copiedKey, copiedValue] = copiedKeyValue[i];
385
+ EXPECT_EQ (copiedKey, key);
386
+ EXPECT_EQ (copiedValue, expectedVal);
387
+ }
388
+
389
+ // insert special key for prefix lookup
390
+ std::vector<std::pair<std::string, std::string>> kvToTest2;
391
+ for (size_t i = 0 ; i < numKVs; ++i) {
392
+ std::string key (" prefix_key_" + std::string (10 , ' x' ) + std::to_string (i));
393
+ std::string val (" prefix_value_" + std::string (100 , ' x' ) + std::to_string (i));
394
+ mStore ->ExecSync (0 , [&]() { EXPECT_EQ (btree->Insert (key, val), OpCode::kOK ); });
395
+ kvToTest2.emplace_back (std::move (key), std::move (val));
396
+ }
397
+
398
+ // prefix lookup the partial set
399
+ copiedKeyValue.clear ();
400
+ auto prefixString2 (" prefix_key_" + std::string (10 , ' x' ));
401
+ auto prefixKey2 = Slice (prefixString2);
402
+ EXPECT_EQ (btree->PrefixLookup (prefixKey2, copyKeyAndValueOut), OpCode::kOK );
403
+ EXPECT_EQ (copiedKeyValue.size (), kvToTest2.size ());
404
+ for (size_t i = 0 ; i < copiedKeyValue.size (); i++) {
405
+ const auto & [key, expectedVal] = kvToTest2[i];
406
+ const auto & [copiedKey, copiedValue] = copiedKeyValue[i];
407
+ EXPECT_EQ (copiedKey, key);
408
+ EXPECT_EQ (copiedValue, expectedVal);
409
+ }
410
+ }
411
+ }
412
+
345
413
} // namespace leanstore::test
0 commit comments