1
0
forked from blue/lmdbal

two more methods for getting all records from cache, one more test for reading all

This commit is contained in:
Blue 2023-04-07 02:51:45 +03:00
parent 181a645efc
commit 064277fa6e
Signed by untrusted user: blue
GPG Key ID: 9B203B252A63EE38
3 changed files with 102 additions and 24 deletions

View File

@ -93,6 +93,8 @@ public:
virtual std::map<K, V> readAll() const override;
virtual std::map<K, V> readAll(TransactionID txn) const override;
virtual void readAll(std::map<K, V>& out) const override;
virtual void readAll(std::map<K, V>& out, TransactionID txn) const override;
virtual void replaceAll(const std::map<K, V>& data) override;
virtual void replaceAll(const std::map<K, V>& data, TransactionID txn) override;
virtual SizeType addRecords(const std::map<K, V>& data, bool overwrite = false) override;

View File

@ -229,7 +229,6 @@ void LMDBAL::Cache<K, V>::getRecord(const K& key, V& out) const {
}
}
template<class K, class V>
V LMDBAL::Cache<K, V>::getRecord(const K& key, TransactionID txn) const {
iStorage::ensureOpened(iStorage::getRecordMethodName);
@ -449,41 +448,64 @@ std::map<K, V> LMDBAL::Cache<K, V>::readAll() const {
return *cache;
}
template<class K, class V>
void LMDBAL::Cache<K, V>::readAll(std::map<K, V>& out) const {
iStorage::ensureOpened(iStorage::readAllMethodName);
if (*mode != Mode::full) { //there is a room for optimization
*mode = Mode::full; //I can read and deserialize only those values
Storage<K, V>::readAll(out); //that are missing in the cache
*cache = out;
abscent->clear();
*sizeDifference = 0;
}
}
template<class K, class V>
std::map<K, V> LMDBAL::Cache<K, V>::readAll(TransactionID txn) const {
iStorage::ensureOpened(iStorage::readAllMethodName);
std::map<K, V> out;
readAll(out, txn);
return out;
}
template<class K, class V>
void LMDBAL::Cache<K, V>::readAll(std::map<K, V>& out, TransactionID txn) const {
iStorage::ensureOpened(iStorage::readAllMethodName);
typename TransactionCache::iterator tc = transactionCache->find(txn);
if (tc != transactionCache->end()) {
Queue& queue = tc->second;
if (*mode != Mode::full) {
std::map<K, V> result = *cache;
out = *cache;
for (typename Queue::const_iterator i = queue.begin(), end = queue.end(); i != end; ++i) {
const Entry& entry = *i;
switch (entry.first) {
case Operation::add:
result.insert(*static_cast<std::pair<K, V>*>(entry.second));
out.insert(*static_cast<std::pair<K, V>*>(entry.second));
break;
case Operation::remove:
result.erase(*static_cast<K*>(entry.second));
out.erase(*static_cast<K*>(entry.second));
break;
case Operation::change: {
std::pair<K, V>* pair = static_cast<std::pair<K, V>*>(entry.second);
result.at(pair->first) = pair->second;
out.at(pair->first) = pair->second;
}
break;
case Operation::force:{
const std::tuple<bool, K, V>& tuple =
*static_cast<std::tuple<bool, K, V>*>(entry.second);
result[std::get<1>(tuple)] = std::get<2>(tuple);
out[std::get<1>(tuple)] = std::get<2>(tuple);
}
break;
case Operation::drop:
result.clear();
out.clear();
break;
case Operation::replace:
result = *static_cast<std::map<K, V>*>(entry.second);
out = *static_cast<std::map<K, V>*>(entry.second);
break;
case Operation::addMany: {
const std::tuple<bool, SizeType, std::map<K, V>>& t =
@ -492,35 +514,28 @@ std::map<K, V> LMDBAL::Cache<K, V>::readAll(TransactionID txn) const {
bool overwrite = std::get<0>(t);
for (const std::pair<const K, V>& pair : added) {
if (overwrite)
result[pair.first] = pair.second;
out[pair.first] = pair.second;
else
result.insert(pair);
out.insert(pair);
}
}
break;
}
}
return result;
} else {
std::map<K, V>* result = new std::map<K, V>();
Storage<K, V>::readAll(*result, txn);
Storage<K, V>::readAll(out, txn);
//queue.clear(); //since I'm getting a complete state of the database
queue.emplace_back(Operation::replace, result); //I can as well erase all previous cache entries
return *result;
queue.emplace_back(Operation::replace, new std::map<K, V>(out)); //I can as well erase all previous cache entries
}
} else {
if (*mode != Mode::full) { //there is a room for optimization
*mode = Mode::full; //I can read and deserialize only those values
*cache = Storage<K, V>::readAll(txn); //that are missing in the cache
Storage<K, V>::readAll(out); //that are missing in the cache
*cache = out;
abscent->clear();
*sizeDifference = 0;
}
return *cache;
}
}

View File

@ -301,3 +301,64 @@ TEST_F(BaseTest, ReadAll) {
EXPECT_EQ(m2.size(), 3);
EXPECT_EQ(m3.size(), 4);
}
TEST_F(BaseTest, ReplaceAll) {
EXPECT_EQ(db->ready(), true);
t1->replaceAll({
{7, 48},
{194, 582},
{857, 39},
{9717, 8}
});
t2->replaceAll({
{"bringin", "keyboard"},
{"cluster", "throttle"},
{"ronin", "cheese"}
});
c1->replaceAll({});
EXPECT_EQ(t1->count(), 4);
EXPECT_EQ(t2->count(), 3);
EXPECT_EQ(c1->count(), 0);
EXPECT_FALSE(t1->checkRecord(2));
EXPECT_FALSE(t1->checkRecord(58));
EXPECT_FALSE(t1->checkRecord(68));
EXPECT_FALSE(t2->checkRecord("sdfhga"));
EXPECT_FALSE(t2->checkRecord("prophecy"));
EXPECT_FALSE(t2->checkRecord("lawfirm"));
EXPECT_FALSE(c1->checkRecord(15));
EXPECT_FALSE(c1->checkRecord(12));
EXPECT_FALSE(c1->checkRecord(89));
EXPECT_FALSE(c1->checkRecord(98));
EXPECT_EQ(t1->getRecord(7), 48);
EXPECT_EQ(t1->getRecord(194), 582);
EXPECT_EQ(t1->getRecord(857), 39);
EXPECT_EQ(t1->getRecord(9717), 8);
EXPECT_EQ(t2->getRecord("bringin"), "keyboard");
EXPECT_EQ(t2->getRecord("cluster"), "throttle");
EXPECT_EQ(t2->getRecord("ronin"), "cheese");
c1->replaceAll({
{68, "quality"},
{31, "ridgid body"},
{16, "fermentation on your kind"},
{22, "pseudo"},
{-117, "lance of Michael"},
});
EXPECT_EQ(c1->count(), 5);
EXPECT_EQ(c1->getRecord(68), "quality");
EXPECT_EQ(c1->getRecord(31), "ridgid body");
EXPECT_EQ(c1->getRecord(16), "fermentation on your kind");
EXPECT_EQ(c1->getRecord(22), "pseudo");
EXPECT_EQ(c1->getRecord(-117), "lance of Michael");
}