Fix index diffing algorithm
This commit is contained in:
parent
b886a5576a
commit
68f7ce3851
2 changed files with 89 additions and 16 deletions
|
@ -21,16 +21,29 @@ import (
|
||||||
"github.com/abcum/surreal/util/data"
|
"github.com/abcum/surreal/util/data"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Diff(old, now [][]interface{}) (_, _ [][]interface{}) {
|
func Diff(old, now [][]interface{}) (del, add [][]interface{}) {
|
||||||
|
|
||||||
for i := len(old) - 1; i >= 0; i-- {
|
loopo:
|
||||||
if reflect.DeepEqual(old[i], now[i]) {
|
for _, ov := range old {
|
||||||
old = append(old[:i], old[i+1:]...)
|
for _, nv := range now {
|
||||||
now = append(now[:i], now[i+1:]...)
|
if reflect.DeepEqual(ov, nv) {
|
||||||
|
continue loopo
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
del = append(del, ov)
|
||||||
}
|
}
|
||||||
|
|
||||||
return old, now
|
loopn:
|
||||||
|
for _, nv := range now {
|
||||||
|
for _, ov := range old {
|
||||||
|
if reflect.DeepEqual(ov, nv) {
|
||||||
|
continue loopn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add = append(add, nv)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,12 +36,14 @@ func TestDiff(t *testing.T) {
|
||||||
}
|
}
|
||||||
So(old, ShouldHaveLength, 2)
|
So(old, ShouldHaveLength, 2)
|
||||||
So(now, ShouldHaveLength, 2)
|
So(now, ShouldHaveLength, 2)
|
||||||
old, now = Diff(old, now)
|
del, add := Diff(old, now)
|
||||||
So(old, ShouldHaveLength, 0)
|
So(del, ShouldHaveLength, 0)
|
||||||
So(now, ShouldHaveLength, 0)
|
So(del, ShouldResemble, [][]interface{}(nil))
|
||||||
|
So(add, ShouldHaveLength, 0)
|
||||||
|
So(add, ShouldResemble, [][]interface{}(nil))
|
||||||
})
|
})
|
||||||
|
|
||||||
Convey("Perform diff of different arrays", t, func() {
|
Convey("Perform diff of reversed arrays", t, func() {
|
||||||
old := [][]interface{}{
|
old := [][]interface{}{
|
||||||
{"one", "two"},
|
{"one", "two"},
|
||||||
{"two", "tre"},
|
{"two", "tre"},
|
||||||
|
@ -52,9 +54,11 @@ func TestDiff(t *testing.T) {
|
||||||
}
|
}
|
||||||
So(old, ShouldHaveLength, 2)
|
So(old, ShouldHaveLength, 2)
|
||||||
So(now, ShouldHaveLength, 2)
|
So(now, ShouldHaveLength, 2)
|
||||||
old, now = Diff(old, now)
|
del, add := Diff(old, now)
|
||||||
So(old, ShouldHaveLength, 2)
|
So(del, ShouldHaveLength, 0)
|
||||||
So(now, ShouldHaveLength, 2)
|
So(del, ShouldResemble, [][]interface{}(nil))
|
||||||
|
So(add, ShouldHaveLength, 0)
|
||||||
|
So(add, ShouldResemble, [][]interface{}(nil))
|
||||||
})
|
})
|
||||||
|
|
||||||
Convey("Perform diff of same and different arrays", t, func() {
|
Convey("Perform diff of same and different arrays", t, func() {
|
||||||
|
@ -64,13 +68,33 @@ func TestDiff(t *testing.T) {
|
||||||
}
|
}
|
||||||
now := [][]interface{}{
|
now := [][]interface{}{
|
||||||
{"two", "tre"},
|
{"two", "tre"},
|
||||||
{"two", "tre"},
|
{"one", "tre"},
|
||||||
}
|
}
|
||||||
So(old, ShouldHaveLength, 2)
|
So(old, ShouldHaveLength, 2)
|
||||||
So(now, ShouldHaveLength, 2)
|
So(now, ShouldHaveLength, 2)
|
||||||
old, now = Diff(old, now)
|
del, add := Diff(old, now)
|
||||||
So(old, ShouldHaveLength, 1)
|
So(del, ShouldHaveLength, 1)
|
||||||
|
So(del, ShouldResemble, [][]interface{}{{"one", "two"}})
|
||||||
|
So(add, ShouldHaveLength, 1)
|
||||||
|
So(add, ShouldResemble, [][]interface{}{{"one", "tre"}})
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Perform diff of same and different length arrays", t, func() {
|
||||||
|
old := [][]interface{}{
|
||||||
|
{"one", "two"},
|
||||||
|
{"two", "tre"},
|
||||||
|
{"one", "tre"},
|
||||||
|
}
|
||||||
|
now := [][]interface{}{
|
||||||
|
{"two", "tre"},
|
||||||
|
}
|
||||||
|
So(old, ShouldHaveLength, 3)
|
||||||
So(now, ShouldHaveLength, 1)
|
So(now, ShouldHaveLength, 1)
|
||||||
|
del, add := Diff(old, now)
|
||||||
|
So(del, ShouldHaveLength, 2)
|
||||||
|
So(del, ShouldResemble, [][]interface{}{{"one", "two"}, {"one", "tre"}})
|
||||||
|
So(add, ShouldHaveLength, 0)
|
||||||
|
So(add, ShouldResemble, [][]interface{}(nil))
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -140,4 +164,40 @@ func TestBuild(t *testing.T) {
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Convey("Perform build with empty array field", t, func() {
|
||||||
|
|
||||||
|
col := sql.Idents{
|
||||||
|
sql.NewIdent("test.*"),
|
||||||
|
}
|
||||||
|
|
||||||
|
doc := data.Consume(map[string]interface{}{
|
||||||
|
"test": []interface{}{},
|
||||||
|
})
|
||||||
|
|
||||||
|
out := Build(col, doc)
|
||||||
|
|
||||||
|
So(out, ShouldResemble, [][]interface{}(nil))
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Perform build with non-empty array field", t, func() {
|
||||||
|
|
||||||
|
col := sql.Idents{
|
||||||
|
sql.NewIdent("test.*"),
|
||||||
|
}
|
||||||
|
|
||||||
|
doc := data.Consume(map[string]interface{}{
|
||||||
|
"test": []interface{}{"one", "two", "tre"},
|
||||||
|
})
|
||||||
|
|
||||||
|
out := Build(col, doc)
|
||||||
|
|
||||||
|
So(out, ShouldResemble, [][]interface{}{
|
||||||
|
{"one"},
|
||||||
|
{"two"},
|
||||||
|
{"tre"},
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue