tree

package
v0.0.0-...-c447958 Latest Latest
Warning

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

Go to latest
Published: Nov 26, 2021 License: MIT Imports: 23 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DMDIR    = 0x80000000
	DMAPPEND = 0x40000000
	DMEXCL   = 0x20000000
	DMTMP    = 0x04000000
)
View Source
const SnapshotFrequency = 3 * time.Minute

Variables

View Source
var (
	ErrExist      = fmt.Errorf("exists")
	ErrNotEmpty   = fmt.Errorf("not empty")
	ErrNotExist   = fmt.Errorf("does not exist")
	ErrPermission = fmt.Errorf("permission denied")
	ErrReadOnly   = fmt.Errorf("read-only")
)
View Source
var ErrInUse = errors.New("in use")
View Source
var FixBlockSize = false

FixBlockSize guards the block size fix code in the write path. Doing it always would break all tests. So I'm placing this terrible flag here and set it in musclefs.

View Source
var RemoteRootKeyPrefix = "remote.root."

Functions

func DiffTrees

func DiffTrees(a, b *Tree, arootpath, brootpath string, options ...DiffTreesOption) error

DiffTrees produces a metadata diff of the two trees.

Types

type Codec

type Codec interface {
	// contains filtered or unexported methods
}

Codec defines how we serialize and deserialize our types.

type DiffTreesOption

type DiffTreesOption func(*diffTreesOptions)

DiffTreesOption follows the functional options pattern to pass options to DiffTrees.

func DiffTreesInitialPath

func DiffTreesInitialPath(pathname string) DiffTreesOption

func DiffTreesNamesOnly

func DiffTreesNamesOnly(value bool) DiffTreesOption

func DiffTreesOutput

func DiffTreesOutput(w io.Writer) DiffTreesOption

func DiffTreesVerbose

func DiffTreesVerbose(value bool) DiffTreesOption

type Node

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

Node describes a node in the filesystem tree.

func (*Node) Children

func (node *Node) Children() []*Node

func (*Node) Info

func (node *Node) Info() NodeInfo

Info returns a copy of the node's information struct.

func (*Node) IsDir

func (node *Node) IsDir() bool

func (*Node) IsRoot

func (node *Node) IsRoot() bool

func (*Node) Path

func (node *Node) Path() string

Path returns the full path to the node, e.g., "/src/muscle/tree/node.go". A non-loaded node is represented by an asterisk; as a consequence, a path can take the form "/src/muscle/tree/*".

func (*Node) ReadAt

func (node *Node) ReadAt(p []byte, off int64) (int, error)

func (*Node) Ref

func (node *Node) Ref() int

Ref increments the node's ref count, and that of all its ancestors. It also sets the node's access time. Since we can only stat() after walk(), this means we're updating the atime also to answer a stat syscall. That's not correct. But the use case for atime is, as I said, to track when last used in musclefs. It should perhaps be called last ref'd.

func (*Node) Rename

func (node *Node) Rename(newName string) error

Rename changes the node's name. If the parent already contains a file/empty directory with the new name, that file/directory is unlinked first. Stat(5) says that renaming should fail in that case, but conforming to the manual page makes it impossible to use git (which renames 'index.lock' to an already existing 'index', for example) under both 9pfuse and v9fs.

func (*Node) SetMode

func (node *Node) SetMode(mode uint32)

func (*Node) String

func (node *Node) String() string

String returns the path to the node and its hash pointer, plus a "-dirty" suffix if the node hasn't been flushed to disk.

func (*Node) Touch

func (node *Node) Touch(seconds uint32)

Touch updates the modification timestamp of the node and marks the node dirty, so that it is later flushed to disk.

func (*Node) Truncate

func (node *Node) Truncate(requestedSize uint64) error

func (*Node) Unlinked

func (node *Node) Unlinked() bool

func (*Node) Unref

func (node *Node) Unref() int

Unref decrements the node's ref count, and that of all its ancestors.

func (*Node) WriteAt

func (node *Node) WriteAt(p []byte, off int64) error

type NodeInfo

type NodeInfo struct {
	ID       uint64
	Version  uint32
	Name     string
	Size     uint64
	Mode     uint32
	Modified uint32
}

type Revision

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

Revision is the analogue of a git commit.

func NewRevision

func NewRevision(root *Node, parents []Tag) *Revision

func (*Revision) Key

func (r *Revision) Key() storage.Pointer

func (*Revision) Parent

func (r *Revision) Parent(tagName string) (Tag, bool)

func (*Revision) RootIs

func (r *Revision) RootIs(key storage.Pointer) bool

func (*Revision) RootKey

func (r *Revision) RootKey() storage.Pointer

func (*Revision) ShortString

func (r *Revision) ShortString() string

func (*Revision) String

func (r *Revision) String() string

func (*Revision) Time

func (r *Revision) Time() time.Time

type Store

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

Store is a high-level entity that takes care of loading and storing objects (nodes, revisions) from/to a store. Such operations require encryption/decryption, encoding/decoding, actual store put/get. It is built on top of the more basic functionality in muscle/storage.

func NewStore

func NewStore(
	blockFactory *block.Factory,
	pointers storage.Store,
	baseDir string,
) (*Store, error)

func (*Store) History

func (s *Store) History(maxRevisions int, head *Revision, tagName string) (rr []*Revision, err error)

func (*Store) LoadNode

func (s *Store) LoadNode(dst *Node) error

LoadNode assumes that dst.key is the destination node's key, and the parent pointer is also correct. Loading will overwrite any other data.

func (*Store) LoadRevisionByKey

func (s *Store) LoadRevisionByKey(key storage.Pointer) (*Revision, error)

