Change made by: - running "gvt fetch" on each of the packages mentioned in Godeps/Godeps.json - `rm -rf Godeps` - tweaking the build scripts to not mention Godeps - tweaking the build scripts to test `./lib/...`, `./cmd/...` explicitly (to avoid testing vendor) - tweaking the build scripts to not juggle GOPATH for Godeps and instead set GO15VENDOREXPERIMENT. This also results in some updated packages at the same time I bet. Building with Go 1.3 and 1.4 still *works* but won't use our vendored dependencies - the user needs to have the actual packages in their GOPATH then, which they'll get with a normal "go get". Building with Go 1.6+ will get our vendored dependencies by default even when not using our build script, which is nice. By doing this we gain some freedom in that we can pick and choose manually what to include in vendor, as it's not based on just dependency analysis of our own code. This is also a risk as we might pick up dependencies we are unaware of, as the build may work locally with those packages present in GOPATH. On the other hand the build server will detect this as it has no packages in it's GOPATH beyond what is included in the repo. Recommended tool to manage dependencies is github.com/FiloSottile/gvt.
353 lines
7.9 KiB
Go
353 lines
7.9 KiB
Go
// Copyright (c) 2014, Suryandaru Triandana <syndtr@gmail.com>
|
|
// All rights reserved.
|
|
//
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
package testutil
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/syndtr/goleveldb/leveldb/util"
|
|
)
|
|
|
|
type KeyValueEntry struct {
|
|
key, value []byte
|
|
}
|
|
|
|
type KeyValue struct {
|
|
entries []KeyValueEntry
|
|
nbytes int
|
|
}
|
|
|
|
func (kv *KeyValue) Put(key, value []byte) {
|
|
if n := len(kv.entries); n > 0 && cmp.Compare(kv.entries[n-1].key, key) >= 0 {
|
|
panic(fmt.Sprintf("Put: keys are not in increasing order: %q, %q", kv.entries[n-1].key, key))
|
|
}
|
|
kv.entries = append(kv.entries, KeyValueEntry{key, value})
|
|
kv.nbytes += len(key) + len(value)
|
|
}
|
|
|
|
func (kv *KeyValue) PutString(key, value string) {
|
|
kv.Put([]byte(key), []byte(value))
|
|
}
|
|
|
|
func (kv *KeyValue) PutU(key, value []byte) bool {
|
|
if i, exist := kv.Get(key); !exist {
|
|
if i < kv.Len() {
|
|
kv.entries = append(kv.entries[:i+1], kv.entries[i:]...)
|
|
kv.entries[i] = KeyValueEntry{key, value}
|
|
} else {
|
|
kv.entries = append(kv.entries, KeyValueEntry{key, value})
|
|
}
|
|
kv.nbytes += len(key) + len(value)
|
|
return true
|
|
} else {
|
|
kv.nbytes += len(value) - len(kv.ValueAt(i))
|
|
kv.entries[i].value = value
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (kv *KeyValue) PutUString(key, value string) bool {
|
|
return kv.PutU([]byte(key), []byte(value))
|
|
}
|
|
|
|
func (kv *KeyValue) Delete(key []byte) (exist bool, value []byte) {
|
|
i, exist := kv.Get(key)
|
|
if exist {
|
|
value = kv.entries[i].value
|
|
kv.DeleteIndex(i)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (kv *KeyValue) DeleteIndex(i int) bool {
|
|
if i < kv.Len() {
|
|
kv.nbytes -= len(kv.KeyAt(i)) + len(kv.ValueAt(i))
|
|
kv.entries = append(kv.entries[:i], kv.entries[i+1:]...)
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (kv KeyValue) Len() int {
|
|
return len(kv.entries)
|
|
}
|
|
|
|
func (kv *KeyValue) Size() int {
|
|
return kv.nbytes
|
|
}
|
|
|
|
func (kv KeyValue) KeyAt(i int) []byte {
|
|
return kv.entries[i].key
|
|
}
|
|
|
|
func (kv KeyValue) ValueAt(i int) []byte {
|
|
return kv.entries[i].value
|
|
}
|
|
|
|
func (kv KeyValue) Index(i int) (key, value []byte) {
|
|
if i < 0 || i >= len(kv.entries) {
|
|
panic(fmt.Sprintf("Index #%d: out of range", i))
|
|
}
|
|
return kv.entries[i].key, kv.entries[i].value
|
|
}
|
|
|
|
func (kv KeyValue) IndexInexact(i int) (key_, key, value []byte) {
|
|
key, value = kv.Index(i)
|
|
var key0 []byte
|
|
var key1 = kv.KeyAt(i)
|
|
if i > 0 {
|
|
key0 = kv.KeyAt(i - 1)
|
|
}
|
|
key_ = BytesSeparator(key0, key1)
|
|
return
|
|
}
|
|
|
|
func (kv KeyValue) IndexOrNil(i int) (key, value []byte) {
|
|
if i >= 0 && i < len(kv.entries) {
|
|
return kv.entries[i].key, kv.entries[i].value
|
|
}
|
|
return nil, nil
|
|
}
|
|
|
|
func (kv KeyValue) IndexString(i int) (key, value string) {
|
|
key_, _value := kv.Index(i)
|
|
return string(key_), string(_value)
|
|
}
|
|
|
|
func (kv KeyValue) Search(key []byte) int {
|
|
return sort.Search(kv.Len(), func(i int) bool {
|
|
return cmp.Compare(kv.KeyAt(i), key) >= 0
|
|
})
|
|
}
|
|
|
|
func (kv KeyValue) SearchString(key string) int {
|
|
return kv.Search([]byte(key))
|
|
}
|
|
|
|
func (kv KeyValue) Get(key []byte) (i int, exist bool) {
|
|
i = kv.Search(key)
|
|
if i < kv.Len() && cmp.Compare(kv.KeyAt(i), key) == 0 {
|
|
exist = true
|
|
}
|
|
return
|
|
}
|
|
|
|
func (kv KeyValue) GetString(key string) (i int, exist bool) {
|
|
return kv.Get([]byte(key))
|
|
}
|
|
|
|
func (kv KeyValue) Iterate(fn func(i int, key, value []byte)) {
|
|
for i, x := range kv.entries {
|
|
fn(i, x.key, x.value)
|
|
}
|
|
}
|
|
|
|
func (kv KeyValue) IterateString(fn func(i int, key, value string)) {
|
|
kv.Iterate(func(i int, key, value []byte) {
|
|
fn(i, string(key), string(value))
|
|
})
|
|
}
|
|
|
|
func (kv KeyValue) IterateShuffled(rnd *rand.Rand, fn func(i int, key, value []byte)) {
|
|
ShuffledIndex(rnd, kv.Len(), 1, func(i int) {
|
|
fn(i, kv.entries[i].key, kv.entries[i].value)
|
|
})
|
|
}
|
|
|
|
func (kv KeyValue) IterateShuffledString(rnd *rand.Rand, fn func(i int, key, value string)) {
|
|
kv.IterateShuffled(rnd, func(i int, key, value []byte) {
|
|
fn(i, string(key), string(value))
|
|
})
|
|
}
|
|
|
|
func (kv KeyValue) IterateInexact(fn func(i int, key_, key, value []byte)) {
|
|
for i := range kv.entries {
|
|
key_, key, value := kv.IndexInexact(i)
|
|
fn(i, key_, key, value)
|
|
}
|
|
}
|
|
|
|
func (kv KeyValue) IterateInexactString(fn func(i int, key_, key, value string)) {
|
|
kv.IterateInexact(func(i int, key_, key, value []byte) {
|
|
fn(i, string(key_), string(key), string(value))
|
|
})
|
|
}
|
|
|
|
func (kv KeyValue) Clone() KeyValue {
|
|
return KeyValue{append([]KeyValueEntry{}, kv.entries...), kv.nbytes}
|
|
}
|
|
|
|
func (kv KeyValue) Slice(start, limit int) KeyValue {
|
|
if start < 0 || limit > kv.Len() {
|
|
panic(fmt.Sprintf("Slice %d .. %d: out of range", start, limit))
|
|
} else if limit < start {
|
|
panic(fmt.Sprintf("Slice %d .. %d: invalid range", start, limit))
|
|
}
|
|
return KeyValue{append([]KeyValueEntry{}, kv.entries[start:limit]...), kv.nbytes}
|
|
}
|
|
|
|
func (kv KeyValue) SliceKey(start, limit []byte) KeyValue {
|
|
start_ := 0
|
|
limit_ := kv.Len()
|
|
if start != nil {
|
|
start_ = kv.Search(start)
|
|
}
|
|
if limit != nil {
|
|
limit_ = kv.Search(limit)
|
|
}
|
|
return kv.Slice(start_, limit_)
|
|
}
|
|
|
|
func (kv KeyValue) SliceKeyString(start, limit string) KeyValue {
|
|
return kv.SliceKey([]byte(start), []byte(limit))
|
|
}
|
|
|
|
func (kv KeyValue) SliceRange(r *util.Range) KeyValue {
|
|
if r != nil {
|
|
return kv.SliceKey(r.Start, r.Limit)
|
|
}
|
|
return kv.Clone()
|
|
}
|
|
|
|
func (kv KeyValue) Range(start, limit int) (r util.Range) {
|
|
if kv.Len() > 0 {
|
|
if start == kv.Len() {
|
|
r.Start = BytesAfter(kv.KeyAt(start - 1))
|
|
} else {
|
|
r.Start = kv.KeyAt(start)
|
|
}
|
|
}
|
|
if limit < kv.Len() {
|
|
r.Limit = kv.KeyAt(limit)
|
|
}
|
|
return
|
|
}
|
|
|
|
func KeyValue_EmptyKey() *KeyValue {
|
|
kv := &KeyValue{}
|
|
kv.PutString("", "v")
|
|
return kv
|
|
}
|
|
|
|
func KeyValue_EmptyValue() *KeyValue {
|
|
kv := &KeyValue{}
|
|
kv.PutString("abc", "")
|
|
kv.PutString("abcd", "")
|
|
return kv
|
|
}
|
|
|
|
func KeyValue_OneKeyValue() *KeyValue {
|
|
kv := &KeyValue{}
|
|
kv.PutString("abc", "v")
|
|
return kv
|
|
}
|
|
|
|
func KeyValue_BigValue() *KeyValue {
|
|
kv := &KeyValue{}
|
|
kv.PutString("big1", strings.Repeat("1", 200000))
|
|
return kv
|
|
}
|
|
|
|
func KeyValue_SpecialKey() *KeyValue {
|
|
kv := &KeyValue{}
|
|
kv.PutString("\xff\xff", "v3")
|
|
return kv
|
|
}
|
|
|
|
func KeyValue_MultipleKeyValue() *KeyValue {
|
|
kv := &KeyValue{}
|
|
kv.PutString("a", "v")
|
|
kv.PutString("aa", "v1")
|
|
kv.PutString("aaa", "v2")
|
|
kv.PutString("aaacccccccccc", "v2")
|
|
kv.PutString("aaaccccccccccd", "v3")
|
|
kv.PutString("aaaccccccccccf", "v4")
|
|
kv.PutString("aaaccccccccccfg", "v5")
|
|
kv.PutString("ab", "v6")
|
|
kv.PutString("abc", "v7")
|
|
kv.PutString("abcd", "v8")
|
|
kv.PutString("accccccccccccccc", "v9")
|
|
kv.PutString("b", "v10")
|
|
kv.PutString("bb", "v11")
|
|
kv.PutString("bc", "v12")
|
|
kv.PutString("c", "v13")
|
|
kv.PutString("c1", "v13")
|
|
kv.PutString("czzzzzzzzzzzzzz", "v14")
|
|
kv.PutString("fffffffffffffff", "v15")
|
|
kv.PutString("g11", "v15")
|
|
kv.PutString("g111", "v15")
|
|
kv.PutString("g111\xff", "v15")
|
|
kv.PutString("zz", "v16")
|
|
kv.PutString("zzzzzzz", "v16")
|
|
kv.PutString("zzzzzzzzzzzzzzzz", "v16")
|
|
return kv
|
|
}
|
|
|
|
var keymap = []byte("012345678ABCDEFGHIJKLMNOPQRSTUVWXYabcdefghijklmnopqrstuvwxy")
|
|
|
|
func KeyValue_Generate(rnd *rand.Rand, n, minlen, maxlen, vminlen, vmaxlen int) *KeyValue {
|
|
if rnd == nil {
|
|
rnd = NewRand()
|
|
}
|
|
if maxlen < minlen {
|
|
panic("max len should >= min len")
|
|
}
|
|
|
|
rrand := func(min, max int) int {
|
|
if min == max {
|
|
return max
|
|
}
|
|
return rnd.Intn(max-min) + min
|
|
}
|
|
|
|
kv := &KeyValue{}
|
|
endC := byte(len(keymap) - 1)
|
|
gen := make([]byte, 0, maxlen)
|
|
for i := 0; i < n; i++ {
|
|
m := rrand(minlen, maxlen)
|
|
last := gen
|
|
retry:
|
|
gen = last[:m]
|
|
if k := len(last); m > k {
|
|
for j := k; j < m; j++ {
|
|
gen[j] = 0
|
|
}
|
|
} else {
|
|
for j := m - 1; j >= 0; j-- {
|
|
c := last[j]
|
|
if c == endC {
|
|
continue
|
|
}
|
|
gen[j] = c + 1
|
|
for j += 1; j < m; j++ {
|
|
gen[j] = 0
|
|
}
|
|
goto ok
|
|
}
|
|
if m < maxlen {
|
|
m++
|
|
goto retry
|
|
}
|
|
panic(fmt.Sprintf("only able to generate %d keys out of %d keys, try increasing max len", kv.Len(), n))
|
|
ok:
|
|
}
|
|
key := make([]byte, m)
|
|
for j := 0; j < m; j++ {
|
|
key[j] = keymap[gen[j]]
|
|
}
|
|
value := make([]byte, rrand(vminlen, vmaxlen))
|
|
for n := copy(value, []byte(fmt.Sprintf("v%d", i))); n < len(value); n++ {
|
|
value[n] = 'x'
|
|
}
|
|
kv.Put(key, value)
|
|
}
|
|
return kv
|
|
}
|