two more methods for getting all records from cache, one more test for reading all
This commit is contained in:
parent
181a645efc
commit
064277fa6e
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user