Move UID handling from Base

Also clean up some of the value creation code.
This commit is contained in:
kortschak 2014-07-30 11:44:36 +09:30
parent 1604dca737
commit 01b7278c3a
13 changed files with 198 additions and 92 deletions

View file

@ -32,6 +32,7 @@ import (
// An All iterator across a range of int64 values, from `max` to `min`. // An All iterator across a range of int64 values, from `max` to `min`.
type Int64 struct { type Int64 struct {
Base Base
uid uint64
tags graph.Tagger tags graph.Tagger
max, min int64 max, min int64
at int64 at int64
@ -39,14 +40,20 @@ type Int64 struct {
// Creates a new Int64 with the given range. // Creates a new Int64 with the given range.
func NewInt64(min, max int64) *Int64 { func NewInt64(min, max int64) *Int64 {
var all Int64 all := Int64{
uid: NextUID(),
min: min,
max: max,
at: min,
}
BaseInit(&all.Base) BaseInit(&all.Base)
all.max = max
all.min = min
all.at = min
return &all return &all
} }
func (it *Int64) UID() uint64 {
return it.uid
}
// Start back at the beginning // Start back at the beginning
func (it *Int64) Reset() { func (it *Int64) Reset() {
it.at = it.min it.at = it.min

View file

@ -26,6 +26,7 @@ import (
// be Next()ed if next is called. // be Next()ed if next is called.
type And struct { type And struct {
Base Base
uid uint64
tags graph.Tagger tags graph.Tagger
internalIterators []graph.Iterator internalIterators []graph.Iterator
itCount int itCount int
@ -35,13 +36,18 @@ type And struct {
// Creates a new And iterator. // Creates a new And iterator.
func NewAnd() *And { func NewAnd() *And {
var and And and := And{
uid: NextUID(),
internalIterators: make([]graph.Iterator, 0, 20),
}
BaseInit(&and.Base) BaseInit(&and.Base)
and.internalIterators = make([]graph.Iterator, 0, 20)
and.checkList = nil
return &and return &and
} }
func (it *And) UID() uint64 {
return it.uid
}
// Reset all internal iterators // Reset all internal iterators
func (it *And) Reset() { func (it *And) Reset() {
it.primaryIt.Reset() it.primaryIt.Reset()

View file

@ -31,6 +31,7 @@ import (
// an equality function. // an equality function.
type Fixed struct { type Fixed struct {
Base Base
uid uint64
tags graph.Tagger tags graph.Tagger
values []graph.Value values []graph.Value
lastIndex int lastIndex int
@ -55,14 +56,19 @@ func newFixed() *Fixed {
// Creates a new Fixed iterator with a custom comparitor. // Creates a new Fixed iterator with a custom comparitor.
func NewFixedIteratorWithCompare(compareFn Equality) *Fixed { func NewFixedIteratorWithCompare(compareFn Equality) *Fixed {
var it Fixed it := Fixed{
uid: NextUID(),
values: make([]graph.Value, 0, 20),
cmp: compareFn,
}
BaseInit(&it.Base) BaseInit(&it.Base)
it.values = make([]graph.Value, 0, 20)
it.lastIndex = 0
it.cmp = compareFn
return &it return &it
} }
func (it *Fixed) UID() uint64 {
return it.uid
}
func (it *Fixed) Reset() { func (it *Fixed) Reset() {
it.lastIndex = 0 it.lastIndex = 0
} }

View file

@ -47,6 +47,7 @@ import (
// and a temporary holder for the iterator generated on Check(). // and a temporary holder for the iterator generated on Check().
type HasA struct { type HasA struct {
Base Base
uid uint64
tags graph.Tagger tags graph.Tagger
ts graph.TripleStore ts graph.TripleStore
primaryIt graph.Iterator primaryIt graph.Iterator
@ -57,14 +58,20 @@ type HasA struct {
// Construct a new HasA iterator, given the triple subiterator, and the triple // Construct a new HasA iterator, given the triple subiterator, and the triple
// direction for which it stands. // direction for which it stands.
func NewHasA(ts graph.TripleStore, subIt graph.Iterator, d graph.Direction) *HasA { func NewHasA(ts graph.TripleStore, subIt graph.Iterator, d graph.Direction) *HasA {
var hasa HasA hasa := HasA{
uid: NextUID(),
ts: ts,
primaryIt: subIt,
dir: d,
}
BaseInit(&hasa.Base) BaseInit(&hasa.Base)
hasa.ts = ts
hasa.primaryIt = subIt
hasa.dir = d
return &hasa return &hasa
} }
func (it *HasA) UID() uint64 {
return it.uid
}
// Return our sole subiterator. // Return our sole subiterator.
func (it *HasA) SubIterators() []graph.Iterator { func (it *HasA) SubIterators() []graph.Iterator {
return []graph.Iterator{it.primaryIt} return []graph.Iterator{it.primaryIt}

View file

@ -22,8 +22,6 @@ import (
"strings" "strings"
"sync/atomic" "sync/atomic"
"github.com/barakmich/glog"
"github.com/google/cayley/graph" "github.com/google/cayley/graph"
) )
@ -38,20 +36,12 @@ func NextUID() uint64 {
type Base struct { type Base struct {
Last graph.Value Last graph.Value
canNext bool canNext bool
uid uint64
} }
// Called by subclases. // Called by subclases.
func BaseInit(it *Base) { func BaseInit(it *Base) {
// Your basic iterator is nextable // Your basic iterator is nextable
it.canNext = true it.canNext = true
if glog.V(2) {
it.uid = NextUID()
}
}
func (it *Base) UID() uint64 {
return it.uid
} }
// Prints a silly debug string. Most classes override. // Prints a silly debug string. Most classes override.
@ -115,12 +105,17 @@ func (it *Base) Reset() {}
// so it's important to give it a special iterator. // so it's important to give it a special iterator.
type Null struct { type Null struct {
Base Base
uid uint64
tags graph.Tagger tags graph.Tagger
} }
// Fairly useless New function. // Fairly useless New function.
func NewNull() *Null { func NewNull() *Null {
return &Null{} return &Null{uid: NextUID()}
}
func (it *Null) UID() uint64 {
return it.uid
} }
func (it *Null) Tagger() *graph.Tagger { func (it *Null) Tagger() *graph.Tagger {

View file

@ -41,6 +41,7 @@ import (
// `next_it` is the tempoarary iterator held per result in `primary_it`. // `next_it` is the tempoarary iterator held per result in `primary_it`.
type LinksTo struct { type LinksTo struct {
Base Base
uid uint64
tags graph.Tagger tags graph.Tagger
ts graph.TripleStore ts graph.TripleStore
primaryIt graph.Iterator primaryIt graph.Iterator
@ -51,15 +52,21 @@ type LinksTo struct {
// Construct a new LinksTo iterator around a direction and a subiterator of // Construct a new LinksTo iterator around a direction and a subiterator of
// nodes. // nodes.
func NewLinksTo(ts graph.TripleStore, it graph.Iterator, d graph.Direction) *LinksTo { func NewLinksTo(ts graph.TripleStore, it graph.Iterator, d graph.Direction) *LinksTo {
var lto LinksTo lto := LinksTo{
uid: NextUID(),
ts: ts,
primaryIt: it,
dir: d,
nextIt: &Null{},
}
BaseInit(&lto.Base) BaseInit(&lto.Base)
lto.ts = ts
lto.primaryIt = it
lto.dir = d
lto.nextIt = &Null{}
return &lto return &lto
} }
func (it *LinksTo) UID() uint64 {
return it.uid
}
func (it *LinksTo) Reset() { func (it *LinksTo) Reset() {
it.primaryIt.Reset() it.primaryIt.Reset()
if it.nextIt != nil { if it.nextIt != nil {

View file

@ -39,6 +39,7 @@ import (
// and whether the last check we received was true or false. // and whether the last check we received was true or false.
type Optional struct { type Optional struct {
Base Base
uid uint64
tags graph.Tagger tags graph.Tagger
subIt graph.Iterator subIt graph.Iterator
lastCheck bool lastCheck bool
@ -50,9 +51,14 @@ func NewOptional(it graph.Iterator) *Optional {
BaseInit(&o.Base) BaseInit(&o.Base)
o.canNext = false o.canNext = false
o.subIt = it o.subIt = it
o.uid = NextUID()
return &o return &o
} }
func (it *Optional) UID() uint64 {
return it.uid
}
func (it *Optional) Reset() { func (it *Optional) Reset() {
it.subIt.Reset() it.subIt.Reset()
it.lastCheck = false it.lastCheck = false

View file

@ -30,6 +30,7 @@ import (
type Or struct { type Or struct {
Base Base
uid uint64
tags graph.Tagger tags graph.Tagger
isShortCircuiting bool isShortCircuiting bool
internalIterators []graph.Iterator internalIterators []graph.Iterator
@ -38,23 +39,30 @@ type Or struct {
} }
func NewOr() *Or { func NewOr() *Or {
var or Or or := Or{
uid: NextUID(),
internalIterators: make([]graph.Iterator, 0, 20),
currentIterator: -1,
}
BaseInit(&or.Base) BaseInit(&or.Base)
or.internalIterators = make([]graph.Iterator, 0, 20)
or.isShortCircuiting = false
or.currentIterator = -1
return &or return &or
} }
func NewShortCircuitOr() *Or { func NewShortCircuitOr() *Or {
var or Or or := Or{
uid: NextUID(),
internalIterators: make([]graph.Iterator, 0, 20),
isShortCircuiting: true,
currentIterator: -1,
}
BaseInit(&or.Base) BaseInit(&or.Base)
or.internalIterators = make([]graph.Iterator, 0, 20)
or.isShortCircuiting = true
or.currentIterator = -1
return &or return &or
} }
func (it *Or) UID() uint64 {
return it.uid
}
// Reset all internal iterators // Reset all internal iterators
func (it *Or) Reset() { func (it *Or) Reset() {
for _, sub := range it.internalIterators { for _, sub := range it.internalIterators {

View file

@ -47,6 +47,7 @@ const (
type Comparison struct { type Comparison struct {
Base Base
uid uint64
tags graph.Tagger tags graph.Tagger
subIt graph.Iterator subIt graph.Iterator
op Operator op Operator
@ -55,15 +56,21 @@ type Comparison struct {
} }
func NewComparison(sub graph.Iterator, op Operator, val interface{}, ts graph.TripleStore) *Comparison { func NewComparison(sub graph.Iterator, op Operator, val interface{}, ts graph.TripleStore) *Comparison {
var vc Comparison vc := Comparison{
uid: NextUID(),
subIt: sub,
op: op,
val: val,
ts: ts,
}
BaseInit(&vc.Base) BaseInit(&vc.Base)
vc.subIt = sub
vc.op = op
vc.val = val
vc.ts = ts
return &vc return &vc
} }
func (it *Comparison) UID() uint64 {
return it.uid
}
// Here's the non-boilerplate part of the ValueComparison iterator. Given a value // Here's the non-boilerplate part of the ValueComparison iterator. Given a value
// and our operator, determine whether or not we meet the requirement. // and our operator, determine whether or not we meet the requirement.
func (it *Comparison) doComparison(val graph.Value) bool { func (it *Comparison) doComparison(val graph.Value) bool {

View file

@ -28,6 +28,7 @@ import (
type AllIterator struct { type AllIterator struct {
iterator.Base iterator.Base
uid uint64
tags graph.Tagger tags graph.Tagger
prefix []byte prefix []byte
dir graph.Direction dir graph.Direction
@ -38,23 +39,36 @@ type AllIterator struct {
} }
func NewAllIterator(prefix string, d graph.Direction, ts *TripleStore) *AllIterator { func NewAllIterator(prefix string, d graph.Direction, ts *TripleStore) *AllIterator {
var it AllIterator opts := &opt.ReadOptions{
DontFillCache: true,
}
it := AllIterator{
uid: iterator.NextUID(),
ro: opts,
iter: ts.db.NewIterator(nil, opts),
prefix: []byte(prefix),
dir: d,
open: true,
ts: ts,
}
iterator.BaseInit(&it.Base) iterator.BaseInit(&it.Base)
it.ro = &opt.ReadOptions{}
it.ro.DontFillCache = true
it.iter = ts.db.NewIterator(nil, it.ro)
it.prefix = []byte(prefix)
it.dir = d
it.open = true
it.ts = ts
it.iter.Seek(it.prefix) it.iter.Seek(it.prefix)
if !it.iter.Valid() { 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.open = false
it.iter.Release() it.iter.Release()
} }
return &it return &it
} }
func (it *AllIterator) UID() uint64 {
return it.uid
}
func (it *AllIterator) Reset() { func (it *AllIterator) Reset() {
if !it.open { if !it.open {
it.iter = it.ts.db.NewIterator(nil, it.ro) it.iter = it.ts.db.NewIterator(nil, it.ro)

View file

@ -28,6 +28,7 @@ import (
type Iterator struct { type Iterator struct {
iterator.Base iterator.Base
uid uint64
tags graph.Tagger tags graph.Tagger
nextPrefix []byte nextPrefix []byte
checkId []byte checkId []byte
@ -40,27 +41,43 @@ type Iterator struct {
} }
func NewIterator(prefix string, d graph.Direction, value graph.Value, ts *TripleStore) *Iterator { func NewIterator(prefix string, d graph.Direction, value graph.Value, ts *TripleStore) *Iterator {
var it Iterator vb := value.([]byte)
p := make([]byte, 0, 2+ts.hasher.Size())
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: ts.db.NewIterator(nil, opts),
open: true,
ts: ts,
}
iterator.BaseInit(&it.Base) iterator.BaseInit(&it.Base)
it.checkId = value.([]byte)
it.dir = d
it.originalPrefix = prefix
it.nextPrefix = make([]byte, 0, 2+ts.hasher.Size())
it.nextPrefix = append(it.nextPrefix, []byte(prefix)...)
it.nextPrefix = append(it.nextPrefix, []byte(it.checkId[1:])...)
it.ro = &opt.ReadOptions{}
it.ro.DontFillCache = true
it.iter = ts.db.NewIterator(nil, it.ro)
it.open = true
it.ts = ts
ok := it.iter.Seek(it.nextPrefix) ok := it.iter.Seek(it.nextPrefix)
if !ok { if !ok {
// 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.open = false
it.iter.Release() it.iter.Release()
} }
return &it return &it
} }
func (it *Iterator) UID() uint64 {
return it.uid
}
func (it *Iterator) Reset() { func (it *Iterator) Reset() {
if !it.open { if !it.open {
it.iter = it.ts.db.NewIterator(nil, it.ro) it.iter = it.ts.db.NewIterator(nil, it.ro)

View file

@ -27,6 +27,7 @@ import (
type Iterator struct { type Iterator struct {
iterator.Base iterator.Base
uid uint64
tags graph.Tagger tags graph.Tagger
tree *llrb.LLRB tree *llrb.LLRB
data string data string
@ -54,14 +55,20 @@ func IterateOne(tree *llrb.LLRB, last Int64) Int64 {
} }
func NewLlrbIterator(tree *llrb.LLRB, data string) *Iterator { func NewLlrbIterator(tree *llrb.LLRB, data string) *Iterator {
var it Iterator it := Iterator{
uid: iterator.NextUID(),
tree: tree,
iterLast: Int64(-1),
data: data,
}
iterator.BaseInit(&it.Base) iterator.BaseInit(&it.Base)
it.tree = tree
it.iterLast = Int64(-1)
it.data = data
return &it return &it
} }
func (it *Iterator) UID() uint64 {
return it.uid
}
func (it *Iterator) Reset() { func (it *Iterator) Reset() {
it.iterLast = Int64(-1) it.iterLast = Int64(-1)
} }

View file

@ -28,6 +28,7 @@ import (
type Iterator struct { type Iterator struct {
iterator.Base iterator.Base
uid uint64
tags graph.Tagger tags graph.Tagger
ts *TripleStore ts *TripleStore
dir graph.Direction dir graph.Direction
@ -41,54 +42,72 @@ type Iterator struct {
} }
func NewIterator(ts *TripleStore, collection string, d graph.Direction, val graph.Value) *Iterator { func NewIterator(ts *TripleStore, collection string, d graph.Direction, val graph.Value) *Iterator {
var m Iterator name := ts.NameOf(val)
iterator.BaseInit(&m.Base)
m.name = ts.NameOf(val) var constraint bson.M
m.collection = collection
switch d { switch d {
case graph.Subject: case graph.Subject:
m.constraint = bson.M{"Subject": m.name} constraint = bson.M{"Subject": name}
case graph.Predicate: case graph.Predicate:
m.constraint = bson.M{"Predicate": m.name} constraint = bson.M{"Predicate": name}
case graph.Object: case graph.Object:
m.constraint = bson.M{"Object": m.name} constraint = bson.M{"Object": name}
case graph.Provenance: case graph.Provenance:
m.constraint = bson.M{"Provenance": m.name} constraint = bson.M{"Provenance": name}
} }
m.ts = ts size, err := ts.db.C(collection).Find(constraint).Count()
m.dir = d
m.iter = ts.db.C(collection).Find(m.constraint).Iter()
size, err := ts.db.C(collection).Find(m.constraint).Count()
if err != nil { if err != nil {
// FIXME(kortschak) This should be passed back rather than just logging.
glog.Errorln("Trouble getting size for iterator! ", err) glog.Errorln("Trouble getting size for iterator! ", err)
return nil return nil
} }
m.size = int64(size)
m.hash = val.(string) m := Iterator{
m.isAll = false uid: iterator.NextUID(),
name: name,
constraint: constraint,
collection: collection,
ts: ts,
dir: d,
iter: ts.db.C(collection).Find(constraint).Iter(),
size: int64(size),
hash: val.(string),
isAll: false,
}
iterator.BaseInit(&m.Base)
return &m return &m
} }
func NewAllIterator(ts *TripleStore, collection string) *Iterator { func NewAllIterator(ts *TripleStore, collection string) *Iterator {
var m Iterator
m.ts = ts
m.dir = graph.Any
m.constraint = nil
m.collection = collection
m.iter = ts.db.C(collection).Find(nil).Iter()
size, err := ts.db.C(collection).Count() size, err := ts.db.C(collection).Count()
if err != nil { if err != nil {
// FIXME(kortschak) This should be passed back rather than just logging.
glog.Errorln("Trouble getting size for iterator! ", err) glog.Errorln("Trouble getting size for iterator! ", err)
return nil return nil
} }
m.size = int64(size)
m.hash = "" m := Iterator{
m.isAll = true uid: iterator.NextUID(),
ts: ts,
dir: graph.Any,
constraint: nil,
collection: collection,
iter: ts.db.C(collection).Find(nil).Iter(),
size: int64(size),
hash: "",
isAll: true,
}
// FIXME(kortschak) Was there supposed to be a BaseInit call here?
return &m return &m
} }
func (it *Iterator) UID() uint64 {
return it.uid
}
func (it *Iterator) Reset() { func (it *Iterator) Reset() {
it.iter.Close() it.iter.Close()
it.iter = it.ts.db.C(it.collection).Find(it.constraint).Iter() it.iter = it.ts.db.C(it.collection).Find(it.constraint).Iter()