Example #1
0
// 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
}
Example #2
0
// 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
}
Example #3
0
// 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
}