Fix treebuilder errors
This commit is contained in:
parent
f2f2be36e9
commit
fa733293cb
@ -42,29 +42,44 @@ func (tb *treeBuilder) Reset() {
|
||||
|
||||
func (tb *treeBuilder) Build(theirHeads []string, newChanges []*Change) (*Tree, error) {
|
||||
var proposedHeads []string
|
||||
tb.cache = make(map[string]*Change)
|
||||
heads, err := tb.treeStorage.Heads()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tb.cache = make(map[string]*Change)
|
||||
proposedHeads = append(proposedHeads, heads...)
|
||||
|
||||
// TODO: we can actually get this from database
|
||||
// getting old common snapshot
|
||||
oldBreakpoint, err := tb.findBreakpoint(heads, true)
|
||||
if err != nil {
|
||||
// this should never error out, because otherwise we have broken data
|
||||
return nil, fmt.Errorf("findBreakpoint error: %v", err)
|
||||
}
|
||||
|
||||
if len(theirHeads) > 0 {
|
||||
proposedHeads = append(proposedHeads, theirHeads...)
|
||||
}
|
||||
for _, ch := range newChanges {
|
||||
// we don't know what new heads are, so every change can be head
|
||||
if len(theirHeads) == 0 {
|
||||
// in this case we don't know what new heads are, so every change can be head
|
||||
proposedHeads = append(proposedHeads, ch.Id)
|
||||
}
|
||||
tb.cache[ch.Id] = ch
|
||||
}
|
||||
|
||||
log.With(zap.Strings("heads", proposedHeads)).Debug("building tree")
|
||||
breakpoint, err := tb.findBreakpoint(proposedHeads)
|
||||
// getting common snapshot for new heads
|
||||
breakpoint, err := tb.findBreakpoint(proposedHeads, false)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("findBreakpoint error: %v", err)
|
||||
breakpoint = oldBreakpoint
|
||||
} else {
|
||||
breakpoint, err = tb.findCommonForTwoSnapshots(oldBreakpoint, breakpoint)
|
||||
if err != nil {
|
||||
breakpoint = oldBreakpoint
|
||||
}
|
||||
}
|
||||
proposedHeads = append(proposedHeads, heads...)
|
||||
|
||||
log.With(zap.Strings("heads", proposedHeads)).Debug("building tree")
|
||||
if err = tb.buildTree(proposedHeads, breakpoint); err != nil {
|
||||
return nil, fmt.Errorf("buildTree error: %v", err)
|
||||
}
|
||||
@ -78,13 +93,12 @@ func (tb *treeBuilder) buildTree(heads []string, breakpoint string) (err error)
|
||||
return
|
||||
}
|
||||
tb.tree.AddFast(ch)
|
||||
changes, err := tb.dfs(heads, breakpoint)
|
||||
|
||||
changes := tb.dfs(heads, breakpoint)
|
||||
tb.tree.AddFast(changes...)
|
||||
return
|
||||
}
|
||||
|
||||
func (tb *treeBuilder) dfs(heads []string, breakpoint string) (buf []*Change, err error) {
|
||||
func (tb *treeBuilder) dfs(heads []string, breakpoint string) []*Change {
|
||||
// initializing buffers
|
||||
tb.idStack = tb.idStack[:0]
|
||||
tb.loadBuffer = tb.loadBuffer[:0]
|
||||
@ -118,7 +132,7 @@ func (tb *treeBuilder) dfs(heads []string, breakpoint string) (buf []*Change, er
|
||||
tb.idStack = append(tb.idStack, prev)
|
||||
}
|
||||
}
|
||||
return tb.loadBuffer, nil
|
||||
return tb.loadBuffer
|
||||
}
|
||||
|
||||
func (tb *treeBuilder) loadChange(id string) (ch *Change, err error) {
|
||||
@ -143,18 +157,34 @@ func (tb *treeBuilder) loadChange(id string) (ch *Change, err error) {
|
||||
return ch, nil
|
||||
}
|
||||
|
||||
func (tb *treeBuilder) findBreakpoint(heads []string) (breakpoint string, err error) {
|
||||
func (tb *treeBuilder) findBreakpoint(heads []string, noError bool) (breakpoint string, err error) {
|
||||
var (
|
||||
ch *Change
|
||||
snapshotIds []string
|
||||
)
|
||||
for _, head := range heads {
|
||||
if ch, err = tb.loadChange(head); err != nil {
|
||||
if noError {
|
||||
return
|
||||
}
|
||||
|
||||
log.With(zap.String("head", head), zap.Error(err)).Debug("couldn't find head")
|
||||
continue
|
||||
}
|
||||
|
||||
shId := ch.SnapshotId
|
||||
if ch.IsSnapshot {
|
||||
shId = ch.Id
|
||||
} else {
|
||||
_, err = tb.loadChange(shId)
|
||||
if err != nil {
|
||||
if noError {
|
||||
return
|
||||
}
|
||||
|
||||
log.With(zap.String("snapshot id", shId), zap.Error(err)).Debug("couldn't find head's snapshot")
|
||||
continue
|
||||
}
|
||||
}
|
||||
if slice.FindPos(snapshotIds, shId) == -1 {
|
||||
snapshotIds = append(snapshotIds, shId)
|
||||
@ -170,6 +200,7 @@ func (tb *treeBuilder) findCommonSnapshot(snapshotIds []string) (snapshotId stri
|
||||
return "", fmt.Errorf("snapshots not found")
|
||||
}
|
||||
|
||||
// TODO: use divide and conquer to find the snapshot, then we will have only logN findCommonForTwoSnapshots calls
|
||||
for len(snapshotIds) > 1 {
|
||||
l := len(snapshotIds)
|
||||
shId, e := tb.findCommonForTwoSnapshots(snapshotIds[l-2], snapshotIds[l-1])
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user