From 5d7303c49ac984a9fec60523f2d5297682e16646 Mon Sep 17 00:00:00 2001 From: Máximo Cuadros Ortiz Date: Sun, 5 Apr 2015 23:34:43 +0200 Subject: some refactor in folders and crawler --- packfile/packfile.go | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 packfile/packfile.go (limited to 'packfile/packfile.go') diff --git a/packfile/packfile.go b/packfile/packfile.go new file mode 100644 index 0000000..e670cd0 --- /dev/null +++ b/packfile/packfile.go @@ -0,0 +1,82 @@ +package packfile + +import "fmt" + +type Packfile struct { + Version uint32 + ObjectCount int + Checksum []byte + Commits map[string]*Commit + Trees map[string]*Tree + Blobs map[string]*Blob +} + +func NewPackfile() *Packfile { + return &Packfile{ + Commits: make(map[string]*Commit, 0), + Trees: make(map[string]*Tree, 0), + Blobs: make(map[string]*Blob, 0), + } +} + +type BlobEntry struct { + path string + *Blob +} + +type SubtreeEntry struct { + path string + *Tree + TreeCh +} + +type treeEntry interface { + isTreeEntry() + Path() string +} + +func (b BlobEntry) isTreeEntry() {} +func (b BlobEntry) Path() string { return b.path } +func (b SubtreeEntry) isTreeEntry() {} +func (b SubtreeEntry) Path() string { return b.path } + +type TreeCh <-chan treeEntry + +func (p *Packfile) WalkCommit(commitHash string) (TreeCh, error) { + commit, ok := p.Commits[commitHash] + if !ok { + return nil, fmt.Errorf("Unable to find %q commit", commitHash) + } + + treeHash := fmt.Sprintf("%x", string(commit.Tree)) + return p.WalkTree(p.Trees[treeHash]), nil +} + +func (p *Packfile) WalkTree(tree *Tree) TreeCh { + return p.walkTree(tree, "") +} + +func (p *Packfile) walkTree(tree *Tree, pathPrefix string) TreeCh { + ch := make(chan treeEntry) + + if tree == nil { + close(ch) + return ch + } + + go func() { + defer func() { + close(ch) + }() + for _, e := range tree.Entries { + path := pathPrefix + e.Name + if blob, ok := p.Blobs[e.Hash]; ok { + ch <- BlobEntry{path, blob} + } else if subtree, ok := p.Trees[e.Hash]; ok { + ch <- SubtreeEntry{path, subtree, p.walkTree(subtree, path+"/")} + } + } + }() + + return ch +} -- cgit