Beispiel #1
0
func (hca highContentionAllocator) allocate(tr fdb.Transaction, s subspace.Subspace) (subspace.Subspace, error) {
	rr := tr.Snapshot().GetRange(hca.counters, fdb.RangeOptions{Limit: 1, Reverse: true})
	kvs := rr.GetSliceOrPanic()

	var start, count int64

	if len(kvs) == 1 {
		t, e := hca.counters.Unpack(kvs[0].Key)
		if e != nil {
			return nil, e
		}
		start = t[0].(int64)

		e = binary.Read(bytes.NewBuffer(kvs[0].Value), binary.LittleEndian, &count)
		if e != nil {
			return nil, e
		}
	}

	window := windowSize(start)

	if (count+1)*2 >= window {
		// Advance the window
		tr.ClearRange(fdb.KeyRange{hca.counters, append(hca.counters.Sub(start).FDBKey(), 0x00)})
		start += window
		tr.ClearRange(fdb.KeyRange{hca.recent, hca.recent.Sub(start)})
		window = windowSize(start)
	}

	// Increment the allocation count for the current window
	tr.Add(hca.counters.Sub(start), oneBytes)

	for {
		// As of the snapshot being read from, the window is less than half
		// full, so this should be expected to take 2 tries.  Under high
		// contention (and when the window advances), there is an additional
		// subsequent risk of conflict for this transaction.
		candidate := rand.Int63n(window) + start
		key := hca.recent.Sub(candidate)
		if tr.Get(key).MustGet() == nil {
			tr.Set(key, []byte(""))
			return s.Sub(candidate), nil
		}
	}
}
Beispiel #2
0
func (dl directoryLayer) removeRecursive(tr fdb.Transaction, node subspace.Subspace) error {
	nodes := dl.subdirNodes(tr, node)
	for i := range nodes {
		if e := dl.removeRecursive(tr, nodes[i]); e != nil {
			return e
		}
	}

	p, e := dl.nodeSS.Unpack(node)
	if e != nil {
		return e
	}
	kr, e := fdb.PrefixRange(p[0].([]byte))
	if e != nil {
		return e
	}

	tr.ClearRange(kr)
	tr.ClearRange(node)

	return nil
}