forked from blue/lmdbal
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() const override;
|
||||||
virtual std::map<K, V> readAll(TransactionID txn) 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) override;
|
||||||
virtual void replaceAll(const std::map<K, V>& data, TransactionID txn) 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;
|
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>
|
template<class K, class V>
|
||||||
V LMDBAL::Cache<K, V>::getRecord(const K& key, TransactionID txn) const {
|
V LMDBAL::Cache<K, V>::getRecord(const K& key, TransactionID txn) const {
|
||||||
iStorage::ensureOpened(iStorage::getRecordMethodName);
|
iStorage::ensureOpened(iStorage::getRecordMethodName);
|
||||||
@ -449,41 +448,64 @@ std::map<K, V> LMDBAL::Cache<K, V>::readAll() const {
|
|||||||
return *cache;
|
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>
|
template<class K, class V>
|
||||||
std::map<K, V> LMDBAL::Cache<K, V>::readAll(TransactionID txn) const {
|
std::map<K, V> LMDBAL::Cache<K, V>::readAll(TransactionID txn) const {
|
||||||
iStorage::ensureOpened(iStorage::readAllMethodName);
|
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);
|
typename TransactionCache::iterator tc = transactionCache->find(txn);
|
||||||
if (tc != transactionCache->end()) {
|
if (tc != transactionCache->end()) {
|
||||||
Queue& queue = tc->second;
|
Queue& queue = tc->second;
|
||||||
if (*mode != Mode::full) {
|
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) {
|
for (typename Queue::const_iterator i = queue.begin(), end = queue.end(); i != end; ++i) {
|
||||||
const Entry& entry = *i;
|
const Entry& entry = *i;
|
||||||
switch (entry.first) {
|
switch (entry.first) {
|
||||||
case Operation::add:
|
case Operation::add:
|
||||||
result.insert(*static_cast<std::pair<K, V>*>(entry.second));
|
out.insert(*static_cast<std::pair<K, V>*>(entry.second));
|
||||||
break;
|
break;
|
||||||
case Operation::remove:
|
case Operation::remove:
|
||||||
result.erase(*static_cast<K*>(entry.second));
|
out.erase(*static_cast<K*>(entry.second));
|
||||||
break;
|
break;
|
||||||
case Operation::change: {
|
case Operation::change: {
|
||||||
std::pair<K, V>* pair = static_cast<std::pair<K, V>*>(entry.second);
|
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;
|
break;
|
||||||
case Operation::force:{
|
case Operation::force:{
|
||||||
const std::tuple<bool, K, V>& tuple =
|
const std::tuple<bool, K, V>& tuple =
|
||||||
*static_cast<std::tuple<bool, K, V>*>(entry.second);
|
*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;
|
break;
|
||||||
case Operation::drop:
|
case Operation::drop:
|
||||||
result.clear();
|
out.clear();
|
||||||
break;
|
break;
|
||||||
case Operation::replace:
|
case Operation::replace:
|
||||||
result = *static_cast<std::map<K, V>*>(entry.second);
|
out = *static_cast<std::map<K, V>*>(entry.second);
|
||||||
break;
|
break;
|
||||||
case Operation::addMany: {
|
case Operation::addMany: {
|
||||||
const std::tuple<bool, SizeType, std::map<K, V>>& t =
|
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);
|
bool overwrite = std::get<0>(t);
|
||||||
for (const std::pair<const K, V>& pair : added) {
|
for (const std::pair<const K, V>& pair : added) {
|
||||||
if (overwrite)
|
if (overwrite)
|
||||||
result[pair.first] = pair.second;
|
out[pair.first] = pair.second;
|
||||||
else
|
else
|
||||||
result.insert(pair);
|
out.insert(pair);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
} else {
|
} else {
|
||||||
std::map<K, V>* result = new std::map<K, V>();
|
Storage<K, V>::readAll(out, txn);
|
||||||
Storage<K, V>::readAll(*result, txn);
|
|
||||||
|
|
||||||
//queue.clear(); //since I'm getting a complete state of the database
|
//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
|
queue.emplace_back(Operation::replace, new std::map<K, V>(out)); //I can as well erase all previous cache entries
|
||||||
|
|
||||||
return *result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (*mode != Mode::full) { //there is a room for optimization
|
if (*mode != Mode::full) { //there is a room for optimization
|
||||||
*mode = Mode::full; //I can read and deserialize only those values
|
*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();
|
abscent->clear();
|
||||||
*sizeDifference = 0;
|
*sizeDifference = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *cache;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,3 +301,64 @@ TEST_F(BaseTest, ReadAll) {
|
|||||||
EXPECT_EQ(m2.size(), 3);
|
EXPECT_EQ(m2.size(), 3);
|
||||||
EXPECT_EQ(m3.size(), 4);
|
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