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}) }
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 }