nodes

package
v0.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 30, 2019 License: AGPL-3.0 Imports: 12 Imported by: 3

Documentation

Overview

Package nodes implements all nodes and defines basic operations on it.

It however does not implement any specific database scheme, nor are any operations implemented that require knowledge of other nodes. If knowledge about other nodes is required, the Linker interface needs to be fulfilled by a higher level.

The actual core of brig is built upon this package. Any changes here should thus be well thought through.

Index

Constants

View Source
const (
	// NodeTypeUnknown should not happen in real programs
	NodeTypeUnknown = NodeType(iota)
	// NodeTypeFile indicates a regular file
	NodeTypeFile
	// NodeTypeDirectory indicates a directory
	NodeTypeDirectory
	// NodeTypeCommit indicates a commit
	NodeTypeCommit
	// NodeTypeGhost indicates a moved node
	NodeTypeGhost
)
View Source
const (
	// AuthorOfStage is the Person that is displayed for the stage commit.
	// Currently this is just an empty hash Person that will be set later.
	AuthorOfStage = "unknown"
)

Variables

View Source
var ErrSkipChild = errors.New("skip sub directory")

ErrSkipChild can be returned inside a Walk() closure to stop descending recursively into a directory.

Functions

func ContentHash

func ContentHash(nd Node) (h.Hash, error)

ContentHash returns the correct content hash for `nd`. This also works for ghosts where the content hash is taken from the underlying node (ghosts themselve have no content).

func Depth

func Depth(nd Node) int

Depth returns the depth of the node. It does this by looking at the path separators. The depth of "/" is defined as 0.

func MarshalNode

func MarshalNode(nd Node) ([]byte, error)

MarshalNode will convert any Node to a byte string Use UnmarshalNode to load a Node from it again.

func RemoveNode

func RemoveNode(lkr Linker, nd Node) error

RemoveNode removes `nd` from it's parent directory using `lkr`. Removing the root is a no-op.

func Walk

func Walk(lkr Linker, node Node, dfs bool, visit func(child Node) error) error

Walk calls `visit` for each node below `node`, including `node`. If `dfs` is true, depth first search will be used. If `dfs` is false, breadth first search will be used. It is valid to pass a File to Walk(), then visit will be called exactly once.

It is possible to return the special error value ErrSkipChild in the callback. In this case, the children of this node are skipped. For this to work, `dfs` has to be false.

Types

type Base

type Base struct {
	// contains filtered or unexported fields
}

Base is a place that holds all common attributes of all Nodes. It also defines some utility function that will be mixed into real nodes.

func (*Base) BackendHash

func (b *Base) BackendHash() h.Hash

BackendHash returns the backend hash of this node.

func (*Base) ContentHash

func (b *Base) ContentHash() h.Hash

ContentHash returns the content hash of this node.

func (*Base) Inode

func (b *Base) Inode() uint64

Inode will return a unique ID that is different for each node.

func (*Base) ModTime

func (b *Base) ModTime() time.Time

ModTime will return the last time this node's content was modified. Metadata changes are not recorded.

func (*Base) Name

func (b *Base) Name() string

Name returns the name of this node (e.g. /a/b/c -> c) The root directory will have the name empty string.

func (*Base) TreeHash

func (b *Base) TreeHash() h.Hash

TreeHash returns the hash of this node.

func (*Base) Type

func (b *Base) Type() NodeType

Type returns the type of this node.

func (*Base) User

func (b *Base) User() string

User returns the user that last modified this node.

type Commit

type Commit struct {
	Base
	// contains filtered or unexported fields
}

Commit groups a set of changes

func NewEmptyCommit

func NewEmptyCommit(inode uint64, index int64) (*Commit, error)

NewEmptyCommit creates a new commit after the commit referenced by `parent`. `parent` might be nil for the very first commit.

func (*Commit) BoxCommit

func (c *Commit) BoxCommit(author string, message string) error

BoxCommit takes all currently filled data and calculates the final hash. It also will update the modification time. Only a boxed commit should be

func (*Commit) Child

func (c *Commit) Child(lkr Linker, _ string) (Node, error)

Child will return the root directory, no matter what name is given.

func (*Commit) FromCapnp

func (c *Commit) FromCapnp(msg *capnp.Message) error

FromCapnp will set the content of `msg` into the commit, overwriting any previous state.

func (*Commit) FromCapnpNode

func (c *Commit) FromCapnpNode(capNd capnp_model.Node) error

FromCapnpNode converts a serialized node to a normal node.

