瀏覽代碼

clientv3: support >= Range requests

Turns out grpc will convert an empty byte string to nil, so use "\0" to
indicate Range on >= key in v3 grpc protocol.
Anthony Romano 9 年之前
父節點
當前提交
6851fffdfb
共有 4 個文件被更改,包括 13 次插入3 次删除
  1. 2 2
      clientv3/kv.go
  2. 1 0
      clientv3/op.go
  3. 6 0
      etcdserver/v3demo_server.go
  4. 4 1
      integration/v3_grpc_test.go

+ 2 - 2
clientv3/kv.go

@@ -38,8 +38,8 @@ type KV interface {
 
 	// Get retrieves keys.
 	// By default, Get will return the value for "key", if any.
-	// When passed WithRange(end), Get will return the keys in the range [key, end) if
-	// end is non-empty, otherwise it returns keys greater than or equal to key.
+	// When passed WithRange(end), Get will return the keys in the range [key, end).
+	// When passed WithFromKey(), Get returns keys greater than or equal to key.
 	// When passed WithRev(rev) with rev > 0, Get retrieves keys at the given revision;
 	// if the required revision is compacted, the request will fail with ErrCompacted .
 	// When passed WithLimit(limit), the number of returned keys is bounded by limit.

+ 1 - 0
clientv3/op.go

@@ -132,6 +132,7 @@ func WithSort(tgt SortTarget, order SortOrder) OpOption {
 func WithRange(endKey string) OpOption {
 	return func(op *Op) { op.end = []byte(endKey) }
 }
+func WithFromKey() OpOption { return WithRange("\x00") }
 func WithSerializable() OpOption {
 	return func(op *Op) { op.serializable = true }
 }

+ 6 - 0
etcdserver/v3demo_server.go

@@ -311,6 +311,12 @@ func applyRange(txnID int64, kv dstorage.KV, r *pb.RangeRequest) (*pb.RangeRespo
 		err error
 	)
 
+	// grpc sends empty byte strings as nils, so use a '\0' to indicate
+	// wanting a >= query
+	if len(r.RangeEnd) == 1 && r.RangeEnd[0] == 0 {
+		r.RangeEnd = []byte{}
+	}
+
 	limit := r.Limit
 	if r.SortOrder != pb.RangeRequest_NONE {
 		// fetch everything; sort and truncate afterwards

+ 4 - 1
integration/v3_grpc_test.go

@@ -488,6 +488,8 @@ func TestV3RangeRequest(t *testing.T) {
 				{Key: []byte("c"), RangeEnd: []byte("c")},
 				// [d, b) = empty
 				{Key: []byte("d"), RangeEnd: []byte("b")},
+				// ["\0", "\0") => all in range
+				{Key: []byte{0}, RangeEnd: []byte{0}},
 			},
 
 			[][]string{
@@ -496,8 +498,9 @@ func TestV3RangeRequest(t *testing.T) {
 				{},
 				{},
 				{},
+				{"a", "b", "c", "d", "e"},
 			},
-			[]bool{false, false, false, false, false},
+			[]bool{false, false, false, false, false, false},
 		},
 		// revision
 		{