src/server/pkg/hashtree/db.go
func (h *dbHashTree) PutDirHeaderFooter(path string, header, footer *pfs.Object, headerSize, footerSize int64) error {
	path = clean(path)
	return h.Batch(func(tx *bolt.Tx) error {
		// validation: 'path' must point to directory (or nothing--may not be
		// created yet)
		node, err := get(tx, path)
		if err != nil && Code(err) != PathNotFound {
			return errorf(Internal, "could not get node at %q: %v", path, err)
		}
		if node != nil && node.nodetype() != directory {
			return errorf(PathConflict, "cannot add header to non-directory file "+
				"at %q; a file of type %s is already there", path, node.nodetype())
		}

		// Upsert directory at 'path' with 'Shared' field
		var newNode bool
		if node == nil {
			newNode = true
			node = &NodeProto{
				Name: base(path),
				DirNode: &DirectoryNodeProto{
					Shared: &Shared{},
				},
				// header/footer size are also stored in Shared (for CopyFile) but
				// adding it here makes size calculation in canonicalize() work
				SubtreeSize: headerSize + footerSize,
			}
		}

		// only write node to db if the node is new, or the header or footer
		// changed
		headerSame := (node.DirNode.Shared.Header == nil && header == nil) ||
			(node.DirNode.Shared.Header != nil && node.DirNode.Shared.Header.Hash == header.Hash)
		footerSame := (node.DirNode.Shared.Footer == nil && footer == nil) ||
			(node.DirNode.Shared.Footer != nil && node.DirNode.Shared.Footer.Hash == footer.Hash)
		if newNode || !headerSame || !footerSame {
			node.DirNode.Shared = &Shared{
				Header:     header,
				Footer:     footer,
				HeaderSize: headerSize,
				FooterSize: footerSize,
			}
			return put(tx, path, node)
		}
		return nil
	})
}
func (h *dbHashTree) PutDirHeaderFooter(path string, header, footer *pfs.Object, headerSize, footerSize int64) error {
	path = clean(path)
	return h.Batch(func(tx *bolt.Tx) error {
		// validation: 'path' must point to directory (or nothing--may not be
		// created yet)
		node, err := get(tx, path)
		if err != nil && Code(err) != PathNotFound {
			return errorf(Internal, "could not get node at %q: %v", path, err)
		}
		if node != nil && node.nodetype() != directory {
			return errorf(PathConflict, "cannot add header to non-directory file "+
				"at %q; a file of type %s is already there", path, node.nodetype())
		}

		// Upsert directory at 'path' with 'Shared' field
		var newNode bool
		if node == nil {
			newNode = true
			node = &NodeProto{
				Name: base(path),
				DirNode: &DirectoryNodeProto{
					Shared: &Shared{},
				},
				// header/footer size are also stored in Shared (for CopyFile) but
				// adding it here makes size calculation in canonicalize() work
				SubtreeSize: headerSize + footerSize,
			}
		}

		// only write node to db if the node is new, or the header or footer
		// changed
		headerSame := (node.DirNode.Shared.Header == nil && header == nil) ||
			(node.DirNode.Shared.Header != nil && node.DirNode.Shared.Header.Hash == header.Hash)
		footerSame := (node.DirNode.Shared.Footer == nil && footer == nil) ||
			(node.DirNode.Shared.Footer != nil && node.DirNode.Shared.Footer.Hash == footer.Hash)
		if newNode || !headerSame || !footerSame {
			node.DirNode.Shared = &Shared{
				Header:     header,
				Footer:     footer,
				HeaderSize: headerSize,
				FooterSize: footerSize,
			}
			return put(tx, path, node)
		}
		return nil
	})
}
// PutDirHeaderFooter implements the hashtree.PutDirHeaderFooter interface
// method