func (*Commit) Index

func (c *Commit) Index() int64

Index of the commit. First commit has the index 0, next commit has the index 1 and so on.

func (*Commit) IsBoxed

func (c *Commit) IsBoxed() bool

IsBoxed will return True if the ommit was already boxed (i.e. is a finished commit and no staging commit)

func (*Commit) MergeMarker

func (c *Commit) MergeMarker() (string, h.Hash)

MergeMarker returns the merge info for this commit, if any.

func (*Commit) Message

func (c *Commit) Message() string

Message will return the commit message of this commit

func (*Commit) NChildren

func (c *Commit) NChildren() int

NChildren will always return 1, since a commit has always exactly one root dir attached.

func (*Commit) Name

func (c *Commit) Name() string

Name will return the hash of the commit.

func (*Commit) Parent

func (c *Commit) Parent(lkr Linker) (Node, error)

Parent will return the parent commit of this node or nil if it is the first commit ever made.

func (*Commit) Path

func (c *Commit) Path() string

Path will return the path of the commit, which will

func (*Commit) Root

func (c *Commit) Root() h.Hash

Root returns the current root hash You shall not modify the returned hash.

func (*Commit) SetMergeMarker

func (c *Commit) SetMergeMarker(with string, remoteHead h.Hash)

SetMergeMarker remembers that we merged with the user `with` at this commit at `remoteHead`.

func (*Commit) SetModTime added in v0.4.0

func (c *Commit) SetModTime(t time.Time)

SetModTime sets the commits modtime to `t`. This should only be used for the most recent commit.

func (*Commit) SetParent

func (c *Commit) SetParent(lkr Linker, nd Node) error

SetParent sets the parent of the commit to `nd`.

func (*Commit) SetRoot

func (c *Commit) SetRoot(hash h.Hash)

SetRoot sets the root directory of this commit.

func (*Commit) Size

func (c *Commit) Size() uint64

Size will always return 0 since a commit has no defined size. If you're interested in the size of the snapshot, check the size of the root directory.

func (*Commit) String

func (c *Commit) String() string

String will return a nice representation of a commit.

func (*Commit) ToCapnp

func (c *Commit) ToCapnp() (*capnp.Message, error)

ToCapnp will convert all commit internals to a capnp message.

func (*Commit) ToCapnpNode

func (c *Commit) ToCapnpNode(seg *capnp.Segment, capNd capnp_model.Node) error

ToCapnpNode converts this node to a serializable capnp proto node.

type Directory

type Directory struct {
	Base
	// contains filtered or unexported fields
}

Directory is a typical directory that may contain several other directories or files.

func NewEmptyDirectory

func NewEmptyDirectory(
	lkr Linker, parent *Directory, name string, user string, inode uint64,
) (*Directory, error)

NewEmptyDirectory creates a new empty directory that does not exist yet.

func ParentDirectory

func ParentDirectory(lkr Linker, nd Node) (*Directory, error)

ParentDirectory returns the parent directory of `nd`. For the root it will return nil.

func (*Directory) Add

func (d *Directory) Add(lkr Linker, nd Node) error

Add `nd` to this directory using `lkr`.

func (*Directory) Child

func (d *Directory) Child(lkr Linker, name string) (Node, error)

Child returns a specific child with `name` or nil, if it was not found.

func (*Directory) ChildrenSorted

func (d *Directory) ChildrenSorted(lkr Linker) ([]Node, error)

ChildrenSorted returns a list of children node objects, sorted lexically by their path. Use this whenever you want to have a defined order of nodes, but do not really care what order.

func (*Directory) Copy

func (d *Directory) Copy(inode uint64) ModNode

Copy returns a copy of the directory with `inode` changed.

func (*Directory) FromCapnp

func (d *Directory) FromCapnp(msg *capnp.Message) error

FromCapnp will take the result of ToCapnp and set all of it's attributes.

func (*Directory) FromCapnpNode

func (d *Directory) FromCapnpNode(capNd capnp_model.Node) error

FromCapnpNode converts a serialized node to a normal node.

func (*Directory) IsRoot

func (d *Directory) IsRoot() bool

IsRoot returns true if this directory is the root directory.

func (*Directory) Lookup

func (d *Directory) Lookup(lkr Linker, repoPath string) (Node, error)

Lookup will lookup `repoPath` relative to this directory.

func (*Directory) NChildren

func (d *Directory) NChildren() int

NChildren returns the number of children the directory has.

func (*Directory) Name

func (d *Directory) Name() string

Name returns the dirname of this directory.

func (*Directory) NotifyMove

func (d *Directory) NotifyMove(lkr Linker, newParent *Directory, newPath string) error

NotifyMove should be called whenever a node is being moved.

func (*Directory) Parent

func (d *Directory) Parent(lkr Linker) (Node, error)

Parent will return the parent of this directory or nil, if this directory is already the root directory.

func (*Directory) Path

func (d *Directory) Path() string

Path returns the full path of this node.

func (*Directory) RemoveChild

func (d *Directory) RemoveChild(lkr Linker, nd Node) error

RemoveChild removes the child named `name` from it's children. There is no way to remove the root node.

func (*Directory) SetModTime

func (d *Directory) SetModTime(modTime time.Time)

SetModTime will set a new mod time to this directory (i.e. "touch" it)

func (*Directory) SetName

func (d *Directory) SetName(name string)

SetName will set the name of this directory.

func (*Directory) SetParent

func (d *Directory) SetParent(lkr Linker, nd Node) error

SetParent will set the parent of this directory to `nd`.

func (*Directory) SetSize

func (d *Directory) SetSize(size uint64)

SetSize sets the size of this directory.

func (*Directory) SetUser

func (d *Directory) SetUser(user string)

SetUser sets the user that last modified the directory.

func (*Directory) Size

func (d *Directory) Size() uint64

Size returns the accumulated size of the directory (i.e. the sum of a files in it, excluding ghosts)

func (*Directory) String

func (d *Directory) String() string

func (*Directory) ToCapnp

func (d *Directory) ToCapnp() (*capnp.Message, error)

ToCapnp converts the directory to an easily serializable capnp message.

func (*Directory) ToCapnpNode

func (d *Directory) ToCapnpNode(seg *capnp.Segment, capNd capnp_model.Node) error

ToCapnpNode converts this node to a serializable capnp proto node.

func (*Directory) Up

func (d *Directory) Up(lkr Linker, visit func(par *Directory) error) error

Up will call `visit` for each node onto the way top to the root node, including this directory.

func (*Directory) VisitChildren

func (d *Directory) VisitChildren(lkr Linker, fn func(nd Node) error) error

VisitChildren will call `fn` for each of it's direct children. The order of visits is lexicographical based on the child name.

type File

type File struct {
	Base
	// contains filtered or unexported fields
}

File represents a single file in the repository. It stores all metadata about it and links to the actual data.

func NewEmptyFile

func NewEmptyFile(parent *Directory, name string, user string, inode uint64) *File

NewEmptyFile returns a newly created file under `parent`, named `name`.

func (*File) Child

func (f *File) Child(_ Linker, name string) (Node, error)

Child will return always nil, since files don't have children.

func (*File) Copy

func (f *File) Copy(inode uint64) ModNode

Copy copies the contents of the file, except `inode`.

func (*File) FromCapnp

func (f *File) FromCapnp(msg *capnp.Message) error

FromCapnp sets all state of `msg` into the file.

func (*File) FromCapnpNode

func (f *File) FromCapnpNode(capNd capnp_model.Node) error

FromCapnpNode converts a serialized node to a normal node.

func (*File) Key

func (f *File) Key() []byte

Key returns the current key of the file.

func (*File) NChildren

func (f *File) NChildren() int

NChildren returns the number of children this file node has.

func (*File) NotifyMove

func (f *File) NotifyMove(lkr Linker, newParent *Directory, newPath string) error

NotifyMove should be called when the node moved parents.

func (*File) Parent

func (f *File) Parent(lkr Linker) (Node, error)

Parent returns the parent directory of File. If `f` is already the root, it will return itself (and never nil).

func (*File) Path

func (f *File) Path() string

Path will return the absolute path of the file.

func (*File) SetBackend

func (f *File) SetBackend(lkr Linker, backend h.Hash)

SetBackend will update the hash of the file (and also the mod time)

func (*File) SetContent

func (f *File) SetContent(lkr Linker, content h.Hash)

SetContent will update the hash of the file (and also the mod time)

func (*File) SetKey

func (f *File) SetKey(k []byte)

SetKey updates the key to a new value, taking ownership of the value.

func (*File) SetModTime

func (f *File) SetModTime(t time.Time)

SetModTime udates the mod time of the file (i.e. "touch"es it)

func (*File) SetName

func (f *File) SetName(n string)

SetName set the name of the file.

func (*File) SetParent

func (f *File) SetParent(_ Linker, parent Node) error

