VOL-1174: Keep only latest data and apply changes only when committed.
Change-Id: I2311eb9cf1487b39f23066df50d19b47fd5c7dcc
diff --git a/db/model/merge.go b/db/model/merge.go
index ef490d8..e041e12 100644
--- a/db/model/merge.go
+++ b/db/model/merge.go
@@ -40,30 +40,30 @@
}
type changeAnalysis struct {
- KeyMap1 map[reflect.Value]int
- KeyMap2 map[reflect.Value]int
- AddedKeys map[reflect.Value]struct{}
- RemovedKeys map[reflect.Value]struct{}
- ChangedKeys map[reflect.Value]struct{}
+ KeyMap1 map[string]int
+ KeyMap2 map[string]int
+ AddedKeys map[string]struct{}
+ RemovedKeys map[string]struct{}
+ ChangedKeys map[string]struct{}
}
func newChangeAnalysis(lst1, lst2 []Revision, keyName string) *changeAnalysis {
changes := &changeAnalysis{}
- changes.KeyMap1 = make(map[reflect.Value]int)
- changes.KeyMap2 = make(map[reflect.Value]int)
+ changes.KeyMap1 = make(map[string]int)
+ changes.KeyMap2 = make(map[string]int)
- changes.AddedKeys = make(map[reflect.Value]struct{})
- changes.RemovedKeys = make(map[reflect.Value]struct{})
- changes.ChangedKeys = make(map[reflect.Value]struct{})
+ changes.AddedKeys = make(map[string]struct{})
+ changes.RemovedKeys = make(map[string]struct{})
+ changes.ChangedKeys = make(map[string]struct{})
for i, rev := range lst1 {
_, v := GetAttributeValue(rev.GetData(), keyName, 0)
- changes.KeyMap1[v] = i
+ changes.KeyMap1[v.String()] = i
}
for i, rev := range lst2 {
_, v := GetAttributeValue(rev.GetData(), keyName, 0)
- changes.KeyMap2[v] = i
+ changes.KeyMap2[v.String()] = i
}
for v, _ := range changes.KeyMap2 {
if _, ok := changes.KeyMap1[v]; !ok {
@@ -90,6 +90,7 @@
dryRun bool) (rev Revision, changes []ChangeTuple) {
var configChanged bool
+ var revsToDiscard []Revision
if dstRev.GetConfig() == forkRev.GetConfig() {
configChanged = dstRev.GetConfig() != srcRev.GetConfig()
@@ -153,6 +154,7 @@
}
for key, _ := range src.RemovedKeys {
oldRev := forkList[src.KeyMap1[key]]
+ revsToDiscard = append(revsToDiscard, oldRev)
changes = append(changes, ChangeTuple{POST_REMOVE, oldRev.GetData()})
}
for key, _ := range src.ChangedKeys {
@@ -165,7 +167,9 @@
}
}
- newChildren[fieldName] = newList
+ if !dryRun {
+ newChildren[fieldName] = newList
+ }
} else {
src := newChangeAnalysis(forkList, srcList, field.Key)
dst := newChangeAnalysis(forkList, dstList, field.Key)
@@ -212,9 +216,10 @@
if _, changed := dst.ChangedKeys[key]; changed {
log.Error("conflict error - revision has changed")
}
- if _, removed := dst.ChangedKeys[key]; !removed {
+ if _, removed := dst.RemovedKeys[key]; !removed {
dstIdx := dst.KeyMap2[key]
oldRev := newList[dstIdx]
+ revsToDiscard = append(revsToDiscard, oldRev)
copy(newList[dstIdx:], newList[dstIdx+1:])
newList[len(newList)-1] = nil
@@ -224,8 +229,9 @@
}
}
- newChildren[fieldName] = newList
-
+ if !dryRun {
+ newChildren[fieldName] = newList
+ }
}
}
}
@@ -237,6 +243,11 @@
rev = dstRev
}
+ for _, discarded := range revsToDiscard {
+ discarded.Drop("", true)
+ }
+
+ dstRev.GetBranch().Latest.Drop("", configChanged)
rev = rev.UpdateAllChildren(newChildren, dstRev.GetBranch())
if configChanged {