Browse Source

Merge pull request #4505 from heyitsanthony/v3-range-ge

storage: support ranges for >= key
Anthony Romano 10 years ago
parent
commit
9cd45312d5
5 changed files with 13 additions and 5 deletions
  1. 2 1
      clientv3/kv.go
  2. 2 1
      etcdserver/etcdserverpb/rpc.proto
  3. 2 2
      storage/index.go
  4. 2 1
      storage/kv.go
  5. 5 0
      storage/kv_test.go

+ 2 - 1
clientv3/kv.go

@@ -38,7 +38,8 @@ type KV interface {
 
 
 	// Get retrieves keys.
 	// Get retrieves keys.
 	// By default, Get will return the value for "key", if any.
 	// 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).
+	// 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 WithRev(rev) with rev > 0, Get retrieves keys at the given revision;
 	// 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 .
 	// 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.
 	// When passed WithLimit(limit), the number of returned keys is bounded by limit.

+ 2 - 1
etcdserver/etcdserverpb/rpc.proto

@@ -101,7 +101,8 @@ message RangeRequest {
 
 
   // if the range_end is not given, the request returns the key.
   // if the range_end is not given, the request returns the key.
   bytes key = 1;
   bytes key = 1;
-  // if the range_end is given, it gets the keys in range [key, range_end).
+  // if the range_end is given, it gets the keys in range [key, range_end)
+  // if range_end is nonempty, otherwise it returns all keys >= key.
   bytes range_end = 2;
   bytes range_end = 2;
   // limit the number of keys returned.
   // limit the number of keys returned.
   int64 limit = 3;
   int64 limit = 3;

+ 2 - 2
storage/index.go

@@ -104,7 +104,7 @@ func (ti *treeIndex) Range(key, end []byte, atRev int64) (keys [][]byte, revs []
 	defer ti.RUnlock()
 	defer ti.RUnlock()
 
 
 	ti.tree.AscendGreaterOrEqual(keyi, func(item btree.Item) bool {
 	ti.tree.AscendGreaterOrEqual(keyi, func(item btree.Item) bool {
-		if !item.Less(endi) {
+		if len(endi.key) > 0 && !item.Less(endi) {
 			return false
 			return false
 		}
 		}
 		curKeyi := item.(*keyIndex)
 		curKeyi := item.(*keyIndex)
@@ -154,7 +154,7 @@ func (ti *treeIndex) RangeSince(key, end []byte, rev int64) []revision {
 	endi := &keyIndex{key: end}
 	endi := &keyIndex{key: end}
 	var revs []revision
 	var revs []revision
 	ti.tree.AscendGreaterOrEqual(keyi, func(item btree.Item) bool {
 	ti.tree.AscendGreaterOrEqual(keyi, func(item btree.Item) bool {
-		if !item.Less(endi) {
+		if len(endi.key) > 0 && !item.Less(endi) {
 			return false
 			return false
 		}
 		}
 		curKeyi := item.(*keyIndex)
 		curKeyi := item.(*keyIndex)

+ 2 - 1
storage/kv.go

@@ -33,7 +33,8 @@ type KV interface {
 	// The returned rev is the current revision of the KV when the operation is executed.
 	// The returned rev is the current revision of the KV when the operation is executed.
 	// If rangeRev <=0, range gets the keys at currentRev.
 	// If rangeRev <=0, range gets the keys at currentRev.
 	// If `end` is nil, the request returns the key.
 	// If `end` is nil, the request returns the key.
-	// If `end` is not nil, it gets the keys in range [key, range_end).
+	// If `end` is not nil and not empty, it gets the keys in range [key, range_end).
+	// If `end` is not nil and empty, it gets the keys greater than or equal to key.
 	// Limit limits the number of keys returned.
 	// Limit limits the number of keys returned.
 	// If the required rev is compacted, ErrCompacted will be returned.
 	// If the required rev is compacted, ErrCompacted will be returned.
 	Range(key, end []byte, limit, rangeRev int64) (kvs []storagepb.KeyValue, rev int64, err error)
 	Range(key, end []byte, limit, rangeRev int64) (kvs []storagepb.KeyValue, rev int64, err error)

+ 5 - 0
storage/kv_test.go

@@ -120,6 +120,11 @@ func testKVRange(t *testing.T, f rangeFunc) {
 			[]byte("foo"), nil,
 			[]byte("foo"), nil,
 			kvs[:1],
 			kvs[:1],
 		},
 		},
+		// get entire keyspace
+		{
+			[]byte(""), []byte(""),
+			kvs,
+		},
 	}
 	}
 
 
 	for i, tt := range tests {
 	for i, tt := range tests {