예제 #1
0
파일: quadstore.go 프로젝트: rlugojr/cayley
func (qs *QuadStore) Quad(k graph.Value) quad.Quad {
	var in proto.HistoryEntry
	b, err := qs.db.Get(k.(Token), qs.readopts)
	if err == leveldb.ErrNotFound {
		// No harm, no foul.
		return quad.Quad{}
	} else if err != nil {
		clog.Errorf("Error: could not get quad from DB. %v", err)
		return quad.Quad{}
	}
	err = in.Unmarshal(b)
	if err != nil {
		clog.Errorf("Error: could not reconstruct history. %v", err)
		return quad.Quad{}
	}
	b, err = qs.db.Get(createDeltaKeyFor(int64(in.History[len(in.History)-1])), qs.readopts)
	if err == leveldb.ErrNotFound {
		// No harm, no foul.
		return quad.Quad{}
	} else if err != nil {
		clog.Errorf("Error: could not get quad from DB. %v", err)
		return quad.Quad{}
	}
	var d proto.LogDelta
	err = d.Unmarshal(b)
	if err != nil {
		clog.Errorf("Error: could not reconstruct quad. %v", err)
		return quad.Quad{}
	}
	return d.Quad.ToNative()
}
예제 #2
0
파일: quadstore.go 프로젝트: rlugojr/cayley
func (qs *QuadStore) Quad(k graph.Value) quad.Quad {
	var d proto.LogDelta
	tok := k.(*Token)
	err := qs.db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket(tok.bucket)
		data := b.Get(tok.key)
		if data == nil {
			return nil
		}
		var in proto.HistoryEntry
		err := in.Unmarshal(data)
		if err != nil {
			return err
		}
		if len(in.History) == 0 {
			return nil
		}
		b = tx.Bucket(logBucket)
		data = b.Get(qs.createDeltaKeyFor(int64(in.History[len(in.History)-1])))
		if data == nil {
			// No harm, no foul.
			return nil
		}
		return d.Unmarshal(data)
	})
	if err != nil {
		clog.Errorf("Error getting quad: %v", err)
		return quad.Quad{}
	}
	return d.Quad.ToNative()
}
예제 #3
0
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
}
예제 #4
0
파일: quadstore.go 프로젝트: rlugojr/cayley
func (qs *QuadStore) buildQuadWrite(batch *leveldb.Batch, q quad.Quad, id int64, isAdd bool) error {
	var entry proto.HistoryEntry
	data, err := qs.db.Get(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 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: %#c", entry, q)
		return graph.ErrQuadNotExist
	}

	entry.History = append(entry.History, uint64(id))

	bytes, err := entry.Marshal()
	if err != nil {
		clog.Errorf("could not write to buffer for entry %#v: %s", entry, err)
		return err
	}
	batch.Put(createKeyFor(spo, q), bytes)
	batch.Put(createKeyFor(osp, q), bytes)
	batch.Put(createKeyFor(pos, q), bytes)
	if q.Get(quad.Label) != nil {
		batch.Put(createKeyFor(cps, q), bytes)
	}
	return nil
}
예제 #5
0
func (it *Iterator) isLiveValue(val []byte) bool {
	var entry proto.HistoryEntry
	entry.Unmarshal(val)
	return len(entry.History)%2 != 0
}