IPLD Selector Thoughts #272
Description
This is probably the best place to leave this, but i've been thinking through different usecases for ipld selectors and wrote up my thoughts:
ipld selectors
In order of complexity, here are the types of IPLD selectors we will need.
Basic Paths
<H>{/a/b/c/d}
Returns the object referenced by d
(single object) at the path /a/b/c
below H
, as well as the merkle proof to H
.
Unbounded Recursion
<H>{/a/b/c/d}/*
Returns the entire subgraph referenced by d
at the path /a/b/c
below H
, as well as the merkle proof to H
.
Bounded Recursion
Imagine a structure with the form:
type Node struct {
Next *cid.Cid
}
Essentially a linked list. We want to be able to query through a potentially
infinite linked list. The simple form would be 'get the next four nodes' and
that could naively look like:
<H>{/Next/Next/Next/Next}
We could instead write this as:
<H>{/Next}4
But what if instead, we wanted 'All nodes from H'?
<H>{/Next}.
And what if I wanted 'All nodes from H until H2'?
Maybe this could look like:
<H>{/Next}*[H2]
Syntax
I don't care about the syntax of writing these down by hand, primarily because
i don't really need to ever do that. My usage of these will be entirely in
code. What I do care about is the data structure that will represent these
internally.
type Selector struct {
Root *cid.Cid
Path string
Mod int
Term []*cid.Cid
}
Should allow for most of what I want. Here are the above examples translated
into this form:
// Basic Path
s1 := Selector{
Root: H,
Path: "/a/b/c/d",
Mod: 0, // I figure 'zero' as the default value can have the same meaning as 1
}
// Unbounded Recursion
s2 := Selector{
Root: H,
Path: "/a/b/c/d",
Mod: -1, // negative values can be special sentinels for various special features, like recursion in this case
}
// Bounded Recursion
s3 := Selector{
Root: H,
Path: "/Next",
Mod: 4,
}
s4 := Selector{
Root: H,
Path: "/Next",
Mod: -2,
}
s5 := Selector{
Root: H,
Path: "/Next",
Mod: -2,
Term: []*cid.Cid{H2},
}
Multipath Selectors
I also think it might be nice to have selectors that specify multiple paths at a time, but the number of usecases for that is too small and the complexity too high that I don't really want it to block progress on the really simple and important ones (especially just the simple path one which we desperately need).