Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit a72c4ec

Browse files
committed
Tree.Entries is now a slice
Tree's mapping of names to entries has been made internal, and will only be built when necessary with the first call to Tree.File().
1 parent 9df17e5 commit a72c4ec

File tree

2 files changed

+27
-23
lines changed

2 files changed

+27
-23
lines changed

objects_test.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,12 @@ func (s *ObjectsSuite) TestParseTree(c *C) {
5454
c.Assert(err, IsNil)
5555

5656
c.Assert(tree.Entries, HasLen, 8)
57-
c.Assert(tree.Entries[".gitignore"].Name, Equals, ".gitignore")
58-
c.Assert(tree.Entries[".gitignore"].Mode.String(), Equals, "-rw-r--r--")
59-
c.Assert(tree.Entries[".gitignore"].Hash.String(), Equals, "32858aad3c383ed1ff0a0f9bdf231d54a00c9e88")
57+
58+
tree.buildMap()
59+
c.Assert(tree.m, HasLen, 8)
60+
c.Assert(tree.m[".gitignore"].Name, Equals, ".gitignore")
61+
c.Assert(tree.m[".gitignore"].Mode.String(), Equals, "-rw-r--r--")
62+
c.Assert(tree.m[".gitignore"].Hash.String(), Equals, "32858aad3c383ed1ff0a0f9bdf231d54a00c9e88")
6063

6164
count := 0
6265
iter := tree.Files()

tree.go

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ var (
2424
// Tree is basically like a directory - it references a bunch of other trees
2525
// and/or blobs (i.e. files and sub-directories)
2626
type Tree struct {
27-
Entries map[string]TreeEntry
28-
OrderedNames []string
29-
Hash core.Hash
27+
Entries []TreeEntry
28+
Hash core.Hash
3029

3130
r *Repository
31+
m map[string]*TreeEntry
3232
}
3333

3434
// TreeEntry represents a file
@@ -112,12 +112,15 @@ func (t *Tree) dir(baseName string) (*Tree, error) {
112112
var errEntryNotFound = errors.New("entry not found")
113113

114114
func (t *Tree) entry(baseName string) (*TreeEntry, error) {
115-
entry, ok := t.Entries[baseName]
115+
if t.m == nil {
116+
t.buildMap()
117+
}
118+
entry, ok := t.m[baseName]
116119
if !ok {
117120
return nil, errEntryNotFound
118121
}
119122

120-
return &entry, nil
123+
return entry, nil
121124
}
122125

123126
func (t *Tree) Files() *FileIter {
@@ -135,7 +138,8 @@ func (t *Tree) Decode(o core.Object) error {
135138
return nil
136139
}
137140

138-
t.Entries = make(map[string]TreeEntry)
141+
t.Entries = nil
142+
t.m = nil
139143

140144
r := bufio.NewReader(o.Reader())
141145
for {
@@ -165,17 +169,23 @@ func (t *Tree) Decode(o core.Object) error {
165169
}
166170

167171
baseName := name[:len(name)-1]
168-
t.Entries[baseName] = TreeEntry{
172+
t.Entries = append(t.Entries, TreeEntry{
169173
Hash: hash,
170174
Mode: os.FileMode(fm),
171175
Name: baseName,
172-
}
173-
t.OrderedNames = append(t.OrderedNames, baseName)
176+
})
174177
}
175178

176179
return nil
177180
}
178181

182+
func (t *Tree) buildMap() {
183+
t.m = make(map[string]*TreeEntry)
184+
for i := 0; i < len(t.Entries); i++ {
185+
t.m[t.Entries[i].Name] = &t.Entries[i]
186+
}
187+
}
188+
179189
// TreeEntryIter facilitates iterating through the TreeEntry objects in a Tree.
180190
type TreeEntryIter struct {
181191
t *Tree
@@ -187,20 +197,11 @@ func NewTreeEntryIter(t *Tree) *TreeEntryIter {
187197
}
188198

189199
func (iter *TreeEntryIter) Next() (TreeEntry, error) {
190-
if iter.pos >= len(iter.t.OrderedNames) {
200+
if iter.pos >= len(iter.t.Entries) {
191201
return TreeEntry{}, io.EOF
192202
}
193-
194-
entry, ok := iter.t.Entries[iter.t.OrderedNames[iter.pos]]
195-
if !ok {
196-
// Probable race condition or internal bug
197-
// FIXME: Report more severe error or panic
198-
return TreeEntry{}, io.EOF
199-
}
200-
201203
iter.pos++
202-
203-
return entry, nil
204+
return iter.t.Entries[iter.pos-1], nil
204205
}
205206

206207
// TreeEntryIter facilitates iterating through the descendent subtrees of a

0 commit comments

Comments
 (0)