diff --git a/clients/java/dkv-client/src/main/java/org/dkv/client/DKVClient.java b/clients/java/dkv-client/src/main/java/org/dkv/client/DKVClient.java index 8d0005d8..3b6b3b1d 100644 --- a/clients/java/dkv-client/src/main/java/org/dkv/client/DKVClient.java +++ b/clients/java/dkv-client/src/main/java/org/dkv/client/DKVClient.java @@ -280,6 +280,12 @@ public interface DKVClient extends Closeable { */ Iterator iterate(byte[] startKey, byte[] keyPref); + /** + * This methods returns the approximate count of keys in the DKV database + * @return retunrn the count of keys + */ + long getDbSize(); + @Override void close(); } diff --git a/clients/java/dkv-client/src/main/java/org/dkv/client/ShardedDKVClient.java b/clients/java/dkv-client/src/main/java/org/dkv/client/ShardedDKVClient.java index 7db1a0de..0f9d94bb 100644 --- a/clients/java/dkv-client/src/main/java/org/dkv/client/ShardedDKVClient.java +++ b/clients/java/dkv-client/src/main/java/org/dkv/client/ShardedDKVClient.java @@ -260,6 +260,12 @@ public Iterator iterate(byte[] startKey, byte[] keyPref) { return dkvClient.iterate(startKey, keyPref); } + @Override + public long getDbSize() { + //TODO: implement this behaviour + return 0; + } + @Override public void close() { pool.close(); diff --git a/clients/java/dkv-client/src/main/java/org/dkv/client/SimpleDKVClient.java b/clients/java/dkv-client/src/main/java/org/dkv/client/SimpleDKVClient.java index faad7ea6..e44a8cbd 100644 --- a/clients/java/dkv-client/src/main/java/org/dkv/client/SimpleDKVClient.java +++ b/clients/java/dkv-client/src/main/java/org/dkv/client/SimpleDKVClient.java @@ -3,6 +3,7 @@ import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.jmx.JmxReporter; import com.google.protobuf.ByteString; +import com.google.protobuf.Empty; import dkv.serverpb.Api; import dkv.serverpb.DKVGrpc; import io.grpc.ManagedChannel; @@ -272,6 +273,17 @@ public Iterator iterate(byte[] startKey, byte[] keyPref) { return iterate(copyFrom(startKey), copyFrom(keyPref)); } + @Override + public long getDbSize() { + Empty emptyReq = Empty.newBuilder().build(); + Api.KeySpaceSizeResponse res = blockingStub.getKeySpaceSize(emptyReq); + Api.Status status = res.getStatus(); + if (status.getCode() != 0) { + throw new DKVException(status, "getDbSize", new Object[]{}); + } + return res.getDbSize(); + } + @Override public void close() { reporter.stop(); diff --git a/cmd/dkvctl/main.go b/cmd/dkvctl/main.go index e374b3f7..eac5b95d 100644 --- a/cmd/dkvctl/main.go +++ b/cmd/dkvctl/main.go @@ -32,6 +32,7 @@ var cmds = []*cmd{ {"removeNode", "", "Remove a master node from DKV cluster", (*cmd).removeNode, "", false}, {"listNodes", "", "Lists the various DKV nodes that are part of the Nexus cluster", (*cmd).listNodes, "", true}, {"getClusterInfo", " ", "Gets the latest cluster info", (*cmd).getStatus, "", true}, + {"getDbSize", "", "Fetches the approximate count of keys in the db", (*cmd).getDbSize, "", true}, } func (c *cmd) usage() { @@ -220,6 +221,14 @@ func (c *cmd) getStatus(client *ctl.DKVClient, args ...string) { } } +func (c *cmd) getDbSize(client *ctl.DKVClient, args ...string) { + dbSize, err := client.GetDbSize() + if err != nil { + fmt.Println("Unable to perform getDbSize. Error: %v\n", err) + } + fmt.Printf("%d\n", dbSize.DbSize) +} + var dkvAddr, dkvAuthority string func init() { diff --git a/internal/master/service.go b/internal/master/service.go index 03342cb7..3c43eeb2 100644 --- a/internal/master/service.go +++ b/internal/master/service.go @@ -174,6 +174,20 @@ func (ss *standaloneService) CompareAndSet(ctx context.Context, casReq *serverpb return res, err } +func (ss *standaloneService) GetKeySpaceSize(ctx context.Context, e *emptypb.Empty) (*serverpb.KeySpaceSizeResponse, error) { + ss.rwl.RLock() + defer ss.rwl.RUnlock() + + dbSizeResults, err := ss.store.GetKeySpaceSize() + res := &serverpb.KeySpaceSizeResponse{Status: newEmptyStatus(), DbSize: dbSizeResults} + if err != nil { + ss.opts.Logger.Error("Unable to fetch DBKeySpaceSize", zap.Error(err)) + res.Status = newErrorStatus(err) + } + res.DbSize = dbSizeResults + return res, err +} + func (ss *standaloneService) GetChanges(ctx context.Context, getChngsReq *serverpb.GetChangesRequest) (*serverpb.GetChangesResponse, error) { ss.rwl.RLock() defer ss.rwl.RUnlock() @@ -417,6 +431,10 @@ func (ds *distributedService) CompareAndSet(ctx context.Context, casReq *serverp return res, err } +func (ds *distributedService) GetKeySpaceSize(ctx context.Context, req *emptypb.Empty) (*serverpb.KeySpaceSizeResponse, error) { + return nil, nil +} + func (ds *distributedService) Delete(ctx context.Context, delReq *serverpb.DeleteRequest) (*serverpb.DeleteResponse, error) { reqBts, err := proto.Marshal(&raftpb.InternalRaftRequest{Delete: delReq}) res := &serverpb.DeleteResponse{Status: newEmptyStatus()} diff --git a/internal/slave/service.go b/internal/slave/service.go index f00e5eca..8c1ab54e 100644 --- a/internal/slave/service.go +++ b/internal/slave/service.go @@ -108,6 +108,16 @@ func (ss *slaveService) CompareAndSet(_ context.Context, _ *serverpb.CompareAndS return nil, errors.New("DKV slave service does not support keyspace mutations") } +func (ss *slaveService) GetKeySpaceSize(ctx context.Context, empty *emptypb.Empty) (*serverpb.KeySpaceSizeResponse, error) { + dbSizeResults, err := ss.store.GetKeySpaceSize() + res := &serverpb.KeySpaceSizeResponse{Status: newEmptyStatus(), DbSize: dbSizeResults} + if err != nil { + res.Status = newErrorStatus(err) + } + res.DbSize = dbSizeResults + return res, err +} + func (ss *slaveService) Get(ctx context.Context, getReq *serverpb.GetRequest) (*serverpb.GetResponse, error) { readResults, err := ss.store.Get(getReq.Key) res := &serverpb.GetResponse{Status: newEmptyStatus()} diff --git a/internal/storage/badger/store.go b/internal/storage/badger/store.go index 6337a80e..a509ad7d 100644 --- a/internal/storage/badger/store.go +++ b/internal/storage/badger/store.go @@ -285,6 +285,10 @@ func (bdb *badgerDB) CompareAndSet(key, expect, update []byte) (bool, error) { return err == nil, err } +func (bdb *badgerDB) GetKeySpaceSize() (int64, error) { + return 0, nil +} + const ( badgerSSTPrefix = "badger-snapshot-" ) diff --git a/internal/storage/rocksdb/store.go b/internal/storage/rocksdb/store.go index 9592104f..7af0a6c1 100644 --- a/internal/storage/rocksdb/store.go +++ b/internal/storage/rocksdb/store.go @@ -9,6 +9,7 @@ import ( "os" "path" "path/filepath" + "strconv" "strings" "sync/atomic" "time" @@ -380,6 +381,17 @@ func (rdb *rocksDB) CompareAndSet(key, expect, update []byte) (bool, error) { return err == nil, err } +func (rdb *rocksDB) GetKeySpaceSize() (int64, error) { + defer rdb.opts.statsCli.Timing("rocksdb.property.latency.dbSize", time.Now()) + keySize := rdb.db.GetProperty("rocksdb.estimate-num-keys") + dbKeySize, err := strconv.ParseInt(keySize, 10, 64) + if err != nil { + rdb.opts.statsCli.Incr("rocksdb.property.latency.dbSize", 1) + return 0, err + } + return dbKeySize, nil +} + const ( sstPrefix = "rocksdb-sstfile-" sstDefaultCF = "/default.cf" diff --git a/internal/storage/store.go b/internal/storage/store.go index f9e3b072..861d3c5c 100644 --- a/internal/storage/store.go +++ b/internal/storage/store.go @@ -42,6 +42,8 @@ type KVStore interface { // If the expected value is `nil`, then the key is created and // initialized with the given value, atomically. CompareAndSet(key, expect, update []byte) (bool, error) + //GetKeySpaceSize returns the estimated number of keys the db + GetKeySpaceSize() (int64, error) } // A Backupable represents the capability of the underlying store diff --git a/internal/sync/repl_test.go b/internal/sync/repl_test.go index e865bed7..2ba9dd93 100644 --- a/internal/sync/repl_test.go +++ b/internal/sync/repl_test.go @@ -205,6 +205,10 @@ func (ms *memStore) CompareAndSet(key, expect, update []byte) (bool, error) { return true, nil } +func (ms *memStore) GetKeySpaceSize() (int64, error) { + return 0, nil +} + func (ms *memStore) Close() error { ms.store = nil return nil diff --git a/pkg/ctl/client.go b/pkg/ctl/client.go index a8671310..7a3dabca 100644 --- a/pkg/ctl/client.go +++ b/pkg/ctl/client.go @@ -5,6 +5,7 @@ import ( "errors" "github.com/flipkart-incubator/dkv/internal/hlc" "github.com/flipkart-incubator/nexus/models" + "google.golang.org/protobuf/types/known/emptypb" "io" "time" @@ -262,6 +263,13 @@ func (dkvClnt *DKVClient) Iterate(keyPrefix, startKey []byte) (<-chan *KVPair, e return ch, nil } +// GetDbSize returns the approximate count of the number of the keys in the db +func (dkvClnt *DKVClient) GetDbSize() (*serverpb.KeySpaceSizeResponse, error) { + ctx, cancel := context.WithTimeout(context.Background(), Timeout) + defer cancel() + return dkvClnt.dkvCli.GetKeySpaceSize(ctx, &emptypb.Empty{}) +} + // Close closes the underlying GRPC client connection to DKV service func (dkvClnt *DKVClient) Close() error { if dkvClnt.cliConn != nil { diff --git a/pkg/serverpb/api.pb.go b/pkg/serverpb/api.pb.go index 3e403900..980ae32b 100644 --- a/pkg/serverpb/api.pb.go +++ b/pkg/serverpb/api.pb.go @@ -13,6 +13,7 @@ import ( status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" reflect "reflect" sync "sync" ) @@ -930,128 +931,198 @@ func (x *IterateResponse) GetValue() []byte { return nil } +type KeySpaceSizeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Status indicates the result of the Get operation + Status *Status `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` + //Estimated number of keys in the db + DbSize int64 `protobuf:"varint,2,opt,name=dbSize,proto3" json:"dbSize,omitempty"` +} + +func (x *KeySpaceSizeResponse) Reset() { + *x = KeySpaceSizeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_serverpb_api_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *KeySpaceSizeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*KeySpaceSizeResponse) ProtoMessage() {} + +func (x *KeySpaceSizeResponse) ProtoReflect() protoreflect.Message { + mi := &file_pkg_serverpb_api_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use KeySpaceSizeResponse.ProtoReflect.Descriptor instead. +func (*KeySpaceSizeResponse) Descriptor() ([]byte, []int) { + return file_pkg_serverpb_api_proto_rawDescGZIP(), []int{15} +} + +func (x *KeySpaceSizeResponse) GetStatus() *Status { + if x != nil { + return x.Status + } + return nil +} + +func (x *KeySpaceSizeResponse) GetDbSize() int64 { + if x != nil { + return x.DbSize + } + return 0 +} + var File_pkg_serverpb_api_proto protoreflect.FileDescriptor var file_pkg_serverpb_api_proto_rawDesc = []byte{ 0x0a, 0x16, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2f, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x22, 0x4c, 0x0a, 0x06, 0x4b, 0x56, 0x50, 0x61, 0x69, 0x72, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x70, 0x69, - 0x72, 0x65, 0x54, 0x53, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x65, 0x78, 0x70, 0x69, - 0x72, 0x65, 0x54, 0x53, 0x22, 0x60, 0x0a, 0x14, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x41, - 0x6e, 0x64, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1a, - 0x0a, 0x08, 0x6f, 0x6c, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x08, 0x6f, 0x6c, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x65, - 0x77, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6e, 0x65, - 0x77, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x5f, 0x0a, 0x15, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, - 0x65, 0x41, 0x6e, 0x64, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x2c, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x14, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, - 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x22, 0x36, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, - 0x50, 0x0a, 0x0a, 0x50, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, + 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0x4c, 0x0a, 0x06, 0x4b, 0x56, 0x50, 0x61, 0x69, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x53, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, - 0x53, 0x22, 0x4b, 0x0a, 0x0f, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x50, 0x75, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x70, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x52, 0x0a, 0x70, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3b, - 0x0a, 0x0b, 0x50, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, + 0x53, 0x22, 0x60, 0x0a, 0x14, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x41, 0x6e, 0x64, 0x53, + 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x6f, + 0x6c, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6f, + 0x6c, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6e, 0x65, 0x77, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x22, 0x5f, 0x0a, 0x15, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x41, 0x6e, + 0x64, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x64, + 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x22, 0x36, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, + 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, + 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x50, 0x0a, 0x0a, + 0x50, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x53, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x53, 0x22, 0x4b, + 0x0a, 0x0f, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x50, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x70, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, + 0x0a, 0x70, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3b, 0x0a, 0x0b, 0x50, + 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x64, 0x6b, 0x76, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x21, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x3e, 0x0a, 0x0e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x21, 0x0a, 0x0d, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x3e, - 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x2c, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x67, - 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x47, + 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x67, 0x0a, 0x0a, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x47, 0x0a, 0x0f, 0x72, + 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x63, 0x79, 0x52, 0x0f, 0x72, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, + 0x65, 0x6e, 0x63, 0x79, 0x22, 0x51, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x6e, 0x0a, 0x0f, 0x4d, 0x75, 0x6c, 0x74, 0x69, + 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x65, + 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x47, 0x0a, 0x0f, 0x72, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x0f, 0x72, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x73, - 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x51, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x6e, 0x0a, 0x0f, 0x4d, 0x75, - 0x6c, 0x74, 0x69, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, - 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x04, 0x6b, 0x65, 0x79, - 0x73, 0x12, 0x47, 0x0a, 0x0f, 0x72, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, - 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x64, 0x6b, 0x76, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x43, 0x6f, - 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x0f, 0x72, 0x65, 0x61, 0x64, 0x43, - 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x74, 0x0a, 0x10, 0x4d, 0x75, - 0x6c, 0x74, 0x69, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, - 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, - 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x32, 0x0a, 0x09, - 0x6b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x14, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4b, - 0x56, 0x50, 0x61, 0x69, 0x72, 0x52, 0x09, 0x6b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, - 0x22, 0x4a, 0x0a, 0x0e, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6b, 0x65, 0x79, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, - 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x08, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x22, 0x67, 0x0a, 0x0f, - 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x2c, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x14, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x33, 0x0a, 0x0f, 0x52, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, - 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x45, 0x51, 0x55, - 0x45, 0x4e, 0x54, 0x49, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x49, 0x4e, 0x45, - 0x41, 0x52, 0x49, 0x5a, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x32, 0xf7, 0x03, 0x0a, 0x03, 0x44, - 0x4b, 0x56, 0x12, 0x3a, 0x0a, 0x03, 0x50, 0x75, 0x74, 0x12, 0x18, 0x2e, 0x64, 0x6b, 0x76, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x70, 0x62, 0x2e, 0x50, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, - 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1b, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x18, 0x2e, 0x64, 0x6b, 0x76, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x49, 0x0a, 0x08, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x47, 0x65, 0x74, 0x12, 0x1d, 0x2e, 0x64, 0x6b, - 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, - 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x64, 0x6b, 0x76, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x47, - 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x08, 0x4d, 0x75, - 0x6c, 0x74, 0x69, 0x50, 0x75, 0x74, 0x12, 0x1d, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x50, 0x75, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x48, 0x0a, 0x07, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x64, 0x6b, - 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x49, 0x74, 0x65, 0x72, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x64, 0x6b, 0x76, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x58, 0x0a, 0x0d, 0x43, 0x6f, - 0x6d, 0x70, 0x61, 0x72, 0x65, 0x41, 0x6e, 0x64, 0x53, 0x65, 0x74, 0x12, 0x22, 0x2e, 0x64, 0x6b, - 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x61, - 0x72, 0x65, 0x41, 0x6e, 0x64, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x23, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, - 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x41, 0x6e, 0x64, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x30, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x66, 0x6c, 0x69, 0x70, 0x6b, 0x61, 0x72, 0x74, 0x2d, 0x69, 0x6e, 0x63, 0x75, - 0x62, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x64, 0x6b, 0x76, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x74, 0x0a, 0x10, 0x4d, 0x75, 0x6c, 0x74, 0x69, + 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x64, 0x6b, + 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x32, 0x0a, 0x09, 0x6b, 0x65, 0x79, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x64, + 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4b, 0x56, 0x50, 0x61, + 0x69, 0x72, 0x52, 0x09, 0x6b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x4a, 0x0a, + 0x0e, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1c, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x09, 0x6b, 0x65, 0x79, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x1a, 0x0a, + 0x08, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x08, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x22, 0x67, 0x0a, 0x0f, 0x49, 0x74, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x64, + 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x22, 0x5c, 0x0a, 0x14, 0x4b, 0x65, 0x79, 0x53, 0x70, 0x61, 0x63, 0x65, 0x53, 0x69, + 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x64, 0x6b, 0x76, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x62, 0x53, 0x69, + 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x64, 0x62, 0x53, 0x69, 0x7a, 0x65, + 0x2a, 0x33, 0x0a, 0x0f, 0x52, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x63, 0x79, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x54, 0x49, 0x41, + 0x4c, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x49, 0x4e, 0x45, 0x41, 0x52, 0x49, 0x5a, 0x41, + 0x42, 0x4c, 0x45, 0x10, 0x01, 0x32, 0xc6, 0x04, 0x0a, 0x03, 0x44, 0x4b, 0x56, 0x12, 0x3a, 0x0a, + 0x03, 0x50, 0x75, 0x74, 0x12, 0x18, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x70, 0x62, 0x2e, 0x50, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, + 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x50, 0x75, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x12, 0x1b, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x70, 0x62, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1c, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, + 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x18, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x19, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x08, 0x4d, 0x75, + 0x6c, 0x74, 0x69, 0x47, 0x65, 0x74, 0x12, 0x1d, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x47, 0x65, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x08, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x50, 0x75, + 0x74, 0x12, 0x1d, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, + 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x50, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x19, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, + 0x50, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x07, 0x49, + 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x70, 0x62, 0x2e, 0x49, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x58, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, + 0x41, 0x6e, 0x64, 0x53, 0x65, 0x74, 0x12, 0x22, 0x2e, 0x64, 0x6b, 0x76, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x41, 0x6e, 0x64, + 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x64, 0x6b, 0x76, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, + 0x65, 0x41, 0x6e, 0x64, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x4d, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x53, 0x70, 0x61, 0x63, 0x65, 0x53, 0x69, + 0x7a, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x22, 0x2e, 0x64, 0x6b, 0x76, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, 0x2e, 0x4b, 0x65, 0x79, 0x53, 0x70, 0x61, + 0x63, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x30, + 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x66, 0x6c, 0x69, + 0x70, 0x6b, 0x61, 0x72, 0x74, 0x2d, 0x69, 0x6e, 0x63, 0x75, 0x62, 0x61, 0x74, 0x6f, 0x72, 0x2f, + 0x64, 0x6b, 0x76, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x62, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1067,7 +1138,7 @@ func file_pkg_serverpb_api_proto_rawDescGZIP() []byte { } var file_pkg_serverpb_api_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_pkg_serverpb_api_proto_msgTypes = make([]protoimpl.MessageInfo, 15) +var file_pkg_serverpb_api_proto_msgTypes = make([]protoimpl.MessageInfo, 16) var file_pkg_serverpb_api_proto_goTypes = []interface{}{ (ReadConsistency)(0), // 0: dkv.serverpb.ReadConsistency (*KVPair)(nil), // 1: dkv.serverpb.KVPair @@ -1085,6 +1156,8 @@ var file_pkg_serverpb_api_proto_goTypes = []interface{}{ (*MultiGetResponse)(nil), // 13: dkv.serverpb.MultiGetResponse (*IterateRequest)(nil), // 14: dkv.serverpb.IterateRequest (*IterateResponse)(nil), // 15: dkv.serverpb.IterateResponse + (*KeySpaceSizeResponse)(nil), // 16: dkv.serverpb.KeySpaceSizeResponse + (*emptypb.Empty)(nil), // 17: google.protobuf.Empty } var file_pkg_serverpb_api_proto_depIdxs = []int32{ 4, // 0: dkv.serverpb.CompareAndSetResponse.status:type_name -> dkv.serverpb.Status @@ -1097,25 +1170,28 @@ var file_pkg_serverpb_api_proto_depIdxs = []int32{ 4, // 7: dkv.serverpb.MultiGetResponse.status:type_name -> dkv.serverpb.Status 1, // 8: dkv.serverpb.MultiGetResponse.keyValues:type_name -> dkv.serverpb.KVPair 4, // 9: dkv.serverpb.IterateResponse.status:type_name -> dkv.serverpb.Status - 5, // 10: dkv.serverpb.DKV.Put:input_type -> dkv.serverpb.PutRequest - 8, // 11: dkv.serverpb.DKV.Delete:input_type -> dkv.serverpb.DeleteRequest - 10, // 12: dkv.serverpb.DKV.Get:input_type -> dkv.serverpb.GetRequest - 12, // 13: dkv.serverpb.DKV.MultiGet:input_type -> dkv.serverpb.MultiGetRequest - 6, // 14: dkv.serverpb.DKV.MultiPut:input_type -> dkv.serverpb.MultiPutRequest - 14, // 15: dkv.serverpb.DKV.Iterate:input_type -> dkv.serverpb.IterateRequest - 2, // 16: dkv.serverpb.DKV.CompareAndSet:input_type -> dkv.serverpb.CompareAndSetRequest - 7, // 17: dkv.serverpb.DKV.Put:output_type -> dkv.serverpb.PutResponse - 9, // 18: dkv.serverpb.DKV.Delete:output_type -> dkv.serverpb.DeleteResponse - 11, // 19: dkv.serverpb.DKV.Get:output_type -> dkv.serverpb.GetResponse - 13, // 20: dkv.serverpb.DKV.MultiGet:output_type -> dkv.serverpb.MultiGetResponse - 7, // 21: dkv.serverpb.DKV.MultiPut:output_type -> dkv.serverpb.PutResponse - 15, // 22: dkv.serverpb.DKV.Iterate:output_type -> dkv.serverpb.IterateResponse - 3, // 23: dkv.serverpb.DKV.CompareAndSet:output_type -> dkv.serverpb.CompareAndSetResponse - 17, // [17:24] is the sub-list for method output_type - 10, // [10:17] is the sub-list for method input_type - 10, // [10:10] is the sub-list for extension type_name - 10, // [10:10] is the sub-list for extension extendee - 0, // [0:10] is the sub-list for field type_name + 4, // 10: dkv.serverpb.KeySpaceSizeResponse.status:type_name -> dkv.serverpb.Status + 5, // 11: dkv.serverpb.DKV.Put:input_type -> dkv.serverpb.PutRequest + 8, // 12: dkv.serverpb.DKV.Delete:input_type -> dkv.serverpb.DeleteRequest + 10, // 13: dkv.serverpb.DKV.Get:input_type -> dkv.serverpb.GetRequest + 12, // 14: dkv.serverpb.DKV.MultiGet:input_type -> dkv.serverpb.MultiGetRequest + 6, // 15: dkv.serverpb.DKV.MultiPut:input_type -> dkv.serverpb.MultiPutRequest + 14, // 16: dkv.serverpb.DKV.Iterate:input_type -> dkv.serverpb.IterateRequest + 2, // 17: dkv.serverpb.DKV.CompareAndSet:input_type -> dkv.serverpb.CompareAndSetRequest + 17, // 18: dkv.serverpb.DKV.GetKeySpaceSize:input_type -> google.protobuf.Empty + 7, // 19: dkv.serverpb.DKV.Put:output_type -> dkv.serverpb.PutResponse + 9, // 20: dkv.serverpb.DKV.Delete:output_type -> dkv.serverpb.DeleteResponse + 11, // 21: dkv.serverpb.DKV.Get:output_type -> dkv.serverpb.GetResponse + 13, // 22: dkv.serverpb.DKV.MultiGet:output_type -> dkv.serverpb.MultiGetResponse + 7, // 23: dkv.serverpb.DKV.MultiPut:output_type -> dkv.serverpb.PutResponse + 15, // 24: dkv.serverpb.DKV.Iterate:output_type -> dkv.serverpb.IterateResponse + 3, // 25: dkv.serverpb.DKV.CompareAndSet:output_type -> dkv.serverpb.CompareAndSetResponse + 16, // 26: dkv.serverpb.DKV.GetKeySpaceSize:output_type -> dkv.serverpb.KeySpaceSizeResponse + 19, // [19:27] is the sub-list for method output_type + 11, // [11:19] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name } func init() { file_pkg_serverpb_api_proto_init() } @@ -1304,6 +1380,18 @@ func file_pkg_serverpb_api_proto_init() { return nil } } + file_pkg_serverpb_api_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*KeySpaceSizeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -1311,7 +1399,7 @@ func file_pkg_serverpb_api_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_pkg_serverpb_api_proto_rawDesc, NumEnums: 1, - NumMessages: 15, + NumMessages: 16, NumExtensions: 0, NumServices: 1, }, @@ -1354,6 +1442,8 @@ type DKVClient interface { // CompareAndSet offers the standard CAS style transaction over a given // key. Intended to be used in concurrent workloads with less contention. CompareAndSet(ctx context.Context, in *CompareAndSetRequest, opts ...grpc.CallOption) (*CompareAndSetResponse, error) + //GetKeySpaceSize returns the estimated number of keys the db + GetKeySpaceSize(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*KeySpaceSizeResponse, error) } type dKVClient struct { @@ -1450,6 +1540,15 @@ func (c *dKVClient) CompareAndSet(ctx context.Context, in *CompareAndSetRequest, return out, nil } +func (c *dKVClient) GetKeySpaceSize(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*KeySpaceSizeResponse, error) { + out := new(KeySpaceSizeResponse) + err := c.cc.Invoke(ctx, "/dkv.serverpb.DKV/GetKeySpaceSize", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // DKVServer is the server API for DKV service. type DKVServer interface { // Put puts the given key into the key value store. @@ -1468,6 +1567,8 @@ type DKVServer interface { // CompareAndSet offers the standard CAS style transaction over a given // key. Intended to be used in concurrent workloads with less contention. CompareAndSet(context.Context, *CompareAndSetRequest) (*CompareAndSetResponse, error) + //GetKeySpaceSize returns the estimated number of keys the db + GetKeySpaceSize(context.Context, *emptypb.Empty) (*KeySpaceSizeResponse, error) } // UnimplementedDKVServer can be embedded to have forward compatible implementations. @@ -1495,6 +1596,9 @@ func (*UnimplementedDKVServer) Iterate(*IterateRequest, DKV_IterateServer) error func (*UnimplementedDKVServer) CompareAndSet(context.Context, *CompareAndSetRequest) (*CompareAndSetResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CompareAndSet not implemented") } +func (*UnimplementedDKVServer) GetKeySpaceSize(context.Context, *emptypb.Empty) (*KeySpaceSizeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetKeySpaceSize not implemented") +} func RegisterDKVServer(s *grpc.Server, srv DKVServer) { s.RegisterService(&_DKV_serviceDesc, srv) @@ -1629,6 +1733,24 @@ func _DKV_CompareAndSet_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _DKV_GetKeySpaceSize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DKVServer).GetKeySpaceSize(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dkv.serverpb.DKV/GetKeySpaceSize", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DKVServer).GetKeySpaceSize(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + var _DKV_serviceDesc = grpc.ServiceDesc{ ServiceName: "dkv.serverpb.DKV", HandlerType: (*DKVServer)(nil), @@ -1657,6 +1779,10 @@ var _DKV_serviceDesc = grpc.ServiceDesc{ MethodName: "CompareAndSet", Handler: _DKV_CompareAndSet_Handler, }, + { + MethodName: "GetKeySpaceSize", + Handler: _DKV_GetKeySpaceSize_Handler, + }, }, Streams: []grpc.StreamDesc{ { diff --git a/pkg/serverpb/api.proto b/pkg/serverpb/api.proto index 4007ee09..c700dda1 100644 --- a/pkg/serverpb/api.proto +++ b/pkg/serverpb/api.proto @@ -1,5 +1,5 @@ syntax = "proto3"; - +import "google/protobuf/empty.proto"; package dkv.serverpb; option go_package = "github.com/flipkart-incubator/dkv/pkg/serverpb"; @@ -26,6 +26,9 @@ service DKV { // CompareAndSet offers the standard CAS style transaction over a given // key. Intended to be used in concurrent workloads with less contention. rpc CompareAndSet (CompareAndSetRequest) returns (CompareAndSetResponse); + + //GetKeySpaceSize returns the estimated number of keys the db + rpc GetKeySpaceSize (google.protobuf.Empty) returns (KeySpaceSizeResponse); } message KVPair { @@ -143,3 +146,10 @@ message IterateResponse { // Value of the current iteration. bytes value = 3; } + +message KeySpaceSizeResponse { + // Status indicates the result of the Get operation + Status status = 1; + //Estimated number of keys in the db + int64 dbSize = 2; +} \ No newline at end of file