init commit
This commit is contained in:
commit
6300e42bb2
28 files changed
+104005
No files matched your search
+155
@@ -0,0 +1,155 @@
|
||||
.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 <stdio.h>
|
||||
|
||||
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
|
||||
Reference in new issue
Block a user