MCPcopy Create free account
hub / github.com/argumentcomputer/ix / build_sharing_vec

Function build_sharing_vec

crates/ixon/src/sharing.rs:632–676  ·  view source on GitHub ↗

Rewrite expressions to use Share(idx) references for shared subterms. Returns the rewritten expressions and the sharing vector.

(
  exprs: &[Arc<Expr>],
  shared_hashes: &IndexSet<blake3::Hash>,
  ptr_to_hash: &FxHashMap<*const Expr, blake3::Hash>,
  info_map: &HashMap<blake3::Hash, SubtermInfo>,
  topo_order: &[blake3::Hash],

Source from the content-addressed store, hash-verified

630/// Rewrite expressions to use Share(idx) references for shared subterms.
631///
632/// Returns the rewritten expressions and the sharing vector.
633pub fn build_sharing_vec(
634 exprs: &[Arc<Expr>],
635 shared_hashes: &IndexSet<blake3::Hash>,
636 ptr_to_hash: &FxHashMap<*const Expr, blake3::Hash>,
637 info_map: &FxHashMap<blake3::Hash, SubtermInfo>,
638 topo_order: &[blake3::Hash],
639) -> (Vec<Arc<Expr>>, Vec<Arc<Expr>>) {
640 // CRITICAL: Re-sort shared_hashes in topological order (leaves first).
641 // decide_sharing returns hashes sorted by gross benefit (large terms first),
642 // but we need leaves first so that when serializing sharing[i], all its
643 // children are already available as Share(j) for j < i.
644 let shared_in_topo_order: Vec<blake3::Hash> =
645 topo_order.iter().copied().filter(|h| shared_hashes.contains(h)).collect();
646
647 // Build sharing vector incrementally to avoid forward references.
648 // When building sharing[i], only Share(j) for j < i is allowed.
649 let mut sharing_vec: Vec<Arc<Expr>> = Vec::with_capacity(shared_hashes.len());
650 let mut hash_to_idx: FxHashMap<blake3::Hash, u64> = FxHashMap::default();
651 let mut cache: FxHashMap<*const Expr, Arc<Expr>> = FxHashMap::default();
652
653 for h in &shared_in_topo_order {
654 let info = info_map.get(h).expect("shared hash must be in info_map");
655 // No cache.clear() needed: rewrite_expr checks hash_to_idx BEFORE the
656 // cache, so newly-shareable expressions are always caught even if the
657 // cache has a stale entry from a prior iteration. Topological order
658 // guarantees all children of `h` were already added to hash_to_idx,
659 // so their cached rewrites (containing correct Share references) remain
660 // valid.
661 let rewritten =
662 rewrite_expr(&info.expr, &hash_to_idx, ptr_to_hash, &mut cache);
663
664 let idx = sharing_vec.len() as u64;
665 sharing_vec.push(rewritten);
666 // Now add this hash to the map for subsequent entries
667 hash_to_idx.insert(*h, idx);
668 }
669
670 // Rewrite the root expressions (can use all Share indices)
671 let rewritten_exprs: Vec<Arc<Expr>> = exprs
672 .iter()
673 .map(|e| rewrite_expr(e, &hash_to_idx, ptr_to_hash, &mut cache))
674 .collect();
675
676 (rewritten_exprs, sharing_vec)
677}
678
679/// Frame for iterative rewrite traversal.

Callers 4

apply_sharing_with_statsFunction · 0.85
rs_run_sharing_analysisFunction · 0.85
test_build_sharing_vecFunction · 0.85

Calls 7

rewrite_exprFunction · 0.85
pushMethod · 0.80
iterMethod · 0.45
containsMethod · 0.45
lenMethod · 0.45
getMethod · 0.45
insertMethod · 0.45

Tested by 1

test_build_sharing_vecFunction · 0.68