func NewIterator(prefix string, d quad.Direction, value graph.Value, qs *QuadStore) *Iterator { vb := value.(Token) p := make([]byte, 0, 2+quad.HashSize) p = append(p, []byte(prefix)...) p = append(p, []byte(vb[1:])...) opts := &opt.ReadOptions{ DontFillCache: true, } it := Iterator{ uid: iterator.NextUID(), nextPrefix: p, checkID: vb, dir: d, originalPrefix: prefix, ro: opts, iter: qs.db.NewIterator(nil, opts), open: true, qs: qs, } ok := it.iter.Seek(it.nextPrefix) if !ok { it.open = false it.iter.Release() clog.Errorf("Opening LevelDB iterator couldn't seek to location %v", it.nextPrefix) } return &it }
func NewAllIterator(prefix string, d quad.Direction, qs *QuadStore) *AllIterator { opts := &opt.ReadOptions{ DontFillCache: true, } it := AllIterator{ nodes: prefix == "z", uid: iterator.NextUID(), ro: opts, iter: qs.db.NewIterator(nil, opts), prefix: []byte(prefix), dir: d, open: true, qs: qs, } it.iter.Seek(it.prefix) if !it.iter.Valid() { // FIXME(kortschak) What are the semantics here? Is this iterator usable? // If not, we should return nil *Iterator and an error. it.open = false it.iter.Release() } return &it }
func NewAllIterator(qs *QuadStore, kind string) *Iterator { if kind != nodeKind && kind != quadKind { clog.Errorf("Cannot create iterator for an unknown kind") return &Iterator{done: true} } if qs.context == nil { clog.Errorf("Cannot create iterator without a valid context") return &Iterator{done: true} } var size int64 if kind == nodeKind { size = qs.NodeSize() } else { size = qs.Size() } return &Iterator{ uid: iterator.NextUID(), qs: qs, size: size, dir: quad.Any, isAll: true, kind: kind, done: false, } }
func (it *Iterator) Clone() graph.Iterator { var iter *b.Enumerator if it.result != nil { var ok bool iter, ok = it.tree.Seek(it.result.(int64)) if !ok { panic("value unexpectedly missing") } } else { var err error iter, err = it.tree.SeekFirst() if err != nil { iter = nil } } m := &Iterator{ uid: iterator.NextUID(), qs: it.qs, tree: it.tree, iter: iter, d: it.d, value: it.value, } m.tags.CopyFrom(it) return m }
func TestSQLNodeIteration(t *testing.T) { if *postgres_path == "" { t.SkipNow() } db, err := newQuadStore(*postgres_path, nil) if err != nil { t.Fatal(err) } link := NewSQLLinkIterator(db.(*QuadStore), quad.Object, quad.Raw("/en/humphrey_bogart")) it := &SQLIterator{ uid: iterator.NextUID(), qs: db.(*QuadStore), sql: &SQLNodeIterator{ tableName: newTableName(), linkIt: sqlItDir{ it: link.sql, dir: quad.Subject, }, }, } s, v := it.sql.buildSQL(true, nil) t.Log(s, v) c := 0 for it.Next() { t.Log(it.Result()) c += 1 } if c != 56 { t.Errorf("Not enough results, got %d expected 56", c) } }
func (it *SQLIterator) Clone() graph.Iterator { m := &SQLIterator{ uid: iterator.NextUID(), qs: it.qs, sql: it.sql.sqlClone(), } return m }
func NewSQLIterator(qs *QuadStore, sql sqlIterator) *SQLIterator { l := &SQLIterator{ uid: iterator.NextUID(), qs: qs, sql: sql, } return l }
func NewAllIterator(qs *QuadStore, table string) *AllIterator { it := &AllIterator{ uid: iterator.NextUID(), qs: qs, table: table, } return it }
func NewAllIterator(bucket []byte, d quad.Direction, qs *QuadStore) *AllIterator { return &AllIterator{ uid: iterator.NextUID(), bucket: bucket, dir: d, qs: qs, } }
// NewLinksTo constructs a new indexed LinksTo iterator for Mongo around a direction // and a subiterator of nodes. func NewLinksTo(qs *QuadStore, it graph.Iterator, collection string, d quad.Direction, lset []graph.Linkage) *LinksTo { return &LinksTo{ uid: iterator.NextUID(), qs: qs, primaryIt: it, dir: d, nextIt: nil, lset: lset, collection: collection, } }
func NewIteratorWithConstraints(qs *QuadStore, collection string, constraint bson.M) *Iterator { return &Iterator{ uid: iterator.NextUID(), qs: qs, dir: quad.Any, constraint: constraint, collection: collection, iter: nil, size: -1, hash: "", isAll: false, } }
func NewAllIterator(qs *QuadStore, collection string) *Iterator { return &Iterator{ uid: iterator.NextUID(), qs: qs, dir: quad.Any, constraint: nil, collection: collection, iter: nil, size: -1, hash: "", isAll: true, } }
func NewIterator(tree *b.Tree, qs *QuadStore, d quad.Direction, value graph.Value) *Iterator { iter, err := tree.SeekFirst() if err != nil { iter = nil } return &Iterator{ uid: iterator.NextUID(), qs: qs, tree: tree, iter: iter, d: d, value: value, } }
func NewSQLLinkIterator(qs *QuadStore, d quad.Direction, val string) *SQLIterator { l := &SQLIterator{ uid: iterator.NextUID(), qs: qs, sql: &SQLLinkIterator{ constraints: []constraint{ constraint{ dir: d, vals: []string{val}, }, }, tableName: newTableName(), size: 0, }, } return l }
func NewIterator(qs *QuadStore, collection string, d quad.Direction, val graph.Value) *Iterator { h := val.(NodeHash) constraint := bson.M{d.String(): string(h)} return &Iterator{ uid: iterator.NextUID(), constraint: constraint, collection: collection, qs: qs, dir: d, iter: nil, size: -1, hash: h, isAll: false, } }
func newSQLLinkIterator(qs *QuadStore, d quad.Direction, hash NodeHash) *SQLIterator { l := &SQLIterator{ uid: iterator.NextUID(), qs: qs, sql: &SQLLinkIterator{ constraints: []constraint{ constraint{ dir: d, hashes: []NodeHash{hash}, }, }, tableName: newTableName(), size: 0, }, } return l }
func NewIterator(qs *QuadStore, collection string, d quad.Direction, val graph.Value) *Iterator { name := qs.NameOf(val) constraint := bson.M{d.String(): name} return &Iterator{ uid: iterator.NextUID(), name: name, constraint: constraint, collection: collection, qs: qs, dir: d, iter: nil, size: -1, hash: val.(string), isAll: false, } }
func NewIterator(bucket []byte, d quad.Direction, value graph.Value, qs *QuadStore) *Iterator { tok := value.(*Token) if !bytes.Equal(tok.bucket, nodeBucket) { clog.Errorf("creating an iterator from a non-node value") return &Iterator{done: true} } it := Iterator{ uid: iterator.NextUID(), bucket: bucket, dir: d, qs: qs, size: qs.SizeOf(value), } it.checkID = make([]byte, len(tok.key)) copy(it.checkID, tok.key) return &it }
func NewIterator(qs *QuadStore, k string, d quad.Direction, val graph.Value) *Iterator { t := val.(*Token) if t == nil { clog.Errorf("Token == nil") } if t.Kind != nodeKind { clog.Errorf("Cannot create an iterator from a non-node value") return &Iterator{done: true} } if k != nodeKind && k != quadKind { clog.Errorf("Cannot create iterator for unknown kind") return &Iterator{done: true} } if qs.context == nil { clog.Errorf("Cannot create iterator without a valid context") return &Iterator{done: true} } name := quad.StringOf(qs.NameOf(t)) // The number of references to this node is held in the nodes entity key := qs.createKeyFromToken(t) foundNode := new(NodeEntry) err := datastore.Get(qs.context, key, foundNode) if err != nil && err != datastore.ErrNoSuchEntity { clog.Errorf("Error: %v", err) return &Iterator{done: true} } size := foundNode.Size return &Iterator{ uid: iterator.NextUID(), name: name, dir: d, qs: qs, size: size, isAll: false, kind: k, hash: t.Hash, done: 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 }