Expand description
The generic path::Path
pattern.
As explained in the parent module documentation the path::Path
defines a tree structure.
The path is not an entire tree but simply one path from the root to the current depth of the tree.
A -> B -> C -> D
All possible paths for the above tree:
[]
[ A ]
[ A B ]
[ A B C ]
[ A D ]
Note:
- The path must always start at the root
-
path::Path
are sequential and contigious -
path::Path
may be empty -
path::Path
only track one branch
Applications can discover all links from a path to all children by constructing the known path components.
For example if an application knows [ A ]
then links to B
and D
will be discoverable.
If an application knows [ A B ]
then a link to C
will be discoverable.
Structs
Each path component is arbitrary bytes to be hashed together in a predictable way when the path is hashed to create something that can be linked and discovered by all DHT participants.
A Path
is a vector of Component
.
It represents a single traversal of a tree structure down to some arbitrary point.
The main intent is that we can recursively walk back up the tree, hashing, committing and
linking each sub-path along the way until we reach the root.
At this point it is possible to follow DHT links from the root back up the path.
i.e. the ahead-of-time predictability of the hashes of a given path allows us to travel “up”
the tree and the linking functionality of the holochain DHT allows us to travel “down” the tree
after at least one DHT participant has followed the path “up”.
Note that the Path
is not literally committed and/or linked from/to as
base and target. For this the PathEntry
exists, which achieves a
constant size for the DHT representation of each node of the Path
.
A PathEntry
is the hash of a Path
.
This is what is committed and shared on the DHT to build links off as their
base and target. If we committed the Path
directly then the size of each
node entry content would be the size of all the components of the path.
Given that ensure
populates all the ancestor nodes committing [ A, B, C ]
would create entries with content [ A ], [ A, B ], [ A, B, C ]. For deep
paths, or paths with a large component (in bytes) at any node, this would
create a lot of redundant data in every descendent entry.
Instead, we commit a PathEntry
so each node is constant size, just the
hash of the full Path
up to that point. This means that committing
PathEntry
instead of Path
for [A, B, C]
results in entries with
content [ HashA ], [ HashAB ], [ HashABC ]. Note that if A + B + C is much
less than the size of a holochain hash (~40 bytes) then this approach is
worse than simply committing the Path
but in practise this is often not
the case, and PathEntry
becomes a more scalable generalised solution.
Constants
Allows for “foo.bar.baz” to automatically move to/from [“foo”, “bar”, “baz”] components.
Technically it’s moving each string component in as bytes.
If this is a problem for you simply build the components yourself as a Vec<Vec