func ExternalId(uid uint64) (xid string, rerr error) { key := posting.Key(uid, "_xid_") // uid -> "_xid_" -> xid pl := posting.GetOrCreate(key, uidStore) if pl.Length() == 0 { return "", errors.New("NO external id") } if pl.Length() > 1 { glog.WithField("uid", uid).Fatal("This shouldn't be happening.") return "", errors.New("Multiple external ids for this uid.") } var p types.Posting if ok := pl.Get(&p, 0); !ok { glog.WithField("uid", uid).Error("While retrieving posting") return "", errors.New("While retrieving posting") } if p.Uid() != math.MaxUint64 { glog.WithField("uid", uid).Fatal("Value uid must be MaxUint64.") } var t interface{} rerr = posting.ParseValue(&t, p.ValueBytes()) xid = t.(string) return xid, rerr }
func checkName(t *testing.T, r *task.Result, idx int, expected string) { var tv task.Value if ok := r.Values(&tv, idx); !ok { t.Error("Unable to retrieve value") } var iname interface{} if err := posting.ParseValue(&iname, tv.ValBytes()); err != nil { t.Error(err) } name := iname.(string) if name != expected { t.Errorf("Expected: %v. Got: %v", expected, name) } }
func allocateUniqueUid(xid string, instanceIdx uint64, numInstances uint64) (uid uint64, rerr error) { mod := math.MaxUint64 / numInstances minIdx := instanceIdx * mod for sp := ""; ; sp += " " { txid := xid + sp uid1 := farm.Fingerprint64([]byte(txid)) // Generate from hash. uid = (uid1 % mod) + minIdx glog.WithField("txid", txid).WithField("uid", uid).Debug("Generated") if uid == math.MaxUint64 { glog.Debug("Hit uint64max while generating fingerprint. Ignoring...") continue } // Check if this uid has already been allocated. key := posting.Key(uid, "_xid_") // uid -> "_xid_" -> xid pl := posting.GetOrCreate(key, uidStore) if pl.Length() > 0 { // Something already present here. var p types.Posting pl.Get(&p, 0) var tmp interface{} posting.ParseValue(&tmp, p.ValueBytes()) glog.Debug("Found existing xid: [%q]. Continuing...", tmp.(string)) continue } // Uid hasn't been assigned yet. t := x.DirectedEdge{ Value: xid, // not txid Source: "_assigner_", Timestamp: time.Now(), } rerr = pl.AddMutation(t, posting.Set) if rerr != nil { glog.WithError(rerr).Error("While adding mutation") } return uid, rerr } return 0, errors.New("Some unhandled route lead me here." + " Wake the stupid developer up.") }
func postTraverse(g *SubGraph) (result map[uint64]interface{}, rerr error) { if len(g.query) == 0 { return result, nil } result = make(map[uint64]interface{}) // Get results from all children first. cResult := make(map[uint64]interface{}) for _, child := range g.Children { m, err := postTraverse(child) if err != nil { x.Err(glog, err).Error("Error while traversal") return result, err } // Merge results from all children, one by one. for k, v := range m { if val, present := cResult[k]; !present { cResult[k] = v } else { cResult[k] = mergeInterfaces(val, v) } } } // Now read the query and results at current node. uo := flatbuffers.GetUOffsetT(g.query) q := new(task.Query) q.Init(g.query, uo) ro := flatbuffers.GetUOffsetT(g.result) r := new(task.Result) r.Init(g.result, ro) if q.UidsLength() != r.UidmatrixLength() { glog.Fatal("Result uidmatrixlength: %v. Query uidslength: %v", r.UidmatrixLength(), q.UidsLength()) } if q.UidsLength() != r.ValuesLength() { glog.Fatalf("Result valuelength: %v. Query uidslength: %v", r.ValuesLength(), q.UidsLength()) } var ul task.UidList for i := 0; i < r.UidmatrixLength(); i++ { if ok := r.Uidmatrix(&ul, i); !ok { return result, fmt.Errorf("While parsing UidList") } l := make([]interface{}, ul.UidsLength()) for j := 0; j < ul.UidsLength(); j++ { uid := ul.Uids(j) m := make(map[string]interface{}) m["_uid_"] = fmt.Sprintf("%#x", uid) if ival, present := cResult[uid]; !present { l[j] = m } else { l[j] = mergeInterfaces(m, ival) } } if len(l) > 0 { m := make(map[string]interface{}) m[g.Attr] = l result[q.Uids(i)] = m } } var tv task.Value for i := 0; i < r.ValuesLength(); i++ { if ok := r.Values(&tv, i); !ok { return result, fmt.Errorf("While parsing value") } var ival interface{} if err := posting.ParseValue(&ival, tv.ValBytes()); err != nil { return result, err } if ival == nil { continue } if pval, present := result[q.Uids(i)]; present { glog.WithField("prev", pval). WithField("_uid_", q.Uids(i)). WithField("new", ival). Fatal("Previous value detected.") } m := make(map[string]interface{}) m["_uid_"] = fmt.Sprintf("%#x", q.Uids(i)) glog.WithFields(logrus.Fields{ "_uid_": q.Uids(i), "val": ival, }).Debug("Got value") m[g.Attr] = ival result[q.Uids(i)] = m } return result, nil }
func TestProcessTask(t *testing.T) { // logrus.SetLevel(logrus.DebugLevel) dir, err := ioutil.TempDir("", "storetest_") if err != nil { t.Error(err) return } defer os.RemoveAll(dir) ps := new(store.Store) ps.Init(dir) clog := commit.NewLogger(dir, "mutations", 50<<20) clog.Init() defer clog.Close() posting.Init(clog) Init(ps) edge := x.DirectedEdge{ ValueId: 23, Source: "author0", Timestamp: time.Now(), } addEdge(t, edge, posting.GetOrCreate(posting.Key(10, "friend"), ps)) addEdge(t, edge, posting.GetOrCreate(posting.Key(11, "friend"), ps)) addEdge(t, edge, posting.GetOrCreate(posting.Key(12, "friend"), ps)) edge.ValueId = 25 addEdge(t, edge, posting.GetOrCreate(posting.Key(12, "friend"), ps)) edge.ValueId = 26 addEdge(t, edge, posting.GetOrCreate(posting.Key(12, "friend"), ps)) edge.ValueId = 31 addEdge(t, edge, posting.GetOrCreate(posting.Key(10, "friend"), ps)) addEdge(t, edge, posting.GetOrCreate(posting.Key(12, "friend"), ps)) edge.Value = "photon" addEdge(t, edge, posting.GetOrCreate(posting.Key(12, "friend"), ps)) query := NewQuery("friend", []uint64{10, 11, 12}) result, err := ProcessTask(query) if err != nil { t.Error(err) } ro := flatbuffers.GetUOffsetT(result) r := new(task.Result) r.Init(result, ro) if r.UidmatrixLength() != 3 { t.Errorf("Expected 3. Got uidmatrix length: %v", r.UidmatrixLength()) } if err := check(r, 0, []uint64{23, 31}); err != nil { t.Error(err) } if err := check(r, 1, []uint64{23}); err != nil { t.Error(err) } if err := check(r, 2, []uint64{23, 25, 26, 31}); err != nil { t.Error(err) } if r.ValuesLength() != 3 { t.Errorf("Expected 3. Got values length: %v", r.ValuesLength()) } var tval task.Value if ok := r.Values(&tval, 0); !ok { t.Errorf("Unable to retrieve value") } if tval.ValLength() != 1 || tval.ValBytes()[0] != 0x00 { t.Errorf("Invalid byte value at index 0") } if ok := r.Values(&tval, 1); !ok { t.Errorf("Unable to retrieve value") } if tval.ValLength() != 1 || tval.ValBytes()[0] != 0x00 { t.Errorf("Invalid byte value at index 0") } if ok := r.Values(&tval, 2); !ok { t.Errorf("Unable to retrieve value") } var iout interface{} if err := posting.ParseValue(&iout, tval.ValBytes()); err != nil { t.Error(err) } v := iout.(string) if v != "photon" { t.Errorf("Expected photon. Got: %q", v) } }