MST.Diff
(mst v0.1.0)
View Source
Computes the diff between two MST.Tree instances.
A diff captures:
- Which MST nodes were created (present in
bbut nota) - Which MST nodes were deleted (present in
abut notb) - The per-key record operations (creates, updates, and deletes)
Algorithm
Node sets (created_nodes / deleted_nodes) are computed by collecting all
reachable node CIDs from each tree root with a DFS, then taking set
differences. Equal CIDs short-circuit entire subtrees (no need to recurse
into subtrees both trees share).
Record ops are computed by fully materialising both trees as sorted key/value lists and performing a linear sorted-merge comparison. This is straightforward and correct at the cost of O(n) memory; it is the right tradeoff given that the diff is typically used to inspect the full changeset anyway.
Example
{:ok, diff} = MST.Diff.compute(tree_a, tree_b)
# diff.record_ops is a sorted list of MST.Diff.Op structs
Summary
Functions
Computes the diff from tree_a to tree_b.
Types
@type diff_error() :: {:error, atom()}
@type t() :: %MST.Diff{ created_nodes: MapSet.t(DASL.CID.t()), deleted_nodes: MapSet.t(DASL.CID.t()), record_ops: [MST.Diff.Op.t()] }
Functions
@spec compute(MST.Tree.t(), MST.Tree.t()) :: {:ok, t()} | diff_error()
Computes the diff from tree_a to tree_b.
Both trees must use stores that have their nodes populated (e.g. loaded from
CAR files). Returns {:ok, diff} or an error if a node is missing.
Examples
iex> store = MST.Store.Memory.new()
iex> ta = MST.Tree.new(store)
iex> val = DASL.CID.compute("v")
iex> {:ok, tb} = MST.Tree.put(ta, "col/a", val)
iex> {:ok, diff} = MST.Diff.compute(ta, tb)
iex> length(diff.record_ops)
1
iex> hd(diff.record_ops).key
"col/a"