Change tree Rebuild checks

This commit is contained in:
mcrakhman 2022-09-09 09:01:50 +02:00 committed by Mikhail Iudin
parent e384d549a2
commit b1c6c7e44e
No known key found for this signature in database
GPG Key ID: FAAAA8BAABDFF1C0

View File

@ -82,9 +82,11 @@ func (t *Tree) AddMergedHead(c *Change) error {
} }
func (t *Tree) Add(changes ...*Change) (mode Mode) { func (t *Tree) Add(changes ...*Change) (mode Mode) {
var beforeHeadIds = t.headIds var (
var attached bool beforeHeadIds = t.headIds
var empty = t.Len() == 0 attached bool
empty = t.Len() == 0
)
for _, c := range changes { for _, c := range changes {
// ignore existing // ignore existing
if _, ok := t.attached[c.Id]; ok { if _, ok := t.attached[c.Id]; ok {
@ -103,16 +105,28 @@ func (t *Tree) Add(changes ...*Change) (mode Mode) {
if empty { if empty {
return Rebuild return Rebuild
} }
for _, hid := range beforeHeadIds {
for _, newCh := range changes { stack := make([]*Change, len(beforeHeadIds), len(beforeHeadIds))
if _, ok := t.attached[newCh.Id]; ok { for i, hid := range beforeHeadIds {
if !t.after(newCh.Id, hid) { stack[i] = t.attached[hid]
return Rebuild }
mode = Append
t.dfsNext(stack,
func(_ *Change) (isContinue bool) {
return true
},
func(_ []*Change) {
// checking if some new changes were not visited
for _, ch := range changes {
if !ch.visited {
mode = Rebuild
break
} }
} }
} })
}
return Append return mode
} }
// RemoveInvalidChange removes all the changes that are descendants of id // RemoveInvalidChange removes all the changes that are descendants of id
@ -311,6 +325,37 @@ func (t *Tree) dfsPrev(stack []*Change, breakpoints []string, visit func(ch *Cha
} }
} }
func (t *Tree) dfsNext(stack []*Change, visit func(ch *Change) (isContinue bool), afterVisit func([]*Change)) {
t.visitedBuf = t.visitedBuf[:0]
defer func() {
afterVisit(t.visitedBuf)
for _, ch := range t.visitedBuf {
ch.visited = false
}
}()
for len(stack) > 0 {
ch := stack[len(stack)-1]
stack = stack[:len(stack)-1]
if ch.visited {
continue
}
ch.visited = true
t.visitedBuf = append(t.visitedBuf, ch)
for _, next := range ch.Next {
if !next.visited {
stack = append(stack, next)
}
}
if !visit(ch) {
return
}
}
}
func (t *Tree) updateHeads() { func (t *Tree) updateHeads() {
var newHeadIds []string var newHeadIds []string
t.iterate(t.root, func(c *Change) (isContinue bool) { t.iterate(t.root, func(c *Change) (isContinue bool) {