func (qs *QuadStore) optimizeLinksTo(it *iterator.LinksTo) (graph.Iterator, bool) { subs := it.SubIterators() if len(subs) != 1 { return it, false } primary := subs[0] if primary.Type() == graph.Fixed { size, _ := primary.Size() if size == 1 { if !primary.Next() { panic("unexpected size during optimize") } val := primary.Result() newIt := qs.QuadIterator(it.Direction(), val) nt := newIt.Tagger() nt.CopyFrom(it) for _, tag := range primary.Tagger().Tags() { nt.AddFixed(tag, val) } it.Close() return newIt, true } } return it, false }
func (qs *QuadStore) optimizeLinksTo(it *iterator.LinksTo) (graph.Iterator, bool) { subs := it.SubIterators() if len(subs) != 1 { return it, false } primary := subs[0] switch primary.Type() { case graph.Fixed: size, _ := primary.Size() if size == 0 { return iterator.NewNull(), true } if size == 1 { if !primary.Next() { panic("sql: unexpected size during optimize") } val := primary.Result() newIt := qs.QuadIterator(it.Direction(), val) nt := newIt.Tagger() nt.CopyFrom(it) for _, tag := range primary.Tagger().Tags() { nt.AddFixed(tag, val) } it.Close() return newIt, true } else if size > 1 { var vals []NodeHash for primary.Next() { vals = append(vals, primary.Result().(NodeHash)) } lsql := &SQLLinkIterator{ constraints: []constraint{ constraint{ dir: it.Direction(), hashes: vals, }, }, tableName: newTableName(), size: 0, } l := &SQLIterator{ uid: iterator.NextUID(), qs: qs, sql: lsql, } nt := l.Tagger() nt.CopyFrom(it) for _, t := range primary.Tagger().Tags() { lsql.tagdirs = append(lsql.tagdirs, tagDir{ dir: it.Direction(), tag: t, }) } it.Close() return l, true } case sqlType: p := primary.(*SQLIterator) newit, err := linksto(p.sql, it.Direction(), qs) if err != nil { clog.Errorf("%v", err) return it, false } newit.Tagger().CopyFrom(it) return newit, true case graph.All: linkit := &SQLLinkIterator{ tableName: newTableName(), size: qs.Size(), } for _, t := range primary.Tagger().Tags() { linkit.tagdirs = append(linkit.tagdirs, tagDir{ dir: it.Direction(), tag: t, }) } for k, v := range primary.Tagger().Fixed() { linkit.tagger.AddFixed(k, v) } linkit.tagger.CopyFrom(it) newit := NewSQLIterator(qs, linkit) return newit, true } return it, false }