Loading...
Searching...
No Matches
levelSetCache.tpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License v3 (LGPL)
13 * as published by the Free Software Foundation.
14 *
15 * bitpit is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
25# ifndef __BITPIT_LEVELSET_CACHE_TPP__
26# define __BITPIT_LEVELSET_CACHE_TPP__
27
28namespace bitpit {
29
33template<typename value_t>
35
43template<typename value_t>
48
55template<typename value_t>
57{
58 return m_valid;
59}
60
64template<typename value_t>
66 : LevelSetValueCacheBaseEntry<value_t>(false),
67 m_value(std::cref(LevelSetValueCacheBaseEntry<value_t>::m_dummyValue))
68{
69}
70
76template<typename value_t>
78 : LevelSetValueCacheBaseEntry<value_t>(true),
79 m_value(value)
80{
81}
82
88template<typename value_t>
90{
91 return m_value;
92}
93
102template<typename key_t>
103template<typename Keys>
104std::size_t LevelSetCache<key_t>::erase(const Keys &keys)
106 std::size_t nDeletedEntries = 0;
107 for (const key_t &key : keys) {
108 nDeletedEntries += erase(key);
109 }
110
111 return nDeletedEntries;
112}
113
119template<typename key_t, typename container_t, typename value_t, typename reference_t, typename const_reference_t>
120template<typename... Args>
125
131template<typename key_t, typename container_t, typename value_t, typename reference_t, typename const_reference_t>
132typename LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::iterator LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::begin()
133{
134 return m_container.begin();
135}
136
142template<typename key_t, typename container_t, typename value_t, typename reference_t, typename const_reference_t>
143typename LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::iterator LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::end()
144{
145 return m_container.end();
146}
147
153template<typename key_t, typename container_t, typename value_t, typename reference_t, typename const_reference_t>
154typename LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::const_iterator LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::begin() const
155{
156 return m_container.cbegin();
157}
158
164template<typename key_t, typename container_t, typename value_t, typename reference_t, typename const_reference_t>
165typename LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::const_iterator LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::end() const
166{
167 return m_container.cend();
168}
169
175template<typename key_t, typename container_t, typename value_t, typename reference_t, typename const_reference_t>
176typename LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::const_iterator LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::cbegin() const
177{
178 return m_container.cbegin();
179}
180
186template<typename key_t, typename container_t, typename value_t, typename reference_t, typename const_reference_t>
187typename LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::const_iterator LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::cend() const
188{
189 return m_container.cend();
191
198template<typename key_t, typename container_t, typename value_t, typename reference_t, typename const_reference_t>
201 return (find(key) != m_container.cend());
203
214template<typename key_t, typename container_t, typename value_t, typename reference_t, typename const_reference_t>
216{
217 const_iterator itr = find(key);
218 if (itr != end()) {
219 return Entry(getValue(itr));
220 } else {
221 return Entry();
222 }
223}
224
235template<typename key_t, typename container_t, typename value_t, typename reference_t, typename const_reference_t>
237{
238 const_iterator itr = insert(key, value);
239
240 return Entry(getValue(itr));
241}
242
253template<typename key_t, typename container_t, typename value_t, typename reference_t, typename const_reference_t>
255{
256 const_iterator itr = insert(key, std::move(value));
257
258 return Entry(getValue(itr));
259}
260
269template<typename key_t, typename container_t, typename value_t, typename reference_t, typename const_reference_t>
270typename LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::reference LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::at(const key_t &key)
271{
272 return *(find(key));
273}
274
283template<typename key_t, typename container_t, typename value_t, typename reference_t, typename const_reference_t>
284typename LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::const_reference LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::at(const key_t &key) const
285{
286 return getValue(find(key));
287}
288
297template<typename key_t, typename container_t, typename value_t, typename reference_t, typename const_reference_t>
298typename LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::reference LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::operator[](const key_t &key)
299{
300 return getValue(find(key));
301}
302
311template<typename key_t, typename container_t, typename value_t, typename reference_t, typename const_reference_t>
312typename LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::const_reference LevelSetContainerBaseCache<key_t, container_t, value_t, reference_t, const_reference_t>::operator[](const key_t &key) const
313{
314 return getValue(find(key));
315}
316
317#if BITPIT_ENABLE_MPI
323template<typename key_t, typename container_t, typename value_t, typename reference_t, typename const_reference_t>
325{
326 return sizeof(bool) + sizeof(value_t);
327}
328
335template<typename key_t, typename container_t, typename value_t, typename reference_t, typename const_reference_t>
337{
338 for (const key_t &key : keys) {
339 const_iterator itr = find(key);
340 if (itr != cend()) {
341 buffer << static_cast<unsigned char>(1);
342 buffer << getValue(itr);
343 } else {
344 buffer << static_cast<unsigned char>(0);
345 }
346 }
347}
348
355template<typename key_t, typename container_t, typename value_t, typename reference_t, typename const_reference_t>
357{
358 value_t value;
359 for (const key_t &key : keys) {
360 unsigned char isCached;
361 buffer >> isCached;
362 if (isCached == 1) {
363 buffer >> value;
364
365 insert(key, value);
366 }
367 }
368}
369#endif
370
376template<typename key_t, typename value_t>
377LevelSetContainerCache<key_t, std::unordered_map<key_t, value_t>>::LevelSetContainerCache(std::size_t capacity)
378 : Base()
379{
380 Base::m_container.reserve(capacity);
381}
382
388template<typename key_t, typename value_t>
389std::unique_ptr<LevelSetCache<key_t>> LevelSetContainerCache<key_t, std::unordered_map<key_t, value_t>>::clone() const
390{
391 return std::unique_ptr<LevelSetCache<key_t>>(new LevelSetContainerCache<key_t, std::unordered_map<key_t, value_t>>(*this));
392}
393
399template<typename key_t, typename value_t>
401{
402 Base::m_container.reserve(n);
403}
404
408template<typename key_t, typename value_t>
410{
411 // Nothing to do
412}
413
417template<typename key_t, typename value_t>
419{
420 Base::m_container.clear();
421}
422
432template<typename key_t, typename value_t>
434{
435 return Base::m_container.find(key);
436}
437
447template<typename key_t, typename value_t>
449{
450 return Base::m_container.find(key);
451}
452
463template<typename key_t, typename value_t>
465{
466 auto itr = Base::m_container.find(key);
467 if (itr != Base::m_container.end()) {
468 itr->second = value;
469 } else {
470 itr = Base::m_container.insert({key, value}).first;
471 }
472
473 return itr;
474}
475
486template<typename key_t, typename value_t>
488{
489 auto itr = Base::m_container.find(key);
490 if (itr != Base::m_container.end()) {
491 itr->second = std::move(value);
492 } else {
493 itr = Base::m_container.insert({key, std::move(value)}).first;
494 }
495
496 return itr;
497}
498
505template<typename key_t, typename value_t>
507{
508 return Base::m_container.erase(key);
509}
510
539template<typename key_t, typename value_t>
541{
542 return false;
543}
544
550template<typename key_t, typename value_t>
552{
553 utils::binary::write(stream, Base::m_container.size());
554 for (const auto &entry : Base::m_container) {
555 utils::binary::write(stream, entry.first);
556 utils::binary::write(stream, entry.second);
557 }
558}
559
565template<typename key_t, typename value_t>
567{
568 Base::m_container.clear();
569
570 std::size_t nEntries;
571 utils::binary::read(stream, nEntries);
572 Base::m_container.reserve(nEntries);
573
574 for (std::size_t i = 0; i < nEntries; ++i) {
575 key_t key;
576 utils::binary::read(stream, key);
577
578 value_t value;
579 utils::binary::read(stream, value);
580
581 Base::m_container[key] = std::move(value);
582 }
583}
584
591template<typename key_t, typename value_t>
592key_t LevelSetContainerCache<key_t, std::unordered_map<key_t, value_t>>::getKey(const const_iterator &itr) const
593{
594 return itr->first;
595}
603template<typename key_t, typename value_t>
605{
606 return itr->second;
615template<typename key_t, typename value_t>
617{
618 return itr->second;
619}
620
626template<typename key_t, typename value_t>
627LevelSetContainerCache<key_t, std::vector<value_t>>::LevelSetContainerCache(std::size_t capacity)
628 : Base()
629{
630 Base::m_container.reserve(capacity);
631 m_isCached.reserve(capacity);
632}
633
639template<typename key_t, typename value_t>
640std::unique_ptr<LevelSetCache<key_t>> LevelSetContainerCache<key_t, std::vector<value_t>>::clone() const
641{
642 return std::unique_ptr<LevelSetCache<key_t>>(new LevelSetContainerCache<key_t, std::vector<value_t>>(*this));
644
650template<typename key_t, typename value_t>
652{
653 Base::m_container.reserve(n);
655
659template<typename key_t, typename value_t>
662 if (m_isCached.empty()) {
663 return;
664 }
665
666 std::size_t capacity = m_isCached.size();
667 while (capacity > 0 && !m_isCached[capacity - 1]) {
668 --capacity;
669 }
670
671 Base::m_container.resize(capacity);
672 m_isCached.resize(capacity);
673}
674
678template<typename key_t, typename value_t>
680{
681 std::fill(m_isCached.begin(), m_isCached.end(), false);
682}
683
693template<typename key_t, typename value_t>
695{
696 if (key < static_cast<key_t>(Base::m_container.size()) && m_isCached[key]) {
697 return (Base::m_container.begin() + key);
698 } else {
699 return Base::m_container.end();
700 }
701}
702
712template<typename key_t, typename value_t>
714{
715 if (key < static_cast<key_t>(Base::m_container.size()) && m_isCached[key]) {
716 return (Base::m_container.cbegin() + key);
717 } else {
718 return Base::m_container.cend();
719 }
720}
721
732template<typename key_t, typename value_t>
733typename LevelSetContainerCache<key_t, std::vector<value_t>>::iterator LevelSetContainerCache<key_t, std::vector<value_t>>::insert(const key_t &key, const value_t &value)
734{
735 if (key >= static_cast<key_t>(Base::m_container.size())) {
736 Base::m_container.resize(key + 1);
737 m_isCached.resize(key + 1);
738 }
739
740 auto itr = Base::m_container.begin() + key;
741
742 *itr = value;
743 m_isCached[key] = true;
744
745 return itr;
746}
747
758template<typename key_t, typename value_t>
760{
761 if (key >= static_cast<key_t>(Base::m_container.size())) {
762 Base::m_container.resize(key + 1);
763 m_isCached.resize(key + 1);
764 }
765
766 auto itr = Base::m_container.begin() + key;
767
768 *itr = std::move(value);
769 m_isCached[key] = true;
770
771 return itr;
772}
773
780template<typename key_t, typename value_t>
781std::size_t LevelSetContainerCache<key_t, std::vector<value_t>>::erase(const key_t &key)
782{
783 if (static_cast<std::size_t>(key) >= m_isCached.size()) {
784 return 0;
785 }
786
787 m_isCached[key] = false;
788
789 return 1;
790}
791
820template<typename key_t, typename value_t>
822{
823 return false;
824}
825
831template<typename key_t, typename value_t>
833{
834 utils::binary::write(stream, Base::m_container);
835 utils::binary::write(stream, m_isCached);
836}
837
843template<typename key_t, typename value_t>
844void LevelSetContainerCache<key_t, std::vector<value_t>>::restore(std::istream &stream)
845{
846 utils::binary::read(stream, Base::m_container);
847 utils::binary::read(stream, m_isCached);
848}
849
856template<typename key_t, typename value_t>
857key_t LevelSetContainerCache<key_t, std::vector<value_t>>::getKey(const const_iterator &itr) const
858{
859 return static_cast<key_t>((itr - Base::m_container.begin()));
860}
861
868template<typename key_t, typename value_t>
870{
871 return *itr;
872}
873
880template<typename key_t, typename value_t>
881typename LevelSetContainerCache<key_t, std::vector<value_t>>::const_reference LevelSetContainerCache<key_t, std::vector<value_t>>::getValue(const const_iterator &itr) const
882{
883 return *itr;
884}
885
886
892template<typename key_t, typename value_t>
893LevelSetContainerCache<key_t, PiercedVector<value_t, key_t>>::LevelSetContainerCache(std::size_t capacity)
894 : Base()
895{
896 Base::m_container.reserve(capacity);
897}
898
904template<typename key_t, typename value_t>
905std::unique_ptr<LevelSetCache<key_t>> LevelSetContainerCache<key_t, PiercedVector<value_t, key_t>>::clone() const
906{
907 return std::unique_ptr<LevelSetCache<key_t>>(new LevelSetContainerCache<key_t, PiercedVector<value_t, key_t>>(*this));
908}
909
915template<typename key_t, typename value_t>
917{
918 Base::m_container.reserve(n);
919}
920
924template<typename key_t, typename value_t>
926{
927 Base::m_container.squeeze();
928}
929
933template<typename key_t, typename value_t>
935{
936 Base::m_container.clear();
937}
938
948template<typename key_t, typename value_t>
950{
951 return Base::m_container.find(key);
952}
953
963template<typename key_t, typename value_t>
965{
966 return Base::m_container.find(key);
967}
968
979template<typename key_t, typename value_t>
981{
982 auto itr = Base::m_container.find(key);
983 if (itr == Base::m_container.end()) {
984 itr = Base::m_container.reclaim(key);
985 }
986
987 *itr = value;
988
989 return itr;
990}
991
1002template<typename key_t, typename value_t>
1004{
1005 auto itr = Base::m_container.find(key);
1006 if (itr == Base::m_container.end()) {
1007 itr = Base::m_container.reclaim(key);
1008 }
1009
1010 *itr = std::move(value);
1011
1012 return itr;
1013}
1014
1021template<typename key_t, typename value_t>
1023{
1024 if (!Base::m_container.contains(key)) {
1025 return 0;
1026 }
1027
1028 Base::m_container.erase(key);
1029
1030 return 1;
1031}
1032
1061template<typename key_t, typename value_t>
1063{
1064 return false;
1065}
1066
1072template<typename key_t, typename value_t>
1074{
1075 Base::m_container.dump(stream);
1076}
1077
1083template<typename key_t, typename value_t>
1085{
1086 Base::m_container.restore(stream);
1087}
1088
1095template<typename key_t, typename value_t>
1096key_t LevelSetContainerCache<key_t, PiercedVector<value_t, key_t>>::getKey(const const_iterator &itr) const
1097{
1098 return itr.getId();
1099}
1100
1107template<typename key_t, typename value_t>
1109{
1110 return *itr;
1111}
1112
1119template<typename key_t, typename value_t>
1121{
1122 return *itr;
1123}
1124
1131template<typename key_t, typename value_t>
1133 : Base(1, kernel, syncMode),
1134 m_isCached(1, kernel, syncMode)
1135{
1136 m_isCached.fill(false);
1137}
1138
1144template<typename key_t, typename value_t>
1145std::unique_ptr<LevelSetCache<key_t>> LevelSetContainerCache<key_t, PiercedStorage<value_t, key_t>>::clone() const
1146{
1147 return std::unique_ptr<LevelSetCache<key_t>>(new LevelSetContainerCache<key_t, PiercedStorage<value_t, key_t>>(*this));
1148}
1149
1155template<typename key_t, typename value_t>
1157{
1158 BITPIT_UNUSED(n);
1159
1160 // Nothing to do
1161}
1162
1166template<typename key_t, typename value_t>
1168{
1169 // Nothing to do
1170}
1171
1175template<typename key_t, typename value_t>
1177{
1178 m_isCached.fill(false);
1179}
1180
1190template<typename key_t, typename value_t>
1192{
1193 iterator itr = Base::m_container.find(key);
1194 std::size_t rawId = itr.getRawIndex();
1195
1196 if (m_isCached.rawAt(rawId)) {
1197 return itr;
1198 } else {
1199 return Base::m_container.end();
1200 }
1201}
1202
1212template<typename key_t, typename value_t>
1214{
1215 const_iterator itr = Base::m_container.find(key);
1216 std::size_t rawId = itr.getRawIndex();
1217
1218 if (m_isCached.rawAt(rawId)) {
1219 return itr;
1220 } else {
1221 return Base::m_container.cend();
1222 }
1223}
1224
1235template<typename key_t, typename value_t>
1237{
1238 auto itr = Base::m_container.find(key);
1239 std::size_t rawId = itr.getRawIndex();
1240
1241 *itr = value;
1242 m_isCached.rawAt(rawId) = true;
1243
1244 return itr;
1245}
1246
1257template<typename key_t, typename value_t>
1259{
1260 auto itr = Base::m_container.find(key);
1261 std::size_t rawId = itr.getRawIndex();
1262
1263 *itr = std::move(value);
1264 m_isCached.rawAt(rawId) = true;
1265
1266 return itr;
1267}
1268
1275template<typename key_t, typename value_t>
1277{
1278 // Even if we are calling this function after the storages have been synchronized, we may
1279 // still need to mark the element associated with the key as non-cached. After synchronizing
1280 // the storages, the key may be associated with a different element. However, since we are
1281 // calling this function, no cache have been initialized for this new element. Hence, we need
1282 // to mark the new element as non-cached. If the key is not associated with a new element,
1283 // nothing should be done, because the storages don't contain anymore an entry for the key.
1284 auto itr = Base::m_container.find(key);
1285 if (itr == Base::m_container.end()) {
1286 return 0;
1287 }
1288
1289 std::size_t rawId = itr.getRawIndex();
1290
1291 m_isCached.rawAt(rawId) = false;
1292
1293 return 1;
1294}
1295
1324template<typename key_t, typename value_t>
1326{
1327 return (Base::m_container.getSyncMode() != PiercedSyncMaster::SyncMode::SYNC_MODE_DISABLED);
1328}
1329
1335template<typename key_t, typename value_t>
1337{
1338 Base::m_container.dump(stream);
1339 m_isCached.dump(stream);
1340}
1341
1347template<typename key_t, typename value_t>
1349{
1350 Base::m_container.restore(stream);
1351 m_isCached.restore(stream);
1352}
1353
1360template<typename key_t, typename value_t>
1361key_t LevelSetContainerCache<key_t, PiercedStorage<value_t, key_t>>::getKey(const const_iterator &itr) const
1362{
1363 return itr.getId();
1364}
1365
1372template<typename key_t, typename value_t>
1374{
1375 return *itr;
1376}
1377
1384template<typename key_t, typename value_t>
1386{
1387 return *itr;
1388}
1389
1395template<typename key_t, typename value_t>
1396std::unique_ptr<LevelSetCache<key_t>> LevelSetContainerCacheFactory<key_t, std::unordered_map<key_t ,value_t>>::create() const
1397{
1398 return std::unique_ptr<LevelSetCache<key_t>>(new LevelSetContainerCache<key_t, std::unordered_map<key_t ,value_t>>());
1399}
1400
1406template<typename key_t, typename value_t>
1407std::unique_ptr<LevelSetCache<key_t>> LevelSetContainerCacheFactory<key_t, std::vector<value_t>>::create() const
1408{
1409 return std::unique_ptr<LevelSetCache<key_t>>(new LevelSetContainerCache<key_t, std::vector<value_t>>());
1410}
1411
1417template<typename key_t, typename value_t>
1418std::unique_ptr<LevelSetCache<key_t>> LevelSetContainerCacheFactory<key_t, PiercedVector<value_t, key_t>>::create() const
1419{
1420 return std::unique_ptr<LevelSetCache<key_t>>(new LevelSetContainerCache<key_t, PiercedVector<value_t, key_t>>());
1421}
1422
1429template<typename key_t, typename value_t>
1431 : Base(),
1432 m_kernel(kernel), m_syncMode(syncMode)
1433{
1434}
1435
1441template<typename key_t, typename value_t>
1442std::unique_ptr<LevelSetCache<key_t>> LevelSetContainerCacheFactory<key_t, PiercedStorage<value_t, key_t>>::create() const
1443{
1444 return std::unique_ptr<LevelSetCache<key_t>>(new LevelSetContainerCache<key_t, PiercedStorage<value_t, key_t>>(m_kernel, m_syncMode));
1445}
1446
1461template<typename key_t>
1463 : m_factory(factory),
1464 m_cache(nullptr)
1465{
1466}
1467
1473template<typename key_t>
1475 : m_factory(other.m_factory),
1476 m_cache(other.m_cache->clone())
1477{
1478}
1479
1486template<typename key_t>
1488{
1489 m_factory = other.m_factory;
1490 m_cache = other.m_cache->clone();
1491
1492 return *this;
1493}
1494
1500template<typename key_t>
1502{
1503 return !!m_factory;
1504}
1505
1511template<typename key_t>
1513{
1514 return !!m_cache;
1515}
1516
1526template<typename key_t>
1531
1541template<typename key_t>
1543{
1544 // Early return if the cache has already been created
1545 if (hasCache()) {
1546 return m_cache.get();
1547 }
1548
1549 // Create the cache
1550 if (m_factory) {
1551 m_cache = m_factory->create();
1552 return m_cache.get();
1553 }
1554
1555 // No cache can be created for the item
1556 return nullptr;
1557}
1558
1562template<typename key_t>
1564{
1565 return m_cache.reset();
1566}
1567
1576template<typename key_t>
1578{
1579 return const_cast<LevelSetCache<key_t> *>(const_cast<const LevelSetCacheCollection<key_t>::Item &>(*this).getCache(allowCreation));
1580}
1581
1590template<typename key_t>
1592{
1593 // Early return if the cache has already been created
1594 if (hasCache()) {
1595 return m_cache.get();
1596 }
1597
1598 // Create the cache
1599 if (allowCreation) {
1600 return _createCache();
1601 }
1602
1603 // No cache can be created for the item
1604 return nullptr;
1605}
1606
1615template<typename key_t>
1616template<typename value_t>
1618{
1619 return const_cast<LevelSetValueCache<key_t, value_t> *>(const_cast<const LevelSetCacheCollection<key_t>::Item &>(*this).getCache<value_t>(allowCreation));
1620}
1621
1630template<typename key_t>
1631template<typename value_t>
1633{
1634 assert(!hasCache() || dynamic_cast<const LevelSetValueCache<key_t BITPIT_COMMA value_t> *>(getCache(allowCreation)));
1635
1636 return static_cast<const LevelSetValueCache<key_t, value_t> *>(getCache(allowCreation));
1637}
1638
1649template<typename key_t>
1650const std::size_t LevelSetCacheCollection<key_t>::NULL_CACHE_ID = std::numeric_limits<std::size_t>::max();
1651
1657template<typename key_t>
1659 : m_caches(other.m_caches.size())
1660{
1661 for (std::size_t i = 0; i < other.m_caches.size(); ++i) {
1662 m_caches[i] = other.m_caches[i];
1663 }
1664}
1665
1671template<typename key_t>
1672std::unique_ptr<LevelSetCacheCollection<key_t>> LevelSetCacheCollection<key_t>::clone() const
1673{
1674 return std::unique_ptr<LevelSetCacheCollection<key_t>>(new LevelSetCacheCollection<key_t>(*this));
1675}
1676
1682template<typename key_t>
1683typename LevelSetCacheCollection<key_t>::iterator LevelSetCacheCollection<key_t>::begin()
1684{
1685 return m_caches.begin();
1686}
1687
1693template<typename key_t>
1694typename LevelSetCacheCollection<key_t>::iterator LevelSetCacheCollection<key_t>::end()
1695{
1696 return m_caches.end();
1697}
1698
1704template<typename key_t>
1705typename LevelSetCacheCollection<key_t>::const_iterator LevelSetCacheCollection<key_t>::begin() const
1706{
1707 return m_caches.cbegin();
1708}
1709
1715template<typename key_t>
1716typename LevelSetCacheCollection<key_t>::const_iterator LevelSetCacheCollection<key_t>::end() const
1717{
1718 return m_caches.cend();
1719}
1720
1726template<typename key_t>
1727typename LevelSetCacheCollection<key_t>::const_iterator LevelSetCacheCollection<key_t>::cbegin() const
1728{
1729 return m_caches.cbegin();
1730}
1731
1737template<typename key_t>
1738typename LevelSetCacheCollection<key_t>::const_iterator LevelSetCacheCollection<key_t>::cend() const
1739{
1740 return m_caches.cend();
1741}
1742
1748template<typename key_t>
1750{
1751 return m_caches.size();
1752}
1753
1762template<typename id_t>
1763template<typename container_t, typename... Args>
1764std::size_t LevelSetCacheCollection<id_t>::insert(std::size_t index, Args&&... args)
1765{
1766 std::size_t nCaches = m_caches.size();
1767
1768 // Assign an index to the cache
1769 //
1770 // If a null index is specified, an index will be generated automatically. The automatic
1771 // generation process will first attempt to reuse a previously generated index using the
1772 // following criteria: if an existing cache is not associated with a factory, it means
1773 // that it has been erased and therefore the index can be reused. If no indexes can be
1774 // reused, the newly created cache will be appended at the end of the collection.
1775 if (index == NULL_CACHE_ID) {
1776 index = 0;
1777 while (index < nCaches) {
1778 if (!m_caches[index].hasFactory()) {
1779 break;
1780 }
1781 ++index;
1782 }
1783 }
1784
1785 // Create the factory
1786 typedef typename LevelSetContainerCache<id_t, container_t>::value_type value_type;
1787
1788 auto factory = std::shared_ptr<LevelSetValueCacheFactory<id_t, value_type>>(new LevelSetContainerCacheFactory<id_t, container_t>(std::forward<Args>(args)...));
1789
1790 // Create the cache
1791 if (index < nCaches) {
1792 m_caches.emplace(m_caches.begin() + index, factory);
1793 } else {
1794 for (std::size_t k = nCaches; k < index; ++k) {
1795 m_caches.emplace_back(Item());
1796 }
1797 m_caches.emplace_back(factory);
1798 }
1799
1800 return index;
1801}
1802
1808template<typename key_t>
1810{
1811 // Early return if the specified index is not valid
1812 if (index == NULL_CACHE_ID) {
1813 return;
1814 } else if (index >= m_caches.size()) {
1815 return;
1816 }
1817
1818 // To avoid invalidating the index of other caches, we cannot remove the cache and its
1819 // factory from the collection. A cache will be deleted clearing destroying its storage
1820 // and its factory. The index associated to the cache will be re-used when a new cache
1821 // will be inserted.
1822 m_caches[index] = Item();
1823}
1824
1828template<typename key_t>
1830{
1831 m_caches.clear();
1832 m_caches.shrink_to_fit();
1833}
1834
1845template<typename key_t>
1847{
1848 return const_cast<LevelSetCacheCollection<key_t>::Item &>(const_cast<const LevelSetCacheCollection<key_t> &>(*this).at(index));
1849}
1850
1861template<typename key_t>
1863{
1864 return m_caches[index];
1865}
1866
1876template<typename key_t>
1878{
1879 return const_cast<LevelSetCacheCollection<key_t>::Item &>(const_cast<const LevelSetCacheCollection<key_t> &>(*this).at(index));
1880}
1881
1891template<typename key_t>
1893{
1894 return m_caches.at(index);
1895}
1896
1904template<typename container_t, typename... Args, typename std::enable_if<std::is_same<bitpit::PiercedStorage<typename container_t::value_type>, container_t>::value>::type *>
1905std::size_t ElementCacheCollection::insert(std::size_t index, Args&&... args)
1906{
1907 PiercedSyncMaster::SyncMode cacheSyncMode = PiercedSyncMaster::SyncMode::SYNC_MODE_JOURNALED;
1908
1909 return LevelSetCacheCollection<long>::insert<container_t>(index, m_kernel, cacheSyncMode, std::forward<Args>(args)...);
1910}
1911
1919template<typename container_t, typename... Args, typename std::enable_if<!std::is_same<bitpit::PiercedStorage<typename container_t::value_type>, container_t>::value>::type *>
1920std::size_t ElementCacheCollection::insert(std::size_t index, Args&&... args)
1921{
1922 return Base::insert<container_t, Args...>(index, std::forward<Args>(args)...);
1923}
1924
1925}
1926
1927#endif
std::size_t insert(std::size_t index, Args &&... args)
The class LevelSetCacheCollection::Item defines the items stored in a cache collection....
Item(const std::shared_ptr< LevelSetCacheFactory< key_t > > &factory=nullptr)
LevelSetCache< key_t > * getCache(bool allowCreation=true)
LevelSetCache< key_t > * createCache()
The class LevelSetCacheCollection allows to store a collection of caches.
std::size_t insert(std::size_t index, Args &&... args)
void erase(std::size_t index)
Caches m_caches
Caches owned by the collection.
virtual std::unique_ptr< LevelSetCacheCollection< key_t > > clone() const
Item & operator[](std::size_t index)
Item & at(std::size_t index)
The class LevelSetCacheFactory provides basic functionalities for cache factories.
The class LevelSetCache is the base class for defining caches.
std::size_t erase(const Keys &keys)
The class LevelSetContainerBaseCache is the base class for defining caches that stores the values ins...
Entry findEntry(const key_t &key) const override
void writeBuffer(const std::vector< key_t > &ids, SendBuffer &buffer) const override
Entry insertEntry(const key_t &key, const value_t &value) override
std::size_t getEntryBinarySize() const override
reference at(const key_t &key)
reference operator[](const key_t &key)
void readBuffer(const std::vector< key_t > &ids, RecvBuffer &buffer) override
bool contains(const key_t &key) const override
The class LevelSetContainerCacheFactory provides basic functionalities for cache factories.
The class LevelSetContainerCache is the class for defining caches that stores the values inside a con...
The class LevelSetValueCacheEntry allows to get read-only access to a value stored in the cache.
const value_t & operator*() const
The class LevelSetCache is the base class for defining caches that store values.
Metafunction for generating a pierced kernel.
Buffer to be used for receive communications.
Buffer to be used for send communications.
void write(std::ostream &stream, const std::vector< bool > &container)
void read(std::istream &stream, std::vector< bool > &container)
#define BITPIT_UNUSED(variable)
Definition compiler.hpp:63
--- layout: doxygen_footer ---