60 for (int64_t count = 0; count < numKeys; count++) {
61 int64_t keyValue = keyOffset + count;
64 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
66 dup.emplace_back(
data);
69 testData.emplace_back(pair);
74 std::vector<std::string> dbNames, int64_t numKeys, int64_t numValues,
LMDBStore& store, int64_t keyOffset = 0)
79 for (
auto& name : dbNames) {
142 const std::string name =
"Test Database";
143 store->open_database(name);
151 EXPECT_NO_THROW(store->put(putDatas));
153 EXPECT_NO_THROW(store->close_database(name));
158 toWrite = { { {
key, {
data } } } };
159 putData = { toWrite, toDelete, name };
160 putDatas = { putData };
161 EXPECT_THROW(store->put(putDatas), std::runtime_error);
167 const std::string name =
"Test Database";
168 store->open_database(name);
169 const std::string nameDups =
"Test Database Dups";
170 store->open_database(nameDups,
true);
180 EXPECT_NO_THROW(store->put(putDatas));
182 putDatas = { putDataDups };
183 EXPECT_NO_THROW(store->put(putDatas));
189 const std::string name =
"Test Database";
190 store->open_database(name);
191 const std::string nameDups =
"Test Database Dups";
192 store->open_database(nameDups,
true);
201 EXPECT_NO_THROW(store->put(putDatas));
204 putDatas = { putDataDups };
205 EXPECT_NO_THROW(store->put(putDatas));
208 EXPECT_NO_THROW(store->put(putDatas));
209 EXPECT_NO_THROW(store->put(putDatas));
257 const std::vector<std::string> dbNames = {
"Test Database 1",
"Test Database 2" };
258 for (
const auto& s : dbNames) {
259 EXPECT_NO_THROW(store->open_database(s));
263 int64_t numKeys = 10;
264 int64_t numValues = 1;
271 for (int64_t count = 0; count < numKeys; count++) {
280 store->get(keys, retrieved, dbNames[0]);
281 EXPECT_EQ(retrieved.size(), numKeys);
282 EXPECT_EQ(retrieved, values);
286 store->get(keys, retrieved, dbNames[1]);
287 EXPECT_EQ(retrieved.size(), numKeys);
288 EXPECT_EQ(retrieved, values);
297 const std::vector<std::string> dbNames = {
"Test Database No Dups",
"Test Database Dups" };
298 store->open_database(dbNames[0],
false);
299 store->open_database(dbNames[1],
true);
305 int64_t numValues = 2;
313 for (int64_t count = 0; count < numKeys; count++) {
316 auto expectedNoDup =
get_value(count, numValues - 1);
319 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
320 auto expectedWithDup =
get_value(count, dupCount);
321 dup.emplace_back(expectedWithDup);
323 valuesWithDups.emplace_back(dup);
324 valuesWithoutDups.emplace_back(
ValuesVector{ expectedNoDup });
329 store->get(keys, retrieved, dbNames[0]);
330 EXPECT_EQ(retrieved.size(), numKeys);
331 EXPECT_EQ(retrieved, valuesWithoutDups);
335 store->get(keys, retrieved, dbNames[1]);
336 EXPECT_EQ(retrieved.size(), numKeys);
337 EXPECT_EQ(retrieved, valuesWithDups);
372 const std::string dbName =
"Test Database";
373 store->open_database(dbName);
377 int64_t numKeys = 10;
378 int64_t numValues = 1;
386 for (int64_t count = numKeys; count < numKeys + 2; count++) {
391 toWrite.emplace_back(pair);
393 for (int64_t count = 3; count < numKeys - 2; count++) {
397 toDelete.emplace_back(pair);
401 store->put(putDatas);
407 for (int64_t count = 0; count < numKeys + 2; count++) {
417 store->get(keys, retrieved, dbName);
418 EXPECT_EQ(retrieved.size(), numKeys + 2);
419 EXPECT_EQ(retrieved, values);
428 const std::string dbName =
"Test Database";
429 store->open_database(dbName,
true);
433 int64_t numKeys = 10;
434 int64_t numValues = 5;
442 for (int64_t count = numKeys; count < numKeys + 2; count++) {
445 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
447 dup.emplace_back(
data);
450 toWrite.emplace_back(pair);
454 for (int64_t count = 3; count < numKeys - 2; count++) {
458 for (int64_t dupCount = 1; dupCount < numValues - 1; dupCount++) {
460 dup.emplace_back(
data);
463 toDelete.emplace_back(pair);
467 store->put(putDatas);
473 for (int64_t count = 0; count < numKeys + 2; count++) {
476 int64_t deletedDupStart = (count < 3 || count >= (numKeys - 2)) ? numValues : 1;
477 int64_t deletedDupEnd = (count < 3 || count >= (numKeys - 2)) ? 0 : numValues - 1;
480 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
481 if (dupCount >= deletedDupStart && dupCount < deletedDupEnd) {
485 dup.emplace_back(
data);
492 store->get(keys, retrieved, dbName);
493 EXPECT_EQ(retrieved.size(), numKeys + 2);
494 EXPECT_EQ(retrieved, expectedValues);
503 const std::vector<std::string> dbNames = {
"Test Database No Dups",
"Test Database Dups" };
504 store->open_database(dbNames[0],
false);
505 store->open_database(dbNames[1],
true);
509 int64_t numKeys = 10;
510 int64_t numValues = 5;
516 for (int64_t count = 3; count < numKeys - 2; count++) {
519 toDelete.emplace_back(pair);
524 store->put(putDatas);
530 for (int64_t count = 0; count < numKeys; count++) {
531 if (count >= 3 && count < numKeys - 2) {
537 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
539 dup.emplace_back(
data);
542 expectedValues.emplace_back(pair);
545 LMDBCursor::Ptr cursor = store->create_cursor(readTransaction, dbNames[1]);
546 cursor->set_at_start();
549 cursor->read_next((uint64_t)numKeys, retrieved);
550 EXPECT_EQ(retrieved, expectedValues);
557 for (int64_t count = 0; count < numKeys; count++) {
558 if (count >= 3 && count < numKeys - 2) {
565 expectedValues.emplace_back(pair);
568 LMDBCursor::Ptr cursor = store->create_cursor(readTransaction, dbNames[0]);
569 cursor->set_at_start();
572 cursor->read_next((uint64_t)numKeys, retrieved);
573 EXPECT_EQ(retrieved, expectedValues);
581 const std::string dbName =
"Test Database";
582 store->open_database(dbName);
584 int64_t numKeys = 10;
585 int64_t numValues = 1;
591 int64_t startKey = 3;
595 bool setResult = cursor->set_at_key(
key);
596 EXPECT_TRUE(setResult);
598 int64_t numKeysToRead = 4;
600 cursor->read_next((uint64_t)numKeysToRead, keyValues);
603 for (int64_t count = startKey; count < startKey + numKeysToRead; count++) {
608 EXPECT_EQ(keyValues, expected);
616 const std::string dbName =
"Test Database";
617 store->open_database(dbName,
true);
619 int64_t numKeys = 10;
620 int64_t numValues = 5;
626 int64_t startKey = 3;
630 bool setResult = cursor->set_at_key(
key);
631 EXPECT_TRUE(setResult);
633 int64_t numKeysToRead = 4;
635 cursor->read_next((uint64_t)numKeysToRead, keyValues);
638 for (int64_t count = startKey; count < startKey + numKeysToRead; count++) {
641 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
643 dup.emplace_back(
data);
646 expected.emplace_back(pair);
648 EXPECT_EQ(keyValues, expected);
656 const std::string dbName =
"Test Database";
657 store->open_database(dbName,
true);
659 int64_t numKeys = 10;
660 int64_t numValues = 1;
666 int64_t startKey = 7;
670 bool setResult = cursor->set_at_key(
key);
671 EXPECT_TRUE(setResult);
673 int64_t numKeysToRead = 4;
675 cursor->read_prev((uint64_t)numKeysToRead, keyValues);
678 for (int64_t count = startKey; count > startKey - numKeysToRead; count--) {
683 EXPECT_EQ(keyValues, expected);
691 const std::string dbName =
"Test Database";
692 store->open_database(dbName,
true);
694 int64_t numKeys = 10;
695 int64_t numValues = 5;
701 int64_t startKey = 7;
705 bool setResult = cursor->set_at_key(
key);
706 EXPECT_TRUE(setResult);
708 int64_t numKeysToRead = 4;
710 cursor->read_prev((uint64_t)numKeysToRead, keyValues);
713 for (int64_t count = startKey; count > startKey - numKeysToRead; count--) {
716 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
718 dup.emplace_back(
data);
721 expected.emplace_back(pair);
723 EXPECT_EQ(keyValues, expected);
731 const std::string dbName =
"Test Database";
732 store->open_database(dbName,
false);
734 int64_t numKeys = 10;
735 int64_t numValues = 1;
741 int64_t startKey = 3;
745 bool setResult = cursor->set_at_key(
key);
746 EXPECT_TRUE(setResult);
748 int64_t numKeysToRead = 50;
750 cursor->read_next((uint64_t)numKeysToRead, keyValues);
753 for (int64_t count = startKey; count < numKeys; count++) {
758 EXPECT_EQ(keyValues, expected);
766 const std::string dbName =
"Test Database";
767 store->open_database(dbName,
false);
769 int64_t numKeys = 10;
770 int64_t numValues = 1;
776 int64_t startKey = 7;
780 bool setResult = cursor->set_at_key(
key);
781 EXPECT_TRUE(setResult);
783 int64_t numKeysToRead = 50;
785 cursor->read_prev((uint64_t)numKeysToRead, keyValues);
788 for (int64_t count = startKey; count >= 0; count--) {
793 EXPECT_EQ(keyValues, expected);
801 const std::string dbName =
"Test Database";
802 store->open_database(dbName,
true);
804 int64_t numKeys = 10;
805 int64_t numValues = 5;
811 int64_t startKey = 3;
815 bool setResult = cursor->set_at_key(
key);
816 EXPECT_TRUE(setResult);
818 int64_t numKeysToRead = 50;
820 cursor->read_next((uint64_t)numKeysToRead, keyValues);
823 for (int64_t count = startKey; count < numKeys; count++) {
826 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
828 dup.emplace_back(
data);
831 expected.emplace_back(pair);
833 EXPECT_EQ(keyValues, expected);
841 const std::string dbName =
"Test Database";
842 store->open_database(dbName,
true);
844 int64_t numKeys = 10;
845 int64_t numValues = 5;
851 int64_t startKey = 7;
855 bool setResult = cursor->set_at_key(
key);
856 EXPECT_TRUE(setResult);
858 int64_t numKeysToRead = 50;
860 cursor->read_prev((uint64_t)numKeysToRead, keyValues);
863 for (int64_t count = startKey; count >= 0; count--) {
866 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
868 dup.emplace_back(
data);
871 expected.emplace_back(pair);
873 EXPECT_EQ(keyValues, expected);
881 const std::string dbName =
"Test Database";
882 store->open_database(dbName,
true);
884 int64_t numKeys = 10;
885 int64_t numValues = 5;
891 int64_t startKey = 7;
895 bool setResult = cursor->set_at_key(
key);
896 EXPECT_TRUE(setResult);
898 int64_t numKeysToRead = 4;
900 bool result = cursor->read_prev((uint64_t)numKeysToRead, keyValuesReverse);
901 EXPECT_FALSE(result);
904 startKey = (startKey - numKeysToRead) + 1;
906 setResult = cursor->set_at_key(
key);
907 EXPECT_TRUE(setResult);
909 result = cursor->read_next((uint64_t)numKeysToRead, keyValues);
910 EXPECT_FALSE(result);
914 EXPECT_EQ(temp, keyValues);
922 const std::string dbName =
"Test Database";
923 store->open_database(dbName,
false);
925 int64_t numKeys = 10;
926 int64_t numValues = 1;
932 int64_t startKey = 7;
936 bool setResult = cursor->set_at_key(
key);
937 EXPECT_TRUE(setResult);
941 uint64_t numKeysRead = 0;
942 bool result = cursor->count_until_prev(
key, numKeysRead);
943 EXPECT_FALSE(result);
944 EXPECT_EQ(numKeysRead, startKey - endKey);
951 setResult = cursor->set_at_key(
key);
952 EXPECT_TRUE(setResult);
954 result = cursor->count_until_next(
key, numKeysRead);
955 EXPECT_FALSE(result);
956 EXPECT_EQ(numKeysRead, endKey - startKey);
963 setResult = cursor->set_at_key(
key);
964 EXPECT_TRUE(setResult);
966 result = cursor->count_until_next(
key, numKeysRead);
967 EXPECT_FALSE(result);
968 EXPECT_EQ(numKeysRead, 0);
974 setResult = cursor->set_at_key(
key);
975 EXPECT_TRUE(setResult);
977 result = cursor->count_until_prev(
key, numKeysRead);
978 EXPECT_FALSE(result);
979 EXPECT_EQ(numKeysRead, 0);
987 const std::string dbName =
"Test Database";
988 store->open_database(dbName,
false);
991 int64_t numValues = 1;
998 int64_t startKey = 7;
1002 bool setResult = cursor->set_at_key(
key);
1003 EXPECT_TRUE(setResult);
1007 uint64_t numKeysRead = 0;
1008 bool result = cursor->count_until_prev(
key, numKeysRead);
1009 EXPECT_FALSE(result);
1010 EXPECT_EQ(numKeysRead, 3);
1017 setResult = cursor->set_at_key(
key);
1018 EXPECT_TRUE(setResult);
1020 result = cursor->count_until_next(
key, numKeysRead);
1021 EXPECT_FALSE(result);
1022 EXPECT_EQ(numKeysRead, 3);
1030 const std::string dbName =
"Test Database";
1031 store->open_database(dbName,
false);
1033 int64_t numKeys = 7;
1034 int64_t numValues = 1;
1040 int64_t startKey = 5;
1044 bool setResult = cursor->set_at_key(
key);
1045 EXPECT_TRUE(setResult);
1049 uint64_t numKeysRead = 0;
1050 bool result = cursor->count_until_prev(
key, numKeysRead);
1051 EXPECT_TRUE(result);
1052 EXPECT_EQ(numKeysRead, 4);
1059 setResult = cursor->set_at_key(
key);
1060 EXPECT_TRUE(setResult);
1062 result = cursor->count_until_next(
key, numKeysRead);
1063 EXPECT_TRUE(result);
1064 EXPECT_EQ(numKeysRead, 6);
1071 setResult = cursor->set_at_key(
key);
1072 EXPECT_TRUE(setResult);
1074 result = cursor->count_until_next(
key, numKeysRead);
1075 EXPECT_FALSE(result);
1076 EXPECT_EQ(numKeysRead, 0);
1082 setResult = cursor->set_at_key(
key);
1083 EXPECT_TRUE(setResult);
1085 result = cursor->count_until_prev(
key, numKeysRead);
1086 EXPECT_FALSE(result);
1087 EXPECT_EQ(numKeysRead, 0);
1095 const std::string dbName =
"Test Database";
1096 store->open_database(dbName,
true);
1098 int64_t numKeys = 7;
1099 int64_t numValues = 5;
1105 int64_t startKey = 5;
1109 bool setResult = cursor->set_at_key(
key);
1110 EXPECT_TRUE(setResult);
1114 uint64_t numKeysRead = 0;
1115 bool result = cursor->count_until_prev(
key, numKeysRead);
1116 EXPECT_FALSE(result);
1117 EXPECT_EQ(numKeysRead, numValues * 2);
1124 setResult = cursor->set_at_key(
key);
1125 EXPECT_TRUE(setResult);
1127 result = cursor->count_until_next(
key, numKeysRead);
1128 EXPECT_FALSE(result);
1129 EXPECT_EQ(numKeysRead, numValues * (endKey - startKey));
1136 setResult = cursor->set_at_key(
key);
1137 EXPECT_TRUE(setResult);
1139 result = cursor->count_until_next(
key, numKeysRead);
1140 EXPECT_FALSE(result);
1141 EXPECT_EQ(numKeysRead, 0);
1147 setResult = cursor->set_at_key(
key);
1148 EXPECT_TRUE(setResult);
1150 result = cursor->count_until_prev(
key, numKeysRead);
1151 EXPECT_FALSE(result);
1152 EXPECT_EQ(numKeysRead, 0);
1160 const std::string dbName =
"Test Database";
1161 store->open_database(dbName,
true);
1163 int64_t numKeys = 7;
1164 int64_t numValues = 5;
1170 int64_t startKey = 5;
1174 bool setResult = cursor->set_at_key(
key);
1175 EXPECT_TRUE(setResult);
1179 uint64_t numKeysRead = 0;
1180 bool result = cursor->count_until_prev(
key, numKeysRead);
1181 EXPECT_TRUE(result);
1182 EXPECT_EQ(numKeysRead, numValues * 4);
1189 setResult = cursor->set_at_key(
key);
1190 EXPECT_TRUE(setResult);
1192 result = cursor->count_until_next(
key, numKeysRead);
1193 EXPECT_TRUE(result);
1194 EXPECT_EQ(numKeysRead, numValues * 6);
1200 setResult = cursor->set_at_key(
key);
1201 EXPECT_TRUE(setResult);
1203 result = cursor->count_until_next(
key, numKeysRead);
1204 EXPECT_FALSE(result);
1205 EXPECT_EQ(numKeysRead, 0);
1211 setResult = cursor->set_at_key(
key);
1212 EXPECT_TRUE(setResult);
1214 result = cursor->count_until_prev(
key, numKeysRead);
1215 EXPECT_FALSE(result);
1216 EXPECT_EQ(numKeysRead, 0);
1224 const std::string dbName =
"Test Database";
1225 store->open_database(dbName,
true);
1227 int64_t numKeys = 10;
1228 int64_t numValues = 5;
1234 int64_t startKey = 7;
1238 bool setResult = cursor->set_at_key(
key);
1239 EXPECT_TRUE(setResult);
1241 int64_t numKeysToRead = 4;
1243 cursor->read_prev((uint64_t)numKeysToRead, keyValuesReverse);
1247 startKey = (startKey - numKeysToRead) + 1;
1250 setResult = cursor2->set_at_key(
key);
1251 EXPECT_TRUE(setResult);
1254 cursor2->read_next((uint64_t)numKeysToRead, keyValues);
1257 EXPECT_EQ(temp, keyValues);
1265 const std::vector<std::string> dbNames = {
"Test Database No Dups",
"Test Database Dups" };
1266 store->open_database(dbNames[0],
false);
1267 store->open_database(dbNames[1],
true);
1269 int64_t numKeys = 5000;
1270 int64_t numValues = 10;
1271 int64_t numIterations = 20;
1274 for (int64_t i = 0; i < numIterations; i++) {
1281 for (int64_t k = 0; k < numKeys; k++) {
1282 int64_t keyToDelete = ((i - 1) * numKeys) + k;
1289 EXPECT_NO_THROW(store->put(putDatas));
1297 const std::vector<std::string> dbNames = {
"Test Database No Dups",
"Test Database Dups" };
1298 store->open_database(dbNames[0],
false);
1299 store->open_database(dbNames[1],
true);
1301 int64_t numKeys = 10;
1302 int64_t numValues = 5;
1307 auto [mapSize, physicalFileSize] = store->get_stats(stats);
1308 std::string dataDbPath = (std::filesystem::path(_directory) /
"data.mdb").
string();
1309 EXPECT_TRUE(std::filesystem::exists(dataDbPath));
1312 EXPECT_EQ(physicalFileSize, std::filesystem::file_size(dataDbPath));
1313 EXPECT_EQ(stats.size(), 2);
1314 for (
size_t i = 0; i < 2; i++) {
1315 if (stats[i].name == dbNames[0]) {
1317 EXPECT_EQ(stats[i].numDataItems, numKeys);
1318 }
else if (stats[i].name == dbNames[1]) {
1320 EXPECT_EQ(stats[i].numDataItems, numKeys * numValues);
1331 const std::string dbName =
"Test Database";
1332 store->open_database(dbName,
true);
1334 int64_t numKeys = 10;
1335 int64_t numValues = 5;
1336 int64_t numIterationsPerThread = 1000;
1337 uint64_t numThreads = 10;
1341 std::vector<std::thread> threads;
1343 auto func = [&]() ->
void {
1344 for (int64_t iteration = 0; iteration < numIterationsPerThread; iteration++) {
1345 for (int64_t count = 0; count < numKeys; count++) {
1349 cursor->set_at_key(
key);
1351 cursor->read_next(1, keyValuePairs);
1355 for (int64_t dupCount = 0; dupCount < numValues; dupCount++) {
1357 dup.emplace_back(
data);
1360 expected.emplace_back(pair);
1361 EXPECT_EQ(keyValuePairs, expected);
1366 for (uint64_t count = 0; count < numThreads; count++) {
1369 for (uint64_t count = 0; count < numThreads; count++) {
1370 threads[count]->join();