Browse Source

*: return the number of deleted keys

For https://github.com/coreos/etcd/issues/4576.
Gyu-Ho Lee 9 years ago
parent
commit
fc86e1ded1

+ 29 - 0
etcdserver/etcdserverpb/rpc.pb.go

@@ -232,6 +232,8 @@ func (*DeleteRangeRequest) ProtoMessage()    {}
 
 type DeleteRangeResponse struct {
 	Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
+	// Deleted is the number of keys that got deleted.
+	Deleted int64 `protobuf:"varint,2,opt,name=deleted,proto3" json:"deleted,omitempty"`
 }
 
 func (m *DeleteRangeResponse) Reset()         { *m = DeleteRangeResponse{} }
@@ -2088,6 +2090,11 @@ func (m *DeleteRangeResponse) MarshalTo(data []byte) (int, error) {
 		}
 		i += n3
 	}
+	if m.Deleted != 0 {
+		data[i] = 0x10
+		i++
+		i = encodeVarintRpc(data, i, uint64(m.Deleted))
+	}
 	return i, nil
 }
 
@@ -3342,6 +3349,9 @@ func (m *DeleteRangeResponse) Size() (n int) {
 		l = m.Header.Size()
 		n += 1 + l + sovRpc(uint64(l))
 	}
+	if m.Deleted != 0 {
+		n += 1 + sovRpc(uint64(m.Deleted))
+	}
 	return n
 }
 
@@ -4696,6 +4706,25 @@ func (m *DeleteRangeResponse) Unmarshal(data []byte) error {
 				return err
 			}
 			iNdEx = postIndex
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Deleted", wireType)
+			}
+			m.Deleted = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowRpc
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := data[iNdEx]
+				iNdEx++
+				m.Deleted |= (int64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
 		default:
 			iNdEx = preIndex
 			skippy, err := skipRpc(data[iNdEx:])

+ 2 - 0
etcdserver/etcdserverpb/rpc.proto

@@ -152,6 +152,8 @@ message DeleteRangeRequest {
 
 message DeleteRangeResponse {
   ResponseHeader header = 1;
+  // Deleted is the number of keys that got deleted.
+  int64 deleted = 2;
 }
 
 message RequestUnion {

+ 4 - 2
etcdserver/v3demo_server.go

@@ -384,6 +384,7 @@ func applyDeleteRange(txnID int64, kv dstorage.KV, dr *pb.DeleteRangeRequest) (*
 	resp.Header = &pb.ResponseHeader{}
 
 	var (
+		n   int64
 		rev int64
 		err error
 	)
@@ -393,14 +394,15 @@ func applyDeleteRange(txnID int64, kv dstorage.KV, dr *pb.DeleteRangeRequest) (*
 	}
 
 	if txnID != noTxn {
-		_, rev, err = kv.TxnDeleteRange(txnID, dr.Key, dr.RangeEnd)
+		n, rev, err = kv.TxnDeleteRange(txnID, dr.Key, dr.RangeEnd)
 		if err != nil {
 			return nil, err
 		}
 	} else {
-		_, rev = kv.DeleteRange(dr.Key, dr.RangeEnd)
+		n, rev = kv.DeleteRange(dr.Key, dr.RangeEnd)
 	}
 
+	resp.Deleted = n
 	resp.Header.Revision = rev
 	return resp, nil
 }

+ 10 - 6
integration/v3_grpc_test.go

@@ -282,42 +282,43 @@ func TestV3DeleteRange(t *testing.T) {
 		end    string
 
 		wantSet [][]byte
+		deleted int64
 	}{
 		// delete middle
 		{
 			[]string{"foo", "foo/abc", "fop"},
 			"foo/", "fop",
-			[][]byte{[]byte("foo"), []byte("fop")},
+			[][]byte{[]byte("foo"), []byte("fop")}, 1,
 		},
 		// no delete
 		{
 			[]string{"foo", "foo/abc", "fop"},
 			"foo/", "foo/",
-			[][]byte{[]byte("foo"), []byte("foo/abc"), []byte("fop")},
+			[][]byte{[]byte("foo"), []byte("foo/abc"), []byte("fop")}, 0,
 		},
 		// delete first
 		{
 			[]string{"foo", "foo/abc", "fop"},
 			"fo", "fop",
-			[][]byte{[]byte("fop")},
+			[][]byte{[]byte("fop")}, 2,
 		},
 		// delete tail
 		{
 			[]string{"foo", "foo/abc", "fop"},
 			"foo/", "fos",
-			[][]byte{[]byte("foo")},
+			[][]byte{[]byte("foo")}, 2,
 		},
 		// delete exact
 		{
 			[]string{"foo", "foo/abc", "fop"},
 			"foo/abc", "",
-			[][]byte{[]byte("foo"), []byte("fop")},
+			[][]byte{[]byte("foo"), []byte("fop")}, 1,
 		},
 		// delete none, [x,x)
 		{
 			[]string{"foo"},
 			"foo", "foo",
-			[][]byte{[]byte("foo")},
+			[][]byte{[]byte("foo")}, 0,
 		},
 	}
 
@@ -341,6 +342,9 @@ func TestV3DeleteRange(t *testing.T) {
 		if err != nil {
 			t.Fatalf("couldn't delete range on test %d (%v)", i, err)
 		}
+		if tt.deleted != dresp.Deleted {
+			t.Errorf("expected %d on test %v, got %d", tt.deleted, i, dresp.Deleted)
+		}
 
 		rreq := &pb.RangeRequest{Key: []byte{0x0}, RangeEnd: []byte{0xff}}
 		rresp, err := kvc.Range(context.TODO(), rreq)