Merge pull request #293 from barakmich/and_alls

Add check for multiple all iterators
This commit is contained in:
Barak Michener 2015-08-12 16:00:26 -04:00
commit 17c636ad29
2 changed files with 51 additions and 3 deletions

View file

@ -292,12 +292,15 @@ func hasAnyNullIterators(its []graph.Iterator) bool {
// nothing, and graph.All which returns everything. Particularly, we want
// to see if we're intersecting with a bunch of graph.All iterators, and,
// if we are, then we have only one useful iterator.
//
// We already checked for hasAnyNullIteratators() -- so now we're considering
// All iterators.
func hasOneUsefulIterator(its []graph.Iterator) graph.Iterator {
usefulCount := 0
var usefulIt graph.Iterator
for _, it := range its {
switch it.Type() {
case graph.Null, graph.All:
case graph.All:
continue
case graph.Optional:
// Optional is weird -- it's not useful, but we can't optimize
@ -313,6 +316,10 @@ func hasOneUsefulIterator(its []graph.Iterator) graph.Iterator {
if usefulCount == 1 {
return usefulIt
}
if usefulCount == 0 {
// It's full of All iterators. We can safely return one of them.
return its[0]
}
return nil
}

View file

@ -73,7 +73,7 @@ func TestNullIteratorAnd(t *testing.T) {
}
}
func TestReorderWithTag(t *testing.T) {
func TestAllPromotion(t *testing.T) {
qs := &store{
data: []string{},
iter: NewFixed(Identity),
@ -91,6 +91,43 @@ func TestReorderWithTag(t *testing.T) {
if !changed {
t.Error("Expected new iterator")
}
if newIt.Type() != graph.All {
t.Error("Should have promoted the All iterator")
}
expectedTags := []string{"good", "slow"}
tagsOut := make([]string, 0)
for _, x := range newIt.Tagger().Tags() {
tagsOut = append(tagsOut, x)
}
sort.Strings(tagsOut)
if !reflect.DeepEqual(expectedTags, tagsOut) {
t.Fatalf("Tags don't match: expected: %#v, got: %#v", expectedTags, tagsOut)
}
}
func TestReorderWithTag(t *testing.T) {
qs := &store{
data: []string{},
iter: NewFixed(Identity),
}
all := NewFixed(Identity)
all.Add(3)
all.Tagger().Add("good")
all2 := NewFixed(Identity)
all2.Tagger().Add("slow")
all2.Add(3)
all2.Add(4)
all2.Add(5)
all2.Add(6)
a := NewAnd(qs)
// Make all2 the default iterator
a.AddSubIterator(all2)
a.AddSubIterator(all)
newIt, changed := a.Optimize()
if !changed {
t.Error("Expected new iterator")
}
expectedTags := []string{"good", "slow"}
tagsOut := make([]string, 0)
for _, sub := range newIt.SubIterators() {
@ -98,8 +135,12 @@ func TestReorderWithTag(t *testing.T) {
tagsOut = append(tagsOut, x)
}
}
for _, x := range newIt.Tagger().Tags() {
tagsOut = append(tagsOut, x)
}
sort.Strings(tagsOut)
if !reflect.DeepEqual(expectedTags, tagsOut) {
t.Fatal("Tags don't match")
t.Fatalf("Tags don't match: expected: %#v, got: %#v", expectedTags, tagsOut)
}
}