2121
2222#ifdef ENABLE_HISTORICAL_VERBOSE_LOGGING
2323# define HISTORICAL_LOG (...) LOG_INFO_FMT (__VA_ARGS__)
24+ # include < ranges>
2425#else
2526# define HISTORICAL_LOG (...)
2627#endif
@@ -63,7 +64,6 @@ FMT_END_NAMESPACE
6364namespace ccf ::historical
6465{
6566 static constexpr auto slow_fetch_threshold = std::chrono::milliseconds(1000 );
66- static constexpr size_t soft_to_raw_ratio{5 };
6767
6868 static std::optional<ccf::PrimarySignature> get_signature (
6969 const ccf::kv::StorePtr& sig_store)
@@ -269,9 +269,17 @@ namespace ccf::historical
269269 else if (prev_it != my_stores.end () && *new_it > prev_it->first )
270270 {
271271 // No longer looking for a seqno which was previously requested.
272- // Remove it from my_stores
273- removed.push_back (prev_it->first );
274- prev_it = my_stores.erase (prev_it);
272+ if (
273+ supporting_signatures.find (prev_it->first ) ==
274+ supporting_signatures.end ())
275+ {
276+ removed.push_back (prev_it->first );
277+ prev_it = my_stores.erase (prev_it);
278+ }
279+ else
280+ {
281+ ++prev_it;
282+ }
275283 }
276284 else
277285 {
@@ -307,15 +315,31 @@ namespace ccf::historical
307315 if (prev_it != my_stores.end ())
308316 {
309317 // If we have a suffix of seqnos previously requested, now
310- // unrequested, purge them
311- for (auto it = prev_it; it != my_stores.end (); ++it)
318+ // unrequested, purge them - but keep supporting signature entries
319+ auto it = prev_it;
320+ while (it != my_stores.end ())
312321 {
313- removed.push_back (it->first );
322+ if (
323+ supporting_signatures.find (it->first ) ==
324+ supporting_signatures.end ())
325+ {
326+ removed.push_back (it->first );
327+ it = my_stores.erase (it);
328+ }
329+ else
330+ {
331+ ++it;
332+ }
314333 }
315- my_stores.erase (prev_it, my_stores.end ());
316334 }
317335 }
318336
337+ HISTORICAL_LOG (
338+ " Added seqnos: {}, removed seqnos: {}, supporting signatures: {}" ,
339+ fmt::join (added, " ," ),
340+ fmt::join (removed, " ," ),
341+ fmt::join (std::views::keys (supporting_signatures), " ," ));
342+
319343 const bool any_diff = !removed.empty () || !added.empty ();
320344
321345 if (!any_diff && (should_include_receipts == include_receipts))
@@ -338,13 +362,36 @@ namespace ccf::historical
338362
339363 for (auto seqno : new_seqnos)
340364 {
341- populate_receipts (seqno);
365+ auto more_to_add = populate_receipts (seqno);
366+ std::sort (added.begin (), added.end ());
367+ std::sort (more_to_add.begin (), more_to_add.end ());
368+
369+ std::vector<SeqNo> together;
370+ std::merge (
371+ added.begin (),
372+ added.end (),
373+ more_to_add.begin (),
374+ more_to_add.end (),
375+ std::back_inserter (together));
376+
377+ if (more_to_add.size () + added.size () != together.size ())
378+ {
379+ LOG_FAIL_FMT (
380+ " Invariant violation in adjust_ranges: more_to_add({}) + "
381+ " added({}) != together({})" ,
382+ more_to_add.size (),
383+ added.size (),
384+ together.size ());
385+ assert (false );
386+ }
387+
388+ std::swap (added, together);
342389 }
343390 }
344391 return {removed, added};
345392 }
346393
347- void populate_receipts (ccf::SeqNo new_seqno)
394+ std::vector<ccf::SeqNo> populate_receipts (ccf::SeqNo new_seqno)
348395 {
349396 HISTORICAL_LOG (
350397 " Looking at {}, and populating receipts from it" , new_seqno);
@@ -372,6 +419,16 @@ namespace ccf::historical
372419 HISTORICAL_LOG (" {} is not a signature" , new_seqno);
373420 supporting_signatures.erase (new_seqno);
374421
422+ if (new_details->receipt != nullptr )
423+ {
424+ HISTORICAL_LOG (
425+ " Already have a receipt for {}, so no need to populate more" ,
426+ new_seqno);
427+ return {};
428+ }
429+
430+ std::vector<SeqNo> added;
431+
375432 auto next_seqno = new_seqno + 1 ;
376433 while (true )
377434 {
@@ -383,6 +440,18 @@ namespace ccf::historical
383440 HISTORICAL_LOG (
384441 " Looking for new supporting signature at {}" , next_seqno);
385442 details = std::make_shared<StoreDetails>();
443+ auto my_it = my_stores.find (next_seqno);
444+ if (my_it == my_stores.end ())
445+ {
446+ LOG_TRACE_FMT (
447+ " Tracking potential supporting signature for new seqno {} "
448+ " at {}" ,
449+ new_seqno,
450+ next_seqno);
451+ added.push_back (next_seqno);
452+ my_stores.insert_or_assign (my_it, next_seqno, details);
453+ }
454+
386455 all_stores.insert_or_assign (all_it, next_seqno, details);
387456 }
388457
@@ -396,7 +465,7 @@ namespace ccf::historical
396465 next_seqno,
397466 new_seqno);
398467 supporting_signatures[next_seqno] = details;
399- return ;
468+ return added ;
400469 }
401470
402471 if (details->is_signature )
@@ -415,15 +484,18 @@ namespace ccf::historical
415484 new_seqno));
416485 }
417486
418- return ;
487+ return added ;
419488 }
420489
421490 // This is a normal transaction, and its already fetched.
422491 // Nothing to do, consider the next.
423492 ++next_seqno;
424493 }
494+
495+ return added;
425496 }
426497 }
498+ return {};
427499 }
428500
429501 private:
@@ -525,8 +597,6 @@ namespace ccf::historical
525597 std::unordered_map<ccf::SeqNo, size_t > raw_store_sizes;
526598
527599 CacheSize soft_store_cache_limit{std::numeric_limits<size_t >::max ()};
528- CacheSize soft_store_cache_limit_raw =
529- soft_store_cache_limit / soft_to_raw_ratio;
530600 CacheSize estimated_store_cache_size{0 };
531601
532602 void add_request_ref (SeqNo seq, CompoundHandle handle)
@@ -814,7 +884,11 @@ namespace ccf::historical
814884 request.supporting_signatures .end ());
815885 if (seqno_in_this_request)
816886 {
817- request.populate_receipts (seqno);
887+ auto added = request.populate_receipts (seqno);
888+ for (auto seq : added)
889+ {
890+ add_request_ref (seq, handle);
891+ }
818892 }
819893 }
820894
@@ -1158,7 +1232,6 @@ namespace ccf::historical
11581232 void set_soft_cache_limit (CacheSize cache_limit)
11591233 {
11601234 soft_store_cache_limit = cache_limit;
1161- soft_store_cache_limit_raw = soft_store_cache_limit / soft_to_raw_ratio;
11621235 }
11631236
11641237 void track_deletes_on_missing_keys (bool track)
@@ -1450,7 +1523,7 @@ namespace ccf::historical
14501523 }
14511524 }
14521525
1453- lru_shrink_to_fit (soft_store_cache_limit_raw );
1526+ lru_shrink_to_fit (soft_store_cache_limit );
14541527
14551528 {
14561529 auto it = all_stores.begin ();
@@ -1648,5 +1721,10 @@ namespace ccf::historical
16481721 {
16491722 return StateCacheImpl::drop_cached_states (make_compound_handle (handle));
16501723 }
1724+
1725+ size_t get_estimated_store_cache_size () override
1726+ {
1727+ return StateCacheImpl::get_estimated_store_cache_size ();
1728+ }
16511729 };
16521730}
0 commit comments