Documentation
¶
Index ¶
- func DefaultDirMetadata() fs.Metadata
- func HashBucket(bucket Bucket, hasherFactory func() hash.Hash) []byte
- type Bucket
- type ErrInvalidFilesystem
- type MemoryBucket
- func (b *MemoryBucket) AddRecord(metadata fs.Metadata, contentHash []byte)
- func (b *MemoryBucket) HasRecord(metadata fs.Metadata) bool
- func (b *MemoryBucket) Iterator() RecordIterator
- func (b *MemoryBucket) Length() int
- func (b *MemoryBucket) Root() Record
- func (b *MemoryBucket) UpdateRecord(metadata fs.Metadata, contentHash []byte)
- type Record
- type RecordIterator
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DefaultDirMetadata ¶
Returns a new, consistent, "blank" metadata for a directory. You must assign the `Name` metadata.
func HashBucket ¶
Walks the tree of files and metadata arrayed in a `Bucket` and constructs a tree hash over them. The root of the tree hash is returned. The returned root has can be said to verify the integrity of the entire tree (much like a Merkle tree).
The serial structure is expressed something like the following:
{"node": $dir.metadata.hash, "leaves": [ {"node": $file1.metadata.hash, "content": $file1.contentHash}, {"node": $subdir.metadata.hash, "leaves": [ ... ]}, ] }
This expression is made in cbor (rfc7049) format with indefinite-length arrays and a fixed order for all map fields. Every structure starting with "node" is itself hashed and that value substituted in before hashing the parent. Since the metadata hash contains the file/dir name, and the tree itself is traversed in sorted order, the entire structure is computed deterministically and unambiguously.
Types ¶
type Bucket ¶
type Bucket interface { AddRecord(metadata fs.Metadata, contentHash []byte) // record a file into the bucket Iterator() (rootRecord RecordIterator) // return a treewalk root that does a traversal ordered by path Root() Record // return the 0'th record; is the root if `Iterator` has already been invoked. Length() int }
Bucket keeps hashes of file content and the set of metadata per file and dir. This is to make it possible to range over the filesystem out of order and construct a total hash of the system in order later.
type ErrInvalidFilesystem ¶
type ErrInvalidFilesystem struct {
Msg string
}
Error raised while the bucket is being iterated and we discover it has either a duplicate entry or a missing parent dir for some entry.
If you're getting this after walking a filesystem, you had a bug in your walk; if you're getting it after walking a tar or some format, it may be missing entries as well.
This is not meant to be user facing; map it to something meaningful in your caller.
func (ErrInvalidFilesystem) Error ¶
func (e ErrInvalidFilesystem) Error() string
type MemoryBucket ¶
type MemoryBucket struct {
// contains filtered or unexported fields
}
func (*MemoryBucket) AddRecord ¶
func (b *MemoryBucket) AddRecord(metadata fs.Metadata, contentHash []byte)
func (*MemoryBucket) Iterator ¶
func (b *MemoryBucket) Iterator() RecordIterator
Get a `treewalk.Node` that starts at the root of the bucket. The walk will be in deterministic, sorted order (and thus is appropriate for hashing).
This applies some "finalization" operations before starting the walk:
- All records will be sorted.
- As a sanity check, if records exist, the first one must be ".".
This is only safe for non-concurrent use and depth-first traversal. If the data structure is changed, or (sub)iterators used out of order, behavior is undefined.
func (*MemoryBucket) Length ¶
func (b *MemoryBucket) Length() int
func (*MemoryBucket) Root ¶
func (b *MemoryBucket) Root() Record
func (*MemoryBucket) UpdateRecord ¶
func (b *MemoryBucket) UpdateRecord(metadata fs.Metadata, contentHash []byte)
type RecordIterator ¶
RecordIterator is used for walking Bucket contents in hash-ready order.
May panic with ErrInvalidFilesystem during traversal. TODO : reconsider if maybe you wouldn't like a "sancheck" method that does that scan first?