Skip to main content

Module diff

Module diff 

Source
Expand description

Logical difference between two points in history.

§What this is not

It is not a log slice. A log answers “what happened between A and B”; this answers “how does the state at B differ from the state at A”, and those are different questions with different answers. A document written five times and then restored to its original contents produces five log entries and zero diff entries. A document created and deleted inside the range produces two log entries and, again, zero diff entries — it is absent on both sides, so the state did not change.

It is also not textual. The unit is a document and a collection, not a line.

§How a side is materialised

Exactly the way crate::db::Db::state_root_as_of materialises one:

state(S) = { (coll, id) -> node
             | coll in collections_as_of(S), not reserved,
               id  in list_ids_including_deleted(coll),
               get_as_of(coll, id, S) == Some(node) }

Sharing the definition with the state root is deliberate and load-bearing: if diff(a, b) were empty, the two roots MUST be equal, and a diff computed from a different notion of “the state at S” could not promise that.

One consequence worth stating out loud: dropping a collection removes its documents from the state even though drop_collection never tombstones them individually. So a drop shows up twice in a diff — once as a removed collection, once as a removed document per row. That is not double counting, it is the namespace fact and the row facts, and a consumer restoring state from the diff needs both.

§Cost

Per candidate id, two get_as_of calls, and each one walks prev backward from the current head until it reaches a version at or before the target sequence. The cost is therefore one object read per version stepped over, not a scan of history: a document untouched since seq 3 costs a single read no matter how far apart from and to are, and only hot documents cost more. The candidate set itself is the full id list of every collection live at either end, which is the same enumeration an AS OF query already pays.

Structs§

CollChange
One collection that came into or went out of existence.
DocChange
One document whose visible state differs between the two sequence points.
FieldDelta
Which keys of a document object moved. Only ever describes data.
StateDiff
The complete difference in logical state between two sequence points.
TemporalDelta
The bi-temporal validity window, before and after.

Enums§

ChangeKind
Which direction a thing moved between the two sequence points.

Constants§

HISTORY_PRUNED
Error prefix for a range that reaches below the history floor. Exposed as a constant because callers (and nesql diff) need to branch on the reason without string-matching a sentence that may be reworded.
REVERSED_RANGE
Error prefix for from_seq > to_seq.

Functions§

diff
Difference in logical state between from_seq and to_seq.
tip
The last assigned sequence — the newest point diff can be asked about and get a full answer for. Convenience for callers that want “since X, up to now” without reaching into Db::seq and getting the off-by-one wrong.