Skip to content
/ dag Public

tools for working with directed acyclic graphs (DAGs)

License

Notifications You must be signed in to change notification settings

qri-io/dag

Repository files navigation

dag

-- import "github.com/qri-io/dag"

Package dag is the base of a family of packages for working with directed acyclic graphs (DAGs) most (if not all) use cases assume the dag is a merkle-tree https://en.wikipedia.org/wiki/Merkle_tree

Usage

type Completion

type Completion []uint16

Completion tracks the presence of blocks described in a manifest Completion can be used to store transfer progress, or be stored as a record of which blocks in a DAG are missing each element in the slice represents the index a block in a manifest.Nodes field, which contains the hash of a block needed to complete a manifest the element in the progress slice represents the transmission completion of that block locally. It must be a number from 0-100, 0 = nothing locally, 100 = block is local. note that progress is not necessarily linear. for example the following is 50% complete progress:

manifest.Nodes: ["QmA", "QmB", "QmC", "QmD"] progress: [0, 100, 0, 100]

func NewCompletion

func NewCompletion(mfst, missing *Manifest) Completion

NewCompletion constructs a progress from

func (Completion) Complete

func (p Completion) Complete() bool

Complete returns weather progress is finished

func (Completion) CompletedBlocks

func (p Completion) CompletedBlocks() (count int)

CompletedBlocks returns the number of blocks that are completed

func (Completion) Percentage

func (p Completion) Percentage() (pct float32)

Percentage expressess the completion as a floating point number betwen 0.0 and 1.0

type Info

type Info struct {
	// Info is built upon a manifest
	Manifest *Manifest      `json:"manifest"`
	Paths    map[string]int `json:"paths,omitempty"` // sections are lists of logical sub-DAGs by positions in the nodes list
	Sizes    []uint64       `json:"sizes,omitempty"` // sizes of nodes in bytes
}

Info is os.FileInfo for dags: a struct that describes important details about a graph. Info builds on a manifest

when being sent over the network, the contents of Info should be considered gossip, as Info's are not deterministic. This has important implications Info should contain application-specific info about a datset

func NewInfo

func NewInfo(ctx context.Context, ng ipld.NodeGetter, id cid.Cid) (*Info, error)

NewInfo creates a

type Manifest

type Manifest struct {
	Links [][2]int `json:"links"` // links between nodes
	Nodes []string `json:"nodes"` // list if CIDS contained in the DAG
}

Manifest is a determinsitc description of a complete directed acyclic graph. Analogous to bittorrent .magnet files, manifests contain no content, only a description of the structure of a graph (nodes and links)

Manifests are built around a flat list of node identifiers (usually hashes) and a list of links. A link element is a tuple of [from,to] where from and to are indexes in the nodes list

Manifests always describe the FULL graph, a root node and all it's descendants

A valid manifest has the following properties: * supplying the same dag to the manifest function must be deterministic:

manifest_of_dag = manifest(dag)
hash(manifest_of_dag) == hash(manifest(dag))
  • In order to generate a manifest, you need the full DAG * The list of nodes MUST be sorted by number of descendants. When two nodes

    have the same number of descenants, they MUST be sorted lexographically by node ID. The means the root of the DAG will always be the first index

Manifests are intentionally limited in scope to make them easier to prove, faster to calculate, hard requirement the list of nodes can be used as a base other structures can be built upon. by keeping manifests at a minimum they are easier to verify, forming a foundation for

func Missing

func Missing(ctx context.Context, ng ipld.NodeGetter, m *Manifest) (missing *Manifest, err error)

Missing returns a manifest describing blocks that are not in this node for a given manifest

func NewManifest

func NewManifest(ctx context.Context, ng ipld.NodeGetter, id cid.Cid) (*Manifest, error)

NewManifest generates a manifest from an ipld node

func UnmarshalCBORManifest

func UnmarshalCBORManifest(data []byte) (m *Manifest, err error)

UnmarshalCBORManifest decodes a manifest from a byte slice

func (*Manifest) MarshalCBOR

func (m *Manifest) MarshalCBOR() (data []byte, err error)

MarshalCBOR encodes this manifest as CBOR data

type Node

type Node interface {
	// pulled from blocks.Block format
	Cid() cid.Cid
	// Links is a helper function that returns all links within this object
	Links() []*ipld.Link
	// Size returns the size in bytes of the serialized object
	Size() (uint64, error)
}

Node is a subset of the ipld ipld.Node interface, defining just the necessary bits the dag package works with

type NodeGetter

type NodeGetter struct {
	Dag coreiface.DagAPI
}

NodeGetter wraps the go-ipfs DagAPI to satistfy the IPLD NodeGetter interface

func (*NodeGetter) Get

func (ng *NodeGetter) Get(ctx context.Context, id cid.Cid) (ipld.Node, error)

Get retrieves nodes by CID. Depending on the NodeGetter implementation, this may involve fetching the Node from a remote machine; consider setting a deadline in the context.

func (*NodeGetter) GetMany

func (ng *NodeGetter) GetMany(ctx context.Context, cids []cid.Cid) <-chan *ipld.NodeOption

GetMany returns a channel of NodeOptions given a set of CIDs.

About

tools for working with directed acyclic graphs (DAGs)

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published

Languages