22#include "exceptions.h"
45template<
class K,
class V>
49 cache(new std::map<K, V>()),
57template<
class K,
class V>
64template<
class K,
class V>
68 if (
cache->count(key) > 0)
72 handleAddRecord(key, value);
75template<
class K,
class V>
77 if (
cache->count(key) > 0)
84 std::pair<K, V>* pair =
new std::pair<K, V>(key, value);
85 tc->second.emplace_back(Operation::add, pair);
89template<
class K,
class V>
90void LMDBAL::Cache<K, V>::handleAddRecord(
const K& key,
const V& value) {
91 cache->insert(std::make_pair(key, value));
93 if (mode != Mode::full)
97template<
class K,
class V>
102 handleForceRecord(key, value, added);
107template<
class K,
class V>
113 std::tuple<bool, K, V>* t =
new std::tuple<bool, K, V>(added, key, value);
114 tc->second.emplace_back(Operation::force, t);
120template<
class K,
class V>
121void LMDBAL::Cache<K, V>::handleForceRecord(
const K& key,
const V& value,
bool added) {
122 if (mode == Mode::full) {
123 (*cache)[key] = value;
128 std::pair<typename std::map<K, V>::iterator,
bool> result =
129 cache->insert(std::make_pair(key, value));
131 result.first->second = value;
137template<
class K,
class V>
141 if (
mode == Mode::full) {
142 typename std::map<K, V>::iterator itr =
cache->find(key);
143 if (itr ==
cache->end())
154 typename std::pair<typename std::map<K, V>::iterator,
bool> res =
155 cache->insert(std::make_pair(key, value));
157 res.first->second = value;
167template<
class K,
class V>
169 if (
mode == Mode::full) {
170 typename std::map<K, V>::iterator itr =
cache->find(key);
171 if (itr ==
cache->end())
189 std::pair<K, V>* pair =
new std::pair<K, V>(key, value);
190 tc->second.emplace_back(Operation::add, pair);
194template<
class K,
class V>
195void LMDBAL::Cache<K, V>::handleChangeRecord(
const K& key,
const V& value) {
196 if (mode == Mode::full) {
197 cache->at(key) = value;
199 typename std::pair<typename std::map<K, V>::iterator,
bool> res =
200 cache->insert(std::make_pair(key, value));
202 res.first->second = value;
208template<
class K,
class V>
217template<
class K,
class V>
221 typename std::map<K, V>::const_iterator itr =
cache->find(key);
222 if (itr !=
cache->end()) {
227 if (
mode == Mode::full ||
abscent->count(key) != 0)
232 appendToCache(key, out);
235 if (
mode != Mode::full)
242template<
class K,
class V>
249template<
class K,
class V>
256 bool currentTransaction =
false;
259 currentTransaction =
true;
260 const Queue& queue = tc->second;
261 for (
typename Queue::const_reverse_iterator i = queue.rbegin(), end = queue.rend(); i != end; ++i) {
262 const Entry& entry = *i;
264 switch (entry.first) {
266 if (
static_cast<std::pair<K, V>*
>(entry.second)->first == key) {
267 out =
static_cast<std::pair<K, V>*
>(entry.second)->second;
271 case Operation::remove:
274 case Operation::change:
275 if (
static_cast<std::pair<K, V>*
>(entry.second)->first == key) {
276 out =
static_cast<std::pair<K, V>*
>(entry.second)->second;
281 case Operation::force:
282 if (std::get<1>(*
static_cast<std::tuple<bool, K, V>*
>(entry.second)) == key) {
283 out = std::get<2>(*
static_cast<std::tuple<bool, K, V>*
>(entry.second));
287 case Operation::drop:
290 case Operation::replace: {
291 std::map<K, V>* newMap =
static_cast<std::map<K, V>*
>(entry.second);
292 typename std::map<K, V>::const_iterator vitr = newMap->find(key);
293 if (vitr != newMap->end()) {
301 case Operation::addMany: {
302 const std::tuple<bool, SizeType, std::map<K, V>>& tuple =
303 *
static_cast<std::tuple<bool, SizeType, std::map<K, V>
>*>(entry.second);
304 const std::map<K, V>& newElements = std::get<2>(tuple);
305 typename std::map<K, V>::const_iterator vitr = newElements.find(key);
306 if (vitr != newElements.end()) {
318 typename std::map<K, V>::const_iterator itr =
cache->find(key);
319 if (itr !=
cache->end()) {
324 if (
mode == Mode::full ||
abscent->count(key) != 0)
329 if (!currentTransaction)
330 appendToCache(key, out);
334 if (!currentTransaction &&
mode != Mode::full)
341template<
class K,
class V>
343 appendToCache(key, value);
346template<
class K,
class V>
353template<
class K,
class V>
357 typename std::map<K, V>::const_iterator itr =
cache->find(key);
358 if (itr !=
cache->end())
361 if (
mode == Mode::full ||
abscent->count(key) != 0)
366 appendToCache(key, value);
370 if (
mode != Mode::full)
377template<
class K,
class V>
384 bool currentTransaction =
false;
387 currentTransaction =
true;
388 const Queue& queue = tc->second;
389 for (
typename Queue::const_reverse_iterator i = queue.rbegin(), end = queue.rend(); i != end; ++i) {
390 const Entry& entry = *i;
392 switch (entry.first) {
394 if (
static_cast<std::pair<K, V>*
>(entry.second)->first == key)
397 case Operation::remove:
398 if (*
static_cast<K*
>(entry.second) == key)
401 case Operation::change:
402 if (
static_cast<std::pair<K, V>*
>(entry.second)->first == key)
405 case Operation::force:
406 if (std::get<1>(*
static_cast<std::tuple<bool, K, V>*
>(entry.second)) == key)
409 case Operation::drop:
412 case Operation::replace:
413 if (
static_cast<std::map<K, V>*
>(entry.second)->count(key) > 0)
418 case Operation::addMany:
420 *
static_cast<std::tuple<bool, SizeType, std::map<K, V>
>*>(entry.second)
430 typename std::map<K, V>::const_iterator itr =
cache->find(key);
431 if (itr !=
cache->end())
434 if (
mode == Mode::full ||
abscent->count(key) != 0)
439 if (!currentTransaction)
440 appendToCache(key, value);
444 if (!currentTransaction &&
mode != Mode::full)
451template<
class K,
class V>
452void LMDBAL::Cache<K, V>::appendToCache(
const K& key,
const V& value)
const {
453 typename std::pair<typename std::map<K, V>::const_iterator,
bool> pair = cache->insert(std::make_pair(key, value));
458template<
class K,
class V>
462 if (
mode != Mode::full) {
472template<
class K,
class V>
476 if (
mode != Mode::full) {
485template<
class K,
class V>
493template<
class K,
class V>
497 Queue& queue = tc->second;
498 if (
mode != Mode::full) {
501 for (
typename Queue::const_iterator i = queue.begin(), end = queue.end(); i != end; ++i) {
502 const Entry& entry = *i;
503 switch (entry.first) {
505 out.insert(*
static_cast<std::pair<K, V>*
>(entry.second));
507 case Operation::remove:
508 out.erase(*
static_cast<K*
>(entry.second));
510 case Operation::change: {
511 std::pair<K, V>* pair =
static_cast<std::pair<K, V>*
>(entry.second);
512 out.at(pair->first) = pair->second;
515 case Operation::force:{
516 const std::tuple<bool, K, V>& tuple =
517 *
static_cast<std::tuple<bool, K, V>*
>(entry.second);
518 out[std::get<1>(tuple)] = std::get<2>(tuple);
521 case Operation::drop:
524 case Operation::replace:
525 out = *
static_cast<std::map<K, V>*
>(entry.second);
527 case Operation::addMany: {
528 const std::tuple<bool, SizeType, std::map<K, V>>& t =
529 *
static_cast<std::tuple<bool, SizeType, std::map<K, V>
>*>(entry.second);
530 const std::map<K, V>& added = std::get<2>(t);
531 bool overwrite = std::get<0>(t);
532 for (
const std::pair<const K, V>& pair : added) {
534 out[pair.first] = pair.second;
546 queue.emplace_back(Operation::replace,
new std::map<K, V>(out));
549 if (
mode != Mode::full) {
559template<
class K,
class V>
564 if (
mode != Mode::full) {
571template<
class K,
class V>
578 std::map<K, V>* map =
new std::map<K, V>(data);
579 tc->second.emplace_back(Operation::replace, map);
583template<
class K,
class V>
584void LMDBAL::Cache<K, V>::handleReplaceAll(std::map<K, V>* data) {
588 if (mode != Mode::full) {
595template<
class K,
class V>
598 handleAddRecords(data, overwrite, newSize);
603template<
class K,
class V>
609 std::tuple<bool, SizeType, std::map<K, V>>* tuple =
610 new std::tuple<bool, SizeType, std::map<K, V>>(overwrite, newSize, data);
611 tc->second.emplace_back(Operation::addMany, tuple);
617template<
class K,
class V>
618void LMDBAL::Cache<K, V>::handleAddRecords(
const std::map<K, V>& data,
bool overwrite, SizeType newSize) {
619 if (mode == Mode::nothing)
622 std::map<K, V>& c = *cache;
623 std::set<K>& a = *abscent;
624 for (
const std::pair<const K, V>& pair : data) {
625 std::pair<typename std::map<K, V>::iterator,
bool> res = c.insert(pair);
628 res.first->second = pair.second;
629 }
else if (mode != Mode::full) {
634 if (mode != Mode::full) {
635 sizeDifference = newSize - c.size();
636 if (sizeDifference == 0) {
643template<
class K,
class V>
648 if (
mode != Mode::full)
649 noKey =
cache->count(key) == 0;
651 noKey =
abscent->count(key) > 0;
657 handleRemoveRecord(key);
660template<
class K,
class V>
663 if (
mode != Mode::full)
664 noKey =
cache->count(key) == 0;
666 noKey =
abscent->count(key) > 0;
675 tc->second.emplace_back(Operation::remove,
new K(key));
678template<
class K,
class V>
679void LMDBAL::Cache<K, V>::handleRemoveRecord(
const K& key) {
680 if (cache->erase(key) == 0)
683 if (mode != Mode::full)
684 abscent->insert(key);
687template<
class K,
class V>
705 return cache->size();
711template<
class K,
class V>
714 bool currentTransaction =
false;
717 currentTransaction =
true;
718 const Queue& queue = tc->second;
719 for (
typename Queue::const_reverse_iterator i = queue.rbegin(), end = queue.rend(); i != end; ++i) {
720 const Entry& entry = *i;
722 switch (entry.first) {
726 case Operation::remove:
729 case Operation::change:
731 case Operation::force:
732 if (std::get<0>(*
static_cast<std::tuple<bool, K, V>*
>(entry.second)))
735 case Operation::drop:
738 case Operation::replace:
739 return static_cast<std::map<K, V>*
>(entry.second)->size() + diff;
741 case Operation::addMany:
742 return std::get<1>(*
static_cast<std::tuple<bool, SizeType, std::map<K, V>
>*>(entry.second)) + diff;
749 case Mode::nothing: {
751 if (!currentTransaction) {
765 return cache->size() + diff;
771template<
class K,
class V>
772void LMDBAL::Cache<K, V>::handleMode()
const {
773 if (mode == Mode::size) {
775 if (sizeDifference == 0) {
782template<
class K,
class V>
788 if (res != MDB_SUCCESS)
793 tc->second.emplace_back(Operation::drop,
nullptr);
798template<
class K,
class V>
806template<
class K,
class V>
812template<
class K,
class V>
816 Queue& queue = itr->second;
817 for (
const Entry& entry : queue)
818 handleTransactionEntry(entry);
824template<
class K,
class V>
828 Queue& queue = itr->second;
829 for (
const Entry& entry : queue)
830 destroyTransactionEntry(entry);
836template<
class K,
class V>
837void LMDBAL::Cache<K, V>::handleTransactionEntry(
const Entry& entry) {
838 switch (entry.first) {
839 case Operation::add: {
840 std::pair<K, V>* pair =
static_cast<std::pair<K, V>*
>(entry.second);
841 handleAddRecord(pair->first, pair->second);
844 case Operation::remove: {
845 K* key =
static_cast<K*
>(entry.second);
846 handleRemoveRecord(*key);
849 case Operation::change: {
850 std::pair<K, V>* pair =
static_cast<std::pair<K, V>*
>(entry.second);
851 handleChangeRecord(pair->first, pair->second);
854 case Operation::force: {
855 std::tuple<bool, K, V>* tuple =
static_cast<std::tuple<bool, K, V>*
>(entry.second);
856 const std::tuple<bool, K, V>& t = *tuple;
857 handleForceRecord(std::get<1>(t), std::get<2>(t), std::get<0>(t));
860 case Operation::drop:
863 case Operation::replace:
864 handleReplaceAll(
static_cast<std::map<K, V>*
>(entry.second));
866 case Operation::addMany: {
867 std::tuple<bool, SizeType, std::map<K, V>>* tuple =
static_cast<std::tuple<bool, SizeType, std::map<K, V>
>*>(entry.second);
868 const std::tuple<bool, SizeType, std::map<K, V>>& t = * tuple;
869 handleAddRecords(std::get<2>(t), std::get<0>(t), std::get<1>(t));
875template<
class K,
class V>
876void LMDBAL::Cache<K, V>::destroyTransactionEntry(
const Entry& entry)
const {
877 switch (entry.first) {
879 delete static_cast<std::pair<K, V>*
>(entry.second);
881 case Operation::remove:
882 delete static_cast<K*
>(entry.second);
884 case Operation::change:
885 delete static_cast<std::pair<K, V>*
>(entry.second);
887 case Operation::force:
888 delete static_cast<std::tuple<bool, K, V>*
>(entry.second);
890 case Operation::drop:
892 case Operation::replace:
893 delete static_cast<std::map<K, V>*
>(entry.second);
895 case Operation::addMany:
896 delete static_cast<std::tuple<bool, SizeType, std::map<K, V>
>*>(entry.second);
SizeType sizeDifference
Difference of size between cached data and amount of records in the lmdb storage.
Definition cache.h:129
Mode mode
Cache mode.
Definition cache.h:126
virtual bool forceRecord(const K &key, const V &value, TransactionID txn) override
Adds a key-value record to the storage, overwrites if it already exists (private transaction variant)
Definition cache.hpp:108
virtual std::map< K, V > readAll(TransactionID txn) const override
Reads whole storage into a map (private transaction variant)
Definition cache.hpp:486
virtual void transactionAborted(TransactionID txn) const override
called on abortion of public transaction
Definition cache.hpp:825
virtual std::map< K, V > readAll() const override
Reads whole storage into a map.
Definition cache.hpp:459
virtual bool checkRecord(const K &key, TransactionID txn) const override
Chechs if storage has value (private transaction variant)
Definition cache.hpp:378
virtual void discoveredRecord(const K &key, const V &value) const override
A private virtual method that cursor calls when he reads a record, does nothing here but populates th...
Definition cache.hpp:342
std::map< K, V > * cache
Cached data.
Definition cache.h:127
virtual int drop(const WriteTransaction &transaction) override
Drops content of a storage interface (public transaction variant)
Definition cache.hpp:783
Cache(Base *parent, const std::string &name, bool duplicates=false)
Creates a cache.
Definition cache.hpp:46
TransactionCache * transactionCache
All changes made under under uncommited transactions.
Definition cache.h:130
virtual void replaceAll(const std::map< K, V > &data, TransactionID txn) override
Replaces the content of the whole storage with the given (private transaction variant)
Definition cache.hpp:572
virtual void transactionCommited(TransactionID txn) override
called on commitment of public transaction
Definition cache.hpp:813
virtual void changeRecord(const K &key, const V &value, TransactionID txn) override
Changes key-value record to the storage (private transaction variant)
Definition cache.hpp:168
virtual SizeType addRecords(const std::map< K, V > &data, TransactionID txn, bool overwrite=false) override
Adds records in bulk (private transaction variant)
Definition cache.hpp:604
virtual void getRecord(const K &key, V &out, TransactionID txn) const override
Gets the record from the database (private transaction, reference variant)
Definition cache.hpp:250
virtual SizeType count() const override
Storage size.
Definition cache.hpp:688
virtual void transactionStarted(TransactionID txn, bool readOnly) const override
called on beginning of public transaction
Definition cache.hpp:807
virtual void handleDrop() override
A method where database additionally handles drop.
Definition cache.hpp:799
virtual void removeRecord(const K &key, TransactionID txn) override
Removes one of the records (private transaction variant)
Definition cache.hpp:661
std::set< K > * abscent
Set of keys that are definitely not in the cache.
Definition cache.h:128
~Cache() override
Destroys a cache.
Definition cache.hpp:58
virtual void addRecord(const K &key, const V &value, TransactionID txn) override
Adds a key-value record to the storage (private transaction variant)
Definition cache.hpp:76
Thrown if something in the database was not found.
Definition exceptions.h:138
static const std::string getRecordMethodName
member function name, just for exceptions
Definition storagecommon.h:123
void throwNotFound(const std::string &key) const
Throws LMDBAL::NotFound.
Definition storagecommon.cpp:404
static std::string toString(const T &value)
A method to cast a value (which can be a value or a key) to string.
Definition storagecommon.hpp:71
static const std::string forceRecordMethodName
member function name, just for exceptions
Definition storagecommon.h:119
virtual SizeType count() const
Storage size.
Definition storagecommon.cpp:148
const std::string name
this storage name
Definition storagecommon.h:111
static const std::string checkRecordMethodName
member function name, just for exceptions
Definition storagecommon.h:122
static const std::string dropMethodName
member function name, just for exceptions
Definition storagecommon.h:114
TransactionID extractTransactionId(const Transaction &txn, const std::string &action="") const
Checks if the transaction is still active, returns inner TransactionID.
Definition storagecommon.cpp:72
static const std::string readAllMethodName
member function name, just for exceptions
Definition storagecommon.h:124
static const std::string changeRecordMethodName
member function name, just for exceptions
Definition storagecommon.h:120
void throwDuplicate(const std::string &key) const
Throws LMDBAL::Exist.
Definition storagecommon.cpp:392
static const std::string addRecordMethodName
member function name, just for exceptions
Definition storagecommon.h:118
const bool duplicates
true if storage supports duplicates
Definition storagecommon.h:112
void ensureOpened(const std::string &methodName) const
Helper function, thows exception if the database is not opened.
Definition storagecommon.cpp:135
static const std::string removeRecordMethodName
member function name, just for exceptions
Definition storagecommon.h:121
virtual void addRecord(const K &key, const V &value, TransactionID txn)
Adds a key-value record to the storage (private transaction variant)
Definition storage.hpp:107
virtual std::map< K, V > readAll() const
Reads whole storage into a map.
Definition storage.hpp:638
virtual void replaceAll(const std::map< K, V > &data, TransactionID txn)
Replaces the content of the whole storage with the given (private transaction variant)
Definition storage.hpp:809
virtual void removeRecord(const K &key, TransactionID txn)
Removes one of the records (private transaction variant)
Definition storage.hpp:971
virtual bool forceRecord(const K &key, const V &value, TransactionID txn)
Adds a key-value record to the storage, overwrites if it already exists (private transaction variant)
Definition storage.hpp:198
virtual void changeRecord(const K &key, const V &value, TransactionID txn)
Changes key-value record to the storage (private transaction variant)
Definition storage.hpp:314
virtual void getRecord(const K &key, V &value, TransactionID txn) const
Gets the record from the database (private transaction, reference variant)
Definition storage.hpp:515
Storage(Base *parent, const std::string &name, bool duplicates=false)
Creates a storage.
Definition storage.hpp:48
virtual uint32_t addRecords(const std::map< K, V > &data, TransactionID txn, bool overwrite=false)
Adds records in bulk (private transaction variant)
Definition storage.hpp:887
virtual void drop()
Drops content of a storage interface.
Definition storagecommon.cpp:87
Public writable transaction.
Definition transaction.h:54