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
@@ -64,7 +65,6 @@ FMT_END_NAMESPACE
6465namespace ccf ::historical
6566{
6667 static constexpr auto slow_fetch_threshold = std::chrono::milliseconds(1000 );
67- static constexpr size_t soft_to_raw_ratio{5 };
6868
6969 static std::optional<ccf::PrimarySignature> get_signature (
7070 const ccf::kv::StorePtr& sig_store)
@@ -273,9 +273,17 @@ namespace ccf::historical
273273 else if (prev_it != my_stores.end () && *new_it > prev_it->first )
274274 {
275275 // No longer looking for a seqno which was previously requested.
276- // Remove it from my_stores
277- removed.push_back (prev_it->first );
278- prev_it = my_stores.erase (prev_it);
276+ if (
277+ supporting_signatures.find (prev_it->first ) ==
278+ supporting_signatures.end ())
279+ {
280+ removed.push_back (prev_it->first );
281+ prev_it = my_stores.erase (prev_it);
282+ }
283+ else
284+ {
285+ ++prev_it;
286+ }
279287 }
280288 else
281289 {
@@ -311,15 +319,31 @@ namespace ccf::historical
311319 if (prev_it != my_stores.end ())
312320 {
313321 // If we have a suffix of seqnos previously requested, now
314- // unrequested, purge them
315- for (auto it = prev_it; it != my_stores.end (); ++it)
322+ // unrequested, purge them - but keep supporting signature entries
323+ auto it = prev_it;
324+ while (it != my_stores.end ())
316325 {
317- removed.push_back (it->first );
326+ if (
327+ supporting_signatures.find (it->first ) ==
328+ supporting_signatures.end ())
329+ {
330+ removed.push_back (it->first );
331+ it = my_stores.erase (it);
332+ }
333+ else
334+ {
335+ ++it;
336+ }
318337 }
319- my_stores.erase (prev_it, my_stores.end ());
320338 }
321339 }
322340
341+ HISTORICAL_LOG (
342+ " Added seqnos: {}, removed seqnos: {}, supporting signatures: {}" ,
343+ fmt::join (added, " ," ),
344+ fmt::join (removed, " ," ),
345+ fmt::join (std::views::keys (supporting_signatures), " ," ));
346+
323347 const bool any_diff = !removed.empty () || !added.empty ();
324348
325349 if (!any_diff && (should_include_receipts == include_receipts))
@@ -342,13 +366,36 @@ namespace ccf::historical
342366
343367 for (auto seqno : new_seqnos)
344368 {
345- populate_receipts (seqno);
369+ auto more_to_add = populate_receipts (seqno);
370+ std::sort (added.begin (), added.end ());
371+ std::sort (more_to_add.begin (), more_to_add.end ());
372+
373+ std::vector<SeqNo> together;
374+ std::merge (
375+ added.begin (),
376+ added.end (),
377+ more_to_add.begin (),
378+ more_to_add.end (),
379+ std::back_inserter (together));
380+
381+ if (more_to_add.size () + added.size () != together.size ())
382+ {
383+ LOG_FAIL_FMT (
384+ " Invariant violation in adjust_ranges: more_to_add({}) + "
385+ " added({}) != together({})" ,
386+ more_to_add.size (),
387+ added.size (),
388+ together.size ());
389+ assert (false );
390+ }
391+
392+ std::swap (added, together);
346393 }
347394 }
348395 return {removed, added};
349396 }
350397
351- void populate_receipts (ccf::SeqNo new_seqno)
398+ std::vector<ccf::SeqNo> populate_receipts (ccf::SeqNo new_seqno)
352399 {
353400 HISTORICAL_LOG (
354401 " Looking at {}, and populating receipts from it" , new_seqno);
@@ -376,6 +423,16 @@ namespace ccf::historical
376423 HISTORICAL_LOG (" {} is not a signature" , new_seqno);
377424 supporting_signatures.erase (new_seqno);
378425
426+ if (new_details->receipt != nullptr )
427+ {
428+ HISTORICAL_LOG (
429+ " Already have a receipt for {}, so no need to populate more" ,
430+ new_seqno);
431+ return {};
432+ }
433+
434+ std::vector<SeqNo> added;
435+
379436 auto next_seqno = new_seqno + 1 ;
380437 while (true )
381438 {
@@ -387,6 +444,18 @@ namespace ccf::historical
387444 HISTORICAL_LOG (
388445 " Looking for new supporting signature at {}" , next_seqno);
389446 details = std::make_shared<StoreDetails>();
447+ auto my_it = my_stores.find (next_seqno);
448+ if (my_it == my_stores.end ())
449+ {
450+ LOG_TRACE_FMT (
451+ " Tracking potential supporting signature for new seqno {} "
452+ " at {}" ,
453+ new_seqno,
454+ next_seqno);
455+ added.push_back (next_seqno);
456+ my_stores.insert_or_assign (my_it, next_seqno, details);
457+ }
458+
390459 all_stores.insert_or_assign (all_it, next_seqno, details);
391460 }
392461
@@ -400,7 +469,7 @@ namespace ccf::historical
400469 next_seqno,
401470 new_seqno);
402471 supporting_signatures[next_seqno] = details;
403- return ;
472+ return added ;
404473 }
405474 else if (details->is_signature )
406475 {
@@ -418,7 +487,7 @@ namespace ccf::historical
418487 new_seqno));
419488 }
420489
421- return ;
490+ return added ;
422491 }
423492 else
424493 {
@@ -427,8 +496,11 @@ namespace ccf::historical
427496 ++next_seqno;
428497 }
429498 }
499+
500+ return added;
430501 }
431502 }
503+ return {};
432504 }
433505
434506 private:
@@ -521,8 +593,6 @@ namespace ccf::historical
521593 std::unordered_map<ccf::SeqNo, size_t > raw_store_sizes{};
522594
523595 CacheSize soft_store_cache_limit{std::numeric_limits<size_t >::max ()};
524- CacheSize soft_store_cache_limit_raw =
525- soft_store_cache_limit / soft_to_raw_ratio;
526596 CacheSize estimated_store_cache_size{0 };
527597
528598 void add_request_ref (SeqNo seq, CompoundHandle handle)
@@ -806,7 +876,11 @@ namespace ccf::historical
806876 request.supporting_signatures .end ());
807877 if (seqno_in_this_request)
808878 {
809- request.populate_receipts (seqno);
879+ auto added = request.populate_receipts (seqno);
880+ for (auto seq : added)
881+ {
882+ add_request_ref (seq, handle);
883+ }
810884 }
811885 }
812886
@@ -1149,7 +1223,6 @@ namespace ccf::historical
11491223 void set_soft_cache_limit (CacheSize cache_limit)
11501224 {
11511225 soft_store_cache_limit = cache_limit;
1152- soft_store_cache_limit_raw = soft_store_cache_limit / soft_to_raw_ratio;
11531226 }
11541227
11551228 void track_deletes_on_missing_keys (bool track)
@@ -1438,7 +1511,7 @@ namespace ccf::historical
14381511 }
14391512 }
14401513
1441- lru_shrink_to_fit (soft_store_cache_limit_raw );
1514+ lru_shrink_to_fit (soft_store_cache_limit );
14421515
14431516 {
14441517 auto it = all_stores.begin ();
@@ -1633,5 +1706,10 @@ namespace ccf::historical
16331706 {
16341707 return StateCacheImpl::drop_cached_states (make_compound_handle (handle));
16351708 }
1709+
1710+ size_t get_estimated_store_cache_size () override
1711+ {
1712+ return StateCacheImpl::get_estimated_store_cache_size ();
1713+ }
16361714 };
16371715}
0 commit comments