Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(323)

Unified Diff: impl/memory/datastore_index_test.go

Issue 1302813003: impl/memory: Implement Queries (Closed) Base URL: https://github.com/luci/gae.git@add_multi_iterator
Patch Set: stringSet everywhere Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « impl/memory/datastore_index_selection.go ('k') | impl/memory/datastore_query.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: impl/memory/datastore_index_test.go
diff --git a/impl/memory/datastore_index_test.go b/impl/memory/datastore_index_test.go
index 2e93ba2f625788910ecb85f9e1f2940ba5500bac..e54922d62404eb3dfae3dbd28669460fb1f68869 100644
--- a/impl/memory/datastore_index_test.go
+++ b/impl/memory/datastore_index_test.go
@@ -5,6 +5,7 @@
package memory
import (
+ "sort"
"testing"
"time"
@@ -13,10 +14,6 @@ import (
. "github.com/smartystreets/goconvey/convey"
)
-func init() {
- indexCreationDeterministic = true
-}
-
var fakeKey = key("knd", 10, key("parentKind", "sid"))
func TestCollated(t *testing.T) {
@@ -24,22 +21,21 @@ func TestCollated(t *testing.T) {
Convey("TestCollated", t, func() {
Convey("nil list", func() {
- pm := (ds.PropertyMap)(nil)
- sip := partiallySerialize(pm)
- So(sip, ShouldBeNil)
+ pm := ds.PropertyMap(nil)
+ sip := partiallySerialize(fakeKey, pm)
Convey("nil collated", func() {
- Convey("defaultIndicies", func() {
- idxs := defaultIndicies("knd", pm)
+ Convey("defaultIndexes", func() {
+ idxs := defaultIndexes("knd", pm)
So(len(idxs), ShouldEqual, 1)
So(idxs[0].String(), ShouldEqual, "B:knd")
})
Convey("indexEntries", func() {
- s := sip.indexEntries(fakeKey, defaultIndicies("knd", pm))
+ s := sip.indexEntries("ns", defaultIndexes("knd", pm))
numItems, _ := s.GetCollection("idx").GetTotals()
So(numItems, ShouldEqual, 1)
itm := s.GetCollection("idx").MinItem(false)
- So(itm.Key, ShouldResemble, cat(indx("knd")))
+ So(itm.Key, ShouldResemble, cat(indx("knd").PrepForIdxTable()))
numItems, _ = s.GetCollection("idx:ns:" + string(itm.Key)).GetTotals()
So(numItems, ShouldEqual, 1)
})
@@ -52,24 +48,31 @@ func TestCollated(t *testing.T) {
"nerd": {prop(103.7)},
"spaz": {propNI(false)},
}
- sip := partiallySerialize(pm)
- So(len(sip), ShouldEqual, 2)
+ sip := partiallySerialize(fakeKey, pm)
+ So(len(sip), ShouldEqual, 4)
Convey("single collated", func() {
Convey("indexableMap", func() {
So(sip, ShouldResemble, serializedIndexablePmap{
"wat": {
- cat(ds.PTInt, 100),
- cat(ds.PTString, "hat"),
+ cat(prop("hat")),
+ cat(prop(100)),
// 'thing' is skipped, because it's not NoIndex
},
"nerd": {
- cat(ds.PTFloat, 103.7),
+ cat(prop(103.7)),
+ },
+ "__key__": {
+ cat(prop(fakeKey)),
+ },
+ "__ancestor__": {
+ cat(prop(fakeKey)),
+ cat(prop(fakeKey.Parent())),
},
})
})
- Convey("defaultIndicies", func() {
- idxs := defaultIndicies("knd", pm)
+ Convey("defaultIndexes", func() {
+ idxs := defaultIndexes("knd", pm)
So(len(idxs), ShouldEqual, 5)
So(idxs[0].String(), ShouldEqual, "B:knd")
So(idxs[1].String(), ShouldEqual, "B:knd/nerd")
@@ -97,8 +100,9 @@ var rowGenTestCases = []struct {
// just the collections you want to assert. These are checked in
// TestIndexEntries. nil to skip test case.
- collections map[string][]kv
+ collections map[string][][]byte
}{
+
{
name: "simple including builtins",
pmap: ds.PropertyMap{
@@ -111,39 +115,48 @@ var rowGenTestCases = []struct {
indx("knd", "-wat", "nerd"),
},
expected: []serializedPvals{
- {{}}, // B:knd
- {cat(ds.PTFloat, 103.7)}, // B:knd/nerd
- {cat(ds.PTInt, 100), cat(ds.PTString, "hat")}, // B:knd/wat
- {icat(ds.PTFloat, 103.7)}, // B:knd/-nerd
- {icat(ds.PTString, "hat"), icat(ds.PTInt, 100)}, // B:knd/-wat
+ {cat(prop(fakeKey))}, // B:knd
+ {cat(prop(103.7), prop(fakeKey))}, // B:knd/nerd
+ { // B:knd/wat
+ cat(prop(100), prop(fakeKey)),
+ cat(prop("hat"), prop(fakeKey)),
+ },
+ { // B:knd/-nerd
+ cat(icat(prop(103.7)), prop(fakeKey)),
+ },
+ { // B:knd/-wat
+ cat(icat(prop("hat")), prop(fakeKey)),
+ cat(icat(prop(100)), prop(fakeKey)),
+ },
{ // C:knd/-wat/nerd
- cat(icat(ds.PTString, "hat"), cat(ds.PTFloat, 103.7)),
- cat(icat(ds.PTInt, 100), cat(ds.PTFloat, 103.7)),
+ cat(icat(prop("hat")), prop(103.7), prop(fakeKey)),
+ cat(icat(prop(100)), prop(103.7), prop(fakeKey)),
},
},
- collections: map[string][]kv{
+
+ collections: map[string][][]byte{
"idx": {
- // 0 == builtin, 1 == complex
- {cat(byte(0), "knd", byte(0), 0), []byte{}},
- {cat(byte(0), "knd", byte(0), 1, byte(0), "nerd"), []byte{}},
- {cat(byte(0), "knd", byte(0), 1, byte(0), "wat"), []byte{}},
- {cat(byte(0), "knd", byte(0), 1, byte(1), "nerd"), []byte{}},
- {cat(byte(0), "knd", byte(0), 1, byte(1), "wat"), []byte{}},
- {cat(byte(1), "knd", byte(0), 2, byte(1), "wat", byte(0), "nerd"), []byte{}},
+ cat("knd", byte(0), byte(1), byte(0), "__key__", byte(0)),
+ cat("knd", byte(0), byte(1), byte(0), "__key__", byte(1), byte(0), "nerd", byte(0)),
+ cat("knd", byte(0), byte(1), byte(0), "__key__", byte(1), byte(0), "nerd", byte(1), byte(1), "wat", byte(0)),
+ cat("knd", byte(0), byte(1), byte(0), "__key__", byte(1), byte(0), "wat", byte(0)),
+ cat("knd", byte(0), byte(1), byte(0), "__key__", byte(1), byte(1), "nerd", byte(0)),
+ cat("knd", byte(0), byte(1), byte(0), "__key__", byte(1), byte(1), "wat", byte(0)),
},
- "idx:ns:" + sat(indx("knd")): {
- {cat(fakeKey), []byte{}},
+ "idx:ns:" + sat(indx("knd").PrepForIdxTable()): {
+ cat(prop(fakeKey)),
},
- "idx:ns:" + sat(indx("knd", "wat")): {
- {cat(ds.PTInt, 100, fakeKey), []byte{}},
- {cat(ds.PTString, "hat", fakeKey), cat(ds.PTInt, 100)},
+ "idx:ns:" + sat(indx("knd", "wat").PrepForIdxTable()): {
+ cat(prop(100), prop(fakeKey)),
+ cat(prop("hat"), prop(fakeKey)),
},
- "idx:ns:" + sat(indx("knd", "-wat")): {
- {cat(icat(ds.PTString, "hat"), fakeKey), []byte{}},
- {cat(icat(ds.PTInt, 100), fakeKey), icat(ds.PTString, "hat")},
+ "idx:ns:" + sat(indx("knd", "-wat").PrepForIdxTable()): {
+ cat(icat(prop("hat")), prop(fakeKey)),
+ cat(icat(prop(100)), prop(fakeKey)),
},
},
},
+
{
name: "complex",
pmap: ds.PropertyMap{
@@ -163,28 +176,29 @@ var rowGenTestCases = []struct {
{ // C:knd/yerp/-wat/spaz
// thank goodness the binary serialization only happens 1/val in the
// real code :).
- cat(cat(ds.PTString, "hat"), icat(ds.PTKey, rgenComplexKey), cat(ds.PTNull)),
- cat(cat(ds.PTString, "hat"), icat(ds.PTKey, rgenComplexKey), cat(ds.PTBoolFalse)),
- cat(cat(ds.PTString, "hat"), icat(ds.PTKey, rgenComplexKey), cat(ds.PTBoolTrue)),
- cat(cat(ds.PTString, "hat"), icat(ds.PTBytes, "value"), cat(ds.PTNull)),
- cat(cat(ds.PTString, "hat"), icat(ds.PTBytes, "value"), cat(ds.PTBoolFalse)),
- cat(cat(ds.PTString, "hat"), icat(ds.PTBytes, "value"), cat(ds.PTBoolTrue)),
- cat(cat(ds.PTString, "hat"), icat(ds.PTTime, rgenComplexTime), cat(ds.PTNull)),
- cat(cat(ds.PTString, "hat"), icat(ds.PTTime, rgenComplexTime), cat(ds.PTBoolFalse)),
- cat(cat(ds.PTString, "hat"), icat(ds.PTTime, rgenComplexTime), cat(ds.PTBoolTrue)),
-
- cat(cat(ds.PTFloat, 73.9), icat(ds.PTKey, rgenComplexKey), cat(ds.PTNull)),
- cat(cat(ds.PTFloat, 73.9), icat(ds.PTKey, rgenComplexKey), cat(ds.PTBoolFalse)),
- cat(cat(ds.PTFloat, 73.9), icat(ds.PTKey, rgenComplexKey), cat(ds.PTBoolTrue)),
- cat(cat(ds.PTFloat, 73.9), icat(ds.PTBytes, "value"), cat(ds.PTNull)),
- cat(cat(ds.PTFloat, 73.9), icat(ds.PTBytes, "value"), cat(ds.PTBoolFalse)),
- cat(cat(ds.PTFloat, 73.9), icat(ds.PTBytes, "value"), cat(ds.PTBoolTrue)),
- cat(cat(ds.PTFloat, 73.9), icat(ds.PTTime, rgenComplexTime), cat(ds.PTNull)),
- cat(cat(ds.PTFloat, 73.9), icat(ds.PTTime, rgenComplexTime), cat(ds.PTBoolFalse)),
- cat(cat(ds.PTFloat, 73.9), icat(ds.PTTime, rgenComplexTime), cat(ds.PTBoolTrue)),
+ cat(prop("hat"), icat(prop(rgenComplexKey)), prop(nil), prop(fakeKey)),
+ cat(prop("hat"), icat(prop(rgenComplexKey)), prop(false), prop(fakeKey)),
+ cat(prop("hat"), icat(prop(rgenComplexKey)), prop(true), prop(fakeKey)),
+ cat(prop("hat"), icat(prop(ds.ByteString("value"))), prop(nil), prop(fakeKey)),
+ cat(prop("hat"), icat(prop(ds.ByteString("value"))), prop(false), prop(fakeKey)),
+ cat(prop("hat"), icat(prop(ds.ByteString("value"))), prop(true), prop(fakeKey)),
+ cat(prop("hat"), icat(prop(rgenComplexTime)), prop(nil), prop(fakeKey)),
+ cat(prop("hat"), icat(prop(rgenComplexTime)), prop(false), prop(fakeKey)),
+ cat(prop("hat"), icat(prop(rgenComplexTime)), prop(true), prop(fakeKey)),
+
+ cat(prop(73.9), icat(prop(rgenComplexKey)), prop(nil), prop(fakeKey)),
+ cat(prop(73.9), icat(prop(rgenComplexKey)), prop(false), prop(fakeKey)),
+ cat(prop(73.9), icat(prop(rgenComplexKey)), prop(true), prop(fakeKey)),
+ cat(prop(73.9), icat(prop(ds.ByteString("value"))), prop(nil), prop(fakeKey)),
+ cat(prop(73.9), icat(prop(ds.ByteString("value"))), prop(false), prop(fakeKey)),
+ cat(prop(73.9), icat(prop(ds.ByteString("value"))), prop(true), prop(fakeKey)),
+ cat(prop(73.9), icat(prop(rgenComplexTime)), prop(nil), prop(fakeKey)),
+ cat(prop(73.9), icat(prop(rgenComplexTime)), prop(false), prop(fakeKey)),
+ cat(prop(73.9), icat(prop(rgenComplexTime)), prop(true), prop(fakeKey)),
},
},
},
+
{
name: "ancestor",
pmap: ds.PropertyMap{
@@ -193,10 +207,10 @@ var rowGenTestCases = []struct {
idxs: []*ds.IndexDefinition{
indx("knd!", "wat"),
},
- collections: map[string][]kv{
- "idx:ns:" + sat(indx("knd!", "wat")): {
- {cat(fakeKey.Parent(), ds.PTString, "sup", fakeKey), []byte{}},
- {cat(fakeKey, ds.PTString, "sup", fakeKey), []byte{}},
+ collections: map[string][][]byte{
+ "idx:ns:" + sat(indx("knd!", "wat").PrepForIdxTable()): {
+ cat(prop(fakeKey.Parent()), prop("sup"), prop(fakeKey)),
+ cat(prop(fakeKey), prop("sup"), prop(fakeKey)),
},
},
},
@@ -213,10 +227,10 @@ func TestIndexRowGen(t *testing.T) {
}
Convey(tc.name, func() {
- mvals := partiallySerialize(tc.pmap)
+ mvals := partiallySerialize(fakeKey, tc.pmap)
idxs := []*ds.IndexDefinition(nil)
if tc.withBuiltin {
- idxs = append(defaultIndicies("coolKind", tc.pmap), tc.idxs...)
+ idxs = append(defaultIndexes("coolKind", tc.pmap), tc.idxs...)
} else {
idxs = tc.idxs
}
@@ -224,15 +238,18 @@ func TestIndexRowGen(t *testing.T) {
m := matcher{}
for i, idx := range idxs {
Convey(idx.String(), func() {
- iGen, ok := m.match(idx, mvals)
+ iGen, ok := m.match(idx.GetFullSortOrder(), mvals)
if len(tc.expected[i]) > 0 {
So(ok, ShouldBeTrue)
- j := 0
- iGen.permute(func(row []byte) {
- So([]byte(row), ShouldResemble, tc.expected[i][j])
- j++
+ actual := make(serializedPvals, 0, len(tc.expected[i]))
+ iGen.permute(func(row, _ []byte) {
+ actual = append(actual, row)
})
- So(j, ShouldEqual, len(tc.expected[i]))
+ So(len(actual), ShouldEqual, len(tc.expected[i]))
+ sort.Sort(actual)
+ for j, act := range actual {
+ So(act, ShouldResemble, tc.expected[i][j])
+ }
} else {
So(ok, ShouldBeFalse)
}
@@ -258,13 +275,15 @@ func TestIndexEntries(t *testing.T) {
if tc.withBuiltin {
store = indexEntriesWithBuiltins(fakeKey, tc.pmap, tc.idxs)
} else {
- store = partiallySerialize(tc.pmap).indexEntries(fakeKey, tc.idxs)
+ store = partiallySerialize(fakeKey, tc.pmap).indexEntries(fakeKey.Namespace(), tc.idxs)
}
for colName, vals := range tc.collections {
i := 0
- store.GetCollection(colName).VisitItemsAscend(nil, true, func(itm *gkvlite.Item) bool {
- So(itm.Key, ShouldResemble, vals[i].k)
- So(itm.Val, ShouldResemble, vals[i].v)
+ coll := store.GetCollection(colName)
+ numItems, _ := coll.GetTotals()
+ So(numItems, ShouldEqual, len(tc.collections[colName]))
+ coll.VisitItemsAscend(nil, true, func(itm *gkvlite.Item) bool {
+ So(itm.Key, ShouldResemble, vals[i])
i++
return true
})
@@ -280,12 +299,13 @@ type dumbItem struct {
props ds.PropertyMap
}
-var updateIndiciesTests = []struct {
+var updateIndexesTests = []struct {
name string
idxs []*ds.IndexDefinition
data []dumbItem
expected map[string][][]byte
}{
+
{
name: "basic",
data: []dumbItem{
@@ -303,20 +323,21 @@ var updateIndiciesTests = []struct {
},
},
expected: map[string][][]byte{
- "idx:ns:" + sat(indx("knd", "wat")): {
- cat(ds.PTInt, 1, key("knd", 10)),
- cat(ds.PTInt, 10, key("knd", 1)),
+ "idx:ns:" + sat(indx("knd", "wat").PrepForIdxTable()): {
+ cat(prop(1), prop(key("knd", 10))),
+ cat(prop(10), prop(key("knd", 1))),
},
- "idx:ns:" + sat(indx("knd", "-wat")): {
- cat(icat(ds.PTInt, 10), key("knd", 1)),
- cat(icat(ds.PTInt, 1), key("knd", 10)),
+ "idx:ns:" + sat(indx("knd", "-wat").PrepForIdxTable()): {
+ cat(icat(prop(10)), prop(key("knd", 1))),
+ cat(icat(prop(1)), prop(key("knd", 10))),
},
- "idx:ns:" + sat(indx("knd", "yerp")): {
- cat(ds.PTInt, 200, key("knd", 10)),
- cat(ds.PTInt, 202, key("knd", 1)),
+ "idx:ns:" + sat(indx("knd", "yerp").PrepForIdxTable()): {
+ cat(prop(200), prop(key("knd", 10))),
+ cat(prop(202), prop(key("knd", 1))),
},
},
},
+
{
name: "compound",
idxs: []*ds.IndexDefinition{indx("knd", "yerp", "-wat")},
@@ -343,33 +364,33 @@ var updateIndiciesTests = []struct {
},
},
expected: map[string][][]byte{
- "idx:ns:" + sat(indx("knd", "yerp", "-wat")): {
- cat(ds.PTInt, 200, icat(ds.PTInt, 20), key("knd", 11)),
- cat(ds.PTInt, 200, icat(ds.PTInt, 20), key("knd", 14)),
- cat(ds.PTInt, 200, icat(ds.PTInt, 1), key("knd", 10)),
- cat(ds.PTInt, 202, icat(ds.PTInt, 10), key("knd", 1)),
+ "idx:ns:" + sat(indx("knd", "yerp", "-wat").PrepForIdxTable()): {
+ cat(prop(200), icat(prop(20)), prop(key("knd", 11))),
+ cat(prop(200), icat(prop(20)), prop(key("knd", 14))),
+ cat(prop(200), icat(prop(1)), prop(key("knd", 10))),
+ cat(prop(202), icat(prop(10)), prop(key("knd", 1))),
},
},
},
}
-func TestUpdateIndicies(t *testing.T) {
+func TestUpdateIndexes(t *testing.T) {
t.Parallel()
- Convey("Test updateIndicies", t, func() {
- for _, tc := range updateIndiciesTests {
+ Convey("Test updateIndexes", t, func() {
+ for _, tc := range updateIndexesTests {
Convey(tc.name, func() {
store := newMemStore()
idxColl := store.SetCollection("idx", nil)
for _, i := range tc.idxs {
- idxColl.Set(cat(i), []byte{})
+ idxColl.Set(cat(i.PrepForIdxTable()), []byte{})
}
tmpLoader := map[string]ds.PropertyMap{}
for _, itm := range tc.data {
ks := itm.key.String()
prev := tmpLoader[ks]
- updateIndicies(store, itm.key, prev, itm.props)
+ updateIndexes(store, itm.key, prev, itm.props)
tmpLoader[ks] = itm.props
}
tmpLoader = nil
« no previous file with comments | « impl/memory/datastore_index_selection.go ('k') | impl/memory/datastore_query.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698