SetParent will set the parent of the file to `parent`.

func (*File) SetSize

func (f *File) SetSize(s uint64)

SetSize will update the size of the file and update it's mod time.

func (*File) SetUser

func (f *File) SetUser(user string)

SetUser sets the user that last modified the file.

func (*File) Size

func (f *File) Size() uint64

Size returns the number of bytes in the file's content.

func (*File) String

func (f *File) String() string

func (*File) ToCapnp

func (f *File) ToCapnp() (*capnp.Message, error)

ToCapnp converts a file to a capnp message.

func (*File) ToCapnpNode

func (f *File) ToCapnpNode(seg *capnp.Segment, capNd capnp_model.Node) error

ToCapnpNode converts this node to a serializable capnp proto node.

type Ghost

type Ghost struct {
	ModNode
	// contains filtered or unexported fields
}

Ghost is a special kind of Node that marks a moved node. If a file was moved, a ghost will be created for the old place. If another file is moved to the new place, the ghost will be "resurrected" with the new content.

func MakeGhost

func MakeGhost(nd ModNode, inode uint64) (*Ghost, error)

MakeGhost takes an existing node and converts it to a ghost. In the ghost form no metadata is lost, but the node should not show up. `inode` will be the new inode of the ghost. It should differ to the previous node.

func (*Ghost) FromCapnp

func (g *Ghost) FromCapnp(msg *capnp.Message) error

FromCapnp reads all attributes from a previously marshaled ghost.

func (*Ghost) FromCapnpNode

func (g *Ghost) FromCapnpNode(capNd capnp_model.Node) error

FromCapnpNode converts a serialized node to a normal node.

func (*Ghost) Inode

func (g *Ghost) Inode() uint64

Inode returns the inode

func (*Ghost) OldDirectory

func (g *Ghost) OldDirectory() (*Directory, error)

OldDirectory returns the old directory that the node was in lifetime If the ghost was not a directory, ErrBadNode is returned.

func (*Ghost) OldFile

func (g *Ghost) OldFile() (*File, error)

OldFile returns the file the ghost was when it still was alive. Returns ErrBadNode when it wasn't a file.

func (*Ghost) OldNode

func (g *Ghost) OldNode() ModNode

OldNode returns the node the ghost was when it still was alive.

func (*Ghost) Path

func (g *Ghost) Path() string

Path returns the path of the node.

func (*Ghost) SetGhostPath

func (g *Ghost) SetGhostPath(newPath string)

SetGhostPath sets the path of the ghost.

func (*Ghost) String

func (g *Ghost) String() string

func (*Ghost) ToCapnp

func (g *Ghost) ToCapnp() (*capnp.Message, error)

ToCapnp serializes the underlying node

func (*Ghost) ToCapnpNode

func (g *Ghost) ToCapnpNode(seg *capnp.Segment, capNd capnp_model.Node) error

ToCapnpNode converts this node to a serializable capnp proto node.

func (*Ghost) TreeHash

func (g *Ghost) TreeHash() h.Hash

TreeHash returns the hash of the node.

func (*Ghost) Type

func (g *Ghost) Type() NodeType

Type always returns NodeTypeGhost

type HierarchyEntry

type HierarchyEntry interface {
	// NChildren returns the total number of children to a node.
	NChildren() int

	// Child returns a named child.
	Child(lkr Linker, name string) (Node, error)

	// Parent returns the parent node or nil if there is none.
	Parent(lkr Linker) (Node, error)

	// SetParent sets the parent new. Care must be taken to remove old
	// references to the node to avoid loops.
	SetParent(lkr Linker, nd Node) error
}

HierarchyEntry represents a thing that is placed in a file hierarchy and may have other children beneath it.

type Linker

type Linker interface {
	// Root should return the current root directory.
	Root() (*Directory, error)

	// LookupNode should resolve `path` starting from the root directory.
	// If the path does not exist an error is returned and can be checked
	// with IsNoSuchFileError()
	LookupNode(path string) (Node, error)

	// NodeByHash resolves the hash to a specific node.
	// If the node does not exist, nil is returned.
	NodeByHash(hash h.Hash) (Node, error)

	// MemIndexSwap should be called when
	// the hash of a node changes.
	MemIndexSwap(nd Node, oldHash h.Hash, updatePathIndex bool)

	// MemSetRoot should be called when the current root directory changed.
	MemSetRoot(root *Directory)
}

Linker will tell a node how it relates to other nodes and gives it the ability to resolve other nodes by hash. Apart from that it gives the underlying linker implementation the possibility to be notified when a hash changes.

