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:

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>.