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, 0, 0) 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, (hashSize * 4)) 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) createKeyFor(d [4]quad.Direction, q quad.Quad) []byte { key := make([]byte, quad.HashSize*4) quad.HashTo(q.Get(d[0]), key[quad.HashSize*0:quad.HashSize*1]) quad.HashTo(q.Get(d[1]), key[quad.HashSize*1:quad.HashSize*2]) quad.HashTo(q.Get(d[2]), key[quad.HashSize*2:quad.HashSize*3]) quad.HashTo(q.Get(d[3]), key[quad.HashSize*3:quad.HashSize*4]) return key }
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 createKeyFor(d [4]quad.Direction, q quad.Quad) []byte { key := make([]byte, 2+(quad.HashSize*4)) key[0] = d[0].Prefix() key[1] = d[1].Prefix() quad.HashTo(q.Get(d[0]), key[2+quad.HashSize*0:2+quad.HashSize*1]) quad.HashTo(q.Get(d[1]), key[2+quad.HashSize*1:2+quad.HashSize*2]) quad.HashTo(q.Get(d[2]), key[2+quad.HashSize*2:2+quad.HashSize*3]) quad.HashTo(q.Get(d[3]), key[2+quad.HashSize*3:2+quad.HashSize*4]) return key }
func (qs *QuadStore) buildQuadWrite(tx *bolt.Tx, q quad.Quad, id int64, isAdd bool) error { var entry proto.HistoryEntry b := tx.Bucket(spoBucket) b.FillPercent = localFillPercent data := b.Get(qs.createKeyFor(spo, q)) if data != nil { // We got something. err := entry.Unmarshal(data) if err != nil { return err } } if isAdd && len(entry.History)%2 == 1 { clog.Errorf("attempt to add existing quad %v: %#v", entry, q) return graph.ErrQuadExists } if !isAdd && len(entry.History)%2 == 0 { clog.Errorf("attempt to delete non-existent quad %v: %#v", entry, q) return graph.ErrQuadNotExist } entry.History = append(entry.History, uint64(id)) bytes, err := entry.Marshal() if err != nil { clog.Errorf("Couldn't write to buffer for entry %#v: %s", entry, err) return err } for _, index := range [][4]quad.Direction{spo, osp, pos, cps} { if index == cps && q.Get(quad.Label) == "" { continue } b := tx.Bucket(bucketFor(index)) b.FillPercent = localFillPercent err = b.Put(qs.createKeyFor(index, q), bytes) if err != nil { return err } } return nil }
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 { clog.Errorf("could not access DB to prepare index: %v", 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 { clog.Errorf("attempt to add existing quad %v: %#v", entry, q) return graph.ErrQuadExists } if !isAdd && len(entry.History)%2 == 0 { clog.Errorf("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 { clog.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 }