@@ -1310,12 +1310,38 @@ ProofStorageStat::CellStatus ProofStorageStat::get_cell_status(const Cell::Hash&
13101310 return it == cells_.end () ? c_none : it->second .status ;
13111311}
13121312
1313- std::vector<Ref<Cell>> ProofStorageStat::build_collated_data () const {
1313+ std::vector<Ref<Cell>> ProofStorageStat::build_collated_data (std::vector<Ref<Cell>> skip_roots ) const {
13141314 struct Cache {
13151315 Ref<Cell> result;
13161316 bool is_root = true ;
1317+ bool skip = false ;
1318+ bool skip_visited = false ;
13171319 };
13181320 std::map<Cell::Hash, Cache> cache;
1321+
1322+ std::function<void (const Ref<Cell>&)> dfs_skip = [&](const Ref<Cell>& cell) {
1323+ Cell::Hash hash = cell->get_hash ();
1324+ Cache& entry = cache[hash];
1325+ if (entry.skip_visited ) {
1326+ return ;
1327+ }
1328+ entry.skip_visited = entry.skip = true ;
1329+ CellSlice cs{NoVm{}, cell};
1330+ if (cs.special_type () != CellTraits::SpecialType::PrunnedBranch) {
1331+ for (unsigned i = 0 ; i < cell->get_level (); ++i) {
1332+ cache[cell->get_hash (i)].skip = true ;
1333+ }
1334+ }
1335+ for (unsigned i = 0 ; i < cs.size_refs (); ++i) {
1336+ dfs_skip (cs.prefetch_ref (i));
1337+ }
1338+ };
1339+ for (const auto & cell : skip_roots) {
1340+ if (cell.not_null ()) {
1341+ dfs_skip (cell);
1342+ }
1343+ }
1344+
13191345 std::function<Cache&(const CellInfo&)> dfs = [&](const CellInfo& info) -> Cache& {
13201346 Cell::Hash hash = info.cell ->get_hash (info.cell_max_level );
13211347 Cache& entry = cache[hash];
@@ -1333,7 +1359,7 @@ std::vector<Ref<Cell>> ProofStorageStat::build_collated_data() const {
13331359 Ref<Cell> child = info.cell ->get_ref (i);
13341360 Cell::Hash child_hash = child->get_hash (child_max_level);
13351361 auto it = cells_.find (child_hash);
1336- if (it == cells_.end () || it->second .status != c_loaded) {
1362+ if (it == cells_.end () || it->second .status != c_loaded || cache[child_hash]. skip ) {
13371363 cb.store_ref (CellBuilder::create_pruned_branch (child, Cell::max_level, child_max_level));
13381364 } else {
13391365 Cache& child_result = dfs (it->second );
@@ -1345,14 +1371,14 @@ std::vector<Ref<Cell>> ProofStorageStat::build_collated_data() const {
13451371 entry2.result = cb.finalize (info.cell ->is_special ());
13461372 return entry2;
13471373 };
1348- for (auto & [_ , info] : cells_) {
1349- if (info.status == c_loaded) {
1374+ for (auto & [hash , info] : cells_) {
1375+ if (info.status == c_loaded && !cache[hash]. skip ) {
13501376 dfs (info);
13511377 }
13521378 }
13531379 std::vector<Ref<Cell>> result;
13541380 for (auto & [_, entry] : cache) {
1355- if (entry.is_root ) {
1381+ if (entry.result . not_null () && entry. is_root ) {
13561382 result.push_back (std::move (entry.result ));
13571383 }
13581384 }
0 commit comments