func (qs *QuadStore) indexOf(t quad.Quad) (int64, bool) { min := maxInt var tree *b.Tree for d := quad.Subject; d <= quad.Label; d++ { sid := t.Get(d) if d == quad.Label && sid == "" { continue } id, ok := qs.idMap[sid] // If we've never heard about a node, it must not exist if !ok { return 0, false } index, ok := qs.index.Get(d, id) if !ok { // If it's never been indexed in this direction, it can't exist. return 0, false } if l := index.Len(); l < min { min, tree = l, index } } it := NewIterator(tree, "", qs) for it.Next() { val := it.Result() if t == qs.log[val.(int64)].Quad { return val.(int64), true } } return 0, false }
func (qs *QuadStore) createKeyFor(d [4]quad.Direction, q quad.Quad) []byte { key := make([]byte, 0, 2+(hashSize*4)) // TODO(kortschak) Remove dependence on String() method. key = append(key, []byte{d[0].Prefix(), d[1].Prefix()}...) key = append(key, hashOf(q.Get(d[0]))...) key = append(key, hashOf(q.Get(d[1]))...) key = append(key, hashOf(q.Get(d[2]))...) key = append(key, hashOf(q.Get(d[3]))...) return key }
func (qs *QuadStore) buildQuadWrite(batch *leveldb.Batch, q quad.Quad, id int64, isAdd bool) error { var entry IndexEntry data, err := qs.db.Get(qs.createKeyFor(spo, q), qs.readopts) if err != nil && err != leveldb.ErrNotFound { glog.Error("could not access DB to prepare index: ", err) return err } if err == nil { // We got something. err = json.Unmarshal(data, &entry) if err != nil { return err } } else { entry.Quad = q } if isAdd && len(entry.History)%2 == 1 { glog.Errorf("attempt to add existing quad %v: %#v", entry, q) return graph.ErrQuadExists } if !isAdd && len(entry.History)%2 == 0 { glog.Error("attempt to delete non-existent quad %v: %#c", entry, q) return graph.ErrQuadNotExist } entry.History = append(entry.History, id) bytes, err := json.Marshal(entry) if err != nil { glog.Errorf("could not write to buffer for entry %#v: %s", entry, err) return err } batch.Put(qs.createKeyFor(spo, q), bytes) batch.Put(qs.createKeyFor(osp, q), bytes) batch.Put(qs.createKeyFor(pos, q), bytes) if q.Get(quad.Label) != "" { batch.Put(qs.createKeyFor(cps, q), bytes) } return nil }