Replace string type with graph.Direction
This conversion is not complete as there are still uses of string directions via the Direction.String method in leveldb.
This commit is contained in:
parent
cd11053c98
commit
0a03cec497
21 changed files with 340 additions and 298 deletions
|
|
@ -47,18 +47,18 @@ type HasaIterator struct {
|
|||
BaseIterator
|
||||
ts TripleStore
|
||||
primaryIt Iterator
|
||||
direction string
|
||||
dir Direction
|
||||
resultIt Iterator
|
||||
}
|
||||
|
||||
// Construct a new HasA iterator, given the triple subiterator, and the triple
|
||||
// direction for which it stands.
|
||||
func NewHasaIterator(ts TripleStore, subIt Iterator, dir string) *HasaIterator {
|
||||
func NewHasaIterator(ts TripleStore, subIt Iterator, d Direction) *HasaIterator {
|
||||
var hasa HasaIterator
|
||||
BaseIteratorInit(&hasa.BaseIterator)
|
||||
hasa.ts = ts
|
||||
hasa.primaryIt = subIt
|
||||
hasa.direction = dir
|
||||
hasa.dir = d
|
||||
return &hasa
|
||||
}
|
||||
|
||||
|
|
@ -75,13 +75,13 @@ func (it *HasaIterator) Reset() {
|
|||
}
|
||||
|
||||
func (it *HasaIterator) Clone() Iterator {
|
||||
out := NewHasaIterator(it.ts, it.primaryIt.Clone(), it.direction)
|
||||
out := NewHasaIterator(it.ts, it.primaryIt.Clone(), it.dir)
|
||||
out.CopyTagsFrom(it)
|
||||
return out
|
||||
}
|
||||
|
||||
// Direction accessor.
|
||||
func (it *HasaIterator) Direction() string { return it.direction }
|
||||
func (it *HasaIterator) Direction() Direction { return it.dir }
|
||||
|
||||
// Pass the Optimize() call along to the subiterator. If it becomes Null,
|
||||
// then the HasA becomes Null (there are no triples that have any directions).
|
||||
|
|
@ -115,7 +115,7 @@ func (it *HasaIterator) DebugString(indent int) string {
|
|||
for _, k := range it.Tags() {
|
||||
tags += fmt.Sprintf("%s;", k)
|
||||
}
|
||||
return fmt.Sprintf("%s(%s %d tags:%s direction:%s\n%s)", strings.Repeat(" ", indent), it.Type(), it.GetUid(), tags, it.direction, it.primaryIt.DebugString(indent+4))
|
||||
return fmt.Sprintf("%s(%s %d tags:%s direction:%s\n%s)", strings.Repeat(" ", indent), it.Type(), it.GetUid(), tags, it.dir, it.primaryIt.DebugString(indent+4))
|
||||
}
|
||||
|
||||
// Check a value against our internal iterator. In order to do this, we must first open a new
|
||||
|
|
@ -130,7 +130,7 @@ func (it *HasaIterator) Check(val TSVal) bool {
|
|||
if it.resultIt != nil {
|
||||
it.resultIt.Close()
|
||||
}
|
||||
it.resultIt = it.ts.GetTripleIterator(it.direction, val)
|
||||
it.resultIt = it.ts.GetTripleIterator(it.dir, val)
|
||||
return CheckLogOut(it, val, it.GetCheckResult())
|
||||
}
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ func (it *HasaIterator) GetCheckResult() bool {
|
|||
glog.V(4).Infoln("Triple is", it.ts.GetTriple(linkVal).ToString())
|
||||
}
|
||||
if it.primaryIt.Check(linkVal) {
|
||||
it.Last = it.ts.GetTripleDirection(linkVal, it.direction)
|
||||
it.Last = it.ts.GetTripleDirection(linkVal, it.dir)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -182,7 +182,7 @@ func (it *HasaIterator) Next() (TSVal, bool) {
|
|||
if !ok {
|
||||
return NextLogOut(it, 0, false)
|
||||
}
|
||||
name := it.ts.GetTriple(tID).Get(it.direction)
|
||||
name := it.ts.GetTriple(tID).Get(it.dir)
|
||||
val := it.ts.GetIdFor(name)
|
||||
it.Last = val
|
||||
return NextLogOut(it, val, true)
|
||||
|
|
|
|||
|
|
@ -28,21 +28,21 @@ import (
|
|||
type AllIterator struct {
|
||||
graph.BaseIterator
|
||||
prefix []byte
|
||||
dir string
|
||||
dir graph.Direction
|
||||
open bool
|
||||
it iterator.Iterator
|
||||
ts *TripleStore
|
||||
ro *opt.ReadOptions
|
||||
}
|
||||
|
||||
func NewAllIterator(prefix, dir string, ts *TripleStore) *AllIterator {
|
||||
func NewAllIterator(prefix string, d graph.Direction, ts *TripleStore) *AllIterator {
|
||||
var it AllIterator
|
||||
graph.BaseIteratorInit(&it.BaseIterator)
|
||||
it.ro = &opt.ReadOptions{}
|
||||
it.ro.DontFillCache = true
|
||||
it.it = ts.db.NewIterator(nil, it.ro)
|
||||
it.prefix = []byte(prefix)
|
||||
it.dir = dir
|
||||
it.dir = d
|
||||
it.open = true
|
||||
it.ts = ts
|
||||
it.it.Seek(it.prefix)
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ type Iterator struct {
|
|||
graph.BaseIterator
|
||||
nextPrefix []byte
|
||||
checkId []byte
|
||||
dir string
|
||||
dir graph.Direction
|
||||
open bool
|
||||
it iterator.Iterator
|
||||
ts *TripleStore
|
||||
|
|
@ -37,11 +37,11 @@ type Iterator struct {
|
|||
originalPrefix string
|
||||
}
|
||||
|
||||
func NewIterator(prefix, dir string, value graph.TSVal, ts *TripleStore) *Iterator {
|
||||
func NewIterator(prefix string, d graph.Direction, value graph.TSVal, ts *TripleStore) *Iterator {
|
||||
var it Iterator
|
||||
graph.BaseIteratorInit(&it.BaseIterator)
|
||||
it.checkId = value.([]byte)
|
||||
it.dir = dir
|
||||
it.dir = d
|
||||
it.originalPrefix = prefix
|
||||
it.nextPrefix = make([]byte, 0, 2+ts.hasher.Size())
|
||||
it.nextPrefix = append(it.nextPrefix, []byte(prefix)...)
|
||||
|
|
@ -113,56 +113,56 @@ func (it *Iterator) Next() (graph.TSVal, bool) {
|
|||
return nil, false
|
||||
}
|
||||
|
||||
func GetPositionFromPrefix(prefix []byte, dir string, ts *TripleStore) int {
|
||||
func GetPositionFromPrefix(prefix []byte, d graph.Direction, ts *TripleStore) int {
|
||||
if bytes.Equal(prefix, []byte("sp")) {
|
||||
switch dir {
|
||||
case "s":
|
||||
switch d {
|
||||
case graph.Subject:
|
||||
return 2
|
||||
case "p":
|
||||
case graph.Predicate:
|
||||
return ts.hasher.Size() + 2
|
||||
case "o":
|
||||
case graph.Object:
|
||||
return 2*ts.hasher.Size() + 2
|
||||
case "c":
|
||||
case graph.Provenance:
|
||||
return -1
|
||||
}
|
||||
}
|
||||
if bytes.Equal(prefix, []byte("po")) {
|
||||
switch dir {
|
||||
case "s":
|
||||
switch d {
|
||||
case graph.Subject:
|
||||
return 2*ts.hasher.Size() + 2
|
||||
case "p":
|
||||
case graph.Predicate:
|
||||
return 2
|
||||
case "o":
|
||||
case graph.Object:
|
||||
return ts.hasher.Size() + 2
|
||||
case "c":
|
||||
case graph.Provenance:
|
||||
return -1
|
||||
}
|
||||
}
|
||||
if bytes.Equal(prefix, []byte("os")) {
|
||||
switch dir {
|
||||
case "s":
|
||||
switch d {
|
||||
case graph.Subject:
|
||||
return ts.hasher.Size() + 2
|
||||
case "p":
|
||||
case graph.Predicate:
|
||||
return 2*ts.hasher.Size() + 2
|
||||
case "o":
|
||||
case graph.Object:
|
||||
return 2
|
||||
case "c":
|
||||
case graph.Provenance:
|
||||
return -1
|
||||
}
|
||||
}
|
||||
if bytes.Equal(prefix, []byte("cp")) {
|
||||
switch dir {
|
||||
case "s":
|
||||
switch d {
|
||||
case graph.Subject:
|
||||
return 2*ts.hasher.Size() + 2
|
||||
case "p":
|
||||
case graph.Predicate:
|
||||
return ts.hasher.Size() + 2
|
||||
case "o":
|
||||
case graph.Object:
|
||||
return 3*ts.hasher.Size() + 2
|
||||
case "c":
|
||||
case graph.Provenance:
|
||||
return 2
|
||||
}
|
||||
}
|
||||
panic("Notreached")
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func (it *Iterator) Check(v graph.TSVal) bool {
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ func TestSetIterator(t *testing.T) {
|
|||
var it graph.Iterator
|
||||
|
||||
Convey("Can create a subject iterator", func() {
|
||||
it = ts.GetTripleIterator("s", ts.GetIdFor("C"))
|
||||
it = ts.GetTripleIterator(graph.Subject, ts.GetIdFor("C"))
|
||||
|
||||
Convey("Containing the right things", func() {
|
||||
expected := []string{
|
||||
|
|
@ -282,7 +282,7 @@ func TestSetIterator(t *testing.T) {
|
|||
})
|
||||
|
||||
Convey("Can create an object iterator", func() {
|
||||
it = ts.GetTripleIterator("o", ts.GetIdFor("F"))
|
||||
it = ts.GetTripleIterator(graph.Object, ts.GetIdFor("F"))
|
||||
|
||||
Convey("Containing the right things", func() {
|
||||
expected := []string{
|
||||
|
|
@ -297,7 +297,7 @@ func TestSetIterator(t *testing.T) {
|
|||
|
||||
Convey("Mutually and-checkable", func() {
|
||||
and := graph.NewAndIterator()
|
||||
and.AddSubIterator(ts.GetTripleIterator("s", ts.GetIdFor("B")))
|
||||
and.AddSubIterator(ts.GetTripleIterator(graph.Subject, ts.GetIdFor("B")))
|
||||
and.AddSubIterator(it)
|
||||
|
||||
expected := []string{
|
||||
|
|
@ -312,7 +312,7 @@ func TestSetIterator(t *testing.T) {
|
|||
})
|
||||
|
||||
Convey("Can create a predicate iterator", func() {
|
||||
it = ts.GetTripleIterator("p", ts.GetIdFor("status"))
|
||||
it = ts.GetTripleIterator(graph.Predicate, ts.GetIdFor("status"))
|
||||
|
||||
Convey("Containing the right things", func() {
|
||||
expected := []string{
|
||||
|
|
@ -329,7 +329,7 @@ func TestSetIterator(t *testing.T) {
|
|||
})
|
||||
|
||||
Convey("Can create a provenance iterator", func() {
|
||||
it = ts.GetTripleIterator("c", ts.GetIdFor("status_graph"))
|
||||
it = ts.GetTripleIterator(graph.Provenance, ts.GetIdFor("status_graph"))
|
||||
|
||||
Convey("Containing the right things", func() {
|
||||
expected := []string{
|
||||
|
|
@ -346,7 +346,7 @@ func TestSetIterator(t *testing.T) {
|
|||
Convey("Can be cross-checked", func() {
|
||||
and := graph.NewAndIterator()
|
||||
// Order is important
|
||||
and.AddSubIterator(ts.GetTripleIterator("s", ts.GetIdFor("B")))
|
||||
and.AddSubIterator(ts.GetTripleIterator(graph.Subject, ts.GetIdFor("B")))
|
||||
and.AddSubIterator(it)
|
||||
|
||||
expected := []string{
|
||||
|
|
@ -360,7 +360,7 @@ func TestSetIterator(t *testing.T) {
|
|||
and := graph.NewAndIterator()
|
||||
// Order is important
|
||||
and.AddSubIterator(it)
|
||||
and.AddSubIterator(ts.GetTripleIterator("s", ts.GetIdFor("B")))
|
||||
and.AddSubIterator(ts.GetTripleIterator(graph.Subject, ts.GetIdFor("B")))
|
||||
|
||||
expected := []string{
|
||||
graph.MakeTriple("B", "status", "cool", "status_graph").ToString(),
|
||||
|
|
@ -400,7 +400,7 @@ func TestOptimize(t *testing.T) {
|
|||
fixed := ts.MakeFixed()
|
||||
fixed.AddValue(ts.GetIdFor("F"))
|
||||
fixed.AddTag("internal")
|
||||
lto = graph.NewLinksToIterator(ts, fixed, "o")
|
||||
lto = graph.NewLinksToIterator(ts, fixed, graph.Object)
|
||||
|
||||
Convey("Creates an appropriate iterator", func() {
|
||||
oldIt := lto.Clone()
|
||||
|
|
|
|||
|
|
@ -24,15 +24,17 @@ import (
|
|||
|
||||
"github.com/barakmich/glog"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
cache "github.com/syndtr/goleveldb/leveldb/cache"
|
||||
"github.com/syndtr/goleveldb/leveldb/cache"
|
||||
"github.com/syndtr/goleveldb/leveldb/opt"
|
||||
util "github.com/syndtr/goleveldb/leveldb/util"
|
||||
"github.com/syndtr/goleveldb/leveldb/util"
|
||||
|
||||
"github.com/google/cayley/graph"
|
||||
)
|
||||
|
||||
const DefaultCacheSize = 2
|
||||
const DefaultWriteBufferSize = 20
|
||||
const (
|
||||
DefaultCacheSize = 2
|
||||
DefaultWriteBufferSize = 20
|
||||
)
|
||||
|
||||
type TripleStore struct {
|
||||
dbOpts *opt.Options
|
||||
|
|
@ -49,7 +51,7 @@ func CreateNewLevelDB(path string) bool {
|
|||
opts := &opt.Options{}
|
||||
db, err := leveldb.OpenFile(path, opts)
|
||||
if err != nil {
|
||||
glog.Errorln("Error: couldn't create database", err)
|
||||
glog.Errorln("Error: couldn't create database: ", err)
|
||||
return false
|
||||
}
|
||||
defer db.Close()
|
||||
|
|
@ -108,22 +110,24 @@ func (ts *TripleStore) Size() int64 {
|
|||
return ts.size
|
||||
}
|
||||
|
||||
func (ts *TripleStore) createKeyFor(dir1, dir2, dir3 string, triple *graph.Triple) []byte {
|
||||
func (ts *TripleStore) createKeyFor(d [3]graph.Direction, triple *graph.Triple) []byte {
|
||||
key := make([]byte, 0, 2+(ts.hasher.Size()*3))
|
||||
key = append(key, []byte(dir1+dir2)...)
|
||||
key = append(key, ts.convertStringToByteHash(triple.Get(dir1))...)
|
||||
key = append(key, ts.convertStringToByteHash(triple.Get(dir2))...)
|
||||
key = append(key, ts.convertStringToByteHash(triple.Get(dir3))...)
|
||||
// TODO(kortschak) Remove dependence on String() method.
|
||||
key = append(key, []byte(d[0].String()+d[1].String())...)
|
||||
key = append(key, ts.convertStringToByteHash(triple.Get(d[0]))...)
|
||||
key = append(key, ts.convertStringToByteHash(triple.Get(d[1]))...)
|
||||
key = append(key, ts.convertStringToByteHash(triple.Get(d[2]))...)
|
||||
return key
|
||||
}
|
||||
|
||||
func (ts *TripleStore) createProvKeyFor(dir1, dir2, dir3 string, triple *graph.Triple) []byte {
|
||||
func (ts *TripleStore) createProvKeyFor(d [3]graph.Direction, triple *graph.Triple) []byte {
|
||||
key := make([]byte, 0, 2+(ts.hasher.Size()*4))
|
||||
key = append(key, []byte("c"+dir1)...)
|
||||
key = append(key, ts.convertStringToByteHash(triple.Get("c"))...)
|
||||
key = append(key, ts.convertStringToByteHash(triple.Get(dir1))...)
|
||||
key = append(key, ts.convertStringToByteHash(triple.Get(dir2))...)
|
||||
key = append(key, ts.convertStringToByteHash(triple.Get(dir3))...)
|
||||
// TODO(kortschak) Remove dependence on String() method.
|
||||
key = append(key, []byte(graph.Provenance.String()+d[0].String())...)
|
||||
key = append(key, ts.convertStringToByteHash(triple.Get(graph.Provenance))...)
|
||||
key = append(key, ts.convertStringToByteHash(triple.Get(d[0]))...)
|
||||
key = append(key, ts.convertStringToByteHash(triple.Get(d[1]))...)
|
||||
key = append(key, ts.convertStringToByteHash(triple.Get(d[2]))...)
|
||||
return key
|
||||
}
|
||||
|
||||
|
|
@ -145,8 +149,16 @@ func (ts *TripleStore) AddTriple(t *graph.Triple) {
|
|||
ts.size++
|
||||
}
|
||||
|
||||
// Short hand for direction permutations.
|
||||
var (
|
||||
spo = [3]graph.Direction{graph.Subject, graph.Predicate, graph.Object}
|
||||
osp = [3]graph.Direction{graph.Object, graph.Subject, graph.Predicate}
|
||||
pos = [3]graph.Direction{graph.Predicate, graph.Object, graph.Subject}
|
||||
pso = [3]graph.Direction{graph.Predicate, graph.Subject, graph.Object}
|
||||
)
|
||||
|
||||
func (ts *TripleStore) RemoveTriple(t *graph.Triple) {
|
||||
_, err := ts.db.Get(ts.createKeyFor("s", "p", "o", t), ts.readopts)
|
||||
_, err := ts.db.Get(ts.createKeyFor(spo, t), ts.readopts)
|
||||
if err != nil && err != leveldb.ErrNotFound {
|
||||
glog.Errorf("Couldn't access DB to confirm deletion")
|
||||
return
|
||||
|
|
@ -156,15 +168,15 @@ func (ts *TripleStore) RemoveTriple(t *graph.Triple) {
|
|||
return
|
||||
}
|
||||
batch := &leveldb.Batch{}
|
||||
batch.Delete(ts.createKeyFor("s", "p", "o", t))
|
||||
batch.Delete(ts.createKeyFor("o", "s", "p", t))
|
||||
batch.Delete(ts.createKeyFor("p", "o", "s", t))
|
||||
ts.UpdateValueKeyBy(t.Get("s"), -1, batch)
|
||||
ts.UpdateValueKeyBy(t.Get("p"), -1, batch)
|
||||
ts.UpdateValueKeyBy(t.Get("o"), -1, batch)
|
||||
if t.Get("c") != "" {
|
||||
batch.Delete(ts.createProvKeyFor("p", "s", "o", t))
|
||||
ts.UpdateValueKeyBy(t.Get("c"), -1, batch)
|
||||
batch.Delete(ts.createKeyFor(spo, t))
|
||||
batch.Delete(ts.createKeyFor(osp, t))
|
||||
batch.Delete(ts.createKeyFor(pos, t))
|
||||
ts.UpdateValueKeyBy(t.Get(graph.Subject), -1, batch)
|
||||
ts.UpdateValueKeyBy(t.Get(graph.Predicate), -1, batch)
|
||||
ts.UpdateValueKeyBy(t.Get(graph.Object), -1, batch)
|
||||
if t.Get(graph.Provenance) != "" {
|
||||
batch.Delete(ts.createProvKeyFor(pso, t))
|
||||
ts.UpdateValueKeyBy(t.Get(graph.Provenance), -1, batch)
|
||||
}
|
||||
err = ts.db.Write(batch, nil)
|
||||
if err != nil {
|
||||
|
|
@ -180,21 +192,21 @@ func (ts *TripleStore) buildTripleWrite(batch *leveldb.Batch, t *graph.Triple) {
|
|||
glog.Errorf("Couldn't write to buffer for triple %s\n %s\n", t.ToString(), err)
|
||||
return
|
||||
}
|
||||
batch.Put(ts.createKeyFor("s", "p", "o", t), bytes)
|
||||
batch.Put(ts.createKeyFor("o", "s", "p", t), bytes)
|
||||
batch.Put(ts.createKeyFor("p", "o", "s", t), bytes)
|
||||
if t.Get("c") != "" {
|
||||
batch.Put(ts.createProvKeyFor("p", "s", "o", t), bytes)
|
||||
batch.Put(ts.createKeyFor(spo, t), bytes)
|
||||
batch.Put(ts.createKeyFor(osp, t), bytes)
|
||||
batch.Put(ts.createKeyFor(pos, t), bytes)
|
||||
if t.Get(graph.Provenance) != "" {
|
||||
batch.Put(ts.createProvKeyFor(pso, t), bytes)
|
||||
}
|
||||
}
|
||||
|
||||
func (ts *TripleStore) buildWrite(batch *leveldb.Batch, t *graph.Triple) {
|
||||
ts.buildTripleWrite(batch, t)
|
||||
ts.UpdateValueKeyBy(t.Get("s"), 1, nil)
|
||||
ts.UpdateValueKeyBy(t.Get("p"), 1, nil)
|
||||
ts.UpdateValueKeyBy(t.Get("o"), 1, nil)
|
||||
if t.Get("c") != "" {
|
||||
ts.UpdateValueKeyBy(t.Get("c"), 1, nil)
|
||||
ts.UpdateValueKeyBy(t.Get(graph.Subject), 1, nil)
|
||||
ts.UpdateValueKeyBy(t.Get(graph.Predicate), 1, nil)
|
||||
ts.UpdateValueKeyBy(t.Get(graph.Object), 1, nil)
|
||||
if t.Get(graph.Provenance) != "" {
|
||||
ts.UpdateValueKeyBy(t.Get(graph.Provenance), 1, nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -255,9 +267,9 @@ func (ts *TripleStore) AddTripleSet(t_s []*graph.Triple) {
|
|||
resizeMap := make(map[string]int)
|
||||
for _, t := range t_s {
|
||||
ts.buildTripleWrite(batch, t)
|
||||
resizeMap[t.Sub]++
|
||||
resizeMap[t.Pred]++
|
||||
resizeMap[t.Obj]++
|
||||
resizeMap[t.Subject]++
|
||||
resizeMap[t.Predicate]++
|
||||
resizeMap[t.Object]++
|
||||
if t.Provenance != "" {
|
||||
resizeMap[t.Provenance]++
|
||||
}
|
||||
|
|
@ -388,35 +400,38 @@ func (ts *TripleStore) GetApproximateSizeForPrefix(pre []byte) (int64, error) {
|
|||
return 0, nil
|
||||
}
|
||||
|
||||
func (ts *TripleStore) GetTripleIterator(dir string, val graph.TSVal) graph.Iterator {
|
||||
switch dir {
|
||||
case "s":
|
||||
return NewIterator("sp", "s", val, ts)
|
||||
case "p":
|
||||
return NewIterator("po", "p", val, ts)
|
||||
case "o":
|
||||
return NewIterator("os", "o", val, ts)
|
||||
case "c":
|
||||
return NewIterator("cp", "c", val, ts)
|
||||
func (ts *TripleStore) GetTripleIterator(d graph.Direction, val graph.TSVal) graph.Iterator {
|
||||
var prefix string
|
||||
switch d {
|
||||
case graph.Subject:
|
||||
prefix = "sp"
|
||||
case graph.Predicate:
|
||||
prefix = "po"
|
||||
case graph.Object:
|
||||
prefix = "os"
|
||||
case graph.Provenance:
|
||||
prefix = "cp"
|
||||
default:
|
||||
panic("unreachable " + d.String())
|
||||
}
|
||||
panic("Notreached " + dir)
|
||||
return NewIterator(prefix, d, val, ts)
|
||||
}
|
||||
|
||||
func (ts *TripleStore) GetNodesAllIterator() graph.Iterator {
|
||||
return NewAllIterator("z", "v", ts)
|
||||
return NewAllIterator("z", graph.Any, ts)
|
||||
}
|
||||
|
||||
func (ts *TripleStore) GetTriplesAllIterator() graph.Iterator {
|
||||
return NewAllIterator("po", "p", ts)
|
||||
return NewAllIterator("po", graph.Predicate, ts)
|
||||
}
|
||||
|
||||
func (ts *TripleStore) GetTripleDirection(val graph.TSVal, direction string) graph.TSVal {
|
||||
func (ts *TripleStore) GetTripleDirection(val graph.TSVal, d graph.Direction) graph.TSVal {
|
||||
v := val.([]uint8)
|
||||
offset := GetPositionFromPrefix(v[0:2], direction, ts)
|
||||
offset := GetPositionFromPrefix(v[0:2], d, ts)
|
||||
if offset != -1 {
|
||||
return append([]byte("z"), v[offset:offset+ts.hasher.Size()]...)
|
||||
} else {
|
||||
return ts.GetTriple(val).Get(direction)
|
||||
return ts.GetTriple(val).Get(d)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,18 +41,18 @@ type LinksToIterator struct {
|
|||
BaseIterator
|
||||
ts TripleStore
|
||||
primaryIt Iterator
|
||||
direction string
|
||||
dir Direction
|
||||
nextIt Iterator
|
||||
}
|
||||
|
||||
// Construct a new LinksTo iterator around a direction and a subiterator of
|
||||
// nodes.
|
||||
func NewLinksToIterator(ts TripleStore, it Iterator, dir string) *LinksToIterator {
|
||||
func NewLinksToIterator(ts TripleStore, it Iterator, d Direction) *LinksToIterator {
|
||||
var lto LinksToIterator
|
||||
BaseIteratorInit(<o.BaseIterator)
|
||||
lto.ts = ts
|
||||
lto.primaryIt = it
|
||||
lto.direction = dir
|
||||
lto.dir = d
|
||||
lto.nextIt = &NullIterator{}
|
||||
return <o
|
||||
}
|
||||
|
|
@ -66,13 +66,13 @@ func (it *LinksToIterator) Reset() {
|
|||
}
|
||||
|
||||
func (it *LinksToIterator) Clone() Iterator {
|
||||
out := NewLinksToIterator(it.ts, it.primaryIt.Clone(), it.direction)
|
||||
out := NewLinksToIterator(it.ts, it.primaryIt.Clone(), it.dir)
|
||||
out.CopyTagsFrom(it)
|
||||
return out
|
||||
}
|
||||
|
||||
// Return the direction under consideration.
|
||||
func (it *LinksToIterator) Direction() string { return it.direction }
|
||||
func (it *LinksToIterator) Direction() Direction { return it.dir }
|
||||
|
||||
// Tag these results, and our subiterator's results.
|
||||
func (it *LinksToIterator) TagResults(out *map[string]TSVal) {
|
||||
|
|
@ -91,14 +91,14 @@ func (it *LinksToIterator) GetResultTree() *ResultTree {
|
|||
func (it *LinksToIterator) DebugString(indent int) string {
|
||||
return fmt.Sprintf("%s(%s %d direction:%s\n%s)",
|
||||
strings.Repeat(" ", indent),
|
||||
it.Type(), it.GetUid(), it.direction, it.primaryIt.DebugString(indent+4))
|
||||
it.Type(), it.GetUid(), it.dir, it.primaryIt.DebugString(indent+4))
|
||||
}
|
||||
|
||||
// If it checks in the right direction for the subiterator, it is a valid link
|
||||
// for the LinksTo.
|
||||
func (it *LinksToIterator) Check(val TSVal) bool {
|
||||
CheckLogIn(it, val)
|
||||
node := it.ts.GetTripleDirection(val, it.direction)
|
||||
node := it.ts.GetTripleDirection(val, it.dir)
|
||||
if it.primaryIt.Check(node) {
|
||||
it.Last = val
|
||||
return CheckLogOut(it, val, true)
|
||||
|
|
@ -144,7 +144,7 @@ func (it *LinksToIterator) Next() (TSVal, bool) {
|
|||
return NextLogOut(it, 0, false)
|
||||
}
|
||||
it.nextIt.Close()
|
||||
it.nextIt = it.ts.GetTripleIterator(it.direction, candidate)
|
||||
it.nextIt = it.ts.GetTripleIterator(it.dir, candidate)
|
||||
// Recurse -- return the first in the next set.
|
||||
return it.Next()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@ func TestLinksTo(t *testing.T) {
|
|||
tsFixed := newFixedIterator()
|
||||
tsFixed.AddValue(2)
|
||||
ts.On("GetIdFor", "cool").Return(1)
|
||||
ts.On("GetTripleIterator", "o", 1).Return(tsFixed)
|
||||
ts.On("GetTripleIterator", Object, 1).Return(tsFixed)
|
||||
fixed := newFixedIterator()
|
||||
fixed.AddValue(ts.GetIdFor("cool"))
|
||||
lto := NewLinksToIterator(ts, fixed, "o")
|
||||
lto := NewLinksToIterator(ts, fixed, Object)
|
||||
val, ok := lto.Next()
|
||||
if !ok {
|
||||
t.Error("At least one triple matches the fixed object")
|
||||
|
|
|
|||
|
|
@ -39,29 +39,30 @@ func NewTripleDirectionIndex() *TripleDirectionIndex {
|
|||
return &tdi
|
||||
}
|
||||
|
||||
func (tdi *TripleDirectionIndex) GetForDir(s string) map[int64]*llrb.LLRB {
|
||||
if s == "s" {
|
||||
func (tdi *TripleDirectionIndex) GetForDir(d graph.Direction) map[int64]*llrb.LLRB {
|
||||
switch d {
|
||||
case graph.Subject:
|
||||
return tdi.subject
|
||||
} else if s == "o" {
|
||||
case graph.Object:
|
||||
return tdi.object
|
||||
} else if s == "p" {
|
||||
case graph.Predicate:
|
||||
return tdi.predicate
|
||||
} else if s == "c" {
|
||||
case graph.Provenance:
|
||||
return tdi.provenance
|
||||
}
|
||||
panic("Bad direction")
|
||||
panic("illegal direction")
|
||||
}
|
||||
|
||||
func (tdi *TripleDirectionIndex) GetOrCreate(dir string, id int64) *llrb.LLRB {
|
||||
directionIndex := tdi.GetForDir(dir)
|
||||
func (tdi *TripleDirectionIndex) GetOrCreate(d graph.Direction, id int64) *llrb.LLRB {
|
||||
directionIndex := tdi.GetForDir(d)
|
||||
if _, ok := directionIndex[id]; !ok {
|
||||
directionIndex[id] = llrb.New()
|
||||
}
|
||||
return directionIndex[id]
|
||||
}
|
||||
|
||||
func (tdi *TripleDirectionIndex) Get(dir string, id int64) (*llrb.LLRB, bool) {
|
||||
directionIndex := tdi.GetForDir(dir)
|
||||
func (tdi *TripleDirectionIndex) Get(d graph.Direction, id int64) (*llrb.LLRB, bool) {
|
||||
directionIndex := tdi.GetForDir(d)
|
||||
tree, exists := directionIndex[id]
|
||||
return tree, exists
|
||||
}
|
||||
|
|
@ -101,9 +102,9 @@ func (ts *TripleStore) AddTripleSet(triples []*graph.Triple) {
|
|||
func (ts *TripleStore) tripleExists(t *graph.Triple) (bool, int64) {
|
||||
smallest := -1
|
||||
var smallest_tree *llrb.LLRB
|
||||
for _, dir := range graph.TripleDirections {
|
||||
sid := t.Get(dir)
|
||||
if dir == "c" && sid == "" {
|
||||
for d := graph.Subject; d <= graph.Provenance; d++ {
|
||||
sid := t.Get(d)
|
||||
if d == graph.Provenance && sid == "" {
|
||||
continue
|
||||
}
|
||||
id, ok := ts.idMap[sid]
|
||||
|
|
@ -111,7 +112,7 @@ func (ts *TripleStore) tripleExists(t *graph.Triple) (bool, int64) {
|
|||
if !ok {
|
||||
return false, 0
|
||||
}
|
||||
index, exists := ts.index.Get(dir, id)
|
||||
index, exists := ts.index.Get(d, id)
|
||||
if !exists {
|
||||
// If it's never been indexed in this direction, it can't exist.
|
||||
return false, 0
|
||||
|
|
@ -145,9 +146,9 @@ func (ts *TripleStore) AddTriple(t *graph.Triple) {
|
|||
ts.size++
|
||||
ts.tripleIdCounter++
|
||||
|
||||
for _, dir := range graph.TripleDirections {
|
||||
sid := t.Get(dir)
|
||||
if dir == "c" && sid == "" {
|
||||
for d := graph.Subject; d <= graph.Provenance; d++ {
|
||||
sid := t.Get(d)
|
||||
if d == graph.Provenance && sid == "" {
|
||||
continue
|
||||
}
|
||||
if _, ok := ts.idMap[sid]; !ok {
|
||||
|
|
@ -157,12 +158,12 @@ func (ts *TripleStore) AddTriple(t *graph.Triple) {
|
|||
}
|
||||
}
|
||||
|
||||
for _, dir := range graph.TripleDirections {
|
||||
if dir == "c" && t.Get(dir) == "" {
|
||||
for d := graph.Subject; d <= graph.Provenance; d++ {
|
||||
if d == graph.Provenance && t.Get(d) == "" {
|
||||
continue
|
||||
}
|
||||
id := ts.idMap[t.Get(dir)]
|
||||
tree := ts.index.GetOrCreate(dir, id)
|
||||
id := ts.idMap[t.Get(d)]
|
||||
tree := ts.index.GetOrCreate(d, id)
|
||||
tree.ReplaceOrInsert(Int64(tripleID))
|
||||
}
|
||||
|
||||
|
|
@ -180,36 +181,36 @@ func (ts *TripleStore) RemoveTriple(t *graph.Triple) {
|
|||
ts.triples[tripleID] = graph.Triple{}
|
||||
ts.size--
|
||||
|
||||
for _, dir := range graph.TripleDirections {
|
||||
if dir == "c" && t.Get(dir) == "" {
|
||||
for d := graph.Subject; d <= graph.Provenance; d++ {
|
||||
if d == graph.Provenance && t.Get(d) == "" {
|
||||
continue
|
||||
}
|
||||
id := ts.idMap[t.Get(dir)]
|
||||
tree := ts.index.GetOrCreate(dir, id)
|
||||
id := ts.idMap[t.Get(d)]
|
||||
tree := ts.index.GetOrCreate(d, id)
|
||||
tree.Delete(Int64(tripleID))
|
||||
}
|
||||
|
||||
for _, dir := range graph.TripleDirections {
|
||||
if dir == "c" && t.Get(dir) == "" {
|
||||
for d := graph.Subject; d <= graph.Provenance; d++ {
|
||||
if d == graph.Provenance && t.Get(d) == "" {
|
||||
continue
|
||||
}
|
||||
id, ok := ts.idMap[t.Get(dir)]
|
||||
id, ok := ts.idMap[t.Get(d)]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
stillExists := false
|
||||
for _, dir := range graph.TripleDirections {
|
||||
if dir == "c" && t.Get(dir) == "" {
|
||||
for d := graph.Subject; d <= graph.Provenance; d++ {
|
||||
if d == graph.Provenance && t.Get(d) == "" {
|
||||
continue
|
||||
}
|
||||
nodeTree := ts.index.GetOrCreate(dir, id)
|
||||
nodeTree := ts.index.GetOrCreate(d, id)
|
||||
if nodeTree.Len() != 0 {
|
||||
stillExists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !stillExists {
|
||||
delete(ts.idMap, t.Get(dir))
|
||||
delete(ts.idMap, t.Get(d))
|
||||
delete(ts.revIdMap, id)
|
||||
}
|
||||
}
|
||||
|
|
@ -219,9 +220,9 @@ func (ts *TripleStore) GetTriple(index graph.TSVal) *graph.Triple {
|
|||
return &ts.triples[index.(int64)]
|
||||
}
|
||||
|
||||
func (ts *TripleStore) GetTripleIterator(direction string, value graph.TSVal) graph.Iterator {
|
||||
index, ok := ts.index.Get(direction, value.(int64))
|
||||
data := fmt.Sprintf("dir:%s val:%d", direction, value.(int64))
|
||||
func (ts *TripleStore) GetTripleIterator(d graph.Direction, value graph.TSVal) graph.Iterator {
|
||||
index, ok := ts.index.Get(d, value.(int64))
|
||||
data := fmt.Sprintf("dir:%s val:%d", d, value.(int64))
|
||||
if ok {
|
||||
return NewLlrbIterator(index, data)
|
||||
}
|
||||
|
|
@ -257,8 +258,8 @@ func (ts *TripleStore) MakeFixed() *graph.FixedIterator {
|
|||
return graph.NewFixedIteratorWithCompare(graph.BasicEquality)
|
||||
}
|
||||
|
||||
func (ts *TripleStore) GetTripleDirection(val graph.TSVal, direction string) graph.TSVal {
|
||||
name := ts.GetTriple(val).Get(direction)
|
||||
func (ts *TripleStore) GetTripleDirection(val graph.TSVal, d graph.Direction) graph.TSVal {
|
||||
name := ts.GetTriple(val).Get(d)
|
||||
return ts.GetIdFor(name)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,15 +41,15 @@ func TestIteratorsAndNextResultOrderA(t *testing.T) {
|
|||
fixed := ts.MakeFixed()
|
||||
fixed.AddValue(ts.GetIdFor("C"))
|
||||
all := ts.GetNodesAllIterator()
|
||||
lto := graph.NewLinksToIterator(ts, all, "o")
|
||||
lto := graph.NewLinksToIterator(ts, all, graph.Object)
|
||||
innerAnd := graph.NewAndIterator()
|
||||
|
||||
fixed2 := ts.MakeFixed()
|
||||
fixed2.AddValue(ts.GetIdFor("follows"))
|
||||
lto2 := graph.NewLinksToIterator(ts, fixed2, "p")
|
||||
lto2 := graph.NewLinksToIterator(ts, fixed2, graph.Predicate)
|
||||
innerAnd.AddSubIterator(lto2)
|
||||
innerAnd.AddSubIterator(lto)
|
||||
hasa := graph.NewHasaIterator(ts, innerAnd, "s")
|
||||
hasa := graph.NewHasaIterator(ts, innerAnd, graph.Subject)
|
||||
outerAnd := graph.NewAndIterator()
|
||||
outerAnd.AddSubIterator(fixed)
|
||||
outerAnd.AddSubIterator(hasa)
|
||||
|
|
@ -98,7 +98,7 @@ func TestLinksToOptimization(t *testing.T) {
|
|||
ts := MakeTestingMemstore()
|
||||
fixed := ts.MakeFixed()
|
||||
fixed.AddValue(ts.GetIdFor("cool"))
|
||||
lto := graph.NewLinksToIterator(ts, fixed, "o")
|
||||
lto := graph.NewLinksToIterator(ts, fixed, graph.Object)
|
||||
lto.AddTag("foo")
|
||||
newIt, changed := lto.Optimize()
|
||||
if !changed {
|
||||
|
|
@ -122,14 +122,14 @@ func TestRemoveTriple(t *testing.T) {
|
|||
ts.RemoveTriple(graph.MakeTriple("E", "follows", "F", ""))
|
||||
fixed := ts.MakeFixed()
|
||||
fixed.AddValue(ts.GetIdFor("E"))
|
||||
lto := graph.NewLinksToIterator(ts, fixed, "s")
|
||||
lto := graph.NewLinksToIterator(ts, fixed, graph.Subject)
|
||||
fixed2 := ts.MakeFixed()
|
||||
fixed2.AddValue(ts.GetIdFor("follows"))
|
||||
lto2 := graph.NewLinksToIterator(ts, fixed2, "p")
|
||||
lto2 := graph.NewLinksToIterator(ts, fixed2, graph.Predicate)
|
||||
innerAnd := graph.NewAndIterator()
|
||||
innerAnd.AddSubIterator(lto2)
|
||||
innerAnd.AddSubIterator(lto)
|
||||
hasa := graph.NewHasaIterator(ts, innerAnd, "o")
|
||||
hasa := graph.NewHasaIterator(ts, innerAnd, graph.Object)
|
||||
newIt, _ := hasa.Optimize()
|
||||
_, ok := newIt.Next()
|
||||
if ok {
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ func (ts *TestTripleStore) GetIdFor(s string) TSVal {
|
|||
func (ts *TestTripleStore) AddTriple(*Triple) {}
|
||||
func (ts *TestTripleStore) AddTripleSet([]*Triple) {}
|
||||
func (ts *TestTripleStore) GetTriple(TSVal) *Triple { return &Triple{} }
|
||||
func (ts *TestTripleStore) GetTripleIterator(s string, i TSVal) Iterator {
|
||||
args := ts.Mock.Called(s, i)
|
||||
func (ts *TestTripleStore) GetTripleIterator(d Direction, i TSVal) Iterator {
|
||||
args := ts.Mock.Called(d, i)
|
||||
return args.Get(0).(Iterator)
|
||||
}
|
||||
func (ts *TestTripleStore) GetNodesAllIterator() Iterator { return &NullIterator{} }
|
||||
|
|
@ -53,6 +53,6 @@ func (ts *TestTripleStore) OptimizeIterator(it Iterator) (Iterator, bool) {
|
|||
func (ts *TestTripleStore) MakeFixed() *FixedIterator {
|
||||
return NewFixedIteratorWithCompare(BasicEquality)
|
||||
}
|
||||
func (ts *TestTripleStore) Close() {}
|
||||
func (ts *TestTripleStore) GetTripleDirection(TSVal, string) TSVal { return 0 }
|
||||
func (ts *TestTripleStore) RemoveTriple(t *Triple) {}
|
||||
func (ts *TestTripleStore) Close() {}
|
||||
func (ts *TestTripleStore) GetTripleDirection(TSVal, Direction) TSVal { return 0 }
|
||||
func (ts *TestTripleStore) RemoveTriple(t *Triple) {}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import (
|
|||
type Iterator struct {
|
||||
graph.BaseIterator
|
||||
ts *TripleStore
|
||||
dir string
|
||||
dir graph.Direction
|
||||
iter *mgo.Iter
|
||||
hash string
|
||||
name string
|
||||
|
|
@ -38,26 +38,25 @@ type Iterator struct {
|
|||
collection string
|
||||
}
|
||||
|
||||
func NewIterator(ts *TripleStore, collection string, dir string, val graph.TSVal) *Iterator {
|
||||
func NewIterator(ts *TripleStore, collection string, d graph.Direction, val graph.TSVal) *Iterator {
|
||||
var m Iterator
|
||||
graph.BaseIteratorInit(&m.BaseIterator)
|
||||
|
||||
m.name = ts.GetNameFor(val)
|
||||
m.collection = collection
|
||||
switch dir {
|
||||
|
||||
case "s":
|
||||
m.constraint = bson.M{"Sub": m.name}
|
||||
case "p":
|
||||
m.constraint = bson.M{"Pred": m.name}
|
||||
case "o":
|
||||
m.constraint = bson.M{"Obj": m.name}
|
||||
case "c":
|
||||
switch d {
|
||||
case graph.Subject:
|
||||
m.constraint = bson.M{"Subject": m.name}
|
||||
case graph.Predicate:
|
||||
m.constraint = bson.M{"Predicate": m.name}
|
||||
case graph.Object:
|
||||
m.constraint = bson.M{"Object": m.name}
|
||||
case graph.Provenance:
|
||||
m.constraint = bson.M{"Provenance": m.name}
|
||||
}
|
||||
|
||||
m.ts = ts
|
||||
m.dir = dir
|
||||
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 {
|
||||
|
|
@ -73,7 +72,7 @@ func NewIterator(ts *TripleStore, collection string, dir string, val graph.TSVal
|
|||
func NewAllIterator(ts *TripleStore, collection string) *Iterator {
|
||||
var m Iterator
|
||||
m.ts = ts
|
||||
m.dir = "all"
|
||||
m.dir = graph.Any
|
||||
m.constraint = nil
|
||||
m.collection = collection
|
||||
m.iter = ts.db.C(collection).Find(nil).Iter()
|
||||
|
|
@ -136,13 +135,13 @@ func (it *Iterator) Check(v graph.TSVal) bool {
|
|||
}
|
||||
var offset int
|
||||
switch it.dir {
|
||||
case "s":
|
||||
case graph.Subject:
|
||||
offset = 0
|
||||
case "p":
|
||||
case graph.Predicate:
|
||||
offset = (it.ts.hasher.Size() * 2)
|
||||
case "o":
|
||||
case graph.Object:
|
||||
offset = (it.ts.hasher.Size() * 2) * 2
|
||||
case "c":
|
||||
case graph.Provenance:
|
||||
offset = (it.ts.hasher.Size() * 2) * 3
|
||||
}
|
||||
val := v.(string)[offset : it.ts.hasher.Size()*2+offset]
|
||||
|
|
|
|||
|
|
@ -84,9 +84,9 @@ func NewTripleStore(addr string, options graph.OptionsDict) *TripleStore {
|
|||
}
|
||||
|
||||
func (ts *TripleStore) getIdForTriple(t *graph.Triple) string {
|
||||
id := ts.ConvertStringToByteHash(t.Sub)
|
||||
id += ts.ConvertStringToByteHash(t.Pred)
|
||||
id += ts.ConvertStringToByteHash(t.Obj)
|
||||
id := ts.ConvertStringToByteHash(t.Subject)
|
||||
id += ts.ConvertStringToByteHash(t.Predicate)
|
||||
id += ts.ConvertStringToByteHash(t.Object)
|
||||
id += ts.ConvertStringToByteHash(t.Provenance)
|
||||
return id
|
||||
}
|
||||
|
|
@ -143,7 +143,13 @@ func (ts *TripleStore) updateNodeBy(node_name string, inc int) {
|
|||
}
|
||||
|
||||
func (ts *TripleStore) writeTriple(t *graph.Triple) bool {
|
||||
tripledoc := bson.M{"_id": ts.getIdForTriple(t), "Sub": t.Sub, "Pred": t.Pred, "Obj": t.Obj, "Provenance": t.Provenance}
|
||||
tripledoc := bson.M{
|
||||
"_id": ts.getIdForTriple(t),
|
||||
"Subject": t.Subject,
|
||||
"Predicate": t.Predicate,
|
||||
"Object": t.Object,
|
||||
"Provenance": t.Provenance,
|
||||
}
|
||||
err := ts.db.C("triples").Insert(tripledoc)
|
||||
if err != nil {
|
||||
// Among the reasons I hate MongoDB. "Errors don't happen! Right guys?"
|
||||
|
|
@ -158,9 +164,9 @@ func (ts *TripleStore) writeTriple(t *graph.Triple) bool {
|
|||
|
||||
func (ts *TripleStore) AddTriple(t *graph.Triple) {
|
||||
_ = ts.writeTriple(t)
|
||||
ts.updateNodeBy(t.Sub, 1)
|
||||
ts.updateNodeBy(t.Pred, 1)
|
||||
ts.updateNodeBy(t.Obj, 1)
|
||||
ts.updateNodeBy(t.Subject, 1)
|
||||
ts.updateNodeBy(t.Predicate, 1)
|
||||
ts.updateNodeBy(t.Object, 1)
|
||||
if t.Provenance != "" {
|
||||
ts.updateNodeBy(t.Provenance, 1)
|
||||
}
|
||||
|
|
@ -168,19 +174,19 @@ func (ts *TripleStore) AddTriple(t *graph.Triple) {
|
|||
|
||||
func (ts *TripleStore) AddTripleSet(in []*graph.Triple) {
|
||||
ts.session.SetSafe(nil)
|
||||
idMap := make(map[string]int)
|
||||
ids := make(map[string]int)
|
||||
for _, t := range in {
|
||||
wrote := ts.writeTriple(t)
|
||||
if wrote {
|
||||
idMap[t.Sub]++
|
||||
idMap[t.Obj]++
|
||||
idMap[t.Pred]++
|
||||
ids[t.Subject]++
|
||||
ids[t.Object]++
|
||||
ids[t.Predicate]++
|
||||
if t.Provenance != "" {
|
||||
idMap[t.Provenance]++
|
||||
ids[t.Provenance]++
|
||||
}
|
||||
}
|
||||
}
|
||||
for k, v := range idMap {
|
||||
for k, v := range ids {
|
||||
ts.updateNodeBy(k, v)
|
||||
}
|
||||
ts.session.SetSafe(&mgo.Safe{})
|
||||
|
|
@ -194,9 +200,9 @@ func (ts *TripleStore) RemoveTriple(t *graph.Triple) {
|
|||
log.Println("Error: ", err, " while removing triple ", t)
|
||||
return
|
||||
}
|
||||
ts.updateNodeBy(t.Sub, -1)
|
||||
ts.updateNodeBy(t.Pred, -1)
|
||||
ts.updateNodeBy(t.Obj, -1)
|
||||
ts.updateNodeBy(t.Subject, -1)
|
||||
ts.updateNodeBy(t.Predicate, -1)
|
||||
ts.updateNodeBy(t.Object, -1)
|
||||
if t.Provenance != "" {
|
||||
ts.updateNodeBy(t.Provenance, -1)
|
||||
}
|
||||
|
|
@ -215,8 +221,8 @@ func (ts *TripleStore) GetTriple(val graph.TSVal) *graph.Triple {
|
|||
bsonDoc["Provenance"].(string))
|
||||
}
|
||||
|
||||
func (ts *TripleStore) GetTripleIterator(dir string, val graph.TSVal) graph.Iterator {
|
||||
return NewIterator(ts, "triples", dir, val)
|
||||
func (ts *TripleStore) GetTripleIterator(d graph.Direction, val graph.TSVal) graph.Iterator {
|
||||
return NewIterator(ts, "triples", d, val)
|
||||
}
|
||||
|
||||
func (ts *TripleStore) GetNodesAllIterator() graph.Iterator {
|
||||
|
|
@ -266,17 +272,17 @@ func (ts *TripleStore) Close() {
|
|||
ts.db.Session.Close()
|
||||
}
|
||||
|
||||
func (ts *TripleStore) GetTripleDirection(in graph.TSVal, dir string) graph.TSVal {
|
||||
func (ts *TripleStore) GetTripleDirection(in graph.TSVal, d graph.Direction) graph.TSVal {
|
||||
// Maybe do the trick here
|
||||
var offset int
|
||||
switch dir {
|
||||
case "s":
|
||||
switch d {
|
||||
case graph.Subject:
|
||||
offset = 0
|
||||
case "p":
|
||||
case graph.Predicate:
|
||||
offset = (ts.hasher.Size() * 2)
|
||||
case "o":
|
||||
case graph.Object:
|
||||
offset = (ts.hasher.Size() * 2) * 2
|
||||
case "c":
|
||||
case graph.Provenance:
|
||||
offset = (ts.hasher.Size() * 2) * 3
|
||||
}
|
||||
val := in.(string)[offset : ts.hasher.Size()*2+offset]
|
||||
|
|
|
|||
|
|
@ -35,17 +35,14 @@ type queryShape struct {
|
|||
ts TripleStore
|
||||
nodeId int
|
||||
hasaIds []int
|
||||
hasaDirs []string
|
||||
hasaDirs []Direction
|
||||
}
|
||||
|
||||
func OutputQueryShapeForIterator(it Iterator, ts TripleStore, outputMap *map[string]interface{}) {
|
||||
qs := &queryShape{}
|
||||
qs.nodes = make([]Node, 0)
|
||||
qs.links = make([]Link, 0)
|
||||
qs.hasaIds = make([]int, 0)
|
||||
qs.hasaDirs = make([]string, 0)
|
||||
qs.ts = ts
|
||||
qs.nodeId = 1
|
||||
qs := &queryShape{
|
||||
ts: ts,
|
||||
nodeId: 1,
|
||||
}
|
||||
|
||||
node := qs.MakeNode(it.Clone())
|
||||
qs.AddNode(node)
|
||||
|
|
@ -61,13 +58,13 @@ func (qs *queryShape) AddLink(l *Link) {
|
|||
qs.links = append(qs.links, *l)
|
||||
}
|
||||
|
||||
func (qs *queryShape) LastHasa() (int, string) {
|
||||
func (qs *queryShape) LastHasa() (int, Direction) {
|
||||
return qs.hasaIds[len(qs.hasaIds)-1], qs.hasaDirs[len(qs.hasaDirs)-1]
|
||||
}
|
||||
|
||||
func (qs *queryShape) PushHasa(i int, s string) {
|
||||
func (qs *queryShape) PushHasa(i int, d Direction) {
|
||||
qs.hasaIds = append(qs.hasaIds, i)
|
||||
qs.hasaDirs = append(qs.hasaDirs, s)
|
||||
qs.hasaDirs = append(qs.hasaDirs, d)
|
||||
}
|
||||
|
||||
func (qs *queryShape) RemoveHasa() {
|
||||
|
|
@ -136,7 +133,7 @@ func (qs *queryShape) MakeNode(it Iterator) *Node {
|
|||
}
|
||||
case "hasa":
|
||||
hasa := it.(*HasaIterator)
|
||||
qs.PushHasa(n.Id, hasa.direction)
|
||||
qs.PushHasa(n.Id, hasa.dir)
|
||||
qs.nodeId++
|
||||
newNode := qs.MakeNode(hasa.primaryIt)
|
||||
qs.AddNode(newNode)
|
||||
|
|
@ -158,10 +155,10 @@ func (qs *queryShape) MakeNode(it Iterator) *Node {
|
|||
qs.nodeId++
|
||||
newNode := qs.MakeNode(lto.primaryIt)
|
||||
hasaID, hasaDir := qs.LastHasa()
|
||||
if (hasaDir == "s" && lto.direction == "o") ||
|
||||
(hasaDir == "o" && lto.direction == "s") {
|
||||
if (hasaDir == Subject && lto.dir == Object) ||
|
||||
(hasaDir == Object && lto.dir == Subject) {
|
||||
qs.AddNode(newNode)
|
||||
if hasaDir == "s" {
|
||||
if hasaDir == Subject {
|
||||
qs.AddLink(&Link{hasaID, newNode.Id, 0, n.Id})
|
||||
} else {
|
||||
qs.AddLink(&Link{newNode.Id, hasaID, 0, n.Id})
|
||||
|
|
|
|||
|
|
@ -15,8 +15,9 @@
|
|||
package graph
|
||||
|
||||
import (
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func buildHasaWithTag(ts TripleStore, tag string, target string) *HasaIterator {
|
||||
|
|
@ -25,12 +26,12 @@ func buildHasaWithTag(ts TripleStore, tag string, target string) *HasaIterator {
|
|||
fixed_obj.AddValue(ts.GetIdFor(target))
|
||||
fixed_pred.AddValue(ts.GetIdFor("status"))
|
||||
fixed_obj.AddTag(tag)
|
||||
lto1 := NewLinksToIterator(ts, fixed_obj, "o")
|
||||
lto2 := NewLinksToIterator(ts, fixed_pred, "p")
|
||||
lto1 := NewLinksToIterator(ts, fixed_obj, Object)
|
||||
lto2 := NewLinksToIterator(ts, fixed_pred, Predicate)
|
||||
and := NewAndIterator()
|
||||
and.AddSubIterator(lto1)
|
||||
and.AddSubIterator(lto2)
|
||||
hasa := NewHasaIterator(ts, and, "s")
|
||||
hasa := NewHasaIterator(ts, and, Subject)
|
||||
return hasa
|
||||
}
|
||||
|
||||
|
|
@ -91,12 +92,12 @@ func TestQueryShape(t *testing.T) {
|
|||
andInternal.AddSubIterator(hasa2)
|
||||
fixed_pred := ts.MakeFixed()
|
||||
fixed_pred.AddValue(ts.GetIdFor("name"))
|
||||
lto1 := NewLinksToIterator(ts, andInternal, "s")
|
||||
lto2 := NewLinksToIterator(ts, fixed_pred, "p")
|
||||
lto1 := NewLinksToIterator(ts, andInternal, Subject)
|
||||
lto2 := NewLinksToIterator(ts, fixed_pred, Predicate)
|
||||
and := NewAndIterator()
|
||||
and.AddSubIterator(lto1)
|
||||
and.AddSubIterator(lto2)
|
||||
hasa := NewHasaIterator(ts, and, "o")
|
||||
hasa := NewHasaIterator(ts, and, Object)
|
||||
OutputQueryShapeForIterator(hasa, ts, &queryShape)
|
||||
|
||||
Convey("It should have seven nodes and three links", func() {
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ func buildIteratorTree(tree *peg.ExpressionTree, ts graph.TripleStore) graph.Ite
|
|||
i++
|
||||
}
|
||||
it := buildIteratorTree(tree.Children[i], ts)
|
||||
lto := graph.NewLinksToIterator(ts, it, "p")
|
||||
lto := graph.NewLinksToIterator(ts, it, graph.Predicate)
|
||||
return lto
|
||||
case "RootConstraint":
|
||||
constraintCount := 0
|
||||
|
|
@ -228,16 +228,16 @@ func buildIteratorTree(tree *peg.ExpressionTree, ts graph.TripleStore) graph.Ite
|
|||
return and
|
||||
case "Constraint":
|
||||
var hasa *graph.HasaIterator
|
||||
topLevelDir := "s"
|
||||
subItDir := "o"
|
||||
topLevelDir := graph.Subject
|
||||
subItDir := graph.Object
|
||||
subAnd := graph.NewAndIterator()
|
||||
isOptional := false
|
||||
for _, c := range tree.Children {
|
||||
switch c.Name {
|
||||
case "PredIdentifier":
|
||||
if c.Children[0].Name == "Reverse" {
|
||||
topLevelDir = "o"
|
||||
subItDir = "s"
|
||||
topLevelDir = graph.Object
|
||||
subItDir = graph.Subject
|
||||
}
|
||||
it := buildIteratorTree(c, ts)
|
||||
subAnd.AddSubIterator(it)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2014 The Cayley Authors. All rights reserved.
|
||||
// Copyright 2014 The Cayley Authors. Any rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
|
@ -35,16 +35,13 @@ package graph
|
|||
// There will never be that much in this file except for the definition, but
|
||||
// the consequences are not to be taken lightly. But do suggest cool features!
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
import "fmt"
|
||||
|
||||
// Our triple struct, used throughout.
|
||||
type Triple struct {
|
||||
Sub string `json:"subject"`
|
||||
Pred string `json:"predicate"`
|
||||
Obj string `json:"object"`
|
||||
Subject string `json:"subject"`
|
||||
Predicate string `json:"predicate"`
|
||||
Object string `json:"object"`
|
||||
Provenance string `json:"provenance,omitempty"`
|
||||
}
|
||||
|
||||
|
|
@ -56,43 +53,68 @@ func MakeTriple(sub string, pred string, obj string, provenance string) *Triple
|
|||
return &Triple{sub, pred, obj, provenance}
|
||||
}
|
||||
|
||||
// List of the valid directions of a triple.
|
||||
// TODO(barakmich): Replace all instances of "dir string" in the codebase
|
||||
// with an enum of valid directions, to make this less stringly typed.
|
||||
var TripleDirections = [4]string{"s", "p", "o", "c"}
|
||||
// Direction specifies an edge's type.
|
||||
type Direction byte
|
||||
|
||||
// Per-field accessor for triples
|
||||
func (t *Triple) Get(dir string) string {
|
||||
if dir == "s" {
|
||||
return t.Sub
|
||||
} else if dir == "p" {
|
||||
return t.Pred
|
||||
} else if dir == "prov" || dir == "c" {
|
||||
return t.Provenance
|
||||
} else if dir == "o" {
|
||||
return t.Obj
|
||||
} else {
|
||||
panic(fmt.Sprintf("No Such Triple Direction, %s", dir))
|
||||
// List of the valid directions of a triple.
|
||||
const (
|
||||
Any Direction = iota
|
||||
Subject
|
||||
Predicate
|
||||
Object
|
||||
Provenance
|
||||
)
|
||||
|
||||
func (d Direction) String() string {
|
||||
switch d {
|
||||
case Any:
|
||||
return "a"
|
||||
case Subject:
|
||||
return "s"
|
||||
case Predicate:
|
||||
return "p"
|
||||
case Provenance:
|
||||
return "c"
|
||||
case Object:
|
||||
return "o"
|
||||
default:
|
||||
return fmt.Sprint("illegal direction:", byte(d))
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Triple) Equals(other *Triple) bool {
|
||||
return reflect.DeepEqual(t, other)
|
||||
// Per-field accessor for triples
|
||||
func (t *Triple) Get(d Direction) string {
|
||||
switch d {
|
||||
case Subject:
|
||||
return t.Subject
|
||||
case Predicate:
|
||||
return t.Predicate
|
||||
case Provenance:
|
||||
return t.Provenance
|
||||
case Object:
|
||||
return t.Object
|
||||
default:
|
||||
panic(d.String())
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Triple) Equals(o *Triple) bool {
|
||||
return *t == *o
|
||||
}
|
||||
|
||||
// Pretty-prints a triple.
|
||||
func (t *Triple) ToString() string {
|
||||
return fmt.Sprintf("%s -- %s -> %s\n", t.Sub, t.Pred, t.Obj)
|
||||
return fmt.Sprintf("%s -- %s -> %s\n", t.Subject, t.Predicate, t.Object)
|
||||
}
|
||||
|
||||
func (t *Triple) IsValid() bool {
|
||||
if t.Sub == "" {
|
||||
if t.Subject == "" {
|
||||
return false
|
||||
}
|
||||
if t.Pred == "" {
|
||||
if t.Predicate == "" {
|
||||
return false
|
||||
}
|
||||
if t.Obj == "" {
|
||||
if t.Object == "" {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
|
@ -102,8 +124,8 @@ func (t *Triple) IsValid() bool {
|
|||
func (t *Triple) ToNTriple() string {
|
||||
if t.Provenance == "" {
|
||||
//TODO(barakmich): Proper escaping.
|
||||
return fmt.Sprintf("%s %s %s .", t.Sub, t.Pred, t.Obj)
|
||||
return fmt.Sprintf("%s %s %s .", t.Subject, t.Predicate, t.Object)
|
||||
} else {
|
||||
return fmt.Sprintf("%s %s %s %s .", t.Sub, t.Pred, t.Obj, t.Provenance)
|
||||
return fmt.Sprintf("%s %s %s %s .", t.Subject, t.Predicate, t.Object, t.Provenance)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ type TripleStore interface {
|
|||
|
||||
// Given a direction and a token, creates an iterator of links which have
|
||||
// that node token in that directional field.
|
||||
GetTripleIterator(string, TSVal) Iterator
|
||||
GetTripleIterator(Direction, TSVal) Iterator
|
||||
|
||||
// Returns an iterator enumerating all nodes in the graph.
|
||||
GetNodesAllIterator() Iterator
|
||||
|
|
@ -89,7 +89,7 @@ type TripleStore interface {
|
|||
//
|
||||
// Iterators will call this. At worst, a valid implementation is
|
||||
// self.GetIdFor(self.GetTriple(triple_id).Get(dir))
|
||||
GetTripleDirection(triple_id TSVal, dir string) TSVal
|
||||
GetTripleDirection(triple_id TSVal, d Direction) TSVal
|
||||
}
|
||||
|
||||
type OptionsDict map[string]interface{}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ package http
|
|||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
|
|
@ -28,7 +29,7 @@ func TestParseJSONOkay(t *testing.T) {
|
|||
x, err := ParseJsonToTripleList(bytelist)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(x), ShouldEqual, 2)
|
||||
So(x[0].Sub, ShouldEqual, "foo")
|
||||
So(x[0].Subject, ShouldEqual, "foo")
|
||||
So(x[0].Provenance, ShouldEqual, "")
|
||||
So(x[1].Provenance, ShouldEqual, "graph")
|
||||
})
|
||||
|
|
|
|||
|
|
@ -35,55 +35,55 @@ func TestParsingNTriples(t *testing.T) {
|
|||
Convey("It should parse simple triples", func() {
|
||||
x := Parse("this is valid .")
|
||||
So(x, ShouldNotBeNil)
|
||||
So(x.Sub, ShouldEqual, "this")
|
||||
So(x.Subject, ShouldEqual, "this")
|
||||
})
|
||||
Convey("It should parse quoted triples", func() {
|
||||
x := Parse("this is \"valid too\" .")
|
||||
So(x, ShouldNotBeNil)
|
||||
So(x.Obj, ShouldEqual, "valid too")
|
||||
So(x.Object, ShouldEqual, "valid too")
|
||||
So(x.Provenance, ShouldEqual, "")
|
||||
})
|
||||
Convey("It should parse escaped quoted triples", func() {
|
||||
x := Parse("he said \"\\\"That's all folks\\\"\" .")
|
||||
So(x, ShouldNotBeNil)
|
||||
So(x.Obj, ShouldEqual, "\"That's all folks\"")
|
||||
So(x.Object, ShouldEqual, "\"That's all folks\"")
|
||||
So(x.Provenance, ShouldEqual, "")
|
||||
})
|
||||
|
||||
Convey("It should parse an example real triple", func() {
|
||||
x := Parse("\":/guid/9202a8c04000641f80000000010c843c\" \"name\" \"George Morris\" .")
|
||||
So(x, ShouldNotBeNil)
|
||||
So(x.Obj, ShouldEqual, "George Morris")
|
||||
So(x.Object, ShouldEqual, "George Morris")
|
||||
So(x.Provenance, ShouldEqual, "")
|
||||
})
|
||||
|
||||
Convey("It should parse a pathologically spaced triple", func() {
|
||||
x := Parse("foo is \"\\tA big tough\\r\\nDeal\\\\\" .")
|
||||
So(x, ShouldNotBeNil)
|
||||
So(x.Obj, ShouldEqual, "\tA big tough\r\nDeal\\")
|
||||
So(x.Object, ShouldEqual, "\tA big tough\r\nDeal\\")
|
||||
So(x.Provenance, ShouldEqual, "")
|
||||
})
|
||||
|
||||
Convey("It should parse a simple quad", func() {
|
||||
x := Parse("this is valid quad .")
|
||||
So(x, ShouldNotBeNil)
|
||||
So(x.Obj, ShouldEqual, "valid")
|
||||
So(x.Object, ShouldEqual, "valid")
|
||||
So(x.Provenance, ShouldEqual, "quad")
|
||||
})
|
||||
|
||||
Convey("It should parse a quoted quad", func() {
|
||||
x := Parse("this is valid \"quad thing\" .")
|
||||
So(x, ShouldNotBeNil)
|
||||
So(x.Obj, ShouldEqual, "valid")
|
||||
So(x.Object, ShouldEqual, "valid")
|
||||
So(x.Provenance, ShouldEqual, "quad thing")
|
||||
})
|
||||
|
||||
Convey("It should parse crazy escaped quads", func() {
|
||||
x := Parse("\"\\\"this\" \"\\\"is\" \"\\\"valid\" \"\\\"quad thing\".")
|
||||
So(x, ShouldNotBeNil)
|
||||
So(x.Sub, ShouldEqual, "\"this")
|
||||
So(x.Pred, ShouldEqual, "\"is")
|
||||
So(x.Obj, ShouldEqual, "\"valid")
|
||||
So(x.Subject, ShouldEqual, "\"this")
|
||||
So(x.Predicate, ShouldEqual, "\"is")
|
||||
So(x.Object, ShouldEqual, "\"valid")
|
||||
So(x.Provenance, ShouldEqual, "\"quad thing")
|
||||
})
|
||||
})
|
||||
|
|
@ -95,27 +95,27 @@ func TestParsingNTriplesOfficial(t *testing.T) {
|
|||
var x *graph.Triple
|
||||
x = Parse("<http://example/s> <http://example/p> <http://example/o> . # comment")
|
||||
So(x, ShouldNotBeNil)
|
||||
So(x.Sub, ShouldEqual, "http://example/s")
|
||||
So(x.Pred, ShouldEqual, "http://example/p")
|
||||
So(x.Obj, ShouldEqual, "http://example/o")
|
||||
So(x.Subject, ShouldEqual, "http://example/s")
|
||||
So(x.Predicate, ShouldEqual, "http://example/p")
|
||||
So(x.Object, ShouldEqual, "http://example/o")
|
||||
So(x.Provenance, ShouldEqual, "")
|
||||
x = Parse("<http://example/s> <http://example/p> _:o . # comment")
|
||||
So(x, ShouldNotBeNil)
|
||||
So(x.Sub, ShouldEqual, "http://example/s")
|
||||
So(x.Pred, ShouldEqual, "http://example/p")
|
||||
So(x.Obj, ShouldEqual, "_:o")
|
||||
So(x.Subject, ShouldEqual, "http://example/s")
|
||||
So(x.Predicate, ShouldEqual, "http://example/p")
|
||||
So(x.Object, ShouldEqual, "_:o")
|
||||
So(x.Provenance, ShouldEqual, "")
|
||||
x = Parse("<http://example/s> <http://example/p> \"o\" . # comment")
|
||||
So(x, ShouldNotBeNil)
|
||||
So(x.Obj, ShouldEqual, "o")
|
||||
So(x.Object, ShouldEqual, "o")
|
||||
So(x.Provenance, ShouldEqual, "")
|
||||
x = Parse("<http://example/s> <http://example/p> \"o\"^^<http://example/dt> . # comment")
|
||||
So(x, ShouldNotBeNil)
|
||||
So(x.Obj, ShouldEqual, "o")
|
||||
So(x.Object, ShouldEqual, "o")
|
||||
So(x.Provenance, ShouldEqual, "")
|
||||
x = Parse("<http://example/s> <http://example/p> \"o\"@en . # comment")
|
||||
So(x, ShouldNotBeNil)
|
||||
So(x.Obj, ShouldEqual, "o")
|
||||
So(x.Object, ShouldEqual, "o")
|
||||
So(x.Provenance, ShouldEqual, "")
|
||||
})
|
||||
})
|
||||
|
|
@ -124,7 +124,7 @@ func TestParsingNTriplesOfficial(t *testing.T) {
|
|||
func BenchmarkParser(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
x := Parse("<http://example/s> <http://example/p> \"object of some real\\tlength\"@en . # comment")
|
||||
if x.Obj != "object of some real\tlength" {
|
||||
if x.Object != "object of some real\tlength" {
|
||||
b.Fail()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,13 +138,13 @@ func buildInOutIterator(obj *otto.Object, ts graph.TripleStore, base graph.Itera
|
|||
}
|
||||
}
|
||||
|
||||
in, out := "s", "o"
|
||||
in, out := graph.Subject, graph.Object
|
||||
if isReverse {
|
||||
in, out = out, in
|
||||
}
|
||||
lto := graph.NewLinksToIterator(ts, base, in)
|
||||
and := graph.NewAndIterator()
|
||||
and.AddSubIterator(graph.NewLinksToIterator(ts, predicateNodeIterator, "p"))
|
||||
and.AddSubIterator(graph.NewLinksToIterator(ts, predicateNodeIterator, graph.Predicate))
|
||||
and.AddSubIterator(lto)
|
||||
return graph.NewHasaIterator(ts, and, out)
|
||||
}
|
||||
|
|
@ -193,9 +193,9 @@ func buildIteratorTreeHelper(obj *otto.Object, ts graph.TripleStore, base graph.
|
|||
predFixed := ts.MakeFixed()
|
||||
predFixed.AddValue(ts.GetIdFor(stringArgs[0]))
|
||||
subAnd := graph.NewAndIterator()
|
||||
subAnd.AddSubIterator(graph.NewLinksToIterator(ts, predFixed, "p"))
|
||||
subAnd.AddSubIterator(graph.NewLinksToIterator(ts, all, "o"))
|
||||
hasa := graph.NewHasaIterator(ts, subAnd, "s")
|
||||
subAnd.AddSubIterator(graph.NewLinksToIterator(ts, predFixed, graph.Predicate))
|
||||
subAnd.AddSubIterator(graph.NewLinksToIterator(ts, all, graph.Object))
|
||||
hasa := graph.NewHasaIterator(ts, subAnd, graph.Subject)
|
||||
and := graph.NewAndIterator()
|
||||
and.AddSubIterator(hasa)
|
||||
and.AddSubIterator(subIt)
|
||||
|
|
@ -213,9 +213,9 @@ func buildIteratorTreeHelper(obj *otto.Object, ts graph.TripleStore, base graph.
|
|||
predFixed := ts.MakeFixed()
|
||||
predFixed.AddValue(ts.GetIdFor(stringArgs[0]))
|
||||
subAnd := graph.NewAndIterator()
|
||||
subAnd.AddSubIterator(graph.NewLinksToIterator(ts, predFixed, "p"))
|
||||
subAnd.AddSubIterator(graph.NewLinksToIterator(ts, all, "s"))
|
||||
hasa := graph.NewHasaIterator(ts, subAnd, "o")
|
||||
subAnd.AddSubIterator(graph.NewLinksToIterator(ts, predFixed, graph.Predicate))
|
||||
subAnd.AddSubIterator(graph.NewLinksToIterator(ts, all, graph.Subject))
|
||||
hasa := graph.NewHasaIterator(ts, subAnd, graph.Object)
|
||||
and := graph.NewAndIterator()
|
||||
and.AddSubIterator(hasa)
|
||||
and.AddSubIterator(subIt)
|
||||
|
|
@ -231,9 +231,9 @@ func buildIteratorTreeHelper(obj *otto.Object, ts graph.TripleStore, base graph.
|
|||
predFixed := ts.MakeFixed()
|
||||
predFixed.AddValue(ts.GetIdFor(stringArgs[0]))
|
||||
subAnd := graph.NewAndIterator()
|
||||
subAnd.AddSubIterator(graph.NewLinksToIterator(ts, predFixed, "p"))
|
||||
subAnd.AddSubIterator(graph.NewLinksToIterator(ts, fixed, "o"))
|
||||
hasa := graph.NewHasaIterator(ts, subAnd, "s")
|
||||
subAnd.AddSubIterator(graph.NewLinksToIterator(ts, predFixed, graph.Predicate))
|
||||
subAnd.AddSubIterator(graph.NewLinksToIterator(ts, fixed, graph.Object))
|
||||
hasa := graph.NewHasaIterator(ts, subAnd, graph.Subject)
|
||||
and := graph.NewAndIterator()
|
||||
and.AddSubIterator(hasa)
|
||||
and.AddSubIterator(subIt)
|
||||
|
|
|
|||
|
|
@ -138,16 +138,16 @@ func (q *Query) buildIteratorTreeMapInternal(query map[string]interface{}, path
|
|||
subAnd := graph.NewAndIterator()
|
||||
predFixed := q.ses.ts.MakeFixed()
|
||||
predFixed.AddValue(q.ses.ts.GetIdFor(pred))
|
||||
subAnd.AddSubIterator(graph.NewLinksToIterator(q.ses.ts, predFixed, "p"))
|
||||
subAnd.AddSubIterator(graph.NewLinksToIterator(q.ses.ts, predFixed, graph.Predicate))
|
||||
if reverse {
|
||||
lto := graph.NewLinksToIterator(q.ses.ts, builtIt, "s")
|
||||
lto := graph.NewLinksToIterator(q.ses.ts, builtIt, graph.Subject)
|
||||
subAnd.AddSubIterator(lto)
|
||||
hasa := graph.NewHasaIterator(q.ses.ts, subAnd, "o")
|
||||
hasa := graph.NewHasaIterator(q.ses.ts, subAnd, graph.Object)
|
||||
subit = hasa
|
||||
} else {
|
||||
lto := graph.NewLinksToIterator(q.ses.ts, builtIt, "o")
|
||||
lto := graph.NewLinksToIterator(q.ses.ts, builtIt, graph.Object)
|
||||
subAnd.AddSubIterator(lto)
|
||||
hasa := graph.NewHasaIterator(q.ses.ts, subAnd, "s")
|
||||
hasa := graph.NewHasaIterator(q.ses.ts, subAnd, graph.Subject)
|
||||
subit = hasa
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue