clientv3: WithPrefix operation option

release-2.3
Anthony Romano 2016-02-18 00:53:04 -08:00
parent cf71b64286
commit 59291770d6
3 changed files with 49 additions and 46 deletions

View File

@ -96,10 +96,9 @@ func TestKVRange(t *testing.T) {
wheader := resp.Header
tests := []struct {
begin, end string
rev int64
sortOption *clientv3.SortOption
serializable bool
begin, end string
rev int64
opts []clientv3.OpOption
wantSet []*storagepb.KeyValue
}{
@ -108,7 +107,6 @@ func TestKVRange(t *testing.T) {
"a", "c",
0,
nil,
false,
[]*storagepb.KeyValue{
{Key: []byte("a"), Value: nil, CreateRevision: 2, ModRevision: 2, Version: 1},
@ -119,8 +117,7 @@ func TestKVRange(t *testing.T) {
{
"a", "c",
0,
nil,
true,
[]clientv3.OpOption{clientv3.WithSerializable()},
[]*storagepb.KeyValue{
{Key: []byte("a"), Value: nil, CreateRevision: 2, ModRevision: 2, Version: 1},
@ -132,7 +129,6 @@ func TestKVRange(t *testing.T) {
"a", "x",
2,
nil,
false,
[]*storagepb.KeyValue{
{Key: []byte("a"), Value: nil, CreateRevision: 2, ModRevision: 2, Version: 1},
@ -142,8 +138,7 @@ func TestKVRange(t *testing.T) {
{
"a", "x",
0,
&clientv3.SortOption{Target: clientv3.SortByKey, Order: clientv3.SortAscend},
false,
[]clientv3.OpOption{clientv3.WithSort(clientv3.SortByKey, clientv3.SortAscend)},
[]*storagepb.KeyValue{
{Key: []byte("a"), Value: nil, CreateRevision: 2, ModRevision: 2, Version: 1},
@ -158,8 +153,7 @@ func TestKVRange(t *testing.T) {
{
"a", "x",
0,
&clientv3.SortOption{Target: clientv3.SortByCreatedRev, Order: clientv3.SortDescend},
false,
[]clientv3.OpOption{clientv3.WithSort(clientv3.SortByCreatedRev, clientv3.SortDescend)},
[]*storagepb.KeyValue{
{Key: []byte("fop"), Value: nil, CreateRevision: 9, ModRevision: 9, Version: 1},
@ -174,8 +168,7 @@ func TestKVRange(t *testing.T) {
{
"a", "x",
0,
&clientv3.SortOption{Target: clientv3.SortByModifiedRev, Order: clientv3.SortDescend},
false,
[]clientv3.OpOption{clientv3.WithSort(clientv3.SortByModifiedRev, clientv3.SortDescend)},
[]*storagepb.KeyValue{
{Key: []byte("fop"), Value: nil, CreateRevision: 9, ModRevision: 9, Version: 1},
@ -186,16 +179,34 @@ func TestKVRange(t *testing.T) {
{Key: []byte("a"), Value: nil, CreateRevision: 2, ModRevision: 2, Version: 1},
},
},
// WithPrefix
{
"foo", "",
0,
[]clientv3.OpOption{clientv3.WithPrefix()},
[]*storagepb.KeyValue{
{Key: []byte("foo"), Value: nil, CreateRevision: 7, ModRevision: 7, Version: 1},
{Key: []byte("foo/abc"), Value: nil, CreateRevision: 8, ModRevision: 8, Version: 1},
},
},
// WithFromKey
{
"fo", "",
0,
[]clientv3.OpOption{clientv3.WithFromKey()},
[]*storagepb.KeyValue{
{Key: []byte("foo"), Value: nil, CreateRevision: 7, ModRevision: 7, Version: 1},
{Key: []byte("foo/abc"), Value: nil, CreateRevision: 8, ModRevision: 8, Version: 1},
{Key: []byte("fop"), Value: nil, CreateRevision: 9, ModRevision: 9, Version: 1},
},
},
}
for i, tt := range tests {
opts := []clientv3.OpOption{clientv3.WithRange(tt.end), clientv3.WithRev(tt.rev)}
if tt.sortOption != nil {
opts = append(opts, clientv3.WithSort(tt.sortOption.Target, tt.sortOption.Order))
}
if tt.serializable == true {
opts = append(opts, clientv3.WithSerializable())
}
opts = append(opts, tt.opts...)
resp, err := kv.Get(ctx, tt.begin, opts...)
if err != nil {
t.Fatalf("#%d: couldn't range (%v)", i, err)

View File

@ -129,6 +129,22 @@ func WithSort(tgt SortTarget, order SortOrder) OpOption {
op.sort = &SortOption{tgt, order}
}
}
func WithPrefix() OpOption {
return func(op *Op) {
op.end = make([]byte, len(op.key))
copy(op.end, op.key)
for i := len(op.end) - 1; i >= 0; i-- {
if op.end[i] < 0xff {
op.end[i] = op.end[i] + 1
op.end = op.end[:i+1]
return
}
}
// next prefix does not exist (e.g., 0xffff);
// default to WithFromKey policy
op.end = []byte{0}
}
}
func WithRange(endKey string) OpOption {
return func(op *Op) { op.end = []byte(endKey) }
}

View File

@ -65,7 +65,7 @@ func (s *syncer) SyncBase(ctx context.Context) (<-chan clientv3.GetResponse, cha
defer close(respchan)
defer close(errchan)
var key, end string
var key string
opts := []clientv3.OpOption{clientv3.WithLimit(batchLimit), clientv3.WithRev(s.rev)}
@ -78,15 +78,8 @@ func (s *syncer) SyncBase(ctx context.Context) (<-chan clientv3.GetResponse, cha
// If len(s.prefix) != 0, we will sync key-value space with given prefix.
// We then range from the prefix to the next prefix if exists. Or we will
// range from the prefix to the end if the next prefix does not exists.
// (For example, when the given prefix is 0xffff, the next prefix does not
// exist).
opts = append(opts, clientv3.WithPrefix())
key = s.prefix
end = string(incr([]byte(s.prefix)))
if len(end) == 0 {
opts = append(opts, clientv3.WithFromKey())
} else {
opts = append(opts, clientv3.WithRange(string(end)))
}
}
for {
@ -131,20 +124,3 @@ func (s *syncer) SyncUpdates(ctx context.Context) clientv3.WatchChan {
return respchan
}
func incr(bs []byte) []byte {
c := int8(1)
for i := range bs {
j := len(bs) - i - 1
n := int8(bs[j])
n += c
bs[j] = byte(n)
if n == 0 {
c = 1
} else {
c = 0
return bs
}
}
return nil
}