// ApplyFilter applies a filter to our UIDList. func ApplyFilter(u *task.List, f func(uint64, int) bool) { out := u.Uids[:0] for i, uid := range u.Uids { if f(uid, i) { out = append(out, uid) } } u.Uids = out }
// IntersectWith intersects u with v. The update is made to u. // u, v should be sorted. func IntersectWith(u, v *task.List) { out := u.Uids[:0] n := len(u.Uids) m := len(v.Uids) for i, k := 0, 0; i < n && k < m; { uid := u.Uids[i] vid := v.Uids[k] if uid > vid { for k = k + 1; k < m && v.Uids[k] < uid; k++ { } } else if uid == vid { out = append(out, uid) k++ i++ } else { for i = i + 1; i < n && u.Uids[i] < vid; i++ { } } } u.Uids = out }
// assignUids returns a byte slice containing uids. // This function is triggered by an RPC call. We ensure that only leader can assign new UIDs, // so we can tackle any collisions that might happen with the lockmanager. // In essence, we just want one server to be handing out new uids. func assignUids(ctx context.Context, num *task.Num) (*task.List, error) { node := groups().Node(num.Group) if !node.AmLeader() { return &emptyUIDList, x.Errorf("Assigning UIDs is only allowed on leader.") } val := int(num.Val) markNum := len(num.Uids) if val == 0 && markNum == 0 { return &emptyUIDList, x.Errorf("Nothing to be marked or assigned") } mutations := uid.AssignNew(val, 0, 1) for _, uid := range num.Uids { mutations.Set = append(mutations.Set, &task.DirectedEdge{ Entity: uid, Attr: "_uid_", Value: []byte("_"), // not txid Label: "A", }) } proposal := &task.Proposal{Mutations: mutations} if err := node.ProposeAndWait(ctx, proposal); err != nil { return &emptyUIDList, err } // Mutations successfully applied. out := new(task.List) // Only the First N entities are newly assigned UIDs, so we collect them. for i := 0; i < val; i++ { out.Uids = append(out.Uids, mutations.Set[i].Entity) } return out, nil }