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
- Variables
- func ContentHash(nd Node) (h.Hash, error)
- func Depth(nd Node) int
- func MarshalNode(nd Node) ([]byte, error)
- func RemoveNode(lkr Linker, nd Node) error
- func Walk(lkr Linker, node Node, dfs bool, visit func(child Node) error) error
- type Base
- type Commit
- func (c *Commit) BoxCommit(author string, message string) error
- func (c *Commit) Child(lkr Linker, _ string) (Node, error)
- func (c *Commit) FromCapnp(msg *capnp.Message) error
- func (c *Commit) FromCapnpNode(capNd capnp_model.Node) error
- func (c *Commit) Index() int64
- func (c *Commit) IsBoxed() bool
- func (c *Commit) MergeMarker() (string, h.Hash)
- func (c *Commit) Message() string
- func (c *Commit) NChildren() int
- func (c *Commit) Name() string
- func (c *Commit) Parent(lkr Linker) (Node, error)
- func (c *Commit) Path() string
- func (c *Commit) Root() h.Hash
- func (c *Commit) SetMergeMarker(with string, remoteHead h.Hash)
- func (c *Commit) SetParent(lkr Linker, nd Node) error
- func (c *Commit) SetRoot(hash h.Hash)
- func (c *Commit) Size() uint64
- func (c *Commit) String() string
- func (c *Commit) ToCapnp() (*capnp.Message, error)
- func (c *Commit) ToCapnpNode(seg *capnp.Segment, capNd capnp_model.Node) error
- type Directory
- func (d *Directory) Add(lkr Linker, nd Node) error
- func (d *Directory) Child(lkr Linker, name string) (Node, error)
- func (d *Directory) ChildrenSorted(lkr Linker) ([]Node, error)
- func (d *Directory) Copy(inode uint64) ModNode
- func (d *Directory) FromCapnp(msg *capnp.Message) error
- func (d *Directory) FromCapnpNode(capNd capnp_model.Node) error
- func (d *Directory) IsRoot() bool
- func (d *Directory) Lookup(lkr Linker, repoPath string) (Node, error)
- func (d *Directory) NChildren() int
- func (d *Directory) Name() string
- func (d *Directory) NotifyMove(lkr Linker, newParent *Directory, newPath string) error
- func (d *Directory) Parent(lkr Linker) (Node, error)
- func (d *Directory) Path() string
- func (d *Directory) RemoveChild(lkr Linker, nd Node) error
- func (d *Directory) SetModTime(modTime time.Time)
- func (d *Directory) SetName(name string)
- func (d *Directory) SetParent(lkr Linker, nd Node) error
- func (d *Directory) SetSize(size uint64)
- func (d *Directory) SetUser(user string)
- func (d *Directory) Size() uint64
- func (d *Directory) String() string
- func (d *Directory) ToCapnp() (*capnp.Message, error)
- func (d *Directory) ToCapnpNode(seg *capnp.Segment, capNd capnp_model.Node) error
- func (d *Directory) Up(lkr Linker, visit func(par *Directory) error) error
- func (d *Directory) VisitChildren(lkr Linker, fn func(nd Node) error) error
- type File
- func (f *File) Child(_ Linker, name string) (Node, error)
- func (f *File) Copy(inode uint64) ModNode
- func (f *File) FromCapnp(msg *capnp.Message) error
- func (f *File) FromCapnpNode(capNd capnp_model.Node) error
- func (f *File) Key() []byte
- func (f *File) NChildren() int
- func (f *File) NotifyMove(lkr Linker, newParent *Directory, newPath string) error
- func (f *File) Parent(lkr Linker) (Node, error)
- func (f *File) Path() string
- func (f *File) SetBackend(lkr Linker, backend h.Hash)
- func (f *File) SetContent(lkr Linker, content h.Hash)
- func (f *File) SetKey(k []byte)
- func (f *File) SetModTime(t time.Time)
- func (f *File) SetName(n string)
- func (f *File) SetParent(_ Linker, parent Node) error
- func (f *File) SetSize(s uint64)
- func (f *File) SetUser(user string)
- func (f *File) Size() uint64
- func (f *File) String() string
- func (f *File) ToCapnp() (*capnp.Message, error)
- func (f *File) ToCapnpNode(seg *capnp.Segment, capNd capnp_model.Node) error
- type Ghost
- func (g *Ghost) FromCapnp(msg *capnp.Message) error
- func (g *Ghost) FromCapnpNode(capNd capnp_model.Node) error
- func (g *Ghost) Inode() uint64
- func (g *Ghost) OldDirectory() (*Directory, error)
- func (g *Ghost) OldFile() (*File, error)
- func (g *Ghost) OldNode() ModNode
- func (g *Ghost) Path() string
- func (g *Ghost) SetGhostPath(newPath string)
- func (g *Ghost) String() string
- func (g *Ghost) ToCapnp() (*capnp.Message, error)
- func (g *Ghost) ToCapnpNode(seg *capnp.Segment, capNd capnp_model.Node) error
- func (g *Ghost) TreeHash() h.Hash
- func (g *Ghost) Type() NodeType
- type HierarchyEntry
- type Linker
- type Metadatable
- type MockLinker
- func (ml *MockLinker) AddNode(nd Node, updatePathIndex bool)
- func (ml *MockLinker) LookupNode(path string) (Node, error)
- func (ml *MockLinker) MemIndexSwap(nd Node, oldHash h.Hash, updatePathIndex bool)
- func (ml *MockLinker) MemSetRoot(root *Directory)
- func (ml *MockLinker) NodeByHash(hash h.Hash) (Node, error)
- func (ml *MockLinker) Root() (*Directory, error)
- type ModNode
- type Node
- type NodeType
- type Serializable
- type Streamable
Constants ¶
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 )
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 ¶
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 ¶
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 ¶
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 ¶
MarshalNode will convert any Node to a byte string Use UnmarshalNode to load a Node from it again.
func RemoveNode ¶
RemoveNode removes `nd` from it's parent directory using `lkr`. Removing the root is a no-op.
func Walk ¶
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 ¶
BackendHash returns the backend hash of this node.
func (*Base) ContentHash ¶
ContentHash returns the content hash of this node.
func (*Base) ModTime ¶
ModTime will return the last time this node's content was modified. Metadata changes are not recorded.
type Commit ¶
type Commit struct { Base // contains filtered or unexported fields }
Commit groups a set of changes
func NewEmptyCommit ¶
NewEmptyCommit creates a new commit after the commit referenced by `parent`. `parent` might be nil for the very first commit.
func (*Commit) BoxCommit ¶
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) FromCapnp ¶
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 ¶
Index of the commit. First commit has the index 0, next commit has the index 1 and so on.
func (*Commit) IsBoxed ¶
IsBoxed will return True if the ommit was already boxed (i.e. is a finished commit and no staging commit)
func (*Commit) MergeMarker ¶
MergeMarker returns the merge info for this commit, if any.
func (*Commit) NChildren ¶
NChildren will always return 1, since a commit has always exactly one root dir attached.
func (*Commit) Parent ¶
Parent will return the parent commit of this node or nil if it is the first commit ever made.
func (*Commit) SetMergeMarker ¶
SetMergeMarker remembers that we merged with the user `with` at this commit at `remoteHead`.
func (*Commit) Size ¶
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) ToCapnpNode ¶
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 ¶
ParentDirectory returns the parent directory of `nd`. For the root it will return nil.
func (*Directory) ChildrenSorted ¶
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) FromCapnp ¶
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) NotifyMove ¶
NotifyMove should be called whenever a node is being moved.
func (*Directory) Parent ¶
Parent will return the parent of this directory or nil, if this directory is already the root directory.
func (*Directory) RemoveChild ¶
RemoveChild removes the child named `name` from it's children. There is no way to remove the root node.
func (*Directory) SetModTime ¶
SetModTime will set a new mod time to this directory (i.e. "touch" it)
func (*Directory) Size ¶
Size returns the accumulated size of the directory (i.e. the sum of a files in it, excluding ghosts)
func (*Directory) ToCapnpNode ¶
ToCapnpNode converts this node to a serializable capnp proto node.
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 ¶
NewEmptyFile returns a newly created file under `parent`, named `name`.
func (*File) FromCapnpNode ¶
func (f *File) FromCapnpNode(capNd capnp_model.Node) error
FromCapnpNode converts a serialized node to a normal node.
func (*File) NotifyMove ¶
NotifyMove should be called when the node moved parents.
func (*File) Parent ¶
Parent returns the parent directory of File. If `f` is already the root, it will return itself (and never nil).
func (*File) SetBackend ¶
SetBackend will update the hash of the file (and also the mod time)
func (*File) SetContent ¶
SetContent will update the hash of the file (and also the mod time)
func (*File) SetModTime ¶
SetModTime udates the mod time of the file (i.e. "touch"es it)
func (*File) ToCapnpNode ¶
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 ¶
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) FromCapnpNode ¶
func (g *Ghost) FromCapnpNode(capNd capnp_model.Node) error
FromCapnpNode converts a serialized node to a normal node.
func (*Ghost) OldDirectory ¶
OldDirectory returns the old directory that the node was in lifetime If the ghost was not a directory, ErrBadNode is returned.
func (*Ghost) OldFile ¶
OldFile returns the file the ghost was when it still was alive. Returns ErrBadNode when it wasn't a file.
func (*Ghost) SetGhostPath ¶
SetGhostPath sets the path of the ghost.
func (*Ghost) ToCapnpNode ¶
ToCapnpNode converts this node to a serializable capnp proto node.
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 ¶
UnmarshalNode will try to interpret data as a Node
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.