diff --git a/posting/list.go b/posting/list.go index a367d08d75e6e0b752fe0083793c3db765140546..db552522e455dae88a6c7e81c9dbf083576dbbff 100644 --- a/posting/list.go +++ b/posting/list.go @@ -69,6 +69,9 @@ func addTripleToPosting(b *flatbuffers.Builder, var bo flatbuffers.UOffsetT if t.Value != nil { + if t.ValueId != math.MaxUint64 { + log.Fatal("This should have already been set by the caller.") + } var buf bytes.Buffer enc := gob.NewEncoder(&buf) if err := enc.Encode(t.Value); err != nil { @@ -81,14 +84,9 @@ func addTripleToPosting(b *flatbuffers.Builder, types.PostingStart(b) if bo > 0 { - // All triples with a value set, have the same uid. In other words, - // an (entity, attribute) can only have one interface{} value. - types.PostingAddUid(b, math.MaxUint64) types.PostingAddValue(b, bo) - - } else { - types.PostingAddUid(b, t.ValueId) } + types.PostingAddUid(b, t.ValueId) types.PostingAddSource(b, so) types.PostingAddTs(b, t.Timestamp.UnixNano()) types.PostingAddOp(b, op) @@ -131,6 +129,16 @@ func init() { len(empty), len(emptyPosting)) } +func ParseValue(i interface{}, p types.Posting) error { + if p.ValueLength() == 0 { + return errors.New("No value found in posting") + } + var buf bytes.Buffer + buf.Write(p.ValueBytes()) + dec := gob.NewDecoder(&buf) + return dec.Decode(i) +} + func (l *List) Init(key []byte, pstore, mstore *store.Store) { l.mutex.Lock() defer l.mutex.Unlock() @@ -391,6 +399,13 @@ func (l *List) AddMutation(t x.Triple, op byte) error { // a) check if the entity exists in main posting list. // - If yes, store the mutation. // - If no, disregard this mutation. + + // All triples with a value set, have the same uid. In other words, + // an (entity, attribute) can only have one interface{} value. + if t.Value != nil { + t.ValueId = math.MaxUint64 + } + b := flatbuffers.NewBuilder(0) muts := types.GetRootAsPostingList(l.mbuffer, 0) var offsets []flatbuffers.UOffsetT diff --git a/posting/list_test.go b/posting/list_test.go index 52de6deeec9600dacabde0eac166ee2b9cce0601..5e9b8f739494f70c54feff1c12aefe494ae7fbae 100644 --- a/posting/list_test.go +++ b/posting/list_test.go @@ -19,6 +19,7 @@ package posting import ( "fmt" "io/ioutil" + "math" "os" "testing" "time" @@ -54,7 +55,7 @@ func NewStore(t *testing.T) string { return path } -func TestAddTriple(t *testing.T) { +func TestAddMutation(t *testing.T) { var l List key := store.Key("name", 1) pdir := NewStore(t) @@ -189,10 +190,60 @@ func TestAddTriple(t *testing.T) { if err := checkUids(t, dl, uids...); err != nil { t.Error(err) } +} +func TestAddMutation_Value(t *testing.T) { var ol List + key := store.Key("value", 10) + pdir := NewStore(t) + defer os.RemoveAll(pdir) + ps := new(store.Store) + ps.Init(pdir) + + mdir := NewStore(t) + defer os.RemoveAll(mdir) + ms := new(store.Store) + ms.Init(mdir) + ol.Init(key, ps, ms) - if err := checkUids(t, ol, uids...); err != nil { + + triple := x.Triple{ + Value: "oh hey there", + Source: "new-testing", + Timestamp: time.Now(), + } + if err := ol.AddMutation(triple, Set); err != nil { + t.Error(err) + } + var p types.Posting + ol.Get(&p, 0) + if p.Uid() != math.MaxUint64 { + t.Errorf("All value uids should go to MaxUint64. Got: %v", p.Uid()) + } + var out string + if err := ParseValue(&out, p); err != nil { + t.Error(err) + } + if out != "oh hey there" { + t.Errorf("Expected a value. Got: [%q]", out) + } + + // The value made it to the posting list. Changing it now. + triple.Value = 119 + if err := ol.AddMutation(triple, Set); err != nil { t.Error(err) } + if ol.Length() != 1 { + t.Errorf("Length should be one. Got: %v", ol.Length()) + } + if ok := ol.Get(&p, 0); !ok { + t.Error("While retrieving posting") + } + var iout int + if err := ParseValue(&iout, p); err != nil { + t.Error(err) + } + if iout != 119 { + t.Errorf("Expected 119. Got: %v", iout) + } }