type Metadatable

type Metadatable interface {
	// Name returns the name of the object, i.e. the last part of the path,
	// which is also commonly called 'basename' in unix filesystems.
	Name() string

	// User returns the id of the user that last modified this file.
	// (There is no real ownership)
	User() string

	// Size returns the size of the node in bytes.
	Size() uint64

	// ModTime returns the time when the last modification to the node happened.
	ModTime() time.Time

	// Path of this node.
	Path() string

	// GetType returns the type of the node.
	Type() NodeType

	// INode shall return a unique identifier for this node that does
	// not change, even when the content of the node changes.
	Inode() uint64

	// TreeHash returns the hash value of the node.
	//
	// It is an error to modify the hash value.
	// If you need to modify it, you have to make an own copy via .Clone().
	TreeHash() h.Hash

	// ContentHash is the actual plain text hash of the node.
	// This is used for comparing file and directory equality.
	ContentHash() h.Hash

	// BackendHash returns the hash under which the stored content
	// can be read from the backend.
	// It is valid to return nil if the file is empty.
	BackendHash() h.Hash
}

Metadatable is a thing that accumulates certain common node attributes.

type MockLinker

type MockLinker struct {
	// contains filtered or unexported fields
}

MockLinker is supposed to be used for testing. It simply holds all nodes in memory. New nodes should be added via AddNode.

func NewMockLinker

func NewMockLinker() *MockLinker

NewMockLinker returns a Linker that can be easily used for testing.

func (*MockLinker) AddNode

func (ml *MockLinker) AddNode(nd Node, updatePathIndex bool)

AddNode will add a node to the memory index. This is not part of the linker interface.

func (*MockLinker) LookupNode

func (ml *MockLinker) LookupNode(path string) (Node, error)

LookupNode tries to lookup if there is already a node with this path.

func (*MockLinker) MemIndexSwap

func (ml *MockLinker) MemIndexSwap(nd Node, oldHash h.Hash, updatePathIndex bool)

MemIndexSwap will replace a node (referenced by `oldHash`) with `nd`. The path does not change.

func (*MockLinker) MemSetRoot

func (ml *MockLinker) MemSetRoot(root *Directory)

MemSetRoot sets the current root to be `root`.

func (*MockLinker) NodeByHash

func (ml *MockLinker) NodeByHash(hash h.Hash) (Node, error)

NodeByHash will return a previously added node (via AddNode) by it's hash.

func (*MockLinker) Root

func (ml *MockLinker) Root() (*Directory, error)

Root returns the currently set root. If none was created yet, an empty directory is returned.

type ModNode

type ModNode interface {
	Node

	// SetSize sets the size of the node in bytes
	SetSize(size uint64)

	// SetModTime updates the modtime timestamp
	SetModTime(modTime time.Time)

	// SetName sets the user that last modified the file
	SetName(name string)

	// SetUser sets the user that last modified the file
	SetUser(user string)

	// NotifyMove tells the node that it was moved.
	// It should be called whenever the path of the node changed.
	// (i.e. not only the name, but parts of the parent path)
	NotifyMove(lkr Linker, parent *Directory, newPath string) error

	// Copy creates a copy of this node with the inode `inode`.
	Copy(inode uint64) ModNode
}

ModNode is a node that supports modification of it's core attributes. File and Directory are settable, but a commit is not.

type Node

type Node interface {
	Metadatable
	Serializable
	HierarchyEntry
}

Node is a single node in brig's MDAG. It is currently either a Commit, a File or a Directory.

func CapNodeToNode

func CapNodeToNode(capNd capnp_model.Node) (Node, error)

CapNodeToNode converts a capnproto `capNd` to a normal `Node`.

func UnmarshalNode

func UnmarshalNode(data []byte) (Node, error)

UnmarshalNode will try to interpret data as a Node

type NodeType

type NodeType uint8

NodeType defines the type of a specific node.

func (NodeType) String

func (n NodeType) String() string

type Serializable

type Serializable interface {
	ToCapnp() (*capnp.Message, error)
	FromCapnp(*capnp.Message) error

	ToCapnpNode(seg *capnp.Segment, capNd capnp_model.Node) error
	FromCapnpNode(capNd capnp_model.Node) error
}

Serializable is a thing that can be converted to a capnproto message.

type Streamable

type Streamable interface {
	Key() []byte
}

Streamable represents a thing that can be streamed, given a cryptographic key.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL