MVault 0.0.1
Loading...
Searching...
No Matches
Vault.hpp
1#pragma once
2
3#include "Vault.h"
4#include "VaultRecordSet.h"
5
6#include "VaultRecord.hpp"
7#include "VaultParamInput.hpp"
8
9// This file contains an implementation of the Vault template methods
10namespace mvlt
11{
12 template <class T>
14 {
15 // Fill res info known at start
17 res.Key = key;
18 res.RequestedType = typeid(T);
19
20 // A pointer for storing a hash table with T type key and vault record as value
22
23 // A pointer for storing a binary tree with T type key and vault record as value
25
26 // Lock Vault to write
27 WriteLock<RecursiveReadWriteMutex> writeLock(RecursiveReadWriteMtx);
28
29 // Check if dataRecord valid
30 if (dataRecord == nullptr || !dataRecord->GetIsValid())
31 {
32 res.IsOperationSuccess = false;
34 return res;
35 }
36
37 // If key not exist
38 if(!GetKeyType(key, res.SavedType))
39 {
40 res.IsOperationSuccess = false;
42 return res;
43 }
44
45 // Check types
46 if (res.SavedType != res.RequestedType)
47 {
48 res.IsOperationSuccess = false;
50 return res;
51 }
52
53
54 // Get std::unordered_multimap with T key and VaultRecord* value
55 VaultHashMapStructure.GetData(key, TtoVaultRecordHashMap);
56
57 // Get the current value of the key key inside the VaultRecordRef and save it for further work
58 T oldData;
59 dataRecord->GetData(key, oldData);
60
61 // Remove oldData from TtoVaultRecordHashMap from VaultHashMapStructure
63
64 // Iterate over all data records with oldData key
66 {
67 // Find required data record
68 if ((*pairIt).second == dataRecord)
69 {
70 TtoVaultRecordHashMap->Erase((*pairIt).first);
71 break;
72 }
73 }
74
75 // Add new data to TtoVaultRecordHashMap to Vault VaultHashMapStructure
77
78
79 // Get std::multimap with T key and VaultRecord* value
80 VaultMapStructure.GetData(key, TtoVaultRecordMap);
81
82 // Remove oldData from TtoVaultRecordMap from VaultMapStructure
84
85 // Iterate over all data records with oldData key
87 {
88 // Find required data record
89 if ((*pairIt).second == dataRecord)
90 {
91 TtoVaultRecordMap->Erase((*pairIt).first);
92 break;
93 }
94 }
95
96 // Add new data to TtoVaultRecordMap to Vault VaultMapStructure
98
99
100 // Check if this method was original called. That mean that this method called not from next if statement.
101 // It is required since VaultRecordSet child of Vault and may also call this method
102 if (VaultDerivedClass == VaultDerivedClasses::VaultBase)
103 {
104 // Update all dependent VaultRecordSets
105 dataRecord->UpdateDependentSets(key, data);
106
107 // Update data inside VaultRecord pointer inside VaultRecordRef and Vault
108 dataRecord->SetData(key, data);
109 }
110
111 res.IsOperationSuccess = true;
113
114 return res;
115 }
116
117 template <class T>
118 VaultOperationResult Vault::RequestRecordsSet(const VaultRequestType& requestType, const std::string& key, const T& beginKeyValue,
119 const T& endKeyValue, std::unordered_set<VaultRecord*>& vaultRecords, const bool& isIncludeBeginKeyValue,
120 const bool& isIncludeEndKeyValue, const std::size_t& amountOfRecords, const std::function<bool(const VaultRecordRef&)>& requestPredicat) const noexcept
121 {
122 // Fill res info known at start
124 res.Key = key;
125 res.RequestedType = typeid(T);
126
127 // Lock Vault to read
128 ReadLock<RecursiveReadWriteMutex> readLock(RecursiveReadWriteMtx);
129
130 // If key not exist
131 if(!GetKeyType(key, res.SavedType))
132 {
133 res.IsOperationSuccess = false;
135 return res;
136 }
137
138 // Check types
139 if (res.SavedType != res.RequestedType)
140 {
141 res.IsOperationSuccess = false;
143 return res;
144 }
145
146 // Check if request type is equal
147 if (requestType == VaultRequestType::Equal)
148 {
149 // Pointer to store hash map inside VaultStructureHashMap
151
152 // Get hash map
153 VaultHashMapStructure.GetData(key, TtoVaultRecordHashMap);
154
155 // Pair with begin and end iterator with T type and beginKeyValue value
157 if (equalRange.first != TtoVaultRecordHashMap->End())
158 {
159 std::size_t counter = 0;
160 for (auto equalRangeIt = equalRange.first; equalRangeIt != equalRange.second; ++equalRangeIt)
161 {
162 // Check added records count
163 if (counter >= amountOfRecords) break;
164
165 // Check if it is not default predicate
166 if (&requestPredicat != &DefaultRequestPredicat)
167 {
168 if (requestPredicat(VaultRecordRef((*equalRangeIt).second, const_cast<Vault*>(this))))
169 vaultRecords.emplace((*equalRangeIt).second);
170 }
171 else
172 vaultRecords.emplace((*equalRangeIt).second);
173
174 ++counter;
175 }
176 }
177 }
178 else
179 {
180 // Pointer to store map inside VaultStructureHashMap
182
183 // Get map
184 VaultMapStructure.GetData(key, TtoVaultRecordMap);
185
186 // Iterator to set it in switch
187 decltype(TtoVaultRecordMap->End()) startIt, endIt;
188
189 // Lambda function for finding greater value iterator
190 auto findGreater = [&]()
191 {
192 bool flag = false;
194
195 // If it is not beginKeyValue in map and it is value bigger than beginKeyValue in map
196 if (startIt != TtoVaultRecordMap->End() && (*startIt).first > beginKeyValue)
197 return;
198
199 // Iterate to the next value
201 {
202 if ((*TtoVaultRecordMapIt).first != (*startIt).first)
203 {
205 flag = true;
206 break;
207 }
208 }
209
210 // Check if it is any record with key value greater than beginKeyValue
211 if (!flag) startIt = TtoVaultRecordMap->End();
212 };
213
214 // Lambda function for finding less value iterator
215 auto findLess = [&]()
216 {
217 endIt = TtoVaultRecordMap->UpperBound(endKeyValue);
218
219 // Check if TtoVaultRecordMap size not zero and endIt not last iterator
220 if (endIt != TtoVaultRecordMap->Begin() && TtoVaultRecordMap->Size() > 0)
221 {
222 // Upper bound return next iterator with value greater then endKeyValue
223 --endIt;
224
225 // Iterate to previous value
226 while(endIt != (*TtoVaultRecordMap).Begin() && (*endIt).first == endKeyValue)
227 --endIt;
228
229 // Increase iterator to add later last element in vaultRecords
230 if (endIt != TtoVaultRecordMap->Begin())
231 ++endIt;
232 }
233 };
234
235 // Switch by request type
236 switch (requestType)
237 {
238 case VaultRequestType::GreaterOrEqual:
240 endIt = TtoVaultRecordMap->End();
241 break;
242
243 case VaultRequestType::Greater:
244 findGreater();
245 endIt = TtoVaultRecordMap->End();
246 break;
247
248 case VaultRequestType::Less:
249 startIt = TtoVaultRecordMap->Begin();
250 findLess();
251 break;
252
253 case VaultRequestType::LessOrEqual:
254 startIt = TtoVaultRecordMap->Begin();
256 break;
257
258 case VaultRequestType::Interval:
260 {
261 startIt = TtoVaultRecordMap->End();
262 endIt = TtoVaultRecordMap->End();
263 break;
264 }
265
267 else findGreater();
269 else findLess();
270 break;
271
272 case VaultRequestType::Equal:
273 case VaultRequestType::Or:
274 case VaultRequestType::And:
275 break;
276 }
277
278 std::size_t counter = 0;
280 {
281 if (counter >= amountOfRecords) break;
282
283 // Check if it is not default predicate
284 if (&requestPredicat != &DefaultRequestPredicat)
285 {
286 if (requestPredicat(VaultRecordRef((*TtoVaultRecordMapIt).second, const_cast<Vault*>(this))))
287 vaultRecords.emplace((*TtoVaultRecordMapIt).second);
288 }
289 else
290 vaultRecords.emplace((*TtoVaultRecordMapIt).second);
291
292 ++counter;
293 }
294 }
295
297 res.SavedType = res.RequestedType;
298 res.IsOperationSuccess = true;
299
300 return res;
301 }
302
303 template <class T>
304 VaultOperationResult Vault::RequestRecords(const VaultRequestType& requestType, const std::string& key, const T& beginKeyValue,
306 const bool& isIncludeEndKeyValue, const std::size_t& amountOfRecords, const std::function<bool(const VaultRecordRef&)>& requestPredicat) const noexcept
307 {
309
310 // Lock Vault to read
311 ReadLock<RecursiveReadWriteMutex> readLock(RecursiveReadWriteMtx);
312
313 // If it is Vault object
314 if (VaultDerivedClass == VaultDerivedClasses::VaultBase)
315 {
316 // Save vaultRecordSet
317 RecordSetsSet.emplace(&vaultRecordSet);
318
319 // Remove old data from vaultRecordSet
320 if (vaultRecordSet.ParentVault != this)
321 {
322 vaultRecordSet.Reset();
323
324 // Set new parent vault to vaultRecordSet
325 vaultRecordSet.ParentVault = const_cast<Vault*>(this);
326
327 // Copy keys from this to vaultRecordSet
328 for (auto& keyCopierIt : VaultKeyCopiers)
330
331 // Set proper key order
332 vaultRecordSet.KeysOrder = KeysOrder;
333
334 // Set unique keys
335 vaultRecordSet.UniqueKeys = UniqueKeys;
336 }
337 else vaultRecordSet.Clear();
338 }
339
341
342 for (VaultRecord* record : vaultRecordSet.RecordsSet)
343 {
344 // Add pointer to record from this to vaultRecordSet structure
345 for (auto& adder : vaultRecordSet.VaultRecordAdders)
346 adder.second(record);
347
348 record->AddToDependentSets(&vaultRecordSet);
349 }
350
351 return res;
352 }
353
354 template <class T>
355 VaultOperationResult Vault::AddKey(const std::string& key, const T& defaultKeyValue, const bool& isUniqueKey, const bool& isUniqueKeyWithoutLambda,
356 std::function<T(std::size_t, const VaultRecordRef&)> uniqueKeyFunction) noexcept
357 {
359 res.Key = key;
360 res.RequestedType = typeid(T);
361
362 // Lock Vault to write
363 WriteLock<RecursiveReadWriteMutex> writeLock(RecursiveReadWriteMtx);
364
365 // If the key was added earlier
366 if (KeysTypes.find(key) != KeysTypes.end())
367 {
368 res.IsOperationSuccess = false;
370 return res;
371 }
372
373 // Create new hash map to store data with template T key
375 VaultHashMapStructure.SetData(key, TtoVaultRecordHashMap, [](const void* ptr)
376 {
378 }
379 );
380
381 // Create new map to store data with template T key
383 VaultMapStructure.SetData(key, TtoVaultRecordMap, [](const void* ptr)
384 {
385 delete* (Map<T, VaultRecord*>**)ptr;
386 }
387 );
388
389 // Add new data to record set
390 if (isUniqueKey)
391 {
392 // If no lamda provided and vault not empty
393 if (isUniqueKeyWithoutLambda && !RecordsSet.empty())
394 {
395 res.IsOperationSuccess = false;
397 return res;
398 }
399
400 std::size_t counter = 0;
401 std::vector<T> cachedData;
402 bool isCorrectKey = true;
403
404 // Cycle for check uniqueKeyFunction validity
405 for (VaultRecord* recordsSetIt : RecordsSet)
406 {
408 ++counter;
409
411 // If failed to emplace unique key then it is duplicate and error in uniqueKeyFunction
412 if (!emplacePair.second)
413 {
414 isCorrectKey = false;
415 break;
416 }
417
418 cachedData.emplace_back(std::move(value));
419 }
420
421 // If key correct then add data to all places
422 if (isCorrectKey)
423 {
424 counter = 0;
425 for (VaultRecord* recordsSetIt : RecordsSet)
426 {
428 if (VaultDerivedClass == VaultDerivedClasses::VaultBase)
430
431 ++counter;
432 }
433 }
434 else
435 {
436 VaultHashMapStructure.EraseData(key);
437 VaultMapStructure.EraseData(key);
438
439 res.IsOperationSuccess = false;
441 return res;
442 }
443 }
444 else
445 {
446 for (VaultRecord* recordsSetIt : RecordsSet)
447 {
451 }
452 }
453
454 // Add key to list with key order
455 if(VaultDerivedClass == VaultDerivedClasses::VaultBase)
456 KeysOrder.emplace_back(key);
457
458 // Add key type to hash map with keys types
459 KeysTypes.emplace(key, typeid(T));
460
461 // Add data to template
462 RecordTemplate.SetData(key, defaultKeyValue);
463
464 // Add unique key
465 if (isUniqueKey) UniqueKeys.emplace(key);
466
467 // Add function to VaultRecord creation
468 VaultRecordAdders.emplace(key, [=](VaultRecord* newRecord)
469 {
470 // Make temporary variable to store key value
472 // Try to get key value from new record. If it is not value inside then defaultKeyValue will be used
473 newRecord->GetData(key, value);
474
475 // Try to emplace data into hash table. If it is multi container then it is always emplaced
476 // If it is not multi container then data emplaced only if it was not same data alredy in hash table
478
479 // Return false if data alredy in hash table
480 if (!emplaceRes.second) return false;
481
483 return true;
484 }
485 );
486
487 // Add function to TtoVaultRecordHashMap cleareing
488 VaultRecordClearers.emplace(key, [=]()
489 {
490 TtoVaultRecordHashMap->Clear();
491 TtoVaultRecordMap->Clear();
492 }
493 );
494
495 // Add function to erase newRecord from TtoVaultRecordHashMap
496 VaultRecordErasers.emplace(key, [=](VaultRecord* newRecord)
497 {
498 // Get T type data with key key
500 newRecord->GetData(key, recordTData);
501
502 // Find all elements on multi_map with recordTData value
504
505 // Find newRecord and erase it from TtoVaultRecordHashMap
507 {
508 if ((*pairIt).second == newRecord)
509 {
511 break;
512 }
513 }
514
515 // Find all elements on map with recordTData value
517 // Find newRecord and erase it from TtoVaultRecordHashMap
519 {
520 if ((*pairIt).second == newRecord)
521 {
522 TtoVaultRecordMap->Erase((*pairIt).first);
523 break;
524 }
525 }
526 }
527 );
528
529 VaultRecordSorters.emplace(key, [=](std::function<bool(const VaultRecordRef&)> functionToSortedData, Vault* vltPtr, bool isReverse)
530 {
531 if (!isReverse)
532 {
533 for (const auto& TtoVaultRecordMapIt : *TtoVaultRecordMap)
535 break;
536 }
537 else
538 {
540 if(!functionToSortedData(VaultRecordRef((*TtoVaultRecordMapIt).second, vltPtr)))
541 break;
542 }
543 });
544
545 VaultKeyCopiers.emplace(key, [=](Vault* vaultRecordSet)
546 {
548 });
549
550 if (VaultDerivedClass == VaultDerivedClasses::VaultBase)
551 {
552 for (VaultRecordSet* set : RecordSetsSet)
553 {
554 if (isUniqueKey)
555 set->AddUniqueKey(key, uniqueKeyFunction);
556 else
557 set->AddKey(key, defaultKeyValue);
558 set->KeysOrder.emplace_back(key);
559 }
560 }
561
562 res.IsOperationSuccess = true;
564 return res;
565 }
566
567 template <class T>
568 bool Vault::AddKey(const std::string& key, const T& defaultKeyValue) noexcept
569 {
570 static_assert(!std::is_array<T>::value, "It is not possible to use a c array as a key value. \n\
571 If you want to use a string as a key, you must specialize the function with a string. Like this: \n\
572 AddKey<std::string>(\"Key\", \"Value\") or AddKey(\"Key\", std::string(\"Value\"))");
573
574 return AddKey(key, defaultKeyValue, false, false, {[&](std::size_t counter, const VaultRecordRef&) -> T{ return defaultKeyValue; }}).IsOperationSuccess;
575 }
576
577 template <class T>
578 VaultOperationResult Vault::AddUniqueKey(const std::string& key) noexcept
579 {
580 static_assert(!std::is_array<T>::value, "It is not possible to use a c array as a key value. \n\
581 If you want to use a string as a key, you must specialize the function with a string. Like this: \n\
582 AddUniqueKey<std::string>(\"Key\")");
583
584 return AddKey(key, T(), true, true, {[&](std::size_t counter, const VaultRecordRef&) -> T{ return T(); }});
585 }
586
587 template <class T>
588 VaultOperationResult Vault::AddUniqueKey(const std::string& key, std::function<T(std::size_t, const VaultRecordRef&)> uniqueKeyFunction) noexcept
589 {
590 return AddKey(key, T(), true, false, uniqueKeyFunction);
591 }
592
593 template <class T>
594 VaultOperationResult Vault::UpdateKey(const std::string& key, const T& defaultKeyValue) noexcept
595 {
596 static_assert(!std::is_array<T>::value, "It is not possible to use a c array as a key value. \n\
597 If you want to use a string as a key, you must specialize the function with a string. Like this: \n\
598 UpdateKey<std::string>(\"Key\", \"Value\") or UpdateKey(\"Key\", std::string(\"Value\"))");
599
601 res.Key = key;
602 res.RequestedType = typeid(defaultKeyValue);
603
604 // Lock Vault to write
605 WriteLock<RecursiveReadWriteMutex> writeLock(RecursiveReadWriteMtx);
606
607 // If the key was not added earlier, then it can not be updated
608 std::unordered_map<std::string, std::type_index>::iterator keyTypeIt = KeysTypes.find(key);
609 if (keyTypeIt == KeysTypes.end())
610 {
611 res.IsOperationSuccess = false;
613 return res;
614 }
615
616 // Check it is trying to set coorect type
617 if (res.RequestedType != keyTypeIt->second)
618 {
619 res.SavedType = keyTypeIt->second;
620 res.IsOperationSuccess = false;
622 return res;
623 }
624
625 // Check if it is unique key
626 if (UniqueKeys.find(key) != UniqueKeys.end())
627 {
628 res.SavedType = keyTypeIt->second;
629 res.IsOperationSuccess = false;
631 return res;
632 }
633
634 // Change data in template
635 RecordTemplate.SetData(key, defaultKeyValue);
636
637 return res;
638 }
639
640 template <class T>
641 VaultOperationResult Vault::GetKeyValue(const std::string& key, T& defaultKeyValue) const noexcept
642 {
643 static_assert(!std::is_array<T>::value, "It is not possible to use a c array as a key value.");
644
646 res.Key = key;
647 res.RequestedType = typeid(T);
648
649 // Lock Vault to read
650 ReadLock<RecursiveReadWriteMutex> readLock(RecursiveReadWriteMtx);
651
652 // If key not exist
653 if(!GetKeyType(key, res.SavedType))
654 {
655 res.IsOperationSuccess = false;
657 return res;
658 }
659
660 // Check types
661 if (res.SavedType != res.RequestedType)
662 {
663 res.IsOperationSuccess = false;
665 return res;
666 }
667
668 for (auto& it : UniqueKeys)
669 {
670 std::cout << it << std::endl;
671 }
672
673 // Check if it is unique key
674 if (UniqueKeys.find(key) != UniqueKeys.end())
675 {
676 res.IsOperationSuccess = false;
678 return res;
679 }
680
681 RecordTemplate.GetData(key, defaultKeyValue);
682
683 res.IsOperationSuccess = true;
685 res.SavedType = res.RequestedType;
686
687 return res;
688 }
689
690 template <class T>
692 {
693 static_assert(!std::is_array<T>::value, "It is not possible to use a c array as a key value. \n\
694 If you want to use a string as a key, you must specialize the function with a string. Like this: \n\
695 GetRecord<std::string>(\"Key\", \"Value\") or GetRecord(\"Key\", std::string(\"Value\"))");
696
697 // Fill res info known at start
699 res.Key = key;
700 res.RequestedType = typeid(T);
701
702 // Lock Vault to read
703 ReadLock<RecursiveReadWriteMutex> readLock(RecursiveReadWriteMtx);
704
705 // If key not exist
706 if(!GetKeyType(key, res.SavedType))
707 {
708 res.IsOperationSuccess = false;
710 return res;
711 }
712
713 // Check types
714 if (res.SavedType != res.RequestedType)
715 {
716 res.IsOperationSuccess = false;
718 return res;
719 }
720
721 // Pointer to store map inside VaultStructureHashMap
723
724 // Checking whether such a key exists
725 VaultHashMapStructure.GetData(key, TtoVaultRecordHashMap);
726
727 // Iterator to element with T type and keyValue value
730 {
731 vaultRecordRef.SetRecord((*TtoVaultRecordIt).second, const_cast<Vault*>(this));
732 res.IsOperationSuccess = true;
734 }
735 else
736 {
737 vaultRecordRef.SetRecord(nullptr, const_cast<Vault*>(this));
738 res.IsOperationSuccess = false;
740 }
741
742 return res;
743 }
744
745 template <class T>
746 VaultOperationResult Vault::GetRecords(const std::string& key, const T& keyValue, std::vector<VaultRecordRef>& recordsRefs, const std::size_t& amountOfRecords) const noexcept
747 {
748 static_assert(!std::is_array<T>::value, "It is not possible to use a c array as a key value. \n\
749 If you want to use a string as a key, you must specialize the function with a string. Like this: \n\
750 GetRecords<std::string>(\"Key\", \"Value\") or GetRecords(\"Key\", std::string(\"Value\"))");
751
752 // Fill res info known at start
754 res.Key = key;
755 res.RequestedType = typeid(T);
756
757 recordsRefs.clear();
758
759 // Lock Vault to read
760 ReadLock<RecursiveReadWriteMutex> readLock(RecursiveReadWriteMtx);
761
762 // If key not exist
763 if(!GetKeyType(key, res.SavedType))
764 {
765 res.IsOperationSuccess = false;
767 return res;
768 }
769
770 // Check types
771 if (res.SavedType != res.RequestedType)
772 {
773 res.IsOperationSuccess = false;
775 return res;
776 }
777
778 // Pointer to store map inside VaultStructureHashMap
780
781 // Checking whether such a key exists
782 VaultHashMapStructure.GetData(key, TtoVaultRecordHashMap);
783
784 // Pair with begin and end iterator with T type and keyValue value
785 auto equalRange = TtoVaultRecordHashMap->EqualRange(keyValue);
786 if (equalRange.first != TtoVaultRecordHashMap->end())
787 {
788 std::size_t counter = 0;
789 for (auto equalRangeIt = equalRange.first; equalRangeIt != equalRange.second; ++equalRangeIt)
790 {
791 ++counter;
792 recordsRefs.emplace_back(VaultRecordRef((*equalRangeIt).second, const_cast<Vault*>(this)));
793 if (counter >= amountOfRecords) break;
794 }
795 }
796 else
797 {
798 res.IsOperationSuccess = false;
800 }
801
802 return res;
803 }
804
805 template <class T>
807 const std::size_t& amountOfRecords, const std::function<bool(const VaultRecordRef&)>& requestPredicat) const noexcept
808 {
809 static_assert(!std::is_array<T>::value, "It is not possible to use a c array as a key value. \n\
810 If you want to use a string as a key, you must specialize the function with a string. Like this: \n\
811 RequestEqual<std::string>(\"Key\", \"Value\") or RequestEqual(\"Key\", std::string(\"Value\"))");
812
813 return RequestRecords(VaultRequestType::Equal, key, keyValue, keyValue, vaultRecordSet, false, false, amountOfRecords, requestPredicat);
814 }
815
816 template <class T>
818 const std::size_t& amountOfRecords, const std::function<bool(const VaultRecordRef&)>& requestPredicat) const noexcept
819 {
820 static_assert(!std::is_array<T>::value, "It is not possible to use a c array as a key value. \n\
821 If you want to use a string as a key, you must specialize the function with a string. Like this: \n\
822 RequestGreater<std::string>(\"Key\", \"Value\") or RequestGreater(\"Key\", std::string(\"Value\"))");
823
824 return RequestRecords(VaultRequestType::Greater, key, keyValue, keyValue, vaultRecordSet, false, false, amountOfRecords, requestPredicat);
825 }
826
827 template <class T>
829 const std::size_t& amountOfRecords, const std::function<bool(const VaultRecordRef&)>& requestPredicat) const noexcept
830 {
831 static_assert(!std::is_array<T>::value, "It is not possible to use a c array as a key value. \n\
832 If you want to use a string as a key, you must specialize the function with a string. Like this: \n\
833 RequestGreaterOrEqual<std::string>(\"Key\", \"Value\") or RequestGreaterOrEqual(\"Key\", std::string(\"Value\"))");
834
835 return RequestRecords(VaultRequestType::GreaterOrEqual, key, keyValue, keyValue, vaultRecordSet, false, false, amountOfRecords, requestPredicat);
836 }
837
838 template <class T>
840 const std::size_t& amountOfRecords, const std::function<bool(const VaultRecordRef&)>& requestPredicat) const noexcept
841 {
842 static_assert(!std::is_array<T>::value, "It is not possible to use a c array as a key value. \n\
843 If you want to use a string as a key, you must specialize the function with a string. Like this: \n\
844 RequestLess<std::string>(\"Key\", \"Value\") or RequestLess(\"Key\", std::string(\"Value\"))");
845
846 return RequestRecords(VaultRequestType::Less, key, keyValue, keyValue, vaultRecordSet, false, false, amountOfRecords, requestPredicat);
847 }
848
849 template <class T>
851 const std::size_t& amountOfRecords, const std::function<bool(const VaultRecordRef&)>& requestPredicat) const noexcept
852 {
853 static_assert(!std::is_array<T>::value, "It is not possible to use a c array as a key value. \n\
854 If you want to use a string as a key, you must specialize the function with a string. Like this: \n\
855 RequestLessOrEqual<std::string>(\"Key\", \"Value\") or RequestLessOrEqual(\"Key\", std::string(\"Value\"))");
856
857 return RequestRecords(VaultRequestType::LessOrEqual, key, keyValue, keyValue, vaultRecordSet, false, false, amountOfRecords, requestPredicat);
858 }
859
860 template <class T>
863 const bool& isIncludeEndKeyValue, const std::size_t& amountOfRecords, const std::function<bool(const VaultRecordRef&)>& requestPredicat) const noexcept
864 {
865 static_assert(!std::is_array<T>::value, "It is not possible to use a c array as a key value. \n\
866 If you want to use a string as a key, you must specialize the function with a string. Like this: \n\
867 RequestInterval<std::string>(\"Key\", \"Value\") or RequestInterval(\"Key\", std::string(\"Value\"))");
868
869 return RequestRecords(VaultRequestType::Interval, key, beginKeyValue,
872 }
873
874 template <VaultRequestType Type>
876 {
878 res.IsOperationSuccess = true;
880
881 // Lock Vault to read
882 ReadLock<RecursiveReadWriteMutex> readLock(RecursiveReadWriteMtx);
883
884 // If it is Vault object
886 {
887 // Save vaultRecordSet
889
890 // Remove old data from vaultRecordSet
891 if (vaultRecordSet.ParentVault != this)
892 {
893 vaultRecordSet.Reset();
894
895 // Set new parent vault to vaultRecordSet
896 vaultRecordSet.ParentVault = const_cast<Vault*>(this);
897
898 // Copy keys from this to vaultRecordSet
899 for (auto& keyCopierIt : VaultKeyCopiers)
901
902 // Set proper key order
903 vaultRecordSet.KeysOrder = KeysOrder;
904
905 // Set unique keys
906 vaultRecordSet.UniqueKeys = UniqueKeys;
907 }
908 else vaultRecordSet.Clear();
909 }
910
911 // Try to make complex request
912 try
913 {
914 request.Request(const_cast<Vault*>(this), vaultRecordSet.RecordsSet);
915
916 for (VaultRecord* record : vaultRecordSet.RecordsSet)
917 {
918 // Add pointer to record from this to vaultRecordSet structure
919 for (auto& adder : vaultRecordSet.VaultRecordAdders)
920 adder.second(record);
921
922 // Lock VaultRecord to thread safety add new dependent VaultRecordSet
923 record->AddToDependentSets(&vaultRecordSet);
924 }
925 }
926 catch(VaultOperationResult& result) // Catch complex request errors
927 {
928 vaultRecordSet.Clear();
929 res = result;
930 }
931
932 return res;
933 }
934
935 template <class T>
936 VaultOperationResult Vault::EraseRecord(const std::string& key, const T& keyValue) noexcept
937 {
938 static_assert(!std::is_array<T>::value, "It is not possible to use a c array as a key value. \n\
939 If you want to use a string as a key, you must specialize the function with a string. Like this: \n\
940 EraseRecord<std::string>(\"Key\", \"Value\") or EraseRecord(\"Key\", std::string(\"Value\"))");
941
942 // Fill res info known at start
944 res.Key = key;
945 res.RequestedType = typeid(T);
946
947 // Lock Vault to write
948 WriteLock<RecursiveReadWriteMutex> writeLock(RecursiveReadWriteMtx);
949
950 // If key not exist
951 if(!GetKeyType(key, res.SavedType))
952 {
953 res.IsOperationSuccess = false;
955 return res;
956 }
957
958 // Check types
959 if (res.SavedType != res.RequestedType)
960 {
961 res.IsOperationSuccess = false;
963 return res;
964 }
965
966 // Pointer to store map inside VaultStructureHashMap
968
969 // Checking whether such a key exists
970 VaultHashMapStructure.GetData(key, TtoVaultRecordHashMap);
971
972 // Iterator to element with T type and keyValue value
975 {
976 VaultRecord* tmpRec = (*TtoVaultRecordIt).second;
977
978 for (auto& eraser : VaultRecordErasers)
979 eraser.second(tmpRec);
980
981 RecordsSet.erase(tmpRec);
982
983 // Check if it is delete. By now it is deletion when EraseRecord called from vault.
984 // It is not deleting when RemoveRecord called from VaultRecordSet
985 if (VaultDerivedClass == VaultDerivedClasses::VaultBase)
986 {
987 tmpRec->RemoveFromDependentSets();
988 tmpRec->Invalidate();
989 }
990
991 res.IsOperationSuccess = true;
993 }
994 else
995 {
996 res.IsOperationSuccess = false;
998 }
999
1000 return res;
1001 }
1002
1003 template <class T>
1004 VaultOperationResult Vault::EraseRecords(const std::string& key, const T& keyValue, const std::size_t& amountOfRecords) noexcept
1005 {
1006 static_assert(!std::is_array<T>::value, "It is not possible to use a c array as a key value. \n\
1007 If you want to use a string as a key, you must specialize the function with a string. Like this: \n\
1008 EraseRecords<std::string>(\"Key\", \"Value\") or EraseRecords(\"Key\", std::string(\"Value\"))");
1009
1010 // Fill res info known at start
1012 res.Key = key;
1013 res.RequestedType = typeid(T);
1014
1015 // Lock Vault to write
1016 WriteLock<RecursiveReadWriteMutex> writeLock(RecursiveReadWriteMtx);
1017
1018 // If key not exist
1019 if(!GetKeyType(key, res.SavedType))
1020 {
1021 res.IsOperationSuccess = false;
1023 return res;
1024 }
1025
1026 // Check types
1027 if (res.SavedType != res.RequestedType)
1028 {
1029 res.IsOperationSuccess = false;
1031 return res;
1032 }
1033
1034 // Pointer to store map inside VaultStructureHashMap
1036
1037 // Checking whether such a key exists
1038 VaultHashMapStructure.GetData(key, TtoVaultRecordHashMap);
1039
1040 // Pair with begin and end iterator with T type and keyValue value
1041 auto equalRange = TtoVaultRecordHashMap->EqualRange(keyValue);
1042 if (equalRange.first != TtoVaultRecordHashMap->end())
1043 {
1044 res.IsOperationSuccess = true;
1046
1047 std::size_t counter = 0;
1048 for (auto equalRangeIt = equalRange.first; equalRangeIt != equalRange.second;)
1049 {
1050 // Save next iterator
1051 auto nextIt = equalRangeIt;
1052 ++nextIt;
1053
1054 ++counter;
1055
1056 VaultRecord* tmpRec = (*equalRangeIt).second;
1057 for (auto& eraser : VaultRecordErasers)
1058 eraser.second(tmpRec);
1059
1060 RecordsSet.erase(tmpRec);
1061
1062 // Check if it is delete. By now it is deletion when EraseRecord called from vault.
1063 // It is not deleting when RemoveRecord called from VaultRecordSet
1064 if (VaultDerivedClass == VaultDerivedClasses::VaultBase)
1065 {
1066 tmpRec->RemoveFromDependentSets();
1067 tmpRec->Invalidate();
1068 }
1069
1070 if (counter >= amountOfRecords) break;
1071
1073 }
1074 }
1075 else
1076 {
1077 res.IsOperationSuccess = false;
1079 }
1080
1081 return res;
1082 }
1083
1084 template<class F>
1085 void Vault::SortBy(const std::string& key, const F&& func, const bool& isReverse, const std::size_t& amountOfRecords) const noexcept
1086 {
1087 std::size_t counter = 0;
1088
1089 // Lock Vault to read
1090 ReadLock<RecursiveReadWriteMutex> readLock(RecursiveReadWriteMtx);
1091
1092 auto findResIt = VaultRecordSorters.find(key);
1093 if (findResIt != VaultRecordSorters.end())
1094 {
1095 VaultRecordSorters.find(key)->second([&](const VaultRecordRef& vaultRecordRef)
1096 {
1097 if (counter >= amountOfRecords) return false;
1098
1099 if (!func(vaultRecordRef)) return false;
1100
1101 ++counter;
1102 return true;
1103 }, const_cast<Vault*>(this), isReverse);
1104 }
1105 }
1106}
Iterator class for all library maps.
Definition Map.h:18
A class for storing data with the ability to quickly search for a variety of different keys of any ty...
Definition Vault.h:33
bool EraseRecord(const VaultRecordRef &recordRefToErase) noexcept
Method for deleting a record from a Vault.
Definition Vault.cpp:593
VaultOperationResult RequestGreater(const std::string &key, const T &keyValue, VaultRecordSet &vaultRecordSet, const std::size_t &amountOfRecords=-1, const std::function< bool(const VaultRecordRef &)> &requestPredicat=DefaultRequestPredicat) const noexcept
A method for getting all records that have a value greater than keyValue stored by the key key.
Definition Vault.hpp:817
VaultOperationResult GetKeyValue(const std::string &key, T &defaultKeyValue) const noexcept
The method for getting a default key value.
Definition Vault.hpp:641
VaultOperationResult SetDataToRecord(VaultRecord *dataRecord, const std::string &key, const T &data) noexcept
Method for setting a new value in VaultRecord and Vault.
Definition Vault.hpp:13
VaultOperationResult RequestEqual(const std::string &key, const T &keyValue, VaultRecordSet &vaultRecordSet, const std::size_t &amountOfRecords=-1, const std::function< bool(const VaultRecordRef &)> &requestPredicat=DefaultRequestPredicat) const noexcept
A method for getting all records that have a value equal to keyValue stored by the key key.
Definition Vault.hpp:806
@ VaultBase
Vault class itself.
VaultOperationResult RequestLess(const std::string &key, const T &keyValue, VaultRecordSet &vaultRecordSet, const std::size_t &amountOfRecords=-1, const std::function< bool(const VaultRecordRef &)> &requestPredicat=DefaultRequestPredicat) const noexcept
A method for getting all records that have a value less than keyValue stored by the key key.
Definition Vault.hpp:839
void SortBy(const std::string &key, const F &&func, const bool &isReverse=false, const std::size_t &amountOfRecords=-1) const noexcept
Method for handle sorted records.
Definition Vault.hpp:1085
VaultOperationResult GetRecord(const std::string &key, const T &keyValue, VaultRecordRef &vaultRecordRef) const noexcept
The method for getting a reference to the data inside Vault.
Definition Vault.hpp:691
VaultOperationResult RequestRecords(const VaultRequestType &requestType, const std::string &key, const T &beginKeyValue, const T &endKeyValue, VaultRecordSet &vaultRecordSet, const bool &isIncludeBeginKeyValue, const bool &isIncludeEndKeyValue, const std::size_t &amountOfRecords, const std::function< bool(const VaultRecordRef &)> &requestPredicat) const noexcept
The method for getting the result of the request.
Definition Vault.hpp:304
VaultOperationResult RequestGreaterOrEqual(const std::string &key, const T &keyValue, VaultRecordSet &vaultRecordSet, const std::size_t &amountOfRecords=-1, const std::function< bool(const VaultRecordRef &)> &requestPredicat=DefaultRequestPredicat) const noexcept
A method for getting all records that have a value greater than or equal to keyValue stored by the ke...
Definition Vault.hpp:828
VaultOperationResult GetRecords(const std::string &key, const T &keyValue, std::vector< VaultRecordRef > &recordsRefs, const std::size_t &amountOfRecords=-1) const noexcept
The method for getting a vector of references to the data inside Vault.
Definition Vault.hpp:746
VaultDerivedClasses VaultDerivedClass
A variable for storing the object type in the Vault inheritance tree.
Definition Vault.h:106
VaultOperationResult RequestInterval(const std::string &key, const T &beginKeyValue, const T &endKeyValue, VaultRecordSet &vaultRecordSet, const bool &isIncludeBeginKeyValue=true, const bool &isIncludeEndKeyValue=true, const std::size_t &amountOfRecords=-1, const std::function< bool(const VaultRecordRef &)> &requestPredicat=DefaultRequestPredicat) const noexcept
The method for getting the result of the request.
Definition Vault.hpp:861
VaultOperationResult Request(const VaultRequest< Type > &&request, VaultRecordSet &vaultRecordSet) const
A method for complex requests.
Definition Vault.hpp:875
VaultOperationResult RequestLessOrEqual(const std::string &key, const T &keyValue, VaultRecordSet &vaultRecordSet, const std::size_t &amountOfRecords=-1, const std::function< bool(const VaultRecordRef &)> &requestPredicat=DefaultRequestPredicat) const noexcept
A method for getting all records that have a value less than or equal to keyValue stored by the key k...
Definition Vault.hpp:850
std::unordered_set< VaultRecordSet * > RecordSetsSet
Unordered set with all VaultRecordSet pointers.
Definition Vault.h:112
VaultOperationResult AddKey(const std::string &key, const T &defaultKeyValue, const bool &isUniqueKey, const bool &isUniqueKeyWithoutLambda, std::function< T(std::size_t, const VaultRecordRef &)> uniqueKeyFunction) noexcept
Template method to add new key with default value to Vault.
Definition Vault.hpp:355
VaultOperationResult EraseRecords(const std::string &key, const T &keyValue, const std::size_t &amountOfRecords=-1) noexcept
The method for erase records using key and value.
Definition Vault.hpp:1004
VaultOperationResult RequestRecordsSet(const VaultRequestType &requestType, const std::string &key, const T &beginKeyValue, const T &endKeyValue, std::unordered_set< VaultRecord * > &recordsSet, const bool &isIncludeBeginKeyValue, const bool &isIncludeEndKeyValue, const std::size_t &amountOfRecords, const std::function< bool(const VaultRecordRef &)> &requestPredicat) const noexcept
The method for getting the result of the request in the std::set.
Definition Vault.hpp:118
VaultOperationResult UpdateKey(const std::string &key, const T &defaultKeyValue) noexcept
Template method to update default key value.
Definition Vault.hpp:594
VaultOperationResult AddUniqueKey(const std::string &key) noexcept
Template method to add new unique key to Vault.
Definition Vault.hpp:578
A class for storing data inside Vault.
Definition VaultRecord.h:18
A class that provides access to data inside Vault.
Definition VaultRecordRef.h:21
A class for storing query results.
Definition VaultRecordSet.h:14
@ Success
This value is returned when the request was completely successful.
@ DataRecordNotValid
This code is returned when data is requested from the VaultRecordRef and the record it refers to is n...
@ UniqueKeyValueAlredyInSet
This value is returned when the key was found, the requested type and the saved type are equal,...
@ WrongKey
This code is returned when the requested key has not been found.
@ WrongValue
This value is returned when the key was found, the requested type and the saved type are equal,...
@ TryToUpdateUniqueKey
This code is returned when trying to update default value in an unique key.
@ TryToAddUniqueKeyInNonEmptyVaultWithoutLambda
This code is returned when trying to add unique key without lamda in non-empty vault.
@ DuplicateKey
This code is returned when trying to add key which alredy in vault.
@ WrongType
This code is returned when the requested type does not match the saved type.
Structure for storing the results of MVault operations.
Definition VaultOperationResult.h:40