func TestEmptyLength(t *testing.T) { spec := gspec.New(t) empty := NewEmpty("x") empty.Set(key.Type(4)) empty.Set(key.Type(6)) spec.Expect(empty.Len()).ToEqual(0) }
func TestLoadsTheMap(t *testing.T) { spec := gspec.New(t) m := newIdMap() data := map[uint]string{1: "a1", 2: "b2", 10: "c3"} m.load(data) spec.Expect(m.get("c3", false)).ToEqual(key.Type(10)) spec.Expect(m.get("c4", true)).ToEqual(key.Type(11)) }
func TestSortedStringsOrderOnRemove(t *testing.T) { spec := gspec.New(t) s := NewSortedStrings("test") sortedSetLoad(s, 1, "banana", 2, "apples", 3, "oranges") s.Remove(key.Type(3)) spec.Expect(s.list[1].id).ToEqual(key.Type(2)) spec.Expect(s.list[2].id).ToEqual(key.Type(1)) spec.Expect(s.Len()).ToEqual(2) }
func TestSortedStringsContains(t *testing.T) { spec := gspec.New(t) s := NewSortedStrings("test") sortedSetLoad(s, 1, "banana", 2, "apples", 3, "oranges") s.SetString(key.Type(1), "prune") s.SetString(key.Type(4), "apes") s.Remove(1) spec.Expect(s.Contains(key.Type(1))).ToEqual(false) spec.Expect(s.Contains(key.Type(3))).ToEqual(true) }
func TestSortedIntsForwardIterationMovesUpToNextClosest(t *testing.T) { for i := 0; i < 1000; i++ { rand.Seed(int64(i)) s := NewSortedInts("test") s.SetInt(key.Type(1), 1) s.SetInt(key.Type(3), 3) s.SetInt(key.Type(4), 4) s.SetInt(key.Type(5), 5) assertIterator(t, s.Forwards().Range(2, 4).Offset(0), 3, 4) } }
func (m *IdMap) get(s string, create bool) key.Type { bucket := m.getBucket(s) bucket.RLock() id, exists := bucket.lookup[s] bucket.RUnlock() if exists { return id } if create == false { return key.NULL } bucket.Lock() defer bucket.Unlock() id, exists = bucket.lookup[s] if exists { return id } id = key.Type(atomic.AddUint64(&m.counter, 1)) bucket.lookup[s] = id return id }
func TestEmptyBackwards(t *testing.T) { spec := gspec.New(t) empty := NewEmpty("x") empty.Set(key.Type(4)) iter := empty.Backwards() spec.Expect(iter.Current()).ToEqual(key.NULL) }
func TestIdMapReturnsAnExistingId(t *testing.T) { spec := gspec.New(t) m := newIdMap() m.get("over", true) m.get("9000", true) spec.Expect(m.get("over", false)).ToEqual(key.Type(1)) }
func TestUnionDoesNotContainANonExistantId(t *testing.T) { spec := gspec.New(t) union := NewUnion("x", []string{"apple", "orange"}) union.On(makeSetIndex(20, 23, 24, 25, 26)) union.On(makeSetIndex(20, 25, 28, 29)) spec.Expect(union.Contains(key.Type(22))).ToEqual(false) }
func makeSetIndex(ids ...int) indexes.Index { set := indexes.NewSetString("test") for _, id := range ids { set.Set(key.Type(id)) } return set }
func TestSetContainsAnExistingIdIfMultipleIndexesContainsIt(t *testing.T) { spec := gspec.New(t) union := NewUnion("x", []string{"apple", "orange"}) union.On(makeSetIndex(20, 23, 24, 25, 26)) union.On(makeSetIndex(20, 25, 28, 29)) spec.Expect(union.Contains(key.Type(20))).ToEqual(true) }
func TestGreaterThanOrEqualContainsAnIdWithAScoreEqualToOurTarget(t *testing.T) { spec := gspec.New(t) gte := NewGreaterThanOrEqual("x", 10) gte.On(makeIndex(1, 7, 8, 10, 11, 12, 13, 20)) score, exists := gte.Score(key.Type(3)) spec.Expect(score).ToEqual(10) spec.Expect(exists).ToEqual(true) }
func TestEqualContainsAnIdWithAScoreEqualOurTarget(t *testing.T) { spec := gspec.New(t) eq := NewEqual("x", 10) eq.On(makeIndex(1, 7, 8, 10, 11, 12, 13, 20)) score, exists := eq.Score(key.Type(3)) spec.Expect(score).ToEqual(10) spec.Expect(exists).ToEqual(true) }
func TestLessThanOrEqualContainsAnIdWithAScoreLessThanOrEqualOurTarget(t *testing.T) { spec := gspec.New(t) lte := NewLessThanOrEqual("x", 10) lte.On(makeIndex(1, 7, 8, 10, 11, 12, 13, 20)) score, exists := lte.Score(key.Type(2)) spec.Expect(score).ToEqual(8) spec.Expect(exists).ToEqual(true) }
func TestEqualReturnsTheLength(t *testing.T) { spec := gspec.New(t) eq := NewEqual("x", 10) idx := makeIndex(1, 7, 8, 10, 11, 12, 13, 20) idx.(indexes.WithIntScores).SetInt(key.Type(22), 10) eq.On(idx) spec.Expect(eq.Len()).ToEqual(2) }
func TestBetweenContainsAnIdWithAScoreWithinOurTarget(t *testing.T) { spec := gspec.New(t) bt := NewBetween("x", 7, 11) bt.On(makeIndex(1, 7, 8, 10, 11, 12, 13, 20)) score, exists := bt.Score(key.Type(3)) spec.Expect(score).ToEqual(10) spec.Expect(exists).ToEqual(true) }
func TestBetweenReturnsTheLength(t *testing.T) { spec := gspec.New(t) bt := NewBetween("x", 7, 11) idx := makeIndex(1, 7, 8, 10, 11, 12, 13, 20) idx.(indexes.WithIntScores).SetInt(key.Type(22), 10) bt.On(idx) spec.Expect(bt.Len()).ToEqual(5) }
func TestMetaCanBeSetWithStringId(t *testing.T) { spec := gspec.New(t) meta := newMeta(SmallDB(), false) spec.Expect(meta.IsUpdate).ToEqual(false) spec.Expect(meta.StringId("123aa")).ToEqual(uint(1)) id, stringId := meta.getId() spec.Expect(id).ToEqual(key.Type(1)) spec.Expect(stringId).ToEqual("123aa") }
func TestSetCanDeleteItem(t *testing.T) { s := NewSetString("test") setLoad(s, 1, 2, 3, 4, 5, 6, 7, 8, 9) s.Remove(3) s.Remove(6) s.Remove(22) s.Set(key.Type(3)) assertIterator(t, s.Backwards(), 3, 9, 8, 7, 5, 4, 2, 1) }
func assertIterator(t *testing.T, iterator Iterator, ids ...key.Type) { defer iterator.Close() spec := gspec.New(t) i := 0 for id := iterator.Current(); id != key.NULL; id = iterator.Next() { spec.Expect(id).ToEqual(key.Type(ids[i])) i++ } }
// assumes not being called from multiple threads func (m *IdMap) load(ids map[uint]string) { max := uint(0) for id, s := range ids { if id > max { max = id } m.getBucket(s).lookup[s] = key.Type(id) } m.counter = uint64(max) }
func makeSet(db *Database, name string, ids ...int) indexes.Index { index := indexes.NewSetString(name) for _, id := range ids { index.Set(key.Type(id)) } if db != nil { addIndex(db, index) } return index }
func (d *Database) KeyContains(indexName string, id key.Type) bool { d.indexLock.RLock() index, exists := d.indexes[indexName].(indexes.Index) d.indexLock.RUnlock() if exists == false { return false } index.RLock() defer index.RUnlock() return index.Contains(key.Type(id)) }
func TestMetaCanBeSet(t *testing.T) { spec := gspec.New(t) meta := newMeta(nil, true) spec.Expect(meta.IsUpdate).ToEqual(true) meta.IntId(33) meta.SortedInt("age", 22) meta.SortedInt("power", 9001) spec.Expect(meta.getId()).ToEqual(key.Type(33)) spec.Expect(len(meta.sortedInts)).ToEqual(2) }
func assertSortedStringsIterator(t *testing.T, iterator Iterator, expectedInts ...int) { spec := gspec.New(t) expected := make([]key.Type, len(expectedInts)) for index, id := range expectedInts { expected[index] = key.Type(id) } for id := iterator.Current(); id != key.NULL; id = iterator.Next() { spec.Expect(id).ToEqual(expected[0]) copy(expected, expected[1:]) } }
func TestSortedIntsSetAndRemoveItems(t *testing.T) { spec := gspec.New(t) for i := 0; i < 500; i++ { rand.Seed(int64(i)) s := NewSortedInts("test") s.SetInt(1, 1) s.SetInt(2, 2) s.SetInt(3, 3) assertIterator(t, s.Forwards().Offset(0), 1, 2, 3) spec.Expect(s.offset(0).id).ToEqual(key.Type(1)) spec.Expect(s.offset(1).id).ToEqual(key.Type(2)) spec.Expect(s.offset(2).id).ToEqual(key.Type(3)) spec.Expect(s.offset(3).id).ToEqual(key.NULL) s.Remove(4) assertIterator(t, s.Forwards().Offset(0), 1, 2, 3) s.Remove(2) assertIterator(t, s.Forwards().Offset(0), 1, 3) spec.Expect(s.offset(0).id).ToEqual(key.Type(1)) spec.Expect(s.offset(1).id).ToEqual(key.Type(3)) spec.Expect(s.offset(2).id).ToEqual(key.NULL) s.Remove(3) assertIterator(t, s.Forwards().Offset(0), 1) spec.Expect(s.offset(0).id).ToEqual(key.Type(1)) spec.Expect(s.offset(1).id).ToEqual(key.NULL) s.SetInt(2, 0) assertIterator(t, s.Forwards().Offset(0), 2, 1) spec.Expect(s.offset(0).id).ToEqual(key.Type(2)) spec.Expect(s.offset(1).id).ToEqual(key.Type(1)) spec.Expect(s.offset(2).id).ToEqual(key.NULL) s.Remove(1) assertIterator(t, s.Forwards().Offset(0), 2) spec.Expect(s.offset(0).id).ToEqual(key.Type(2)) spec.Expect(s.offset(1).id).ToEqual(key.NULL) } }
func TestSortedStringsBulkLoad(t *testing.T) { spec := gspec.New(t) s := NewSortedStrings("test") sortedSetLoad(s, 1, "banana", 2, "apples", 3, "oranges") s.BulkLoad([]key.Type{key.Type(5), key.Type(10), key.Type(2)}) spec.Expect(s.list[0].id).ToEqual(key.NULL) spec.Expect(s.list[1].id).ToEqual(key.Type(5)) spec.Expect(s.list[2].id).ToEqual(key.Type(10)) spec.Expect(s.list[3].id).ToEqual(key.Type(2)) spec.Expect(s.list[4].id).ToEqual(key.NULL) spec.Expect(s.Len()).ToEqual(3) }
func TestEmptyContains(t *testing.T) { spec := gspec.New(t) empty := NewEmpty("x") empty.Set(key.Type(4)) spec.Expect(empty.Contains(key.Type(4))).ToEqual(false) }
func TestLessThanOrEqualContainAnIdWithAScoreEqualteoOurtarget(t *testing.T) { spec := gspec.New(t) lte := NewLessThanOrEqual("x", 10) lte.On(makeIndex(1, 7, 8, 10, 11, 12, 13, 20)) spec.Expect(lte.Contains(key.Type(3))).ToEqual(true) }
func TestLessThanOrEqualDoesNotContainAnIdWithAScoreGreaterThanOurtarget(t *testing.T) { spec := gspec.New(t) lte := NewLessThanOrEqual("x", 10) lte.On(makeIndex(1, 7, 8, 10, 11, 12, 13, 20)) spec.Expect(lte.Contains(key.Type(4))).ToEqual(false) }