Merge pull request #103 from barakmich/materializer_iterator
Fix Materializer iterator
This commit is contained in:
commit
272829f3e9
5 changed files with 50 additions and 24 deletions
|
|
@ -32,6 +32,10 @@ type result struct {
|
||||||
tags map[string]graph.Value
|
tags map[string]graph.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type hashable interface {
|
||||||
|
Hashable() interface{}
|
||||||
|
}
|
||||||
|
|
||||||
type Materialize struct {
|
type Materialize struct {
|
||||||
uid uint64
|
uid uint64
|
||||||
tags graph.Tagger
|
tags graph.Tagger
|
||||||
|
|
@ -200,7 +204,11 @@ func (it *Materialize) Contains(v graph.Value) bool {
|
||||||
if it.aborted {
|
if it.aborted {
|
||||||
return it.subIt.Contains(v)
|
return it.subIt.Contains(v)
|
||||||
}
|
}
|
||||||
if i, ok := it.containsMap[v]; ok {
|
key := v
|
||||||
|
if h, ok := v.(hashable); ok {
|
||||||
|
key = h.Hashable()
|
||||||
|
}
|
||||||
|
if i, ok := it.containsMap[key]; ok {
|
||||||
it.index = i
|
it.index = i
|
||||||
it.subindex = 0
|
it.subindex = 0
|
||||||
return graph.ContainsLogOut(it, v, true)
|
return graph.ContainsLogOut(it, v, true)
|
||||||
|
|
@ -228,7 +236,7 @@ func (it *Materialize) NextResult() bool {
|
||||||
func (it *Materialize) materializeSet() {
|
func (it *Materialize) materializeSet() {
|
||||||
i := 0
|
i := 0
|
||||||
for {
|
for {
|
||||||
val, ok := graph.Next(it.subIt)
|
id, ok := graph.Next(it.subIt)
|
||||||
if !ok {
|
if !ok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -237,6 +245,10 @@ func (it *Materialize) materializeSet() {
|
||||||
it.aborted = true
|
it.aborted = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
val := id
|
||||||
|
if h, ok := id.(hashable); ok {
|
||||||
|
val = h.Hashable()
|
||||||
|
}
|
||||||
if _, ok := it.containsMap[val]; !ok {
|
if _, ok := it.containsMap[val]; !ok {
|
||||||
it.containsMap[val] = len(it.values)
|
it.containsMap[val] = len(it.values)
|
||||||
it.values = append(it.values, nil)
|
it.values = append(it.values, nil)
|
||||||
|
|
@ -244,11 +256,11 @@ func (it *Materialize) materializeSet() {
|
||||||
index := it.containsMap[val]
|
index := it.containsMap[val]
|
||||||
tags := make(map[string]graph.Value)
|
tags := make(map[string]graph.Value)
|
||||||
it.subIt.TagResults(tags)
|
it.subIt.TagResults(tags)
|
||||||
it.values[index] = append(it.values[index], result{id: val, tags: tags})
|
it.values[index] = append(it.values[index], result{id: id, tags: tags})
|
||||||
for it.subIt.NextResult() == true {
|
for it.subIt.NextResult() == true {
|
||||||
tags := make(map[string]graph.Value)
|
tags := make(map[string]graph.Value)
|
||||||
it.subIt.TagResults(tags)
|
it.subIt.TagResults(tags)
|
||||||
it.values[index] = append(it.values[index], result{id: val, tags: tags})
|
it.values[index] = append(it.values[index], result{id: id, tags: tags})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if it.aborted {
|
if it.aborted {
|
||||||
|
|
|
||||||
|
|
@ -117,8 +117,8 @@ func (it *AllIterator) Next() (graph.Value, bool) {
|
||||||
it.Close()
|
it.Close()
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
it.result = out
|
it.result = Token(out)
|
||||||
return out, true
|
return it.result, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *AllIterator) ResultTree() *graph.ResultTree {
|
func (it *AllIterator) ResultTree() *graph.ResultTree {
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ type Iterator struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIterator(prefix string, d quad.Direction, value graph.Value, qs *TripleStore) *Iterator {
|
func NewIterator(prefix string, d quad.Direction, value graph.Value, qs *TripleStore) *Iterator {
|
||||||
vb := value.([]byte)
|
vb := value.(Token)
|
||||||
p := make([]byte, 0, 2+qs.hasher.Size())
|
p := make([]byte, 0, 2+qs.hasher.Size())
|
||||||
p = append(p, []byte(prefix)...)
|
p = append(p, []byte(prefix)...)
|
||||||
p = append(p, []byte(vb[1:])...)
|
p = append(p, []byte(vb[1:])...)
|
||||||
|
|
@ -105,7 +105,7 @@ func (it *Iterator) TagResults(dst map[string]graph.Value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *Iterator) Clone() graph.Iterator {
|
func (it *Iterator) Clone() graph.Iterator {
|
||||||
out := NewIterator(it.originalPrefix, it.dir, it.checkId, it.qs)
|
out := NewIterator(it.originalPrefix, it.dir, Token(it.checkId), it.qs)
|
||||||
out.tags.CopyFrom(it)
|
out.tags.CopyFrom(it)
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
@ -134,12 +134,12 @@ func (it *Iterator) Next() (graph.Value, bool) {
|
||||||
if bytes.HasPrefix(it.iter.Key(), it.nextPrefix) {
|
if bytes.HasPrefix(it.iter.Key(), it.nextPrefix) {
|
||||||
out := make([]byte, len(it.iter.Key()))
|
out := make([]byte, len(it.iter.Key()))
|
||||||
copy(out, it.iter.Key())
|
copy(out, it.iter.Key())
|
||||||
it.result = out
|
it.result = Token(out)
|
||||||
ok := it.iter.Next()
|
ok := it.iter.Next()
|
||||||
if !ok {
|
if !ok {
|
||||||
it.Close()
|
it.Close()
|
||||||
}
|
}
|
||||||
return out, true
|
return Token(out), true
|
||||||
}
|
}
|
||||||
it.Close()
|
it.Close()
|
||||||
it.result = nil
|
it.result = nil
|
||||||
|
|
@ -216,7 +216,7 @@ func PositionOf(prefix []byte, d quad.Direction, qs *TripleStore) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *Iterator) Contains(v graph.Value) bool {
|
func (it *Iterator) Contains(v graph.Value) bool {
|
||||||
val := v.([]byte)
|
val := v.(Token)
|
||||||
if val[0] == 'z' {
|
if val[0] == 'z' {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -227,7 +227,7 @@ func (it *Iterator) Contains(v graph.Value) bool {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nameForDir := it.qs.Quad(v).Get(it.dir)
|
nameForDir := it.qs.Quad(v).Get(it.dir)
|
||||||
hashForDir := it.qs.ValueOf(nameForDir).([]byte)
|
hashForDir := it.qs.ValueOf(nameForDir).(Token)
|
||||||
if bytes.Equal(hashForDir, it.checkId) {
|
if bytes.Equal(hashForDir, it.checkId) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -236,12 +236,20 @@ func (it *Iterator) Contains(v graph.Value) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *Iterator) Size() (int64, bool) {
|
func (it *Iterator) Size() (int64, bool) {
|
||||||
return it.qs.SizeOf(it.checkId), true
|
return it.qs.SizeOf(Token(it.checkId)), true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *Iterator) DebugString(indent int) string {
|
func (it *Iterator) DebugString(indent int) string {
|
||||||
size, _ := it.Size()
|
size, _ := it.Size()
|
||||||
return fmt.Sprintf("%s(%s %d tags: %v dir: %s size:%d %s)", strings.Repeat(" ", indent), it.Type(), it.UID(), it.tags.Tags(), it.dir, size, it.qs.NameOf(it.checkId))
|
return fmt.Sprintf("%s(%s %d tags: %v dir: %s size:%d %s)",
|
||||||
|
strings.Repeat(" ", indent),
|
||||||
|
it.Type(),
|
||||||
|
it.UID(),
|
||||||
|
it.tags.Tags(),
|
||||||
|
it.dir,
|
||||||
|
size,
|
||||||
|
it.qs.NameOf(Token(it.checkId)),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
var levelDBType graph.Type
|
var levelDBType graph.Type
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,12 @@ const (
|
||||||
DefaultWriteBufferSize = 20
|
DefaultWriteBufferSize = 20
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Token []byte
|
||||||
|
|
||||||
|
func (t Token) Hashable() interface{} {
|
||||||
|
return string(t)
|
||||||
|
}
|
||||||
|
|
||||||
type TripleStore struct {
|
type TripleStore struct {
|
||||||
dbOpts *opt.Options
|
dbOpts *opt.Options
|
||||||
db *leveldb.DB
|
db *leveldb.DB
|
||||||
|
|
@ -308,7 +314,7 @@ func (qs *TripleStore) Close() {
|
||||||
|
|
||||||
func (qs *TripleStore) Quad(k graph.Value) quad.Quad {
|
func (qs *TripleStore) Quad(k graph.Value) quad.Quad {
|
||||||
var triple quad.Quad
|
var triple quad.Quad
|
||||||
b, err := qs.db.Get(k.([]byte), qs.readopts)
|
b, err := qs.db.Get(k.(Token), qs.readopts)
|
||||||
if err != nil && err != leveldb.ErrNotFound {
|
if err != nil && err != leveldb.ErrNotFound {
|
||||||
glog.Error("Error: couldn't get triple from DB.")
|
glog.Error("Error: couldn't get triple from DB.")
|
||||||
return quad.Quad{}
|
return quad.Quad{}
|
||||||
|
|
@ -334,7 +340,7 @@ func (qs *TripleStore) convertStringToByteHash(s string) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (qs *TripleStore) ValueOf(s string) graph.Value {
|
func (qs *TripleStore) ValueOf(s string) graph.Value {
|
||||||
return qs.createValueKeyFor(s)
|
return Token(qs.createValueKeyFor(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (qs *TripleStore) valueData(value_key []byte) ValueData {
|
func (qs *TripleStore) valueData(value_key []byte) ValueData {
|
||||||
|
|
@ -362,14 +368,14 @@ func (qs *TripleStore) NameOf(k graph.Value) string {
|
||||||
glog.V(2).Info("k was nil")
|
glog.V(2).Info("k was nil")
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return qs.valueData(k.([]byte)).Name
|
return qs.valueData(k.(Token)).Name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (qs *TripleStore) SizeOf(k graph.Value) int64 {
|
func (qs *TripleStore) SizeOf(k graph.Value) int64 {
|
||||||
if k == nil {
|
if k == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return int64(qs.valueData(k.([]byte)).Size)
|
return int64(qs.valueData(k.(Token)).Size)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (qs *TripleStore) getSize() {
|
func (qs *TripleStore) getSize() {
|
||||||
|
|
@ -432,17 +438,17 @@ func (qs *TripleStore) TriplesAllIterator() graph.Iterator {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (qs *TripleStore) TripleDirection(val graph.Value, d quad.Direction) graph.Value {
|
func (qs *TripleStore) TripleDirection(val graph.Value, d quad.Direction) graph.Value {
|
||||||
v := val.([]uint8)
|
v := val.(Token)
|
||||||
offset := PositionOf(v[0:2], d, qs)
|
offset := PositionOf(v[0:2], d, qs)
|
||||||
if offset != -1 {
|
if offset != -1 {
|
||||||
return append([]byte("z"), v[offset:offset+qs.hasher.Size()]...)
|
return Token(append([]byte("z"), v[offset:offset+qs.hasher.Size()]...))
|
||||||
} else {
|
} else {
|
||||||
return qs.Quad(val).Get(d)
|
return Token(qs.Quad(val).Get(d))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func compareBytes(a, b graph.Value) bool {
|
func compareBytes(a, b graph.Value) bool {
|
||||||
return bytes.Equal(a.([]uint8), b.([]uint8))
|
return bytes.Equal(a.(Token), b.(Token))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (qs *TripleStore) FixedIterator() graph.FixedIterator {
|
func (qs *TripleStore) FixedIterator() graph.FixedIterator {
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,8 @@ import (
|
||||||
// pointers to structs, or merely triples, or whatever works best for the
|
// pointers to structs, or merely triples, or whatever works best for the
|
||||||
// backing store.
|
// backing store.
|
||||||
//
|
//
|
||||||
// These must be comparable, ie, not arrays or maps, as they may be used as keys
|
// These must be comparable, or implement a `Hashable() interface{}` function
|
||||||
// for maps.
|
// so that they may be stored in maps.
|
||||||
type Value interface{}
|
type Value interface{}
|
||||||
|
|
||||||
type TripleStore interface {
|
type TripleStore interface {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue