You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.5 KiB
92 lines
2.5 KiB
// +build kvdb_etcd |
|
|
|
package etcd |
|
|
|
import ( |
|
"crypto/sha256" |
|
) |
|
|
|
const ( |
|
bucketIDLength = 32 |
|
) |
|
|
|
var ( |
|
valuePostfix = []byte{0x00} |
|
bucketPostfix = []byte{0xFF} |
|
sequencePrefix = []byte("$seq$") |
|
) |
|
|
|
// makeBucketID returns a deterministic key for the passed byte slice. |
|
// Currently it returns the sha256 hash of the slice. |
|
func makeBucketID(key []byte) [bucketIDLength]byte { |
|
return sha256.Sum256(key) |
|
} |
|
|
|
// isValidBucketID checks if the passed slice is the required length to be a |
|
// valid bucket id. |
|
func isValidBucketID(s []byte) bool { |
|
return len(s) == bucketIDLength |
|
} |
|
|
|
// makeKey concatenates parent, key and postfix into one byte slice. |
|
// The postfix indicates the use of this key (whether bucket or value), while |
|
// parent refers to the parent bucket. |
|
func makeKey(parent, key, postfix []byte) []byte { |
|
keyBuf := make([]byte, len(parent)+len(key)+len(postfix)) |
|
copy(keyBuf, parent) |
|
copy(keyBuf[len(parent):], key) |
|
copy(keyBuf[len(parent)+len(key):], postfix) |
|
|
|
return keyBuf |
|
} |
|
|
|
// makeBucketKey returns a bucket key from the passed parent bucket id and |
|
// the key. |
|
func makeBucketKey(parent []byte, key []byte) []byte { |
|
return makeKey(parent, key, bucketPostfix) |
|
} |
|
|
|
// makeValueKey returns a value key from the passed parent bucket id and |
|
// the key. |
|
func makeValueKey(parent []byte, key []byte) []byte { |
|
return makeKey(parent, key, valuePostfix) |
|
} |
|
|
|
// makeSequenceKey returns a sequence key of the passed parent bucket id. |
|
func makeSequenceKey(parent []byte) []byte { |
|
keyBuf := make([]byte, len(sequencePrefix)+len(parent)) |
|
copy(keyBuf, sequencePrefix) |
|
copy(keyBuf[len(sequencePrefix):], parent) |
|
return keyBuf |
|
} |
|
|
|
// isBucketKey returns true if the passed key is a bucket key, meaning it |
|
// keys a bucket name. |
|
func isBucketKey(key string) bool { |
|
if len(key) < bucketIDLength+1 { |
|
return false |
|
} |
|
|
|
return key[len(key)-1] == bucketPostfix[0] |
|
} |
|
|
|
// getKey chops out the key from the raw key (by removing the bucket id |
|
// prefixing the key and the postfix indicating whether it is a bucket or |
|
// a value key) |
|
func getKey(rawKey string) []byte { |
|
return []byte(rawKey[bucketIDLength : len(rawKey)-1]) |
|
} |
|
|
|
// getKeyVal chops out the key from the raw key (by removing the bucket id |
|
// prefixing the key and the postfix indicating whether it is a bucket or |
|
// a value key) and also returns the appropriate value for the key, which is |
|
// nil in case of buckets (or the set value otherwise). |
|
func getKeyVal(kv *KV) ([]byte, []byte) { |
|
var val []byte |
|
|
|
if !isBucketKey(kv.key) { |
|
val = []byte(kv.val) |
|
} |
|
|
|
return getKey(kv.key), val |
|
}
|
|
|