func sequenceCacheKeyPrint(key roachpb.Key) string { b, id, err := encoding.DecodeBytesAscending([]byte(key), nil) if err != nil { return fmt.Sprintf("/%q/err:%v", key, err) } txnID, err := uuid.FromBytes(id) if err != nil { return fmt.Sprintf("/%q/err:%v", key, err) } if len(b) == 0 { return fmt.Sprintf("/%q", txnID) } b, epoch, err := encoding.DecodeUint32Descending(b) if err != nil { return fmt.Sprintf("/%q/err:%v", txnID, err) } _, seq, err := encoding.DecodeUint32Descending(b) if err != nil { return fmt.Sprintf("/%q/epoch:%d/err:%v", txnID, epoch, err) } return fmt.Sprintf("/%q/epoch:%d/seq:%d", txnID, epoch, seq) }
// DecodeSequenceCacheKey decodes the provided sequence cache entry, // returning the transaction ID, the epoch, and the sequence number. func DecodeSequenceCacheKey(key roachpb.Key, dest []byte) (*uuid.UUID, uint32, uint32, error) { // TODO(tschottdorf): redundant check. if !bytes.HasPrefix(key, LocalRangeIDPrefix) { return nil, 0, 0, util.Errorf("key %s does not have %s prefix", key, LocalRangeIDPrefix) } // Cut the prefix, the Range ID, and the infix specifier. b := key[len(LocalRangeIDPrefix):] b, _, err := encoding.DecodeUvarintAscending(b) if err != nil { return nil, 0, 0, err } b = b[1:] if !bytes.HasPrefix(b, LocalSequenceCacheSuffix) { return nil, 0, 0, util.Errorf("key %s does not contain the sequence cache suffix %s", key, LocalSequenceCacheSuffix) } // Cut the sequence cache suffix. b = b[len(LocalSequenceCacheSuffix):] // Decode the id. b, idBytes, err := encoding.DecodeBytesAscending(b, dest) if err != nil { return nil, 0, 0, err } // Decode the epoch. b, epoch, err := encoding.DecodeUint32Descending(b) if err != nil { return nil, 0, 0, err } // Decode the sequence number. b, seq, err := encoding.DecodeUint32Descending(b) if err != nil { return nil, 0, 0, err } if len(b) > 0 { return nil, 0, 0, util.Errorf("key %q has leftover bytes after decode: %s; indicates corrupt key", key, b) } txnID, err := uuid.FromBytes(idBytes) return txnID, epoch, seq, err }