61 for (int64_t count = 0; count < numKeys; count++) {
62 int64_t keyValue = keyOffset + count;
65 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
67 dup.emplace_back(
data);
70 testData.emplace_back(pair);
75 std::vector<std::string> dbNames, int64_t numKeys, int64_t numValues,
LMDBStore& store, int64_t keyOffset = 0)
80 for (
auto& name : dbNames) {
143 const std::string name =
"Test Database";
144 store->open_database(name);
152 EXPECT_NO_THROW(store->put(putDatas));
154 EXPECT_NO_THROW(store->close_database(name));
159 toWrite = { { {
key, {
data } } } };
160 putData = { toWrite, toDelete, name };
161 putDatas = { putData };
162 EXPECT_THROW(store->put(putDatas), std::runtime_error);
168 const std::string name =
"Test Database";
169 store->open_database(name);
170 const std::string nameDups =
"Test Database Dups";
171 store->open_database(nameDups,
true);
181 EXPECT_NO_THROW(store->put(putDatas));
183 putDatas = { putDataDups };
184 EXPECT_NO_THROW(store->put(putDatas));
190 const std::string name =
"Test Database";
191 store->open_database(name);
192 const std::string nameDups =
"Test Database Dups";
193 store->open_database(nameDups,
true);
202 EXPECT_NO_THROW(store->put(putDatas));
205 putDatas = { putDataDups };
206 EXPECT_NO_THROW(store->put(putDatas));
209 EXPECT_NO_THROW(store->put(putDatas));
210 EXPECT_NO_THROW(store->put(putDatas));
258 const std::vector<std::string> dbNames = {
"Test Database 1",
"Test Database 2" };
259 for (
const auto& s : dbNames) {
260 EXPECT_NO_THROW(store->open_database(s));
264 int64_t numKeys = 10;
265 int64_t numValues = 1;
272 for (int64_t count = 0; count < numKeys; count++) {
281 store->get(keys, retrieved, dbNames[0]);
282 EXPECT_EQ(retrieved.size(), numKeys);
283 EXPECT_EQ(retrieved, values);
287 store->get(keys, retrieved, dbNames[1]);
288 EXPECT_EQ(retrieved.size(), numKeys);
289 EXPECT_EQ(retrieved, values);
298 const std::vector<std::string> dbNames = {
"Test Database No Dups",
"Test Database Dups" };
299 store->open_database(dbNames[0],
false);
300 store->open_database(dbNames[1],
true);
306 int64_t numValues = 2;
314 for (int64_t count = 0; count < numKeys; count++) {
317 auto expectedNoDup =
get_value(count, numValues - 1);
320 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
321 auto expectedWithDup =
get_value(count, dupCount);
322 dup.emplace_back(expectedWithDup);
324 valuesWithDups.emplace_back(dup);
325 valuesWithoutDups.emplace_back(
ValuesVector{ expectedNoDup });
330 store->get(keys, retrieved, dbNames[0]);
331 EXPECT_EQ(retrieved.size(), numKeys);
332 EXPECT_EQ(retrieved, valuesWithoutDups);
336 store->get(keys, retrieved, dbNames[1]);
337 EXPECT_EQ(retrieved.size(), numKeys);
338 EXPECT_EQ(retrieved, valuesWithDups);
373 const std::string dbName =
"Test Database";
374 store->open_database(dbName);
378 int64_t numKeys = 10;
379 int64_t numValues = 1;
387 for (int64_t count = numKeys; count < numKeys + 2; count++) {
392 toWrite.emplace_back(pair);
394 for (int64_t count = 3; count < numKeys - 2; count++) {
398 toDelete.emplace_back(pair);
402 store->put(putDatas);
408 for (int64_t count = 0; count < numKeys + 2; count++) {
418 store->get(keys, retrieved, dbName);
419 EXPECT_EQ(retrieved.size(), numKeys + 2);
420 EXPECT_EQ(retrieved, values);
429 const std::string dbName =
"Test Database";
430 store->open_database(dbName,
true);
434 int64_t numKeys = 10;
435 int64_t numValues = 5;
443 for (int64_t count = numKeys; count < numKeys + 2; count++) {
446 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
448 dup.emplace_back(
data);
451 toWrite.emplace_back(pair);
455 for (int64_t count = 3; count < numKeys - 2; count++) {
459 for (int64_t dupCount = 1; dupCount < numValues - 1; dupCount++) {
461 dup.emplace_back(
data);
464 toDelete.emplace_back(pair);
468 store->put(putDatas);
474 for (int64_t count = 0; count < numKeys + 2; count++) {
477 int64_t deletedDupStart = (count < 3 || count >= (numKeys - 2)) ? numValues : 1;
478 int64_t deletedDupEnd = (count < 3 || count >= (numKeys - 2)) ? 0 : numValues - 1;
481 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
482 if (dupCount >= deletedDupStart && dupCount < deletedDupEnd) {
486 dup.emplace_back(
data);
493 store->get(keys, retrieved, dbName);
494 EXPECT_EQ(retrieved.size(), numKeys + 2);
495 EXPECT_EQ(retrieved, expectedValues);
504 const std::vector<std::string> dbNames = {
"Test Database No Dups",
"Test Database Dups" };
505 store->open_database(dbNames[0],
false);
506 store->open_database(dbNames[1],
true);
510 int64_t numKeys = 10;
511 int64_t numValues = 5;
517 for (int64_t count = 3; count < numKeys - 2; count++) {
520 toDelete.emplace_back(pair);
525 store->put(putDatas);
531 for (int64_t count = 0; count < numKeys; count++) {
532 if (count >= 3 && count < numKeys - 2) {
538 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
540 dup.emplace_back(
data);
543 expectedValues.emplace_back(pair);
546 LMDBCursor::Ptr cursor = store->create_cursor(readTransaction, dbNames[1]);
547 cursor->set_at_start();
550 cursor->read_next((uint64_t)numKeys, retrieved);
551 EXPECT_EQ(retrieved, expectedValues);
558 for (int64_t count = 0; count < numKeys; count++) {
559 if (count >= 3 && count < numKeys - 2) {
566 expectedValues.emplace_back(pair);
569 LMDBCursor::Ptr cursor = store->create_cursor(readTransaction, dbNames[0]);
570 cursor->set_at_start();
573 cursor->read_next((uint64_t)numKeys, retrieved);
574 EXPECT_EQ(retrieved, expectedValues);
582 const std::string dbName =
"Test Database";
583 store->open_database(dbName);
585 int64_t numKeys = 10;
586 int64_t numValues = 1;
592 int64_t startKey = 3;
596 bool setResult = cursor->set_at_key(
key);
597 EXPECT_TRUE(setResult);
599 int64_t numKeysToRead = 4;
601 cursor->read_next((uint64_t)numKeysToRead, keyValues);
604 for (int64_t count = startKey; count < startKey + numKeysToRead; count++) {
609 EXPECT_EQ(keyValues, expected);
617 const std::string dbName =
"Test Database";
618 store->open_database(dbName,
true);
620 int64_t numKeys = 10;
621 int64_t numValues = 5;
627 int64_t startKey = 3;
631 bool setResult = cursor->set_at_key(
key);
632 EXPECT_TRUE(setResult);
634 int64_t numKeysToRead = 4;
636 cursor->read_next((uint64_t)numKeysToRead, keyValues);
639 for (int64_t count = startKey; count < startKey + numKeysToRead; count++) {
642 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
644 dup.emplace_back(
data);
647 expected.emplace_back(pair);
649 EXPECT_EQ(keyValues, expected);
657 const std::string dbName =
"Test Database";
658 store->open_database(dbName,
true);
660 int64_t numKeys = 10;
661 int64_t numValues = 1;
667 int64_t startKey = 7;
671 bool setResult = cursor->set_at_key(
key);
672 EXPECT_TRUE(setResult);
674 int64_t numKeysToRead = 4;
676 cursor->read_prev((uint64_t)numKeysToRead, keyValues);
679 for (int64_t count = startKey; count > startKey - numKeysToRead; count--) {
684 EXPECT_EQ(keyValues, expected);
692 const std::string dbName =
"Test Database";
693 store->open_database(dbName,
true);
695 int64_t numKeys = 10;
696 int64_t numValues = 5;
702 int64_t startKey = 7;
706 bool setResult = cursor->set_at_key(
key);
707 EXPECT_TRUE(setResult);
709 int64_t numKeysToRead = 4;
711 cursor->read_prev((uint64_t)numKeysToRead, keyValues);
714 for (int64_t count = startKey; count > startKey - numKeysToRead; count--) {
717 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
719 dup.emplace_back(
data);
722 expected.emplace_back(pair);
724 EXPECT_EQ(keyValues, expected);
732 const std::string dbName =
"Test Database";
733 store->open_database(dbName,
false);
735 int64_t numKeys = 10;
736 int64_t numValues = 1;
742 int64_t startKey = 3;
746 bool setResult = cursor->set_at_key(
key);
747 EXPECT_TRUE(setResult);
749 int64_t numKeysToRead = 50;
751 cursor->read_next((uint64_t)numKeysToRead, keyValues);
754 for (int64_t count = startKey; count < numKeys; count++) {
759 EXPECT_EQ(keyValues, expected);
767 const std::string dbName =
"Test Database";
768 store->open_database(dbName,
false);
770 int64_t numKeys = 10;
771 int64_t numValues = 1;
777 int64_t startKey = 7;
781 bool setResult = cursor->set_at_key(
key);
782 EXPECT_TRUE(setResult);
784 int64_t numKeysToRead = 50;
786 cursor->read_prev((uint64_t)numKeysToRead, keyValues);
789 for (int64_t count = startKey; count >= 0; count--) {
794 EXPECT_EQ(keyValues, expected);
802 const std::string dbName =
"Test Database";
803 store->open_database(dbName,
true);
805 int64_t numKeys = 10;
806 int64_t numValues = 5;
812 int64_t startKey = 3;
816 bool setResult = cursor->set_at_key(
key);
817 EXPECT_TRUE(setResult);
819 int64_t numKeysToRead = 50;
821 cursor->read_next((uint64_t)numKeysToRead, keyValues);
824 for (int64_t count = startKey; count < numKeys; count++) {
827 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
829 dup.emplace_back(
data);
832 expected.emplace_back(pair);
834 EXPECT_EQ(keyValues, expected);
842 const std::string dbName =
"Test Database";
843 store->open_database(dbName,
true);
845 int64_t numKeys = 10;
846 int64_t numValues = 5;
852 int64_t startKey = 7;
856 bool setResult = cursor->set_at_key(
key);
857 EXPECT_TRUE(setResult);
859 int64_t numKeysToRead = 50;
861 cursor->read_prev((uint64_t)numKeysToRead, keyValues);
864 for (int64_t count = startKey; count >= 0; count--) {
867 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
869 dup.emplace_back(
data);
872 expected.emplace_back(pair);
874 EXPECT_EQ(keyValues, expected);
882 const std::string dbName =
"Test Database";
883 store->open_database(dbName,
true);
885 int64_t numKeys = 10;
886 int64_t numValues = 5;
892 int64_t startKey = 7;
896 bool setResult = cursor->set_at_key(
key);
897 EXPECT_TRUE(setResult);
899 int64_t numKeysToRead = 4;
901 bool result = cursor->read_prev((uint64_t)numKeysToRead, keyValuesReverse);
902 EXPECT_FALSE(result);
905 startKey = (startKey - numKeysToRead) + 1;
907 setResult = cursor->set_at_key(
key);
908 EXPECT_TRUE(setResult);
910 result = cursor->read_next((uint64_t)numKeysToRead, keyValues);
911 EXPECT_FALSE(result);
915 EXPECT_EQ(temp, keyValues);
923 const std::string dbName =
"Test Database";
924 store->open_database(dbName,
false);
926 int64_t numKeys = 10;
927 int64_t numValues = 1;
933 int64_t startKey = 7;
937 bool setResult = cursor->set_at_key(
key);
938 EXPECT_TRUE(setResult);
942 uint64_t numKeysRead = 0;
943 bool result = cursor->count_until_prev(
key, numKeysRead);
944 EXPECT_FALSE(result);
945 EXPECT_EQ(numKeysRead, startKey - endKey);
952 setResult = cursor->set_at_key(
key);
953 EXPECT_TRUE(setResult);
955 result = cursor->count_until_next(
key, numKeysRead);
956 EXPECT_FALSE(result);
957 EXPECT_EQ(numKeysRead, endKey - startKey);
964 setResult = cursor->set_at_key(
key);
965 EXPECT_TRUE(setResult);
967 result = cursor->count_until_next(
key, numKeysRead);
968 EXPECT_FALSE(result);
969 EXPECT_EQ(numKeysRead, 0);
975 setResult = cursor->set_at_key(
key);
976 EXPECT_TRUE(setResult);
978 result = cursor->count_until_prev(
key, numKeysRead);
979 EXPECT_FALSE(result);
980 EXPECT_EQ(numKeysRead, 0);
988 const std::string dbName =
"Test Database";
989 store->open_database(dbName,
false);
992 int64_t numValues = 1;
999 int64_t startKey = 7;
1003 bool setResult = cursor->set_at_key(
key);
1004 EXPECT_TRUE(setResult);
1008 uint64_t numKeysRead = 0;
1009 bool result = cursor->count_until_prev(
key, numKeysRead);
1010 EXPECT_FALSE(result);
1011 EXPECT_EQ(numKeysRead, 3);
1018 setResult = cursor->set_at_key(
key);
1019 EXPECT_TRUE(setResult);
1021 result = cursor->count_until_next(
key, numKeysRead);
1022 EXPECT_FALSE(result);
1023 EXPECT_EQ(numKeysRead, 3);
1031 const std::string dbName =
"Test Database";
1032 store->open_database(dbName,
false);
1034 int64_t numKeys = 7;
1035 int64_t numValues = 1;
1041 int64_t startKey = 5;
1045 bool setResult = cursor->set_at_key(
key);
1046 EXPECT_TRUE(setResult);
1050 uint64_t numKeysRead = 0;
1051 bool result = cursor->count_until_prev(
key, numKeysRead);
1052 EXPECT_TRUE(result);
1053 EXPECT_EQ(numKeysRead, 4);
1060 setResult = cursor->set_at_key(
key);
1061 EXPECT_TRUE(setResult);
1063 result = cursor->count_until_next(
key, numKeysRead);
1064 EXPECT_TRUE(result);
1065 EXPECT_EQ(numKeysRead, 6);
1072 setResult = cursor->set_at_key(
key);
1073 EXPECT_TRUE(setResult);
1075 result = cursor->count_until_next(
key, numKeysRead);
1076 EXPECT_FALSE(result);
1077 EXPECT_EQ(numKeysRead, 0);
1083 setResult = cursor->set_at_key(
key);
1084 EXPECT_TRUE(setResult);
1086 result = cursor->count_until_prev(
key, numKeysRead);
1087 EXPECT_FALSE(result);
1088 EXPECT_EQ(numKeysRead, 0);
1096 const std::string dbName =
"Test Database";
1097 store->open_database(dbName,
true);
1099 int64_t numKeys = 7;
1100 int64_t numValues = 5;
1106 int64_t startKey = 5;
1110 bool setResult = cursor->set_at_key(
key);
1111 EXPECT_TRUE(setResult);
1115 uint64_t numKeysRead = 0;
1116 bool result = cursor->count_until_prev(
key, numKeysRead);
1117 EXPECT_FALSE(result);
1118 EXPECT_EQ(numKeysRead, numValues * 2);
1125 setResult = cursor->set_at_key(
key);
1126 EXPECT_TRUE(setResult);
1128 result = cursor->count_until_next(
key, numKeysRead);
1129 EXPECT_FALSE(result);
1130 EXPECT_EQ(numKeysRead, numValues * (endKey - startKey));
1137 setResult = cursor->set_at_key(
key);
1138 EXPECT_TRUE(setResult);
1140 result = cursor->count_until_next(
key, numKeysRead);
1141 EXPECT_FALSE(result);
1142 EXPECT_EQ(numKeysRead, 0);
1148 setResult = cursor->set_at_key(
key);
1149 EXPECT_TRUE(setResult);
1151 result = cursor->count_until_prev(
key, numKeysRead);
1152 EXPECT_FALSE(result);
1153 EXPECT_EQ(numKeysRead, 0);
1161 const std::string dbName =
"Test Database";
1162 store->open_database(dbName,
true);
1164 int64_t numKeys = 7;
1165 int64_t numValues = 5;
1171 int64_t startKey = 5;
1175 bool setResult = cursor->set_at_key(
key);
1176 EXPECT_TRUE(setResult);
1180 uint64_t numKeysRead = 0;
1181 bool result = cursor->count_until_prev(
key, numKeysRead);
1182 EXPECT_TRUE(result);
1183 EXPECT_EQ(numKeysRead, numValues * 4);
1190 setResult = cursor->set_at_key(
key);
1191 EXPECT_TRUE(setResult);
1193 result = cursor->count_until_next(
key, numKeysRead);
1194 EXPECT_TRUE(result);
1195 EXPECT_EQ(numKeysRead, numValues * 6);
1201 setResult = cursor->set_at_key(
key);
1202 EXPECT_TRUE(setResult);
1204 result = cursor->count_until_next(
key, numKeysRead);
1205 EXPECT_FALSE(result);
1206 EXPECT_EQ(numKeysRead, 0);
1212 setResult = cursor->set_at_key(
key);
1213 EXPECT_TRUE(setResult);
1215 result = cursor->count_until_prev(
key, numKeysRead);
1216 EXPECT_FALSE(result);
1217 EXPECT_EQ(numKeysRead, 0);
1225 const std::string dbName =
"Test Database";
1226 store->open_database(dbName,
true);
1228 int64_t numKeys = 10;
1229 int64_t numValues = 5;
1235 int64_t startKey = 7;
1239 bool setResult = cursor->set_at_key(
key);
1240 EXPECT_TRUE(setResult);
1242 int64_t numKeysToRead = 4;
1244 cursor->read_prev((uint64_t)numKeysToRead, keyValuesReverse);
1248 startKey = (startKey - numKeysToRead) + 1;
1251 setResult = cursor2->set_at_key(
key);
1252 EXPECT_TRUE(setResult);
1255 cursor2->read_next((uint64_t)numKeysToRead, keyValues);
1258 EXPECT_EQ(temp, keyValues);
1266 const std::vector<std::string> dbNames = {
"Test Database No Dups",
"Test Database Dups" };
1267 store->open_database(dbNames[0],
false);
1268 store->open_database(dbNames[1],
true);
1270 int64_t numKeys = 5000;
1271 int64_t numValues = 10;
1272 int64_t numIterations = 20;
1275 for (int64_t i = 0; i < numIterations; i++) {
1282 for (int64_t k = 0; k < numKeys; k++) {
1283 int64_t keyToDelete = ((i - 1) * numKeys) + k;
1290 EXPECT_NO_THROW(store->put(putDatas));
1298 const std::vector<std::string> dbNames = {
"Test Database No Dups",
"Test Database Dups" };
1299 store->open_database(dbNames[0],
false);
1300 store->open_database(dbNames[1],
true);
1302 int64_t numKeys = 10;
1303 int64_t numValues = 5;
1308 auto [mapSize, physicalFileSize] = store->get_stats(stats);
1309 std::string dataDbPath = (std::filesystem::path(_directory) /
"data.mdb").
string();
1310 EXPECT_TRUE(std::filesystem::exists(dataDbPath));
1313 EXPECT_EQ(physicalFileSize, std::filesystem::file_size(dataDbPath));
1314 EXPECT_EQ(stats.size(), 2);
1315 for (
size_t i = 0; i < 2; i++) {
1316 if (stats[i].name == dbNames[0]) {
1318 EXPECT_EQ(stats[i].numDataItems, numKeys);
1319 }
else if (stats[i].name == dbNames[1]) {
1321 EXPECT_EQ(stats[i].numDataItems, numKeys * numValues);
1332 const std::string dbName =
"Test Database";
1333 store->open_database(dbName,
true);
1335 int64_t numKeys = 10;
1336 int64_t numValues = 5;
1337 int64_t numIterationsPerThread = 1000;
1338 uint64_t numThreads = 10;
1342 std::vector<std::thread> threads;
1344 auto func = [&]() ->
void {
1345 for (int64_t iteration = 0; iteration < numIterationsPerThread; iteration++) {
1346 for (int64_t count = 0; count < numKeys; count++) {
1350 cursor->set_at_key(
key);
1352 cursor->read_next(1, keyValuePairs);
1356 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
1358 dup.emplace_back(
data);
1361 expected.emplace_back(pair);
1362 EXPECT_EQ(keyValuePairs, expected);
1367 for (uint64_t count = 0; count < numThreads; count++) {
1370 for (uint64_t count = 0; count < numThreads; count++) {
1371 threads[count]->join();