Skip to content
This repository was archived by the owner on Feb 8, 2023. It is now read-only.
This repository was archived by the owner on Feb 8, 2023. It is now read-only.

IPLD Selector Thoughts #272

Open
Open
@whyrusleeping

Description

@whyrusleeping

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions