link.go 4.47 KB
Newer Older
tavit ohanian's avatar
tavit ohanian committed
1
package dms3ld
Eric Myhre's avatar
Eric Myhre committed
2 3 4 5 6

import (
	"context"
)

tavit ohanian's avatar
tavit ohanian committed
7
// Link is a special kind of value in DMS3LD which can be "loaded" to access more nodes.
Eric Myhre's avatar
Eric Myhre committed
8
//
tavit ohanian's avatar
tavit ohanian committed
9 10
// Nodes can be a Link: "link" is one of the kinds in the DMS3LD Data Model;
// and accordingly there is an `dms3ld.Kind_Link` enum value, and Node has an `AsLink` method.
Eric Myhre's avatar
Eric Myhre committed
11
//
tavit ohanian's avatar
tavit ohanian committed
12 13
// Links are considered a scalar value in the DMS3LD Data Model,
// but when "loaded", the result can be any other DMS3LD kind:
Eric Myhre's avatar
Eric Myhre committed
14 15
// maps, lists, strings, etc.
//
tavit ohanian's avatar
tavit ohanian committed
16
// Link is an interface in the go-dms3ld-prime implementation,
Eric Myhre's avatar
Eric Myhre committed
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
// but the most common instantiation of it comes from the `linking/cid` package,
// and represents CIDs (see https://github.com/multiformats/cid).
//
// The Link interface says very little by itself; it's generally necessary to
// use type assertions to unpack more specific forms of data.
// The only real contract is that the Link must be able to return a LinkPrototype,
// which must be able to produce new Link values of a similar form.
// (In practice: if you're familiar with CIDs: Link.Prototype is analogous to cid.Prefix.)
//
// The traversal package contains powerful features for walking through large graphs of Nodes
// while automatically loading and traversing links as the walk goes.
//
// Note that the Link interface should typically be inhabited by a struct or string, as opposed to a pointer.
// This is because Link is often desirable to be able to use as a golang map key,
// and in that context, pointers would not result in the desired behavior.
type Link interface {
	// Prototype should return a LinkPrototype which carries the information
	// to make more Link values similar to this one (but with different hashes).
	Prototype() LinkPrototype

	// String should return a reasonably human-readable debug-friendly representation the Link.
	// There is no contract that requires that the string be able to be parsed back into a Link value,
	// but the string should be unique (e.g. not elide any parts of the hash).
	String() string
}

// LinkPrototype encapsulates any implementation details and parameters
// necessary for creating a Link, expect for the hash result itself.
//
tavit ohanian's avatar
tavit ohanian committed
46
// LinkPrototype, like Link, is an interface in go-dms3ld-prime,
Eric Myhre's avatar
Eric Myhre committed
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
// but the most common instantiation of it comes from the `linking/cid` package,
// and represents CIDs (see https://github.com/multiformats/cid).
// If using CIDs as an implementation, LinkPrototype will encapsulate information
// like multihashType, multicodecType, and cidVersion, for example.
// (LinkPrototype is analogous to cid.Prefix.)
type LinkPrototype interface {
	// BuildLink should return a new Link value based on the given hashsum.
	// The hashsum argument should typically be a value returned from a
	// https://golang.org/pkg/hash/#Hash.Sum call.
	//
	// The hashsum reference must not be retained (the caller is free to reuse it).
	BuildLink(hashsum []byte) Link
}

// LinkContext is a structure carrying ancilary information that may be used
// while loading or storing data -- see its usage in BlockReadOpener, BlockWriteOpener,
// and in the methods on LinkSystem which handle loading and storing data.
//
// A zero value for LinkContext is generally acceptable in any functions that use it.
// In this case, any operations that need a Context will use Context.Background
// (thus being uncancellable) and simply have no additional information to work with.
type LinkContext struct {
	// Ctx is the familiar golang Context pattern.
	// Use this for cancellation, or attaching additional info
	// (for example, perhaps to pass auth tokens through to the storage functions).
	Ctx context.Context

	// Path where the link was encountered.  May be zero.
	//
	// Functions in the traversal package will set this automatically.
	LinkPath Path

	// When traversing data or encoding: the Node containing the link --
	// it may have additional type info, etc, that can be accessed.
	// When building / decoding: not present.
	//
	// Functions in the traversal package will set this automatically.
	LinkNode Node

	// When building data or decoding: the NodeAssembler that will be receiving the link --
	// it may have additional type info, etc, that can be accessed.
	// When traversing / encoding: not present.
	//
	// Functions in the traversal package will set this automatically.
	LinkNodeAssembler NodeAssembler

	// Parent of the LinkNode.  May be zero.
	//
	// Functions in the traversal package will set this automatically.
	ParentNode Node

	// REVIEW: ParentNode in LinkContext -- so far, this has only ever been hypothetically useful.  Keep or drop?
}