Example #1
0
func (l *Layer) LinearizeOn(name string) error {
	// We map names to smaller keys to bound the size of the linearizing data set.
	// When this mapping causes extra collisions, that's only more restrictive,
	// so it affects performance (slightly) but not correctness.
	name = compressLinearizabilityKey(name)

	key, _ := tuple.Append(nil, "linearizability", name)
	pair, err := l.inner.Get(key)
	if err != nil {
		if err != kvl.ErrNotFound {
			return err
		}
		pair.Key = key
		pair.Value = make([]byte, 8)

		// A random value is highly likely to conflict with another random value
		// if we race on the initial linearizability key writes, which will cause
		// the transaction to restart.
		rand.Read(pair.Value)
	}

	newValue := make([]byte, 8)
	copy(newValue, pair.Value)

	// Big-endian integer increment
	for i := 7; i >= 0; i-- {
		newValue[i]++
		if newValue[i] != 0 {
			break
		}
	}

	return l.inner.Set(kvl.Pair{pair.Key, newValue})
}
Example #2
0
func (l *Layer) AllLocations() ([]Location, error) {
	var query kvl.RangeQuery
	key, _ := tuple.Append(nil, "location")
	query.Low, query.High = keys.PrefixRange(key)

	pairs, err := l.inner.Range(query)
	if err != nil {
		return nil, err
	}

	locations := make([]Location, len(pairs))
	for i, pair := range pairs {
		err := locations[i].fromPair(pair)
		if err != nil {
			return nil, err
		}
	}

	return locations, nil
}