.Dd September 24, 2026 .Dt ENFILADE 3 .Os .Sh NAME .Nm enfilade .Nd small Model-T-style tumbler-addressed enfilade .Sh SYNOPSIS .In enfilade.h .Ft enfilade_t * .Fn create_enfilade void .Ft void .Fn destroy_enfilade "enfilade_t *enf" .Ft enf_result_t .Fn put_enfilade "enfilade_t *enf" "const char *tumbler" "void *datum" .Ft enf_result_t .Fn remove_enfilade "enfilade_t *enf" "const char *tumbler" .Ft void * .Fn getXtumbler_enfilade "enfilade_t *enf" "const char *tumbler" .Ft enf_result_t .Fn getXtumbler_values_enfilade "enfilade_t *enf" "const char *tumbler" "void ***items" "size_t *count" .Ft enf_result_t .Fn getXrange_values_enfilade "enfilade_t *enf" "int64_t start" "int64_t end" "void ***items" "size_t *count" .Ft void .Fn enfilade_visit_data "enfilade_t *enf" "enfilade_datum_visitor visitor" "void *context" .Sh DESCRIPTION An .Nm is a tree whose local keys are unsigned integer tumbler fields. Each node can contain terminal datum values and child enfilades at the same numeric keys. .Pp Putting .Ql 1.2.3 creates the path through keys 1, 2, and 3. The datum is stored at the final key. .Pp The interface is intentionally small and follows the behavior of the Model-T-style Python reference implementation used by this project. .Sh CREATION AND LIFETIME .Fn create_enfilade returns an empty enfilade or NULL on allocation failure. .Fn destroy_enfilade recursively frees the enfilade tree. .Pp The enfilade owns its tree nodes but does not own datum pointers supplied by the caller. The caller must keep every datum alive for as long as it may be returned by a lookup and must destroy the enfilade before those datum objects are destroyed. .Sh INSERTION .Fn put_enfilade stores .Fa datum at the exact final field of .Fa tumbler . Missing intermediate child enfilades are created automatically. .Pp A second insertion at the same final key replaces the existing datum. .Pp If a final key already contains a datum and a child subtree, insertion replaces only the datum. .Sh REMOVAL .Fn remove_enfilade removes only the datum stored at the exact final key. .Pp A child subtree at that same key is retained. Empty intermediate child enfilades are pruned after successful removal. The datum pointer itself is never freed. .Pp A missing exact datum returns .Dv ENF_ERR_NOT_FOUND . .Sh EXACT LOOKUP .Fn getXtumbler_enfilade returns only the datum stored at the exact final key, or NULL if none exists or the path is invalid. .Pp For callers that need reference-style flattened lookup, .Fn getXtumbler_values_enfilade walks every component except the last as a child path, then returns a newly allocated array containing the datum at the final key followed by all data in its child subtree. .Pp The caller owns the returned array and releases it with .Xr free 3 . The datum pointers remain owned by the caller. .Sh RANGE .Fn getXrange_values_enfilade walks numeric keys at the current enfilade level from .Fa start through .Fa end , inclusive, and recursively flattens their contents. A negative .Fa end means there is no upper bound. .Pp This operation deliberately remains the existing .Dq range interface. It is not a parser for dotted tumbler intervals. .Sh TRAVERSAL .Fn enfilade_visit_data visits every stored datum. The visitor callback is not retained after the call. The callback must not be assumed to outlive the traversal call. .Sh EXAMPLE .Bd -literal -offset indent #include "enfilade.h" #include int main(void) { enfilade_t *e = create_enfilade(); int value = 42; void *found; if (!e) return 1; if (put_enfilade(e, "1.2.3", &value).code != ENF_OK) return 1; found = getXtumbler_enfilade(e, "1.2.3"); if (found) printf("%d\\n", *(int *)found); destroy_enfilade(e); return 0; } .Ed .Sh ERRORS .Bl -tag -width ENF_ERR_NOT_FOUND .It Dv ENF_OK Success. .It Dv ENF_ERR_NULL A required pointer was null. .It Dv ENF_ERR_ADDR The tumbler text is malformed. .It Dv ENF_ERR_NOT_FOUND A requested datum or intermediate child was absent. .It Dv ENF_ERR_NOMEM An allocation failed. .El .Sh THREADING The enfilade structure does not provide internal locking. External synchronization is required if multiple threads may access the same instance concurrently. .Sh SCOPE This package implements the small tumbler-keyed tree only. It does not implement the broader Green machinery such as WIDs, DISPs, orgls, POOMs, Spanfilades, persistent CRUM storage, rearrangement, or version management. .Sh SEE ALSO .Xr tumbler 3 , .Xr enfilade-s7 7 , .Xr ensifer 7 .Sh REFERENCES .Lk https://raw.githubusercontent.com/enkiv2/ds-lib/refs/heads/master/Enfilade.py .Pp .Lk https://sentido-labs.com/en/library/201904240732/Xanadu%20Hypertext%20Documents.html