Skip to main content

Module refs

Module refs 

Source
Expand description

Named pointers into history: mutable refs and immutable tags.

_nedb.refs   name -> seq     may move       (a branch head)
_nedb.tags   name -> seq     never moves    (a release)

§Why two kinds and not one with a flag

Both are “a name pointing at a sequence”, and it is tempting to make one type with immutable: bool. The reason they are two collections is that the guarantees are what the caller is buying. set_ref is allowed to surprise you; create_tag is not. Keeping them apart means an operation on a tag cannot be reached by accident from ref code, and list_tags cannot ever return something mutable.

§What immutability actually costs

A tag whose target can change is not a tag, it is a ref with good manners: a build that recorded “built from v1.0” would no longer be reproducible, and nothing in the record would say it had moved. So re-pointing a tag is refused, and — the sharper rule — a tag NAME IS NOT REUSABLE AFTER DELETION.

Deletion has to exist (a tag published by mistake must be retractable), but if v1.0 could be deleted and recreated at a different sequence, then “built from v1.0” is temporally ambiguous again and nothing has been gained — the mutation just takes two commands instead of one. So a delete leaves an AUDITED TOMBSTONE: the record stays, carrying the name, the original target, and deleted: true. That tombstone is both the audit trail and the enforcement mechanism, which is deliberate — there is no way to lose the ban without also losing the evidence.

Refs are the deliberate contrast: they move, they can be deleted, and a deleted ref name can be reused. The prev chain on the underlying document gives every move a walkable history for free.

§Reserved, therefore not part of state

Both collections live under _nedb., and they are written with put_unchecked, which does not register them in the collection registry. So they are invisible to crate::db::Db::state_root. That is required, not incidental: a tag records a state root, and if creating one changed the state root it would invalidate what it just recorded.

Structs§

RefRecord
A mutable pointer at a sequence.
TagRecord
An immutable pointer at a sequence.

Constants§

REFS
Mutable named pointers. Ids are ref names.
TAGS
Immutable named pointers, including tombstones for deleted ones. Ids are tag names; a name present here is spent forever.

Functions§

create_tag
Create an immutable tag at at_seq.
delete_ref
Delete a ref. Returns false when there was no live ref by that name.
delete_tag
Retract a tag, leaving an audited tombstone.
get_ref
A live ref by name.
get_tag
A live tag by name. None for a name that was never tagged AND for one whose tag was deleted — both mean “no tag here now”. Use get_tag_including_deleted to tell the two apart.
get_tag_including_deleted
A tag by name, tombstones included. This is what answers “what did v1.0 point at?” for a build that referenced it before it was retracted.
list_refs
Live refs, sorted by name.
list_tags
Live tags, sorted by name (raw UTF-8 bytes, the one ordering everything agrees on).
list_tags_including_deleted
Every tag ever created, tombstones included, sorted by name. The audit view.
set_ref
Point a ref at a sequence, creating it or MOVING it.
validate_ref_name
Is this a name a ref or tag can HAVE?