コード例 #1
0
ファイル: datastore_index_test.go プロジェクト: nishanths/gae
func TestIndexEntries(t *testing.T) {
	t.Parallel()

	Convey("Test indexEntriesWithBuiltins", t, func() {
		for _, tc := range rowGenTestCases {
			if tc.collections == nil {
				Convey(tc.name, nil) // shows up as 'skipped'
				continue
			}

			Convey(tc.name, func() {
				store := (*memStore)(nil)
				if tc.withBuiltin {
					store = indexEntriesWithBuiltins(fakeKey, tc.pmap, tc.idxs)
				} else {
					sip := serialize.PropertyMapPartially(fakeKey, tc.pmap)
					store = indexEntries(sip, fakeKey.Namespace(), tc.idxs)
				}
				for colName, vals := range tc.collections {
					i := 0
					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
					})
					So(i, ShouldEqual, len(vals))
				}
			})
		}
	})
}
コード例 #2
0
ファイル: datastore_index.go プロジェクト: nishanths/gae
func addIndexes(store *memStore, aid, ns string, compIdx []*ds.IndexDefinition) {
	normalized := make([]*ds.IndexDefinition, len(compIdx))
	idxColl := store.SetCollection("idx", nil)
	for i, idx := range compIdx {
		normalized[i] = idx.Normalize()
		idxColl.Set(serialize.ToBytes(*normalized[i].PrepForIdxTable()), []byte{})
	}

	if allEnts := store.GetCollection("ents:" + ns); allEnts != nil {
		allEnts.VisitItemsAscend(nil, true, func(i *gkvlite.Item) bool {
			pm, err := rpm(i.Val)
			memoryCorruption(err)

			prop, err := serialize.ReadProperty(bytes.NewBuffer(i.Key), serialize.WithoutContext, aid, ns)
			memoryCorruption(err)

			k := prop.Value().(*ds.Key)

			sip := serialize.PropertyMapPartially(k, pm)

			mergeIndexes(ns, store,
				newMemStore(),
				indexEntries(sip, ns, normalized))
			return true
		})
	}
}
コード例 #3
0
ファイル: query_merger.go プロジェクト: nishanths/gae
// toComparableString computes the byte-sortable 'order' string for the given
// key/PropertyMap.
//
//   * start/end are byte sequences which are the inequality bounds of the
//     query, if any. These are a serialized datastore.Property. If the
//     inequality column is inverted, then start and end are also inverted and
//     swapped with each other.
//   * order is the list of sort orders in the actual executing queries.
//   * k / pm are the data to derive a sortable string for.
//
// The result of this function is the series of serialized properties, one per
// order column, which represent this key/pm's first entry in the composite
// index that would point to it (e.g. the one with `order` sort orders).
func toComparableString(start, end []byte, order []ds.IndexColumn, k *ds.Key, pm ds.PropertyMap) (row, key []byte) {
	doCmp := true
	soFar := []byte{}
	ps := serialize.PropertyMapPartially(k, nil)
	for _, ord := range order {
		row, ok := ps[ord.Property]
		if !ok {
			if vals, ok := pm[ord.Property]; ok {
				row = serialize.PropertySlice(vals)
			}
		}
		sort.Sort(row)
		foundOne := false
		for _, serialized := range row {
			if ord.Descending {
				serialized = serialize.Invert(serialized)
			}
			if doCmp {
				maybe := serialize.Join(soFar, serialized)
				cmp := bytes.Compare(maybe, start)
				if cmp >= 0 {
					foundOne = true
					soFar = maybe
					doCmp = len(soFar) < len(start)
					break
				}
			} else {
				foundOne = true
				soFar = serialize.Join(soFar, serialized)
				break
			}
		}
		if !foundOne {
			return nil, nil
		}
	}
	if end != nil && bytes.Compare(soFar, end) >= 0 {
		return nil, nil
	}
	return soFar, ps["__key__"][0]
}
コード例 #4
0
ファイル: datastore_index_test.go プロジェクト: nishanths/gae
func TestIndexRowGen(t *testing.T) {
	t.Parallel()

	Convey("Test Index Row Generation", t, func() {
		for _, tc := range rowGenTestCases {
			if tc.expected == nil {
				Convey(tc.name, nil) // shows up as 'skipped'
				continue
			}

			Convey(tc.name, func() {
				mvals := serialize.PropertyMapPartially(fakeKey, tc.pmap)
				idxs := []*ds.IndexDefinition(nil)
				if tc.withBuiltin {
					idxs = append(defaultIndexes("coolKind", tc.pmap), tc.idxs...)
				} else {
					idxs = tc.idxs
				}

				m := matcher{}
				for i, idx := range idxs {
					Convey(idx.String(), func() {
						iGen, ok := m.match(idx.GetFullSortOrder(), mvals)
						if len(tc.expected[i]) > 0 {
							So(ok, ShouldBeTrue)
							actual := make(serialize.SerializedPslice, 0, len(tc.expected[i]))
							iGen.permute(func(row, _ []byte) {
								actual = append(actual, row)
							})
							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)
						}
					})
				}
			})
		}
	})

	Convey("default indexes", t, func() {
		Convey("nil collated", func() {
			Convey("defaultIndexes (nil)", func() {
				idxs := defaultIndexes("knd", ds.PropertyMap(nil))
				So(len(idxs), ShouldEqual, 1)
				So(idxs[0].String(), ShouldEqual, "B:knd")
			})

			Convey("indexEntries", func() {
				sip := serialize.PropertyMapPartially(fakeKey, nil)
				s := indexEntries(sip, "ns", defaultIndexes("knd", ds.PropertyMap(nil)))
				numItems, _ := s.GetCollection("idx").GetTotals()
				So(numItems, ShouldEqual, 1)
				itm := s.GetCollection("idx").MinItem(false)
				So(itm.Key, ShouldResemble, cat(indx("knd").PrepForIdxTable()))
				numItems, _ = s.GetCollection("idx:ns:" + string(itm.Key)).GetTotals()
				So(numItems, ShouldEqual, 1)
			})

			Convey("defaultIndexes", func() {
				pm := ds.PropertyMap{
					"wat":  {propNI("thing"), prop("hat"), prop(100)},
					"nerd": {prop(103.7)},
					"spaz": {propNI(false)},
				}
				idxs := defaultIndexes("knd", pm)
				So(len(idxs), ShouldEqual, 5)
				So(idxs[0].String(), ShouldEqual, "B:knd")
				So(idxs[1].String(), ShouldEqual, "B:knd/nerd")
				So(idxs[2].String(), ShouldEqual, "B:knd/wat")
				So(idxs[3].String(), ShouldEqual, "B:knd/-nerd")
				So(idxs[4].String(), ShouldEqual, "B:knd/-wat")
			})

		})
	})
}
コード例 #5
0
ファイル: datastore_index.go プロジェクト: nishanths/gae
func indexEntriesWithBuiltins(k *ds.Key, pm ds.PropertyMap, complexIdxs []*ds.IndexDefinition) *memStore {
	sip := serialize.PropertyMapPartially(k, pm)
	return indexEntries(sip, k.Namespace(), append(defaultIndexes(k.Kind(), pm), complexIdxs...))
}