summaryrefslogtreecommitdiff
path: root/fi-prune-empty2/prune.go
diff options
context:
space:
mode:
Diffstat (limited to 'fi-prune-empty2/prune.go')
-rw-r--r--fi-prune-empty2/prune.go40
1 files changed, 27 insertions, 13 deletions
diff --git a/fi-prune-empty2/prune.go b/fi-prune-empty2/prune.go
index ff0119b..e3181b2 100644
--- a/fi-prune-empty2/prune.go
+++ b/fi-prune-empty2/prune.go
@@ -75,8 +75,8 @@ type Pruner struct {
replace map[Mark]Mark
- ancestors map[Mark]map[Mark]struct{} // all ancestors, not just immediate parents
- tree map[Mark]Tree
+ parents map[Mark]map[Mark]struct{}
+ tree map[Mark]Tree
newhash2mark map[Hash]Mark
}
@@ -94,8 +94,8 @@ func NewPruner(
replace: make(map[Mark]Mark),
- ancestors: make(map[Mark]map[Mark]struct{}),
- tree: make(map[Mark]Tree),
+ parents: make(map[Mark]map[Mark]struct{}),
+ tree: make(map[Mark]Tree),
newhash2mark: make(map[Hash]Mark),
}
@@ -156,14 +156,13 @@ func (p *Pruner) ProcessCommit(commit Commit) (*Commit, error) {
return nil, nil
}
- ancestors := map[Mark]struct{}{}
- for _, parent := range commit.Parents {
- ancestors[parent] = struct{}{}
- for ancestor := range p.ancestors[parent] {
- ancestors[ancestor] = struct{}{}
+ p.parents[commit.Mark] = func() map[Mark]struct{} {
+ parents := make(map[Mark]struct{}, len(commit.Parents))
+ for _, parent := range commit.Parents {
+ parents[parent] = struct{}{}
}
- }
- p.ancestors[commit.Mark] = ancestors
+ return parents
+ }()
p.tree[commit.Mark] = commit.Tree
return &commit, nil
@@ -241,8 +240,23 @@ func (p *Pruner) isEmpty(commit Commit) (bool, error) {
}
func (p *Pruner) isAncestor(ancestor, descendant Mark) bool {
- _, ret := p.ancestors[descendant][ancestor]
- return ret
+ isDescendentMemo := make(map[Mark]bool)
+ var isDescendent func(desc Mark) bool
+ isDescendent = func(desc Mark) bool {
+ if ret, ok := isDescendentMemo[desc]; ok {
+ return ret
+ }
+ ret := false
+ for descParent := range p.parents[desc] {
+ if descParent == ancestor || isDescendent(descParent) {
+ ret = true
+ break
+ }
+ }
+ isDescendentMemo[desc] = ret
+ return ret
+ }
+ return isDescendent(descendant)
}
// pruneParents prunes "duplicate" parents of a commit. It is