@@ -32,18 +32,13 @@ namespace cbdc::locking_shard {
32
32
m_logger (std::move(logger)),
33
33
m_completed_txs(completed_txs_cache_size),
34
34
m_opts(std::move(opts)) {
35
- m_uhs.max_load_factor (std::numeric_limits<float >::max ());
36
35
m_applied_dtxs.max_load_factor (std::numeric_limits<float >::max ());
37
36
m_prepared_dtxs.max_load_factor (std::numeric_limits<float >::max ());
38
- m_locked.max_load_factor (std::numeric_limits<float >::max ());
39
37
40
38
static constexpr auto dtx_buckets = 100000 ;
41
39
m_applied_dtxs.rehash (dtx_buckets);
42
40
m_prepared_dtxs.rehash (dtx_buckets);
43
41
44
- static constexpr auto locked_buckets = 10000000 ;
45
- m_locked.rehash (locked_buckets);
46
-
47
42
if (!preseed_file.empty ()) {
48
43
m_logger->info (" Reading preseed file into memory" );
49
44
if (!read_preseed_file (preseed_file)) {
@@ -65,12 +60,9 @@ namespace cbdc::locking_shard {
65
60
}
66
61
in.seekg (0 , std::ios::beg);
67
62
auto deser = istream_serializer (in);
68
- m_uhs.clear ();
69
- static constexpr auto uhs_size_factor = 2 ;
70
- auto bucket_count = static_cast <unsigned long >(sz / cbdc::hash_size
71
- * uhs_size_factor);
72
- m_uhs.rehash (bucket_count);
73
- deser >> m_uhs;
63
+ auto uhs = std::map<hash_t , uhs_element>();
64
+ deser >> uhs;
65
+ m_uhs = std::move (uhs);
74
66
return true ;
75
67
}
76
68
return false ;
@@ -215,22 +207,17 @@ namespace cbdc::locking_shard {
215
207
}
216
208
}
217
209
218
- auto locking_shard::audit (uint64_t epoch) const
219
- -> std::optional<uint64_t> {
220
- auto uhs = decltype (m_uhs)();
221
- auto locked = decltype (m_locked)();
222
- auto spent = decltype (m_spent)();
210
+ auto locking_shard::audit (uint64_t epoch) -> std::optional<uint64_t> {
223
211
{
224
- std::shared_lock l (m_mut);
225
- uhs = m_uhs;
226
- locked = m_locked;
227
- spent = m_spent;
212
+ std::unique_lock l (m_mut);
213
+ m_uhs. snapshot () ;
214
+ m_locked. snapshot () ;
215
+ m_spent. snapshot () ;
228
216
}
229
217
230
218
auto check_uhs
231
- = [epoch](
232
- const std::unordered_map<hash_t , uhs_element, hashing::null>&
233
- uhs_map) -> std::optional<uint64_t > {
219
+ = [epoch](const snapshot_map<hash_t , uhs_element>& uhs_map)
220
+ -> std::optional<uint64_t > {
234
221
uint64_t tot{};
235
222
for (const auto & [id, elem] : uhs_map) {
236
223
if (elem.m_creation_epoch <= epoch
@@ -247,24 +234,34 @@ namespace cbdc::locking_shard {
247
234
return tot;
248
235
};
249
236
237
+ // TODO: use bignum because tot will probably overflow
250
238
uint64_t tot{};
251
- auto uhs_tot = check_uhs (uhs );
252
- if (! uhs_tot.has_value ()) {
253
- return std::nullopt ;
239
+ auto uhs_tot = check_uhs (m_uhs );
240
+ if (uhs_tot.has_value ()) {
241
+ tot += uhs_tot. value () ;
254
242
}
255
- tot += uhs_tot.value ();
256
243
257
- auto locked_tot = check_uhs (locked);
258
- if (!locked_tot.has_value ()) {
259
- return std::nullopt;
244
+ auto locked_tot = check_uhs (m_locked);
245
+ if (locked_tot.has_value ()) {
246
+ tot += locked_tot.value ();
247
+ }
248
+
249
+ auto spent_tot = check_uhs (m_spent);
250
+ if (spent_tot.has_value ()) {
251
+ tot += spent_tot.value ();
252
+ }
253
+
254
+ {
255
+ std::unique_lock l (m_mut);
256
+ m_uhs.release_snapshot ();
257
+ m_locked.release_snapshot ();
258
+ m_spent.release_snapshot ();
260
259
}
261
- tot += locked_tot.value ();
262
260
263
- auto spent_tot = check_uhs (spent);
264
- if (!spent_tot .has_value ()) {
261
+ if (! spent_tot. has_value () || !locked_tot. has_value ()
262
+ || !uhs_tot .has_value ()) {
265
263
return std::nullopt;
266
264
}
267
- tot += spent_tot.value ();
268
265
269
266
return tot;
270
267
}
@@ -277,7 +274,7 @@ namespace cbdc::locking_shard {
277
274
void locking_shard::prune (uint64_t epoch) {
278
275
std::unique_lock l (m_mut);
279
276
for (auto it = m_spent.begin (); it != m_spent.end ();) {
280
- auto & elem = it->second ;
277
+ const auto & elem = it->second ;
281
278
if (elem.m_deletion_epoch .value () < epoch) {
282
279
it = m_spent.erase (it);
283
280
} else {
0 commit comments