func (*Store) LocalBasePointer

func (s *Store) LocalBasePointer() (storage.Pointer, error)

LocalBasePointer reads the file $HOME/lib/muscle/base, expecting to find a hex-encoded storage.Pointer that points to a revision.

func (*Store) LocalRoot

func (s *Store) LocalRoot() (*Node, error)

func (*Store) LocalRootKey

func (s *Store) LocalRootKey() (storage.Pointer, error)

func (*Store) RemoteTag

func (s *Store) RemoteTag(tagName string) (tag Tag, err error)

func (*Store) RemoteTags

func (s *Store) RemoteTags(tagNames []string) (tags []Tag, err error)

func (*Store) SealNode

func (s *Store) SealNode(node *Node) error

func (*Store) SetLocalBasePointer

func (s *Store) SetLocalBasePointer(pointer storage.Pointer) error

SetLocalBasePointer atomically updates $HOME/lib/muscle/base, and adds an entry to $HOME/lib/muscle/base.history for the previous base pointer.

func (*Store) SetRemoteTags

func (s *Store) SetRemoteTags(tagNames []string, pointer storage.Pointer) error

pointer must point to a revision.

func (*Store) StoreNode

func (s *Store) StoreNode(node *Node) error

func (*Store) StoreRevision

func (s *Store) StoreRevision(r *Revision) error

type Tag

type Tag struct {
	Name    string
	Pointer storage.Pointer // Needs to point to a Revision.
}

type Tree

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

func NewTree

func NewTree(store *Store, opts ...TreeOption) (*Tree, error)

NewTree constructs a new tree object using the given store, and according to the given options (see the TreeOption section).

func (*Tree) Add

func (tree *Tree) Add(node *Node, name string, perm uint32) (*Node, error)

func (*Tree) Attach

func (tree *Tree) Attach() *Node

func (*Tree) Discard

func (tree *Tree) Discard(node *Node)

func (*Tree) DumpNodes

func (tree *Tree) DumpNodes(w io.Writer)

func (*Tree) Flush

func (tree *Tree) Flush() error

func (*Tree) FlushIfNotDoneRecently

func (tree *Tree) FlushIfNotDoneRecently() error

FlushIfNotDoneRecently dumps the in-memory changes to the staging area if not done recently (according to the snapshot frequency constant).

func (*Tree) Graft

func (tree *Tree) Graft(parent *Node, child *Node, childName string) error

Graft is a low-level operation. The child may come from a historical tree. The parent from the local tree. We will make the child a child of the parent.

func (*Tree) Grow

func (tree *Tree) Grow(parent *Node) error

Grow expands the tree at node (if necessary), by loading child nodes (where necessary). This method protects against the case where the node has more than one child with any given name, by adding a random UUID extension to the duplicates. (Unfortunately this type of inconsistency has happened during development of the merge operation.) This method will also add a random UUID extension to every node that is not found in the storage layer. Such nodes will then represent empty files.

func (*Tree) Ignore

func (tree *Tree) Ignore(revision string, pathname string)

Ignore marks the given pathname within the given revision as ignored for the purpose of pull (merge) operations. In other words, a conflict for pathname when merging the revision will result in the local version to be kept.

func (*Tree) ListNodesInUse

func (tree *Tree) ListNodesInUse() (paths []string)

func (*Tree) PullWorklog

func (tree *Tree) PullWorklog(cfg *config.C, baseTree *Tree, remoteTree *Tree) (output string, err error)

Returns proposed commands to execute via the ctl file. If empty, and no error, it means there's nothing to pull.

func (*Tree) ReachableKeys

func (tree *Tree) ReachableKeys(accumulator map[string]struct{}) (map[string]struct{}, error)

func (*Tree) RemoveForMerge

func (tree *Tree) RemoveForMerge(node *Node) error

RemoveForMerge unlinks the node from its parent even if it is a non-empty directory. This is required when running the 3-way merge algorithm. Also, if we don't find the node within the parent, we return an error, as that is an inconsistency. If we have to remove more than one node (the parent has more than one child matching the name), we do so, and log an error about the inconsistency. We don't return an error as we don't want to prevent the merge algorithm from resolving the inconsistency somehow. It is an error trying to remove the root (it has no parent). The code will panic if the parent of the node is nil. That would be a programming error and I don't want to defend against that.

func (*Tree) Rename

func (tree *Tree) Rename(sourcepath, targetpath string) error

func (*Tree) Root

func (tree *Tree) Root() (storage.Pointer, *Node)

func (*Tree) Seal

func (tree *Tree) Seal() error

func (*Tree) SetRevision

func (tree *Tree) SetRevision(r *Revision)

TODO This is a very ugly hack

func (*Tree) Trim

func (tree *Tree) Trim()
func (tree *Tree) Unlink(node *Node) error

func (*Tree) Walk

func (tree *Tree) Walk(sourceNode *Node, branchNames ...string) (visitedNodes []*Node, err error)

Walk navigates the tree starting from the given node following the given branches in sequence.

type TreeOption

type TreeOption func(*Tree) error

TreeOption values influence the behavior of NewTree.

func WithMutable

func WithMutable() TreeOption

The WithMutable option specifies that the tree to be constructed should allow mutating operations, like writing data, changing file names, and adding new nodes.

func WithRevision

func WithRevision(p storage.Pointer) TreeOption

WithRevision specifies that the tree's root node should be the revision's root node.

func WithRoot

func WithRoot(p storage.Pointer) TreeOption

WithRoot specifies the tree's root node.

func WithRootName

func WithRootName(name string) TreeOption

Jump to

Keyboard shortcuts

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