diff --git a/go/gen/proto/dolt/services/remotesapi/v1alpha1/chunkstore.pb.go b/go/gen/proto/dolt/services/remotesapi/v1alpha1/chunkstore.pb.go index 4fb6fcd3d98..1f2b6e24774 100644 --- a/go/gen/proto/dolt/services/remotesapi/v1alpha1/chunkstore.pb.go +++ b/go/gen/proto/dolt/services/remotesapi/v1alpha1/chunkstore.pb.go @@ -402,9 +402,11 @@ type RangeChunk struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` - Offset uint64 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset,omitempty"` - Length uint32 `protobuf:"varint,3,opt,name=length,proto3" json:"length,omitempty"` + Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` + Offset uint64 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset,omitempty"` + Length uint32 `protobuf:"varint,3,opt,name=length,proto3" json:"length,omitempty"` + DictionaryOffset uint64 `protobuf:"varint,4,opt,name=dictionary_offset,json=dictionaryOffset,proto3" json:"dictionary_offset,omitempty"` + DictionaryLength uint32 `protobuf:"varint,5,opt,name=dictionary_length,json=dictionaryLength,proto3" json:"dictionary_length,omitempty"` } func (x *RangeChunk) Reset() { @@ -460,6 +462,20 @@ func (x *RangeChunk) GetLength() uint32 { return 0 } +func (x *RangeChunk) GetDictionaryOffset() uint64 { + if x != nil { + return x.DictionaryOffset + } + return 0 +} + +func (x *RangeChunk) GetDictionaryLength() uint32 { + if x != nil { + return x.DictionaryLength + } + return 0 +} + type HttpGetRange struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2233,418 +2249,424 @@ var file_dolt_services_remotesapi_v1alpha1_chunkstore_proto_rawDesc = []byte{ 0x74, 0x70, 0x47, 0x65, 0x74, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x68, 0x61, - 0x73, 0x68, 0x65, 0x73, 0x22, 0x50, 0x0a, 0x0a, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x68, 0x75, - 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x16, - 0x0a, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, - 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x22, 0x67, 0x0a, 0x0c, 0x48, 0x74, 0x74, 0x70, 0x47, 0x65, - 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x45, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x67, - 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x61, 0x6e, - 0x67, 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, - 0xe9, 0x02, 0x0a, 0x0b, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x12, - 0x4c, 0x0a, 0x08, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2f, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x47, 0x65, 0x74, 0x43, 0x68, 0x75, - 0x6e, 0x6b, 0x48, 0x00, 0x52, 0x07, 0x68, 0x74, 0x74, 0x70, 0x47, 0x65, 0x74, 0x12, 0x57, 0x0a, - 0x0e, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x47, 0x65, - 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x68, 0x74, 0x74, 0x70, 0x47, 0x65, - 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x3f, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, - 0x68, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72, 0x65, - 0x73, 0x68, 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, 0x66, 0x0a, 0x0f, 0x72, 0x65, 0x66, 0x72, 0x65, - 0x73, 0x68, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x3d, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x73, 0x68, 0x65, 0x73, 0x22, 0xaa, 0x01, 0x0a, 0x0a, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x68, + 0x75, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, + 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x69, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x10, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x72, 0x79, 0x4f, 0x66, + 0x66, 0x73, 0x65, 0x74, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x72, 0x79, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x10, 0x64, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x72, 0x79, 0x4c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x22, 0x67, 0x0a, 0x0c, 0x48, 0x74, 0x74, 0x70, 0x47, 0x65, 0x74, 0x52, 0x61, 0x6e, 0x67, + 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x75, 0x72, 0x6c, 0x12, 0x45, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x68, 0x75, + 0x6e, 0x6b, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0xe9, 0x02, 0x0a, 0x0b, 0x44, + 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x12, 0x4c, 0x0a, 0x08, 0x68, 0x74, + 0x74, 0x70, 0x5f, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x64, + 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, + 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x48, 0x74, 0x74, 0x70, 0x47, 0x65, 0x74, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x48, 0x00, 0x52, + 0x07, 0x68, 0x74, 0x74, 0x70, 0x47, 0x65, 0x74, 0x12, 0x57, 0x0a, 0x0e, 0x68, 0x74, 0x74, 0x70, + 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2f, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x72, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, - 0x0e, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, - 0x0a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x25, 0x0a, 0x11, 0x48, - 0x74, 0x74, 0x70, 0x50, 0x6f, 0x73, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, - 0x72, 0x6c, 0x22, 0x94, 0x01, 0x0a, 0x09, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, - 0x12, 0x26, 0x0a, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x68, - 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x46, 0x69, 0x6c, 0x65, 0x48, 0x61, 0x73, 0x68, 0x12, 0x53, 0x0a, 0x09, 0x68, 0x74, 0x74, 0x70, - 0x5f, 0x70, 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x64, 0x6f, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x47, 0x65, 0x74, 0x52, 0x61, 0x6e, 0x67, + 0x65, 0x48, 0x00, 0x52, 0x0c, 0x68, 0x74, 0x74, 0x70, 0x47, 0x65, 0x74, 0x52, 0x61, 0x6e, 0x67, + 0x65, 0x12, 0x3f, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x61, 0x66, 0x74, + 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x41, 0x66, 0x74, + 0x65, 0x72, 0x12, 0x66, 0x0a, 0x0f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x48, 0x74, 0x74, 0x70, 0x50, 0x6f, 0x73, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, - 0x65, 0x48, 0x00, 0x52, 0x08, 0x68, 0x74, 0x74, 0x70, 0x50, 0x6f, 0x73, 0x74, 0x42, 0x0a, 0x0a, - 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xbb, 0x01, 0x0a, 0x16, 0x47, 0x65, - 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x49, 0x64, - 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x68, 0x75, 0x6e, - 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, - 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x72, - 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, - 0x70, 0x6f, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, - 0x65, 0x70, 0x6f, 0x50, 0x61, 0x74, 0x68, 0x22, 0x7c, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x44, 0x6f, - 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x42, 0x0a, 0x04, 0x6c, 0x6f, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x2e, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, - 0x52, 0x04, 0x6c, 0x6f, 0x63, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x8b, 0x01, 0x0a, 0x10, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, - 0x69, 0x6c, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x65, 0x6e, 0x67, 0x74, - 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, - 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x48, 0x61, 0x73, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x75, 0x6d, 0x5f, 0x63, 0x68, 0x75, 0x6e, - 0x6b, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6e, 0x75, 0x6d, 0x43, 0x68, 0x75, - 0x6e, 0x6b, 0x73, 0x22, 0xa9, 0x02, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, - 0x64, 0x4c, 0x6f, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x07, - 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, - 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, - 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, - 0x12, 0x2e, 0x0a, 0x11, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x68, - 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x02, 0x18, 0x01, 0x52, - 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, - 0x12, 0x61, 0x0a, 0x12, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x64, - 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x64, - 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, - 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, - 0x73, 0x52, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x74, 0x61, - 0x69, 0x6c, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x50, 0x61, 0x74, 0x68, 0x22, - 0x78, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x04, 0x6c, 0x6f, 0x63, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, + 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, + 0x55, 0x72, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0e, 0x72, 0x65, 0x66, 0x72, + 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x6c, 0x6f, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x25, 0x0a, 0x11, 0x48, 0x74, 0x74, 0x70, 0x50, 0x6f, + 0x73, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, + 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x94, 0x01, + 0x0a, 0x09, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x12, 0x26, 0x0a, 0x0f, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x48, + 0x61, 0x73, 0x68, 0x12, 0x53, 0x0a, 0x09, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x70, 0x6f, 0x73, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, - 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, - 0x64, 0x4c, 0x6f, 0x63, 0x52, 0x04, 0x6c, 0x6f, 0x63, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, + 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x50, + 0x6f, 0x73, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x08, + 0x68, 0x74, 0x74, 0x70, 0x50, 0x6f, 0x73, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xbb, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x44, 0x6f, 0x77, 0x6e, + 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x42, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x29, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x52, 0x06, 0x72, 0x65, 0x70, + 0x6f, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x68, 0x61, 0x73, + 0x68, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x68, 0x75, 0x6e, 0x6b, + 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x70, 0x61, + 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x50, 0x61, + 0x74, 0x68, 0x22, 0x7c, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, + 0x64, 0x4c, 0x6f, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, + 0x04, 0x6c, 0x6f, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x64, 0x6f, + 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, + 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x52, 0x04, 0x6c, 0x6f, 0x63, + 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x22, 0x8b, 0x01, 0x0a, 0x10, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, + 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x21, 0x0a, 0x0c, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, + 0x1d, 0x0a, 0x0a, 0x6e, 0x75, 0x6d, 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x09, 0x6e, 0x75, 0x6d, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x73, 0x22, 0xa9, + 0x02, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x49, 0x64, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x11, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0f, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x46, 0x69, 0x6c, 0x65, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x61, 0x0a, 0x12, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x10, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x1d, + 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x0a, + 0x09, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x50, 0x61, 0x74, 0x68, 0x22, 0x78, 0x0a, 0x15, 0x47, 0x65, + 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x04, 0x6c, 0x6f, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x2c, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x52, + 0x04, 0x6c, 0x6f, 0x63, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x8f, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x62, 0x61, 0x73, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, + 0x49, 0x64, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x8f, 0x01, 0x0a, 0x0d, 0x52, 0x65, - 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x07, 0x72, - 0x65, 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x64, - 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, - 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x12, - 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1b, - 0x0a, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x50, 0x61, 0x74, 0x68, 0x22, 0x2f, 0x0a, 0x0e, 0x52, - 0x65, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, - 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x8d, 0x01, 0x0a, - 0x0b, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x07, + 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x70, + 0x6f, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, + 0x70, 0x6f, 0x50, 0x61, 0x74, 0x68, 0x22, 0x2f, 0x0a, 0x0e, 0x52, 0x65, 0x62, 0x61, 0x73, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, + 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x8d, 0x01, 0x0a, 0x0b, 0x52, 0x6f, 0x6f, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x49, 0x64, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, + 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, + 0x70, 0x6f, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, + 0x65, 0x70, 0x6f, 0x50, 0x61, 0x74, 0x68, 0x22, 0x4a, 0x0a, 0x0c, 0x52, 0x6f, 0x6f, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x6f, 0x6f, 0x74, 0x5f, + 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x6f, 0x6f, 0x74, + 0x48, 0x61, 0x73, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x22, 0x45, 0x0a, 0x0e, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x68, 0x75, + 0x6e, 0x6b, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, + 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xde, 0x02, 0x0a, 0x0d, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, - 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, - 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x50, 0x61, 0x74, 0x68, 0x22, 0x4a, 0x0a, 0x0c, - 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, - 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, - 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, - 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x45, 0x0a, 0x0e, 0x43, 0x68, 0x75, 0x6e, - 0x6b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, - 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1f, - 0x0a, 0x0b, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, - 0xde, 0x02, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x42, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x52, 0x06, 0x72, - 0x65, 0x70, 0x6f, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x6c, 0x61, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6c, - 0x61, 0x73, 0x74, 0x12, 0x5b, 0x0a, 0x10, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, - 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, - 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x0e, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x61, 0x0a, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x5f, - 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x64, - 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, - 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x46, 0x6f, 0x72, 0x6d, 0x61, - 0x74, 0x52, 0x10, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x46, 0x6f, 0x72, - 0x6d, 0x61, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x70, 0x61, 0x74, 0x68, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x50, 0x61, 0x74, 0x68, - 0x22, 0x2a, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0xfb, 0x01, 0x0a, - 0x16, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, + 0x12, 0x18, 0x0a, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x61, + 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6c, 0x61, 0x73, 0x74, 0x12, 0x5b, + 0x0a, 0x10, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x69, 0x6e, + 0x66, 0x6f, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, - 0x6f, 0x49, 0x64, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x12, 0x61, 0x0a, 0x12, 0x63, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x75, + 0x6e, 0x6b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0e, 0x63, 0x68, 0x75, + 0x6e, 0x6b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x61, 0x0a, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x10, 0x63, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x1d, - 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x0a, - 0x09, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x50, 0x61, 0x74, 0x68, 0x22, 0x92, 0x02, 0x0a, 0x17, 0x47, - 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x62, 0x66, 0x5f, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x62, 0x66, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x62, 0x73, 0x5f, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x62, - 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, - 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, - 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, - 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x73, 0x0a, 0x18, 0x70, 0x75, - 0x73, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x64, - 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, - 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2e, 0x50, 0x75, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, - 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x16, 0x70, 0x75, 0x73, 0x68, 0x43, 0x6f, 0x6e, - 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x22, - 0x54, 0x0a, 0x10, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x46, 0x6f, 0x72, - 0x6d, 0x61, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x62, 0x66, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x62, 0x66, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x62, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x62, 0x73, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xc0, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x42, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x29, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x52, 0x06, 0x72, 0x65, 0x70, - 0x6f, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0d, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x78, 0x5f, - 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0c, - 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x78, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x1d, 0x0a, 0x0a, - 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x72, - 0x65, 0x70, 0x6f, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x72, 0x65, 0x70, 0x6f, 0x50, 0x61, 0x74, 0x68, 0x22, 0x82, 0x02, 0x0a, 0x0d, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x69, - 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, - 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x75, 0x6d, 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6e, 0x75, 0x6d, 0x43, 0x68, 0x75, 0x6e, - 0x6b, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x75, 0x72, 0x6c, 0x12, 0x3f, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, - 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, - 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, 0x66, 0x0a, 0x0f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, - 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, - 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, - 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, - 0x69, 0x6c, 0x65, 0x55, 0x72, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0e, 0x72, - 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb5, 0x01, - 0x0a, 0x1a, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, - 0x6c, 0x65, 0x55, 0x72, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x07, - 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, - 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, - 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, - 0x12, 0x17, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, - 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, + 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x1b, + 0x0a, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x50, 0x61, 0x74, 0x68, 0x22, 0x2a, 0x0a, 0x0e, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0xfb, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x52, + 0x65, 0x70, 0x6f, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x42, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x52, 0x06, + 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x12, 0x61, 0x0a, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x0e, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, + 0x6f, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x10, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, + 0x65, 0x70, 0x6f, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, + 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x70, 0x6f, - 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, - 0x6f, 0x50, 0x61, 0x74, 0x68, 0x22, 0x8f, 0x01, 0x0a, 0x1b, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, - 0x68, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x72, 0x6c, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x3f, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, - 0x73, 0x68, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72, - 0x65, 0x73, 0x68, 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, - 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x99, 0x02, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, - 0x58, 0x0a, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x6e, - 0x66, 0x6f, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x69, 0x0a, 0x18, 0x61, 0x70, 0x70, - 0x65, 0x6e, 0x64, 0x69, 0x78, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, - 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x64, 0x6f, + 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, + 0x6f, 0x50, 0x61, 0x74, 0x68, 0x22, 0x92, 0x02, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, + 0x6f, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x62, 0x66, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x62, 0x66, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x62, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x62, 0x73, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x73, 0x0a, 0x18, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x63, 0x6f, + 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x75, 0x73, 0x68, + 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x52, 0x16, 0x70, 0x75, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x22, 0x54, 0x0a, 0x10, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x1f, + 0x0a, 0x0b, 0x6e, 0x62, 0x66, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x62, 0x66, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x1f, 0x0a, 0x0b, 0x6e, 0x62, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x62, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x22, 0xc0, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, + 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x07, 0x72, 0x65, + 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x15, 0x61, - 0x70, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x78, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, - 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x22, 0xba, 0x03, 0x0a, 0x14, 0x41, 0x64, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x07, - 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, - 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, - 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, - 0x12, 0x61, 0x0a, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x5f, - 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x64, - 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, - 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x46, 0x6f, 0x72, 0x6d, 0x61, - 0x74, 0x52, 0x10, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x46, 0x6f, 0x72, - 0x6d, 0x61, 0x74, 0x12, 0x5b, 0x0a, 0x10, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, - 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, - 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x0e, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x62, 0x0a, 0x0f, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x78, 0x5f, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x64, 0x6f, 0x6c, 0x74, + 0x52, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x12, 0x27, + 0x0a, 0x0d, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x78, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0c, 0x61, 0x70, 0x70, 0x65, 0x6e, + 0x64, 0x69, 0x78, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, + 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x70, + 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x50, + 0x61, 0x74, 0x68, 0x22, 0x82, 0x02, 0x0a, 0x0d, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, + 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x1d, + 0x0a, 0x0a, 0x6e, 0x75, 0x6d, 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x09, 0x6e, 0x75, 0x6d, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x73, 0x12, 0x10, 0x0a, + 0x03, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, + 0x3f, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x41, 0x66, 0x74, 0x65, 0x72, + 0x12, 0x66, 0x0a, 0x0f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, - 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4d, 0x61, - 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x78, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x78, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, + 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, + 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x72, + 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0e, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, + 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb5, 0x01, 0x0a, 0x1a, 0x52, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x72, 0x6c, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x49, 0x64, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x66, + 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, + 0x6c, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x70, 0x61, 0x74, 0x68, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x50, 0x61, 0x74, 0x68, - 0x22, 0x50, 0x0a, 0x15, 0x41, 0x64, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x2a, 0xa4, 0x01, 0x0a, 0x16, 0x50, 0x75, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x63, 0x75, - 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x28, 0x0a, - 0x24, 0x50, 0x55, 0x53, 0x48, 0x5f, 0x43, 0x4f, 0x4e, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x43, - 0x59, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x2f, 0x0a, 0x2b, 0x50, 0x55, 0x53, 0x48, 0x5f, - 0x43, 0x4f, 0x4e, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x43, 0x4f, 0x4e, 0x54, - 0x52, 0x4f, 0x4c, 0x5f, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x49, - 0x4e, 0x47, 0x5f, 0x53, 0x45, 0x54, 0x10, 0x01, 0x12, 0x2f, 0x0a, 0x2b, 0x50, 0x55, 0x53, 0x48, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x50, 0x61, 0x74, 0x68, + 0x22, 0x8f, 0x01, 0x0a, 0x1b, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x72, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, + 0x72, 0x6c, 0x12, 0x3f, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x61, 0x66, + 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x41, 0x66, + 0x74, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x22, 0x99, 0x02, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, + 0x09, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x58, 0x0a, 0x0f, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, + 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x69, 0x0a, 0x18, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x78, + 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x15, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, + 0x69, 0x78, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xba, + 0x03, 0x0a, 0x14, 0x41, 0x64, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x49, 0x64, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x12, 0x61, 0x0a, 0x12, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x10, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x5b, + 0x0a, 0x10, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x69, 0x6e, + 0x66, 0x6f, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x75, + 0x6e, 0x6b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0e, 0x63, 0x68, 0x75, + 0x6e, 0x6b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x62, 0x0a, 0x0f, 0x61, + 0x70, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x78, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, + 0x74, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x78, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x0e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x78, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1b, + 0x0a, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6f, 0x50, 0x61, 0x74, 0x68, 0x22, 0x50, 0x0a, 0x15, 0x41, + 0x64, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x1d, + 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x2a, 0xa4, 0x01, + 0x0a, 0x16, 0x50, 0x75, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, + 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x28, 0x0a, 0x24, 0x50, 0x55, 0x53, 0x48, 0x5f, 0x43, 0x4f, 0x4e, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x43, 0x4f, 0x4e, - 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, 0x5f, 0x57, 0x4f, 0x52, 0x4b, - 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x45, 0x54, 0x10, 0x02, 0x2a, 0x89, 0x01, 0x0a, 0x16, 0x4d, 0x61, - 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x78, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x24, 0x4d, 0x41, 0x4e, 0x49, 0x46, 0x45, 0x53, 0x54, - 0x5f, 0x41, 0x50, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x58, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x20, - 0x0a, 0x1c, 0x4d, 0x41, 0x4e, 0x49, 0x46, 0x45, 0x53, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x45, 0x4e, - 0x44, 0x49, 0x58, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x10, 0x01, - 0x12, 0x23, 0x0a, 0x1f, 0x4d, 0x41, 0x4e, 0x49, 0x46, 0x45, 0x53, 0x54, 0x5f, 0x41, 0x50, 0x50, - 0x45, 0x4e, 0x44, 0x49, 0x58, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x50, 0x50, - 0x45, 0x4e, 0x44, 0x10, 0x02, 0x32, 0xb2, 0x0b, 0x0a, 0x11, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x53, - 0x74, 0x6f, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x88, 0x01, 0x0a, 0x0f, - 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, - 0x39, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, - 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x64, 0x6f, 0x6c, + 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x2f, 0x0a, 0x2b, 0x50, 0x55, 0x53, 0x48, 0x5f, 0x43, 0x4f, 0x4e, 0x43, 0x55, + 0x52, 0x52, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x49, + 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x45, + 0x54, 0x10, 0x01, 0x12, 0x2f, 0x0a, 0x2b, 0x50, 0x55, 0x53, 0x48, 0x5f, 0x43, 0x4f, 0x4e, 0x43, + 0x55, 0x52, 0x52, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x5f, + 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, 0x5f, 0x57, 0x4f, 0x52, 0x4b, 0x49, 0x4e, 0x47, 0x5f, 0x53, + 0x45, 0x54, 0x10, 0x02, 0x2a, 0x89, 0x01, 0x0a, 0x16, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, + 0x74, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x78, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x28, 0x0a, 0x24, 0x4d, 0x41, 0x4e, 0x49, 0x46, 0x45, 0x53, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x45, + 0x4e, 0x44, 0x49, 0x58, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x20, 0x0a, 0x1c, 0x4d, 0x41, 0x4e, + 0x49, 0x46, 0x45, 0x53, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x58, 0x5f, 0x4f, + 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x1f, 0x4d, + 0x41, 0x4e, 0x49, 0x46, 0x45, 0x53, 0x54, 0x5f, 0x41, 0x50, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x58, + 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x45, 0x4e, 0x44, 0x10, 0x02, + 0x32, 0xb2, 0x0b, 0x0a, 0x11, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x88, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x65, + 0x70, 0x6f, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x39, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x76, 0x0a, 0x09, 0x48, 0x61, 0x73, 0x43, 0x68, 0x75, - 0x6e, 0x6b, 0x73, 0x12, 0x33, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, + 0x6f, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x76, 0x0a, 0x09, 0x48, 0x61, 0x73, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x73, 0x12, 0x33, + 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, + 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x48, 0x61, 0x73, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x61, 0x73, 0x43, 0x68, 0x75, 0x6e, 0x6b, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x61, 0x73, - 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8d, - 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x39, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, - 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, - 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8d, 0x01, 0x0a, 0x14, 0x47, 0x65, + 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x39, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, - 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x94, - 0x01, 0x0a, 0x17, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, - 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x39, 0x2e, 0x64, 0x6f, 0x6c, - 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, - 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, + 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, + 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, + 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x94, 0x01, 0x0a, 0x17, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x39, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x6f, 0x77, - 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x87, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, - 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x37, 0x2e, 0x64, + 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x3a, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, + 0x4c, 0x6f, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, + 0x12, 0x87, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x37, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, + 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x38, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, + 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6d, 0x0a, 0x06, 0x52, 0x65, + 0x62, 0x61, 0x73, 0x65, 0x12, 0x30, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x62, 0x61, 0x73, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x62, 0x61, 0x73, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x04, 0x52, 0x6f, 0x6f, + 0x74, 0x12, 0x2e, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2f, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x6d, 0x0a, 0x06, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x30, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, - 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x6d, 0x0a, 0x06, 0x52, 0x65, 0x62, 0x61, 0x73, 0x65, 0x12, 0x30, 0x2e, 0x64, 0x6f, 0x6c, 0x74, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, - 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, - 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x64, 0x6f, - 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, - 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x52, 0x65, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, - 0x0a, 0x04, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x2e, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, - 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6f, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, - 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6f, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6d, 0x0a, 0x06, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x12, 0x30, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, + 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, + 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x85, 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, + 0x69, 0x6c, 0x65, 0x73, 0x12, 0x38, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, + 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, + 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x94, 0x01, 0x0a, 0x13, 0x52, 0x65, + 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x72, + 0x6c, 0x12, 0x3d, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x85, 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x38, 0x2e, 0x64, 0x6f, 0x6c, 0x74, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, - 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x94, - 0x01, 0x0a, 0x13, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, - 0x69, 0x6c, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x3d, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, - 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, - 0x73, 0x68, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x72, 0x6c, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3e, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, - 0x68, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x72, 0x6c, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x0d, 0x41, 0x64, 0x64, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x37, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, - 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x38, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x72, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x3e, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x53, 0x5a, 0x51, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x6f, 0x6c, 0x74, 0x68, 0x75, 0x62, - 0x2f, 0x64, 0x6f, 0x6c, 0x74, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x64, 0x6f, 0x6c, 0x74, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x3b, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x72, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x82, 0x01, 0x0a, 0x0d, 0x41, 0x64, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, + 0x65, 0x73, 0x12, 0x37, 0x2e, 0x64, 0x6f, 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, + 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x64, 0x6f, + 0x6c, 0x74, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, + 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x41, 0x64, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x53, 0x5a, 0x51, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x6f, 0x6c, 0x74, 0x68, 0x75, 0x62, 0x2f, 0x64, 0x6f, 0x6c, 0x74, + 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x64, 0x6f, + 0x6c, 0x74, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x6d, 0x6f, + 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, + 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/go/libraries/doltcore/remotesrv/grpc.go b/go/libraries/doltcore/remotesrv/grpc.go index d158f47e05b..89f53780bc5 100644 --- a/go/libraries/doltcore/remotesrv/grpc.go +++ b/go/libraries/doltcore/remotesrv/grpc.go @@ -295,7 +295,12 @@ func (rs *RemoteChunkStore) StreamDownloadLocations(stream remotesapi.ChunkStore var ranges []*remotesapi.RangeChunk for h, r := range hashToRange { hCpy := h - ranges = append(ranges, &remotesapi.RangeChunk{Hash: hCpy[:], Offset: r.Offset, Length: r.Length}) + ranges = append(ranges, &remotesapi.RangeChunk{ + Hash: hCpy[:], + Offset: r.Offset, + Length: r.Length, + DictionaryOffset: r.DictOffset, + DictionaryLength: r.DictLength}) } url := rs.getDownloadUrl(md, prefix+"/"+loc) diff --git a/go/libraries/doltcore/remotesrv/http.go b/go/libraries/doltcore/remotesrv/http.go index eedbf926148..1c815e8fcce 100644 --- a/go/libraries/doltcore/remotesrv/http.go +++ b/go/libraries/doltcore/remotesrv/http.go @@ -94,12 +94,18 @@ func (fh filehandler) ServeHTTP(respWr http.ResponseWriter, req *http.Request) { respWr.WriteHeader(http.StatusBadRequest) return } - _, ok := hash.MaybeParse(path[i+1:]) + + fileName := path[i+1:] + if strings.HasSuffix(fileName, ".darc") { + fileName = fileName[:len(fileName)-5] + } + _, ok := hash.MaybeParse(fileName) if !ok { - logger.WithField("last_path_component", path[i+1:]).Warn("bad request with unparseable last path component") + logger.WithField("last_path_component", fileName).Warn("bad request with unparseable last path component") respWr.WriteHeader(http.StatusBadRequest) return } + abs, err := fh.fs.Abs(path) if err != nil { logger.WithError(err).Error("could not get absolute path") diff --git a/go/libraries/doltcore/remotesrv/server.go b/go/libraries/doltcore/remotesrv/server.go index 46b7ec5182f..6b451a63109 100644 --- a/go/libraries/doltcore/remotesrv/server.go +++ b/go/libraries/doltcore/remotesrv/server.go @@ -17,7 +17,6 @@ package remotesrv import ( "context" "crypto/tls" - "errors" "net" "net/http" "strings" @@ -29,7 +28,6 @@ import ( "google.golang.org/grpc" remotesapi "github.com/dolthub/dolt/go/gen/proto/dolt/services/remotesapi/v1alpha1" - "github.com/dolthub/dolt/go/libraries/doltcore/env" "github.com/dolthub/dolt/go/libraries/utils/filesys" ) @@ -80,14 +78,6 @@ func NewServer(args ServerArgs) (*Server, error) { args.Logger = logrus.NewEntry(logrus.StandardLogger()) } - storageMetadata, err := env.GetMultiEnvStorageMetadata(args.FS) - if err != nil { - return nil, err - } - if storageMetadata.ArchiveFilesPresent() { - return nil, errors.New("archive files present. Please run `dolt archive --revert` before running the server.") - } - s := new(Server) s.stopChan = make(chan struct{}) diff --git a/go/libraries/doltcore/remotestorage/chunk_cache.go b/go/libraries/doltcore/remotestorage/chunk_cache.go index 0412b20a0ab..0d1e968844d 100644 --- a/go/libraries/doltcore/remotestorage/chunk_cache.go +++ b/go/libraries/doltcore/remotestorage/chunk_cache.go @@ -22,20 +22,20 @@ import ( // ChunkCache is an interface used for caching chunks type ChunkCache interface { // Put puts a slice of chunks into the cache. - Put(c []nbs.CompressedChunk) bool + Put(c []nbs.ToChunker) bool // Get gets a map of hash to chunk for a set of hashes. In the event that a chunk is not in the cache, chunks.Empty. // is put in it's place - Get(h hash.HashSet) map[hash.Hash]nbs.CompressedChunk + Get(h hash.HashSet) map[hash.Hash]nbs.ToChunker // Has takes a set of hashes and returns the set of hashes that the cache currently does not have in it. Has(h hash.HashSet) (absent hash.HashSet) // PutChunk puts a single chunk in the cache. true returns in the event that the chunk was cached successfully // and false is returned if that chunk is already is the cache. - PutChunk(chunk nbs.CompressedChunk) bool + PutChunk(chunk nbs.ToChunker) bool // GetAndClearChunksToFlush gets a map of hash to chunk which includes all the chunks that were put in the cache // between the last time GetAndClearChunksToFlush was called and now. - GetAndClearChunksToFlush() map[hash.Hash]nbs.CompressedChunk + GetAndClearChunksToFlush() map[hash.Hash]nbs.ToChunker } diff --git a/go/libraries/doltcore/remotestorage/chunk_fetcher.go b/go/libraries/doltcore/remotestorage/chunk_fetcher.go index 51bd4bac614..91c7ef835f0 100644 --- a/go/libraries/doltcore/remotestorage/chunk_fetcher.go +++ b/go/libraries/doltcore/remotestorage/chunk_fetcher.go @@ -48,8 +48,14 @@ type ChunkFetcher struct { eg *errgroup.Group egCtx context.Context + // toGetCh is the channel used to request chunks. This will be initially given a root, + // and as refs are found, they will be added to the channel for workers to batch and request. NM4. toGetCh chan hash.HashSet - resCh chan nbs.CompressedChunk + + // resCh is the results channel for the fetcher. It is used both to return + // chunks themselves, and to indicate which chunks were requested but missing + // buy having a Hash, but are empty. NM4. + resCh chan nbs.ToChunker abortCh chan struct{} stats StatsRecorder @@ -69,7 +75,7 @@ func NewChunkFetcher(ctx context.Context, dcs *DoltChunkStore) *ChunkFetcher { egCtx: ctx, toGetCh: make(chan hash.HashSet), - resCh: make(chan nbs.CompressedChunk), + resCh: make(chan nbs.ToChunker), abortCh: make(chan struct{}), stats: StatsFactory(), @@ -123,7 +129,7 @@ func (f *ChunkFetcher) CloseSend() error { // by |Get|. Returns |io.EOF| after |CloseSend| is called and all requested // chunks have been successfully received. Returns an error if this // |ChunkFetcher| is terminally failed or if the supplied |ctx| is |Done|. -func (f *ChunkFetcher) Recv(ctx context.Context) (nbs.CompressedChunk, error) { +func (f *ChunkFetcher) Recv(ctx context.Context) (nbs.ToChunker, error) { select { case <-ctx.Done(): return nbs.CompressedChunk{}, context.Cause(ctx) @@ -219,7 +225,7 @@ func fetcherHashSetToGetDlLocsReqsThread(ctx context.Context, reqCh chan hash.Ha // delivered in |reqCh|, and they will be delivered in order. // // This function handles backoff and retries for the underlying streaming RPC. -func fetcherRPCDownloadLocsThread(ctx context.Context, reqCh chan *remotesapi.GetDownloadLocsRequest, resCh chan []*remotesapi.DownloadLoc, client remotesapi.ChunkStoreServiceClient, storeRepoToken func(string), missingChunkCh chan nbs.CompressedChunk, host string) error { +func fetcherRPCDownloadLocsThread(ctx context.Context, reqCh chan *remotesapi.GetDownloadLocsRequest, resCh chan []*remotesapi.DownloadLoc, client remotesapi.ChunkStoreServiceClient, storeRepoToken func(string), missingChunkCh chan nbs.ToChunker, host string) error { stream, err := reliable.MakeCall[*remotesapi.GetDownloadLocsRequest, *remotesapi.GetDownloadLocsResponse]( ctx, reliable.CallOptions[*remotesapi.GetDownloadLocsRequest, *remotesapi.GetDownloadLocsResponse]{ @@ -255,6 +261,7 @@ func fetcherRPCDownloadLocsThread(ctx context.Context, reqCh chan *remotesapi.Ge }) eg.Go(func() error { for { + // NM4 - Where there responses come back - resp is an rpc struct. NM4. resp, err := stream.Recv() if err == io.EOF { close(resCh) @@ -300,6 +307,7 @@ func getMissingChunks(req *remotesapi.GetDownloadLocsRequest, resp *remotesapi.G numRequested := len(req.ChunkHashes) numResponded := 0 for _, loc := range resp.Locs { + // NM4 - Looky here. hgr := loc.Location.(*remotesapi.DownloadLoc_HttpGetRange).HttpGetRange numResponded += len(hgr.Ranges) } @@ -362,6 +370,7 @@ func (d downloads) Add(resp *remotesapi.DownloadLoc) { d.refreshes[path] = refresh } for _, r := range gr.Ranges { + // NM4 - this is where the offset is read!! do something here or nearby. d.ranges.Insert(gr.Url, r.Hash, r.Offset, r.Length) } } @@ -527,7 +536,7 @@ func (cc *ConcurrencyControl) Run(ctx context.Context, done <-chan struct{}, ss } } -func fetcherDownloadURLThreads(ctx context.Context, fetchReqCh chan fetchReq, doneCh chan struct{}, chunkCh chan nbs.CompressedChunk, client remotesapi.ChunkStoreServiceClient, stats StatsRecorder, fetcher HTTPFetcher, params NetworkRequestParams) error { +func fetcherDownloadURLThreads(ctx context.Context, fetchReqCh chan fetchReq, doneCh chan struct{}, chunkCh chan nbs.ToChunker, client remotesapi.ChunkStoreServiceClient, stats StatsRecorder, fetcher HTTPFetcher, params NetworkRequestParams) error { eg, ctx := errgroup.WithContext(ctx) cc := &ConcurrencyControl{ MaxConcurrency: params.MaximumConcurrentDownloads, @@ -559,7 +568,7 @@ func fetcherDownloadURLThreads(ctx context.Context, fetchReqCh chan fetchReq, do return nil } -func fetcherDownloadURLThread(ctx context.Context, fetchReqCh chan fetchReq, doneCh <-chan struct{}, chunkCh chan nbs.CompressedChunk, client remotesapi.ChunkStoreServiceClient, stats StatsRecorder, health reliable.HealthRecorder, fetcher HTTPFetcher, params NetworkRequestParams) error { +func fetcherDownloadURLThread(ctx context.Context, fetchReqCh chan fetchReq, doneCh <-chan struct{}, chunkCh chan nbs.ToChunker, client remotesapi.ChunkStoreServiceClient, stats StatsRecorder, health reliable.HealthRecorder, fetcher HTTPFetcher, params NetworkRequestParams) error { respCh := make(chan fetchResp) cancelCh := make(chan struct{}) for { diff --git a/go/libraries/doltcore/remotestorage/chunk_store.go b/go/libraries/doltcore/remotestorage/chunk_store.go index c0ca1777995..72241b2d312 100644 --- a/go/libraries/doltcore/remotestorage/chunk_store.go +++ b/go/libraries/doltcore/remotestorage/chunk_store.go @@ -317,7 +317,7 @@ func (dcs *DoltChunkStore) Get(ctx context.Context, h hash.Hash) (chunks.Chunk, func (dcs *DoltChunkStore) GetMany(ctx context.Context, hashes hash.HashSet, found func(context.Context, *chunks.Chunk)) error { ae := atomicerr.New() decompressedSize := uint64(0) - err := dcs.GetManyCompressed(ctx, hashes, func(ctx context.Context, cc nbs.CompressedChunk) { + err := dcs.GetManyCompressed(ctx, hashes, func(ctx context.Context, cc nbs.ToChunker) { if ae.IsSet() { return } @@ -340,7 +340,7 @@ func (dcs *DoltChunkStore) GetMany(ctx context.Context, hashes hash.HashSet, fou // GetMany gets the Chunks with |hashes| from the store. On return, |foundChunks| will have been fully sent all chunks // which have been found. Any non-present chunks will silently be ignored. -func (dcs *DoltChunkStore) GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, nbs.CompressedChunk)) error { +func (dcs *DoltChunkStore) GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, nbs.ToChunker)) error { ctx, span := tracer.Start(ctx, "remotestorage.GetManyCompressed") defer span.End() @@ -353,7 +353,7 @@ func (dcs *DoltChunkStore) GetManyCompressed(ctx context.Context, hashes hash.Ha for h := range hashes { c := hashToChunk[h] - if c.IsEmpty() { + if c == nil || c.IsEmpty() { notCached = append(notCached, h) } else { found(ctx, c) @@ -432,7 +432,7 @@ func sortRangesBySize(ranges []*GetRange) { type resourcePathToUrlFunc func(ctx context.Context, lastError error, resourcePath string) (url string, err error) -func (gr *GetRange) GetDownloadFunc(ctx context.Context, stats StatsRecorder, health reliable.HealthRecorder, fetcher HTTPFetcher, params NetworkRequestParams, chunkChan chan nbs.CompressedChunk, pathToUrl resourcePathToUrlFunc) func() error { +func (gr *GetRange) GetDownloadFunc(ctx context.Context, stats StatsRecorder, health reliable.HealthRecorder, fetcher HTTPFetcher, params NetworkRequestParams, chunkChan chan nbs.ToChunker, pathToUrl resourcePathToUrlFunc) func() error { if len(gr.Ranges) == 0 { return func() error { return nil } } @@ -574,7 +574,7 @@ type RepoRequest interface { SetRepoPath(string) } -func (dcs *DoltChunkStore) readChunksAndCache(ctx context.Context, hashes []hash.Hash, found func(context.Context, nbs.CompressedChunk)) (err error) { +func (dcs *DoltChunkStore) readChunksAndCache(ctx context.Context, hashes []hash.Hash, found func(context.Context, nbs.ToChunker)) (err error) { toSend := hash.NewHashSet(hashes...) fetcher := dcs.ChunkFetcher(ctx) @@ -603,7 +603,7 @@ func (dcs *DoltChunkStore) readChunksAndCache(ctx context.Context, hashes []hash return err } // Don't forward on empty/not found chunks. - if len(cc.CompressedData) > 0 { + if !cc.IsEmpty() { if dcs.cache.PutChunk(cc) { return ErrCacheCapacityExceeded } @@ -644,7 +644,7 @@ func (dcs *DoltChunkStore) HasMany(ctx context.Context, hashes hash.HashSet) (ha hashSl, byteSl := HashSetToSlices(notCached) absent := make(hash.HashSet) - var found []nbs.CompressedChunk + var found []nbs.ToChunker var err error batchItr(len(hashSl), maxHasManyBatchSize, func(st, end int) (stop bool) { @@ -738,7 +738,7 @@ func (dcs *DoltChunkStore) Put(ctx context.Context, c chunks.Chunk, getAddrs chu } cc := nbs.ChunkToCompressedChunk(c) - if dcs.cache.Put([]nbs.CompressedChunk{cc}) { + if dcs.cache.Put([]nbs.ToChunker{cc}) { return ErrCacheCapacityExceeded } return nil diff --git a/go/libraries/doltcore/remotestorage/map_chunk_cache.go b/go/libraries/doltcore/remotestorage/map_chunk_cache.go index ea5dad323ef..64a0fcf6e6e 100644 --- a/go/libraries/doltcore/remotestorage/map_chunk_cache.go +++ b/go/libraries/doltcore/remotestorage/map_chunk_cache.go @@ -24,16 +24,16 @@ import ( // mapChunkCache is a ChunkCache implementation that stores everything in an in memory map. type mapChunkCache struct { mu *sync.Mutex - hashToChunk map[hash.Hash]nbs.CompressedChunk - toFlush map[hash.Hash]nbs.CompressedChunk + hashToChunk map[hash.Hash]nbs.ToChunker + toFlush map[hash.Hash]nbs.ToChunker cm CapacityMonitor } func newMapChunkCache() *mapChunkCache { return &mapChunkCache{ &sync.Mutex{}, - make(map[hash.Hash]nbs.CompressedChunk), - make(map[hash.Hash]nbs.CompressedChunk), + make(map[hash.Hash]nbs.ToChunker), + make(map[hash.Hash]nbs.ToChunker), NewUncappedCapacityMonitor(), } } @@ -42,14 +42,14 @@ func newMapChunkCache() *mapChunkCache { func NewMapChunkCacheWithMaxCapacity(maxCapacity int64) *mapChunkCache { return &mapChunkCache{ &sync.Mutex{}, - make(map[hash.Hash]nbs.CompressedChunk), - make(map[hash.Hash]nbs.CompressedChunk), + make(map[hash.Hash]nbs.ToChunker), + make(map[hash.Hash]nbs.ToChunker), NewFixedCapacityMonitor(maxCapacity), } } // Put puts a slice of chunks into the cache. -func (mcc *mapChunkCache) Put(chnks []nbs.CompressedChunk) bool { +func (mcc *mapChunkCache) Put(chnks []nbs.ToChunker) bool { mcc.mu.Lock() defer mcc.mu.Unlock() @@ -63,7 +63,7 @@ func (mcc *mapChunkCache) Put(chnks []nbs.CompressedChunk) bool { } } - if mcc.cm.CapacityExceeded(len(c.FullCompressedChunk)) { + if mcc.cm.CapacityExceeded(int(c.FullCompressedChunkLen())) { return true } @@ -79,8 +79,8 @@ func (mcc *mapChunkCache) Put(chnks []nbs.CompressedChunk) bool { // Get gets a map of hash to chunk for a set of hashes. In the event that a chunk is not in the cache, chunks.Empty. // is put in it's place -func (mcc *mapChunkCache) Get(hashes hash.HashSet) map[hash.Hash]nbs.CompressedChunk { - hashToChunk := make(map[hash.Hash]nbs.CompressedChunk) +func (mcc *mapChunkCache) Get(hashes hash.HashSet) map[hash.Hash]nbs.ToChunker { + hashToChunk := make(map[hash.Hash]nbs.ToChunker) mcc.mu.Lock() defer mcc.mu.Unlock() @@ -112,13 +112,13 @@ func (mcc *mapChunkCache) Has(hashes hash.HashSet) (absent hash.HashSet) { return absent } -func (mcc *mapChunkCache) PutChunk(ch nbs.CompressedChunk) bool { +func (mcc *mapChunkCache) PutChunk(ch nbs.ToChunker) bool { mcc.mu.Lock() defer mcc.mu.Unlock() h := ch.Hash() if existing, ok := mcc.hashToChunk[h]; !ok || existing.IsEmpty() { - if mcc.cm.CapacityExceeded(len(ch.FullCompressedChunk)) { + if mcc.cm.CapacityExceeded(int(ch.FullCompressedChunkLen())) { return true } mcc.hashToChunk[h] = ch @@ -130,8 +130,8 @@ func (mcc *mapChunkCache) PutChunk(ch nbs.CompressedChunk) bool { // GetAndClearChunksToFlush gets a map of hash to chunk which includes all the chunks that were put in the cache // between the last time GetAndClearChunksToFlush was called and now. -func (mcc *mapChunkCache) GetAndClearChunksToFlush() map[hash.Hash]nbs.CompressedChunk { - newToFlush := make(map[hash.Hash]nbs.CompressedChunk) +func (mcc *mapChunkCache) GetAndClearChunksToFlush() map[hash.Hash]nbs.ToChunker { + newToFlush := make(map[hash.Hash]nbs.ToChunker) mcc.mu.Lock() defer mcc.mu.Unlock() diff --git a/go/libraries/doltcore/remotestorage/map_chunk_cache_test.go b/go/libraries/doltcore/remotestorage/map_chunk_cache_test.go index 6944eb98c35..8cb5e118d1c 100644 --- a/go/libraries/doltcore/remotestorage/map_chunk_cache_test.go +++ b/go/libraries/doltcore/remotestorage/map_chunk_cache_test.go @@ -27,8 +27,8 @@ import ( "github.com/dolthub/dolt/go/store/nbs" ) -func genRandomChunks(rng *rand.Rand, n int) (hash.HashSet, []nbs.CompressedChunk) { - chks := make([]nbs.CompressedChunk, n) +func genRandomChunks(rng *rand.Rand, n int) (hash.HashSet, []nbs.ToChunker) { + chks := make([]nbs.ToChunker, n) hashes := make(hash.HashSet) for i := 0; i < n; i++ { size := int(rng.Int31n(99) + 1) @@ -88,7 +88,7 @@ func TestMapChunkCache(t *testing.T) { toFlush = mapChunkCache.GetAndClearChunksToFlush() - expected := map[hash.Hash]nbs.CompressedChunk{moreChks[0].Hash(): moreChks[0]} + expected := map[hash.Hash]nbs.ToChunker{moreChks[0].Hash(): moreChks[0]} eq := reflect.DeepEqual(toFlush, expected) assert.True(t, eq, "Missing or unexpected chunks to flush (seed %d)", seed) } diff --git a/go/libraries/doltcore/remotestorage/noop_chunk_cache.go b/go/libraries/doltcore/remotestorage/noop_chunk_cache.go index 8edf589c31b..6b86aa11188 100644 --- a/go/libraries/doltcore/remotestorage/noop_chunk_cache.go +++ b/go/libraries/doltcore/remotestorage/noop_chunk_cache.go @@ -29,22 +29,22 @@ var noopChunkCache = &noopChunkCacheImpl{} type noopChunkCacheImpl struct { } -func (*noopChunkCacheImpl) Put(chnks []nbs.CompressedChunk) bool { +func (*noopChunkCacheImpl) Put(chnks []nbs.ToChunker) bool { return false } -func (*noopChunkCacheImpl) Get(hashes hash.HashSet) map[hash.Hash]nbs.CompressedChunk { - return make(map[hash.Hash]nbs.CompressedChunk) +func (*noopChunkCacheImpl) Get(hashes hash.HashSet) map[hash.Hash]nbs.ToChunker { + return make(map[hash.Hash]nbs.ToChunker) } func (*noopChunkCacheImpl) Has(hashes hash.HashSet) (absent hash.HashSet) { return hashes } -func (*noopChunkCacheImpl) PutChunk(ch nbs.CompressedChunk) bool { +func (*noopChunkCacheImpl) PutChunk(ch nbs.ToChunker) bool { return false } -func (*noopChunkCacheImpl) GetAndClearChunksToFlush() map[hash.Hash]nbs.CompressedChunk { +func (*noopChunkCacheImpl) GetAndClearChunksToFlush() map[hash.Hash]nbs.ToChunker { panic("noopChunkCache does not support GetAndClearChunksToFlush().") } diff --git a/go/store/cmd/noms/noms_manifest.go b/go/store/cmd/noms/noms_manifest.go index 4ece88cb030..1f979ef64c3 100644 --- a/go/store/cmd/noms/noms_manifest.go +++ b/go/store/cmd/noms/noms_manifest.go @@ -103,7 +103,7 @@ func runManifest(ctx context.Context, args []string) int { nbsFiles := make([]NbsFile, numSpecs) for i := 0; i < numSpecs; i++ { tableSpecInfo := manifest.GetTableSpecInfo(i) - path := filepath.Join(spec.DatabaseName, tableSpecInfo.GetName()) + path := filepath.Join(spec.DatabaseName, tableSpecInfo.GetFileName()) fileInfo, err := os.Stat(path) nbsFiles[i] = NbsFile{tableSpecInfo, fileInfo, err} } @@ -130,7 +130,7 @@ func runManifest(ctx context.Context, args []string) int { fmt.Println(" referenced nbs files:") for _, nbsFile := range nbsFiles { - name := nbsFile.manifestSpec.GetName() + name := nbsFile.manifestSpec.GetFileName() chunkCnt := nbsFile.manifestSpec.GetChunkCount() sizeStr := nbsFile.sizeStr() existsStr := nbsFile.fileInfoErr == nil diff --git a/go/store/datas/pull/clone.go b/go/store/datas/pull/clone.go index 9cad9f5e514..a1cae4e9df2 100644 --- a/go/store/datas/pull/clone.go +++ b/go/store/datas/pull/clone.go @@ -19,6 +19,7 @@ import ( "errors" "fmt" "io" + "strings" "github.com/cenkalti/backoff/v4" "golang.org/x/sync/errgroup" @@ -81,9 +82,14 @@ func mapTableFiles(tblFiles []chunks.TableFile) ([]string, map[string]chunks.Tab fileIDtoNumChunks := make(map[string]int) for i, tblFile := range tblFiles { - fileIDtoTblFile[tblFile.FileID()] = tblFile - fileIds[i] = tblFile.FileID() - fileIDtoNumChunks[tblFile.FileID()] = tblFile.NumChunks() + fileId := tblFile.FileID() + if strings.HasSuffix(fileId, ".darc") { + fileId = fileId[:len(fileId)-5] // NM4. + } + + fileIDtoTblFile[fileId] = tblFile + fileIds[i] = fileId + fileIDtoNumChunks[fileId] = tblFile.NumChunks() } return fileIds, fileIDtoTblFile, fileIDtoNumChunks diff --git a/go/store/datas/pull/pull_chunk_fetcher.go b/go/store/datas/pull/pull_chunk_fetcher.go index 2e0d58a0f87..3d2c6d556aa 100644 --- a/go/store/datas/pull/pull_chunk_fetcher.go +++ b/go/store/datas/pull/pull_chunk_fetcher.go @@ -26,7 +26,7 @@ import ( ) type GetManyer interface { - GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, nbs.CompressedChunk)) error + GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, nbs.ToChunker)) error } type ChunkFetcherable interface { @@ -52,7 +52,7 @@ type PullChunkFetcher struct { batchCh chan hash.HashSet doneCh chan struct{} - resCh chan nbs.CompressedChunk + resCh chan nbs.ToChunker } func NewPullChunkFetcher(ctx context.Context, getter GetManyer) *PullChunkFetcher { @@ -63,7 +63,7 @@ func NewPullChunkFetcher(ctx context.Context, getter GetManyer) *PullChunkFetche getter: getter, batchCh: make(chan hash.HashSet), doneCh: make(chan struct{}), - resCh: make(chan nbs.CompressedChunk), + resCh: make(chan nbs.ToChunker), } ret.eg.Go(func() error { return ret.fetcherThread(func() { @@ -86,9 +86,9 @@ func (f *PullChunkFetcher) fetcherThread(finalize func()) error { missing := batch.Copy() // Blocking get, no concurrency, only one fetcher. - err := f.getter.GetManyCompressed(f.ctx, batch, func(ctx context.Context, chk nbs.CompressedChunk) { + err := f.getter.GetManyCompressed(f.ctx, batch, func(ctx context.Context, chk nbs.ToChunker) { mu.Lock() - missing.Remove(chk.H) + missing.Remove(chk.Hash()) mu.Unlock() select { case <-ctx.Done(): @@ -139,7 +139,7 @@ func (f *PullChunkFetcher) Close() error { return f.eg.Wait() } -func (f *PullChunkFetcher) Recv(ctx context.Context) (nbs.CompressedChunk, error) { +func (f *PullChunkFetcher) Recv(ctx context.Context) (nbs.ToChunker, error) { select { case res, ok := <-f.resCh: if !ok { diff --git a/go/store/datas/pull/pull_chunk_fetcher_test.go b/go/store/datas/pull/pull_chunk_fetcher_test.go index 2fa3bd4e187..f2975efb679 100644 --- a/go/store/datas/pull/pull_chunk_fetcher_test.go +++ b/go/store/datas/pull/pull_chunk_fetcher_test.go @@ -70,8 +70,12 @@ func TestPullChunkFetcher(t *testing.T) { defer wg.Done() cmp, err := f.Recv(context.Background()) assert.NoError(t, err) - assert.Equal(t, cmp.H, gm.C.H) - assert.Equal(t, cmp.FullCompressedChunk, gm.C.FullCompressedChunk) + assert.Equal(t, cmp.Hash(), gm.C.H) + + cc, ok := cmp.(nbs.CompressedChunk) + assert.True(t, ok) + + assert.Equal(t, cc.FullCompressedChunk, gm.C.FullCompressedChunk) _, err = f.Recv(context.Background()) assert.ErrorIs(t, err, io.EOF) assert.NoError(t, f.Close()) @@ -92,8 +96,11 @@ func TestPullChunkFetcher(t *testing.T) { defer wg.Done() cmp, err := f.Recv(context.Background()) assert.NoError(t, err) - assert.Equal(t, cmp.H, h) - assert.Nil(t, cmp.FullCompressedChunk) + assert.Equal(t, cmp.Hash(), h) + + cc, ok := cmp.(nbs.CompressedChunk) + assert.True(t, ok) + assert.Nil(t, cc.FullCompressedChunk) _, err = f.Recv(context.Background()) assert.ErrorIs(t, err, io.EOF) assert.NoError(t, f.Close()) @@ -136,7 +143,7 @@ func TestPullChunkFetcher(t *testing.T) { type emptyGetManyer struct { } -func (emptyGetManyer) GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, nbs.CompressedChunk)) error { +func (emptyGetManyer) GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, nbs.ToChunker)) error { return nil } @@ -144,7 +151,7 @@ type deliveringGetManyer struct { C nbs.CompressedChunk } -func (d deliveringGetManyer) GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, nbs.CompressedChunk)) error { +func (d deliveringGetManyer) GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, nbs.ToChunker)) error { for _ = range hashes { found(ctx, d.C) } @@ -155,7 +162,7 @@ type blockingGetManyer struct { block chan struct{} } -func (b blockingGetManyer) GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, nbs.CompressedChunk)) error { +func (b blockingGetManyer) GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, nbs.ToChunker)) error { <-b.block return nil } @@ -165,6 +172,6 @@ type errorGetManyer struct { var getManyerErr = fmt.Errorf("always return an error") -func (errorGetManyer) GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, nbs.CompressedChunk)) error { +func (errorGetManyer) GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, nbs.ToChunker)) error { return getManyerErr } diff --git a/go/store/datas/pull/puller.go b/go/store/datas/pull/puller.go index 9401b58d7e6..3e6a277c3e6 100644 --- a/go/store/datas/pull/puller.go +++ b/go/store/datas/pull/puller.go @@ -346,11 +346,11 @@ func (p *Puller) Pull(ctx context.Context) error { if cChk.IsGhost() { return fmt.Errorf("attempted to push or pull ghost chunk: %w", nbs.ErrGhostChunkRequested) } - if len(cChk.FullCompressedChunk) == 0 { + if cChk.FullCompressedChunkLen() == 0 { return errors.New("failed to get all chunks.") } - atomic.AddUint64(&p.stats.fetchedSourceBytes, uint64(len(cChk.FullCompressedChunk))) + atomic.AddUint64(&p.stats.fetchedSourceBytes, uint64(cChk.FullCompressedChunkLen())) atomic.AddUint64(&p.stats.fetchedSourceChunks, uint64(1)) chnk, err := cChk.ToChunk() @@ -366,9 +366,13 @@ func (p *Puller) Pull(ctx context.Context) error { } tracker.TickProcessed() - err = p.wr.AddCompressedChunk(ctx, cChk) - if err != nil { - return err + if compressedChunk, ok := cChk.(nbs.CompressedChunk); ok { + err = p.wr.AddCompressedChunk(ctx, compressedChunk) + if err != nil { + return err + } + } else { + panic("TODO: handle ZStd-CompressedChunk") // NM4. } } }) diff --git a/go/store/nbs/archive_build.go b/go/store/nbs/archive_build.go index 72f15d94f04..a79a6a50891 100644 --- a/go/store/nbs/archive_build.go +++ b/go/store/nbs/archive_build.go @@ -99,8 +99,8 @@ func UnArchive(ctx context.Context, cs chunks.ChunkStore, smd StorageMetadata, p specs, err := gs.oldGen.tables.toSpecs() newSpecs := make([]tableSpec, 0, len(specs)) for _, spec := range specs { - if newSpec, exists := swapMap[spec.name]; exists { - newSpecs = append(newSpecs, tableSpec{newSpec, spec.chunkCount}) + if newSpec, exists := swapMap[spec.hash]; exists { + newSpecs = append(newSpecs, tableSpec{typeNoms, newSpec, spec.chunkCount}) } else { newSpecs = append(newSpecs, spec) } @@ -169,8 +169,8 @@ func BuildArchive(ctx context.Context, cs chunks.ChunkStore, dagGroups *ChunkRel specs, err := gs.oldGen.tables.toSpecs() newSpecs := make([]tableSpec, 0, len(specs)) for _, spec := range specs { - if newSpec, exists := swapMap[spec.name]; exists { - newSpecs = append(newSpecs, tableSpec{newSpec, spec.chunkCount}) + if newSpec, exists := swapMap[spec.hash]; exists { + newSpecs = append(newSpecs, tableSpec{typeArchive, newSpec, spec.chunkCount}) } else { newSpecs = append(newSpecs, spec) } diff --git a/go/store/nbs/archive_chunk_source.go b/go/store/nbs/archive_chunk_source.go index 3ccd0183c57..24c9d37380d 100644 --- a/go/store/nbs/archive_chunk_source.go +++ b/go/store/nbs/archive_chunk_source.go @@ -120,6 +120,10 @@ func (acs archiveChunkSource) hash() hash.Hash { return acs.aRdr.footer.hash } +func (acs archiveChunkSource) name() string { + return acs.hash().String() + ".darc" // NM4 - second time this const is defined. Fix! +} + func (acs archiveChunkSource) currentSize() uint64 { return acs.aRdr.footer.fileSize } @@ -146,12 +150,37 @@ func (acs archiveChunkSource) clone() (chunkSource, error) { return archiveChunkSource{acs.file, rdr}, nil } -func (acs archiveChunkSource) getRecordRanges(_ context.Context, _ []getRecord) (map[hash.Hash]Range, error) { - return nil, errors.New("Archive chunk source does not support getRecordRanges") +func (acs archiveChunkSource) getRecordRanges(_ context.Context, requests []getRecord) (map[hash.Hash]Range, error) { + result := make(map[hash.Hash]Range, len(requests)) + for _, req := range requests { + hAddr := *req.a + if acs.aRdr.has(hAddr) { + idx := acs.aRdr.search(hAddr) + if idx < 0 { + // Chunk not found. + continue + } + + dictId, dataId := acs.aRdr.getChunkRef(idx) + dataSpan := acs.aRdr.getByteSpanByID(dataId) + dictSpan := acs.aRdr.getByteSpanByID(dictId) + + rng := Range{ + Offset: dataSpan.offset, + Length: uint32(dataSpan.length), + DictOffset: dictSpan.offset, + DictLength: uint32(dictSpan.length), + } + + result[hAddr] = rng + } + } + return result, nil } -func (acs archiveChunkSource) getManyCompressed(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, CompressedChunk), stats *Stats) (bool, error) { +func (acs archiveChunkSource) getManyCompressed(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, ToChunker), stats *Stats) (bool, error) { return acs.getMany(ctx, eg, reqs, func(ctx context.Context, chk *chunks.Chunk) { + // NM4 - UPDATE. this is def wrong. Not sure why I did this! found(ctx, ChunkToCompressedChunk(*chk)) }, stats) } diff --git a/go/store/nbs/archive_test.go b/go/store/nbs/archive_test.go index da3c324cf2a..195ee19f8e8 100644 --- a/go/store/nbs/archive_test.go +++ b/go/store/nbs/archive_test.go @@ -676,7 +676,7 @@ func (tcs *testChunkSource) getMany(ctx context.Context, eg *errgroup.Group, req panic("never used") } -func (tcs *testChunkSource) getManyCompressed(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, CompressedChunk), stats *Stats) (bool, error) { +func (tcs *testChunkSource) getManyCompressed(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, ToChunker), stats *Stats) (bool, error) { panic("never used") } @@ -696,6 +696,10 @@ func (tcs *testChunkSource) hash() hash.Hash { panic("never used") } +func (tcs *testChunkSource) name() string { + panic("never used") +} + func (tcs *testChunkSource) reader(ctx context.Context) (io.ReadCloser, uint64, error) { panic("never used") } diff --git a/go/store/nbs/chunk_fetcher.go b/go/store/nbs/chunk_fetcher.go index 2be1a0aa78d..8b4aae88a45 100644 --- a/go/store/nbs/chunk_fetcher.go +++ b/go/store/nbs/chunk_fetcher.go @@ -46,7 +46,7 @@ type ChunkFetcher interface { CloseSend() error - Recv(context.Context) (CompressedChunk, error) + Recv(context.Context) (ToChunker, error) Close() error } diff --git a/go/store/nbs/chunk_source_adapter.go b/go/store/nbs/chunk_source_adapter.go index db1eb72fd65..45718f5724e 100644 --- a/go/store/nbs/chunk_source_adapter.go +++ b/go/store/nbs/chunk_source_adapter.go @@ -30,6 +30,10 @@ func (csa chunkSourceAdapter) hash() hash.Hash { return csa.h } +func (csa chunkSourceAdapter) name() string { + return csa.h.String() +} + func newReaderFromIndexData(ctx context.Context, q MemoryQuotaProvider, idxData []byte, name hash.Hash, tra tableReaderAt, blockSize uint64) (cs chunkSource, err error) { index, err := parseTableIndexByCopy(ctx, idxData, q) if err != nil { diff --git a/go/store/nbs/cmp_chunk_table_writer.go b/go/store/nbs/cmp_chunk_table_writer.go index 905154463ea..38f66339bf3 100644 --- a/go/store/nbs/cmp_chunk_table_writer.go +++ b/go/store/nbs/cmp_chunk_table_writer.go @@ -75,17 +75,22 @@ func (tw *CmpChunkTableWriter) GetMD5() []byte { } // AddCmpChunk adds a compressed chunk -func (tw *CmpChunkTableWriter) AddCmpChunk(c CompressedChunk) error { - if c.IsGhost() { +func (tw *CmpChunkTableWriter) AddCmpChunk(tc ToChunker) error { + if tc.IsGhost() { // Ghost chunks cannot be written to a table file. They should // always be filtered by the write processes before landing // here. return ErrGhostChunkRequested } - if len(c.CompressedData) == 0 { + if tc.IsEmpty() { panic("NBS blocks cannot be zero length") } + c, ok := tc.(CompressedChunk) + if !ok { + panic("Require a CompressedChunk") // NM4 + } + uncmpLen, err := snappy.DecodedLen(c.CompressedData) if err != nil { diff --git a/go/store/nbs/cmp_chunk_table_writer_test.go b/go/store/nbs/cmp_chunk_table_writer_test.go index 170cc43cb64..0d2e9b9a7e7 100644 --- a/go/store/nbs/cmp_chunk_table_writer_test.go +++ b/go/store/nbs/cmp_chunk_table_writer_test.go @@ -48,10 +48,10 @@ func TestCmpChunkTableWriter(t *testing.T) { } reqs := toGetRecords(hashes) - found := make([]CompressedChunk, 0) + found := make([]ToChunker, 0) eg, egCtx := errgroup.WithContext(ctx) - _, err = tr.getManyCompressed(egCtx, eg, reqs, func(ctx context.Context, c CompressedChunk) { found = append(found, c) }, &Stats{}) + _, err = tr.getManyCompressed(egCtx, eg, reqs, func(ctx context.Context, c ToChunker) { found = append(found, c) }, &Stats{}) require.NoError(t, err) require.NoError(t, eg.Wait()) diff --git a/go/store/nbs/conjoiner.go b/go/store/nbs/conjoiner.go index ad2a12ac61f..0721a49a65f 100644 --- a/go/store/nbs/conjoiner.go +++ b/go/store/nbs/conjoiner.go @@ -162,7 +162,7 @@ func conjoin(ctx context.Context, s conjoinStrategy, upstream manifestContents, return upstream, func() {}, nil } for i := range upstream.appendix { - if upstream.appendix[i].name != appendixSpecs[i].name { + if upstream.appendix[i].hash != appendixSpecs[i].hash { return upstream, func() {}, nil } } @@ -176,19 +176,19 @@ func conjoin(ctx context.Context, s conjoinStrategy, upstream manifestContents, conjoineeSet := map[hash.Hash]struct{}{} upstreamNames := map[hash.Hash]struct{}{} for _, spec := range upstream.specs { - upstreamNames[spec.name] = struct{}{} + upstreamNames[spec.hash] = struct{}{} } for _, c := range conjoinees { - if _, present := upstreamNames[c.name]; !present { + if _, present := upstreamNames[c.hash]; !present { return upstream, func() {}, nil // Bail! } - conjoineeSet[c.name] = struct{}{} + conjoineeSet[c.hash] = struct{}{} } // Filter conjoinees out of upstream.specs to generate new set of keepers keepers = make([]tableSpec, 0, len(upstream.specs)-len(conjoinees)) for _, spec := range upstream.specs { - if _, present := conjoineeSet[spec.name]; !present { + if _, present := conjoineeSet[spec.hash]; !present { keepers = append(keepers, spec) } } @@ -202,7 +202,7 @@ func conjoinTables(ctx context.Context, conjoinees []tableSpec, p tablePersister for idx := range conjoinees { i, spec := idx, conjoinees[idx] eg.Go(func() (err error) { - toConjoin[i], err = p.Open(ectx, spec.name, spec.chunkCount, stats) + toConjoin[i], err = p.Open(ectx, spec.hash, spec.chunkCount, stats) return }) } @@ -240,7 +240,7 @@ func conjoinTables(ctx context.Context, conjoinees []tableSpec, p tablePersister if err != nil { return tableSpec{}, nil, err } - return tableSpec{h, cnt}, cleanup, nil + return tableSpec{typeNoms, h, cnt}, cleanup, nil } func toSpecs(srcs chunkSources) ([]tableSpec, error) { @@ -258,7 +258,7 @@ func toSpecs(srcs chunkSources) ([]tableSpec, error) { if err != nil { return nil, err } - specs[i] = tableSpec{h, cnt} + specs[i] = tableSpec{typeNoms, h, cnt} } return specs, nil diff --git a/go/store/nbs/conjoiner_test.go b/go/store/nbs/conjoiner_test.go index 846aa4c7f4a..88941f8bcde 100644 --- a/go/store/nbs/conjoiner_test.go +++ b/go/store/nbs/conjoiner_test.go @@ -42,7 +42,7 @@ func (ts tableSpecsByAscendingCount) Len() int { return len(ts) } func (ts tableSpecsByAscendingCount) Less(i, j int) bool { tsI, tsJ := ts[i], ts[j] if tsI.chunkCount == tsJ.chunkCount { - return bytes.Compare(tsI.name[:], tsJ.name[:]) < 0 + return bytes.Compare(tsI.hash[:], tsJ.hash[:]) < 0 } return tsI.chunkCount < tsJ.chunkCount } @@ -76,7 +76,7 @@ func makeTestSrcs(t *testing.T, tableSizes []uint32, p tablePersister) (srcs chu // Makes a tableSet with len(tableSizes) upstream tables containing tableSizes[N] unique chunks func makeTestTableSpecs(t *testing.T, tableSizes []uint32, p tablePersister) (specs []tableSpec) { for _, src := range makeTestSrcs(t, tableSizes, p) { - specs = append(specs, tableSpec{src.hash(), mustUint32(src.count())}) + specs = append(specs, tableSpec{typeNoms, src.hash(), mustUint32(src.count())}) err := src.close() require.NoError(t, err) } @@ -134,7 +134,7 @@ func testConjoin(t *testing.T, factory func(t *testing.T) tablePersister) { assertContainAll := func(t *testing.T, p tablePersister, expect, actual []tableSpec) { open := func(specs []tableSpec) (sources chunkSources) { for _, sp := range specs { - cs, err := p.Open(context.Background(), sp.name, sp.chunkCount, stats) + cs, err := p.Open(context.Background(), sp.hash, sp.chunkCount, stats) if err != nil { require.NoError(t, err) } @@ -183,7 +183,7 @@ func testConjoin(t *testing.T, factory func(t *testing.T) tablePersister) { src, err := p.Persist(context.Background(), mt, nil, &Stats{}) require.NoError(t, err) defer src.close() - return tableSpec{src.hash(), mustUint32(src.count())} + return tableSpec{typeNoms, src.hash(), mustUint32(src.count())} } tc := []struct { diff --git a/go/store/nbs/dynamo_manifest_test.go b/go/store/nbs/dynamo_manifest_test.go index e682c35c7be..1c1ba194156 100644 --- a/go/store/nbs/dynamo_manifest_test.go +++ b/go/store/nbs/dynamo_manifest_test.go @@ -68,13 +68,13 @@ func TestDynamoManifestParseIfExists(t *testing.T) { assert.Equal(newLock, contents.lock) assert.Equal(newRoot, contents.root) if assert.Len(contents.appendix, 1) { - assert.Equal(tableName.String(), contents.specs[0].name.String()) + assert.Equal(tableName.String(), contents.specs[0].hash.String()) assert.Equal(uint32(0), contents.specs[0].chunkCount) - assert.Equal(tableName.String(), contents.appendix[0].name.String()) + assert.Equal(tableName.String(), contents.appendix[0].hash.String()) assert.Equal(uint32(0), contents.appendix[0].chunkCount) } if assert.Len(contents.specs, 2) { - assert.Equal(tableName.String(), contents.specs[1].name.String()) + assert.Equal(tableName.String(), contents.specs[1].hash.String()) assert.Equal(uint32(0), contents.specs[1].chunkCount) } } @@ -109,7 +109,7 @@ func TestDynamoManifestUpdate(t *testing.T) { stats := &Stats{} // First, test winning the race against another process. - contents := makeContents("locker", "nuroot", []tableSpec{{computeAddr([]byte("a")), 3}}, nil) + contents := makeContents("locker", "nuroot", []tableSpec{{typeNoms, computeAddr([]byte("a")), 3}}, nil) upstream, err := mm.Update(context.Background(), hash.Hash{}, contents, stats, func() error { // This should fail to get the lock, and therefore _not_ clobber the manifest. So the Update should succeed. lock := computeAddr([]byte("nolock")) @@ -145,7 +145,7 @@ func TestDynamoManifestUpdate(t *testing.T) { require.NoError(t, err) assert.Equal(jerkLock, upstream.lock) assert.Equal(rejected.root, upstream.root) - assert.Equal([]tableSpec{{tableName, 1}}, upstream.specs) + assert.Equal([]tableSpec{{typeNoms, tableName, 1}}, upstream.specs) } func TestDynamoManifestUpdateAppendix(t *testing.T) { @@ -155,11 +155,11 @@ func TestDynamoManifestUpdateAppendix(t *testing.T) { // First, test winning the race against another process. specs := []tableSpec{ - {computeAddr([]byte("app-a")), 3}, - {computeAddr([]byte("a")), 3}, + {typeNoms, computeAddr([]byte("app-a")), 3}, + {typeNoms, computeAddr([]byte("a")), 3}, } - app := []tableSpec{{computeAddr([]byte("app-a")), 3}} + app := []tableSpec{{typeNoms, computeAddr([]byte("app-a")), 3}} contents := makeContents("locker", "nuroot", specs, app) upstream, err := mm.Update(context.Background(), hash.Hash{}, contents, stats, func() error { @@ -204,8 +204,8 @@ func TestDynamoManifestUpdateAppendix(t *testing.T) { require.NoError(t, err) assert.Equal(jerkLock, upstream.lock) assert.Equal(rejected.root, upstream.root) - assert.Equal([]tableSpec{{appTableName, 1}, {tableName, 1}}, upstream.specs) - assert.Equal([]tableSpec{{appTableName, 1}}, upstream.appendix) + assert.Equal([]tableSpec{{typeNoms, appTableName, 1}, {typeNoms, tableName, 1}}, upstream.specs) + assert.Equal([]tableSpec{{typeNoms, appTableName, 1}}, upstream.appendix) } func TestDynamoManifestCaching(t *testing.T) { @@ -231,7 +231,7 @@ func TestDynamoManifestCaching(t *testing.T) { // When failing the optimistic lock, we should hit persistent storage. reads = ddb.NumGets() - contents := makeContents("lock2", "nuroot", []tableSpec{{computeAddr([]byte("a")), 3}}, nil) + contents := makeContents("lock2", "nuroot", []tableSpec{{typeNoms, computeAddr([]byte("a")), 3}}, nil) upstream, err := mm.Update(context.Background(), hash.Hash{}, contents, stats, nil) require.NoError(t, err) assert.NotEqual(contents.lock, upstream.lock) diff --git a/go/store/nbs/empty_chunk_source.go b/go/store/nbs/empty_chunk_source.go index 5df2696c33d..426d6bbaa27 100644 --- a/go/store/nbs/empty_chunk_source.go +++ b/go/store/nbs/empty_chunk_source.go @@ -50,7 +50,7 @@ func (ecs emptyChunkSource) getMany(ctx context.Context, eg *errgroup.Group, req return true, nil } -func (ecs emptyChunkSource) getManyCompressed(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, CompressedChunk), stats *Stats) (bool, error) { +func (ecs emptyChunkSource) getManyCompressed(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, ToChunker), stats *Stats) (bool, error) { return true, nil } @@ -66,6 +66,10 @@ func (ecs emptyChunkSource) hash() hash.Hash { return hash.Hash{} } +func (ecs emptyChunkSource) name() string { + return ecs.hash().String() +} + func (ecs emptyChunkSource) index() (tableIndex, error) { return onHeapTableIndex{}, nil } diff --git a/go/store/nbs/file_manifest_test.go b/go/store/nbs/file_manifest_test.go index 9cb5d51830f..d4cad682dfd 100644 --- a/go/store/nbs/file_manifest_test.go +++ b/go/store/nbs/file_manifest_test.go @@ -73,7 +73,7 @@ func TestFileManifestLoadIfExists(t *testing.T) { assert.Equal(jerk, upstream.lock) assert.Equal(newRoot, upstream.root) if assert.Len(upstream.specs, 1) { - assert.Equal(tableName.String(), upstream.specs[0].name.String()) + assert.Equal(tableName.String(), upstream.specs[0].hash.String()) assert.Equal(uint32(0), upstream.specs[0].chunkCount) } } @@ -134,7 +134,7 @@ func TestFileManifestUpdate(t *testing.T) { nbfVers: constants.FormatLD1String, lock: computeAddr([]byte("locker")), root: hash.Of([]byte("new root")), - specs: []tableSpec{{computeAddr([]byte("a")), 3}}, + specs: []tableSpec{{typeNoms, computeAddr([]byte("a")), 3}}, } upstream, err := fm.Update(context.Background(), hash.Hash{}, contents, stats, func() error { // This should fail to get the lock, and therefore _not_ clobber the manifest. So the Update should succeed. @@ -177,7 +177,7 @@ func TestFileManifestUpdate(t *testing.T) { require.NoError(t, err) assert.Equal(jerkLock, upstream.lock) assert.Equal(contents2.root, upstream.root) - assert.Equal([]tableSpec{{tableName, 1}}, upstream.specs) + assert.Equal([]tableSpec{{typeNoms, tableName, 1}}, upstream.specs) } // tryClobberManifest simulates another process trying to access dir/manifestFileName concurrently. To avoid deadlock, it does a non-blocking lock of dir/lockFileName. If it can get the lock, it clobbers the manifest. diff --git a/go/store/nbs/file_table_reader.go b/go/store/nbs/file_table_reader.go index 873450efd2b..ffdfd7aa3ef 100644 --- a/go/store/nbs/file_table_reader.go +++ b/go/store/nbs/file_table_reader.go @@ -170,6 +170,10 @@ func (ftr *fileTableReader) hash() hash.Hash { return ftr.h } +func (ftr *fileTableReader) name() string { + return ftr.h.String() +} + func (ftr *fileTableReader) iterateAllChunks(ctx context.Context, cb func(chunk chunks.Chunk)) error { count := ftr.idx.chunkCount() diff --git a/go/store/nbs/gc_copier.go b/go/store/nbs/gc_copier.go index 5092a5deeae..ad6fd78b2a6 100644 --- a/go/store/nbs/gc_copier.go +++ b/go/store/nbs/gc_copier.go @@ -55,7 +55,7 @@ func newGarbageCollectionCopier() (*gcCopier, error) { return &gcCopier{writer}, nil } -func (gcc *gcCopier) addChunk(ctx context.Context, c CompressedChunk) error { +func (gcc *gcCopier) addChunk(ctx context.Context, c ToChunker) error { return gcc.writer.AddCmpChunk(c) } @@ -87,7 +87,7 @@ func (gcc *gcCopier) copyTablesToDir(ctx context.Context, tfp tableFilePersister if exists { return []tableSpec{ { - name: addr, + hash: addr, chunkCount: uint32(gcc.writer.ChunkCount()), }, }, nil @@ -99,7 +99,7 @@ func (gcc *gcCopier) copyTablesToDir(ctx context.Context, tfp tableFilePersister if err == nil { return []tableSpec{ { - name: addr, + hash: addr, chunkCount: uint32(gcc.writer.ChunkCount()), }, }, nil @@ -121,7 +121,7 @@ func (gcc *gcCopier) copyTablesToDir(ctx context.Context, tfp tableFilePersister return []tableSpec{ { - name: addr, + hash: addr, chunkCount: uint32(gcc.writer.ChunkCount()), }, }, nil diff --git a/go/store/nbs/generational_chunk_store.go b/go/store/nbs/generational_chunk_store.go index 64846797ad3..0e5a405c5ee 100644 --- a/go/store/nbs/generational_chunk_store.go +++ b/go/store/nbs/generational_chunk_store.go @@ -28,6 +28,7 @@ import ( ) var _ chunks.ChunkStore = (*GenerationalNBS)(nil) +var _ chunks.GenerationalCS = (*GenerationalNBS)(nil) var _ chunks.TableFileStore = (*GenerationalNBS)(nil) var _ chunks.GenerationalCS = (*GenerationalNBS)(nil) var _ chunks.ChunkStoreGarbageCollector = (*GenerationalNBS)(nil) @@ -142,10 +143,10 @@ func (gcs *GenerationalNBS) GetMany(ctx context.Context, hashes hash.HashSet, fo return gcs.ghostGen.GetMany(ctx, notFound, found) } -func (gcs *GenerationalNBS) GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, CompressedChunk)) error { +func (gcs *GenerationalNBS) GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, ToChunker)) error { var mu sync.Mutex notInOldGen := hashes.Copy() - err := gcs.oldGen.GetManyCompressed(ctx, hashes, func(ctx context.Context, chunk CompressedChunk) { + err := gcs.oldGen.GetManyCompressed(ctx, hashes, func(ctx context.Context, chunk ToChunker) { mu.Lock() delete(notInOldGen, chunk.Hash()) mu.Unlock() @@ -159,7 +160,7 @@ func (gcs *GenerationalNBS) GetManyCompressed(ctx context.Context, hashes hash.H } notFound := notInOldGen.Copy() - err = gcs.newGen.GetManyCompressed(ctx, notInOldGen, func(ctx context.Context, chunk CompressedChunk) { + err = gcs.newGen.GetManyCompressed(ctx, notInOldGen, func(ctx context.Context, chunk ToChunker) { mu.Lock() delete(notFound, chunk.Hash()) mu.Unlock() @@ -437,7 +438,7 @@ func (gcs *GenerationalNBS) GetChunkLocationsWithPaths(ctx context.Context, hash return res, nil } -func (gcs *GenerationalNBS) GetChunkLocations(ctx context.Context, hashes hash.HashSet) (map[hash.Hash]map[hash.Hash]Range, error) { +func (gcs *GenerationalNBS) GetChunkLocations(ctx context.Context, hashes hash.HashSet) (map[string]map[hash.Hash]Range, error) { res, err := gcs.newGen.GetChunkLocations(ctx, hashes) if err != nil { return nil, err diff --git a/go/store/nbs/ghost_store.go b/go/store/nbs/ghost_store.go index 11d23de6a68..4b4dc47ca0d 100644 --- a/go/store/nbs/ghost_store.go +++ b/go/store/nbs/ghost_store.go @@ -90,7 +90,7 @@ func (g GhostBlockStore) GetMany(ctx context.Context, hashes hash.HashSet, found return nil } -func (g GhostBlockStore) GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, CompressedChunk)) error { +func (g GhostBlockStore) GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, ToChunker)) error { for h := range hashes { if g.skippedRefs.Has(h) { found(ctx, NewGhostCompressedChunk(h)) diff --git a/go/store/nbs/ghost_store_test.go b/go/store/nbs/ghost_store_test.go index e6fc6146f7e..aa347b1a6bf 100644 --- a/go/store/nbs/ghost_store_test.go +++ b/go/store/nbs/ghost_store_test.go @@ -74,8 +74,8 @@ func TestGhostBlockStore(t *testing.T) { require.Equal(t, ghost, got[0].Hash()) }) t.Run("GetManyCompressed", func(t *testing.T) { - var got []CompressedChunk - err := bs.GetManyCompressed(ctx, hash.NewHashSet(absent, ghost), func(_ context.Context, c CompressedChunk) { + var got []ToChunker + err := bs.GetManyCompressed(ctx, hash.NewHashSet(absent, ghost), func(_ context.Context, c ToChunker) { got = append(got, c) }) require.NoError(t, err) diff --git a/go/store/nbs/journal.go b/go/store/nbs/journal.go index 8f415cbfa3d..095e20ad0cb 100644 --- a/go/store/nbs/journal.go +++ b/go/store/nbs/journal.go @@ -501,7 +501,7 @@ func (c journalConjoiner) chooseConjoinees(upstream []tableSpec) (conjoinees, ke var stash tableSpec // don't conjoin journal pruned := make([]tableSpec, 0, len(upstream)) for _, ts := range upstream { - if isJournalAddr(ts.name) { + if isJournalAddr(ts.hash) { stash = ts } else { pruned = append(pruned, ts) @@ -511,7 +511,7 @@ func (c journalConjoiner) chooseConjoinees(upstream []tableSpec) (conjoinees, ke if err != nil { return nil, nil, err } - if !hash.Hash(stash.name).IsEmpty() { + if !hash.Hash(stash.hash).IsEmpty() { keepers = append(keepers, stash) } return @@ -644,7 +644,7 @@ func (jm *journalManifest) Close() (err error) { func containsJournalSpec(specs []tableSpec) (ok bool) { for _, spec := range specs { - if spec.name == journalAddr { + if spec.hash == journalAddr { ok = true break } diff --git a/go/store/nbs/journal_chunk_source.go b/go/store/nbs/journal_chunk_source.go index c8dd8a4ac02..c5957ead647 100644 --- a/go/store/nbs/journal_chunk_source.go +++ b/go/store/nbs/journal_chunk_source.go @@ -84,7 +84,7 @@ type journalRecord struct { } func (s journalChunkSource) getMany(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, *chunks.Chunk), stats *Stats) (bool, error) { - return s.getManyCompressed(ctx, eg, reqs, func(ctx context.Context, cc CompressedChunk) { + return s.getManyCompressed(ctx, eg, reqs, func(ctx context.Context, cc ToChunker) { ch, err := cc.ToChunk() if err != nil { eg.Go(func() error { @@ -103,7 +103,7 @@ func (s journalChunkSource) getMany(ctx context.Context, eg *errgroup.Group, req // and then (4) asynchronously perform reads. We release the journal read // lock after returning when all reads are completed, which can be after the // function returns. -func (s journalChunkSource) getManyCompressed(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, CompressedChunk), stats *Stats) (bool, error) { +func (s journalChunkSource) getManyCompressed(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, ToChunker), stats *Stats) (bool, error) { defer trace.StartRegion(ctx, "journalChunkSource.getManyCompressed").End() var remaining bool @@ -165,6 +165,10 @@ func (s journalChunkSource) hash() hash.Hash { return journalAddr } +func (s journalChunkSource) name() string { + return s.hash().String() +} + // reader implements chunkSource. func (s journalChunkSource) reader(ctx context.Context) (io.ReadCloser, uint64, error) { rdr, sz, err := s.journal.snapshot(ctx) @@ -277,10 +281,10 @@ func equalSpecs(left, right []tableSpec) bool { } l := make(map[hash.Hash]struct{}, len(left)) for _, s := range left { - l[s.name] = struct{}{} + l[s.hash] = struct{}{} } for _, s := range right { - if _, ok := l[s.name]; !ok { + if _, ok := l[s.hash]; !ok { return false } } diff --git a/go/store/nbs/manifest.go b/go/store/nbs/manifest.go index f125353849d..e4ab6841acf 100644 --- a/go/store/nbs/manifest.go +++ b/go/store/nbs/manifest.go @@ -177,7 +177,7 @@ func (mc manifestContents) removeAppendixSpecs() (manifestContents, []tableSpec) filtered := make([]tableSpec, 0) removed := make([]tableSpec, 0) for _, s := range mc.specs { - if _, ok := appendixSet[s.name]; ok { + if _, ok := appendixSet[s.hash]; ok { removed = append(removed, s) } else { filtered = append(filtered, s) @@ -204,7 +204,7 @@ func (mc manifestContents) getAppendixSet() (ss map[hash.Hash]struct{}) { func toSpecSet(specs []tableSpec) (ss map[hash.Hash]struct{}) { ss = make(map[hash.Hash]struct{}, len(specs)) for _, ts := range specs { - ss[ts.name] = struct{}{} + ss[ts.hash] = struct{}{} } return ss } @@ -212,7 +212,7 @@ func toSpecSet(specs []tableSpec) (ss map[hash.Hash]struct{}) { func (mc manifestContents) size() (size uint64) { size += uint64(len(mc.nbfVers)) + hash.ByteLen + hash.ByteLen for _, sp := range mc.specs { - size += uint64(len(sp.name)) + uint32Size // for sp.chunkCount + size += uint64(len(sp.hash)) + uint32Size // for sp.chunkCount } return } @@ -439,17 +439,32 @@ func (mm manifestManager) Name() string { // TableSpecInfo is an interface for retrieving data from a tableSpec outside of this package type TableSpecInfo interface { - GetName() string + GetFileName() string GetChunkCount() uint32 } +type tableFileType int + +const ( + typeNoms tableFileType = iota + typeArchive +) + type tableSpec struct { - name hash.Hash + fileType tableFileType + hash hash.Hash chunkCount uint32 } -func (ts tableSpec) GetName() string { - return ts.name.String() +func (ts tableSpec) GetFileName() string { + switch ts.fileType { + case typeNoms: + return ts.hash.String() + case typeArchive: + return ts.hash.String() + ".darc" // NM4 - common code for this??? + default: + panic(fmt.Sprintf("runtime error: unknown table file type: %d", ts.fileType)) + } } func (ts tableSpec) GetChunkCount() uint32 { @@ -459,7 +474,7 @@ func (ts tableSpec) GetChunkCount() uint32 { func tableSpecsToMap(specs []tableSpec) map[string]int { m := make(map[string]int) for _, spec := range specs { - m[spec.name.String()] = int(spec.chunkCount) + m[spec.hash.String()] = int(spec.chunkCount) } return m @@ -470,7 +485,7 @@ func parseSpecs(tableInfo []string) ([]tableSpec, error) { for i := range specs { var err error var ok bool - specs[i].name, ok = hash.MaybeParse(tableInfo[2*i]) + specs[i].hash, ok = hash.MaybeParse(tableInfo[2*i]) if !ok { return nil, fmt.Errorf("invalid table file name: %s", tableInfo[2*i]) } @@ -490,7 +505,7 @@ func parseSpecs(tableInfo []string) ([]tableSpec, error) { func formatSpecs(specs []tableSpec, tableInfo []string) { d.Chk.True(len(tableInfo) == 2*len(specs)) for i, t := range specs { - tableInfo[2*i] = t.name.String() + tableInfo[2*i] = t.hash.String() tableInfo[2*i+1] = strconv.FormatUint(uint64(t.chunkCount), 10) } } @@ -505,11 +520,11 @@ func generateLockHash(root hash.Hash, specs []tableSpec, appendix []tableSpec, e blockHash := sha512.New() blockHash.Write(root[:]) for _, spec := range appendix { - blockHash.Write(spec.name[:]) + blockHash.Write(spec.hash[:]) } blockHash.Write([]byte{0}) for _, spec := range specs { - blockHash.Write(spec.name[:]) + blockHash.Write(spec.hash[:]) } if len(extra) > 0 { blockHash.Write([]byte{0}) diff --git a/go/store/nbs/mem_table.go b/go/store/nbs/mem_table.go index cbffa34a72b..ff4817d00a1 100644 --- a/go/store/nbs/mem_table.go +++ b/go/store/nbs/mem_table.go @@ -181,7 +181,7 @@ func (mt *memTable) getMany(ctx context.Context, eg *errgroup.Group, reqs []getR return remaining, nil } -func (mt *memTable) getManyCompressed(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, CompressedChunk), stats *Stats) (bool, error) { +func (mt *memTable) getManyCompressed(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, ToChunker), stats *Stats) (bool, error) { var remaining bool for i, r := range reqs { data := mt.chunks[*r.a] diff --git a/go/store/nbs/mem_table_test.go b/go/store/nbs/mem_table_test.go index 250f2994636..9368f5194c6 100644 --- a/go/store/nbs/mem_table_test.go +++ b/go/store/nbs/mem_table_test.go @@ -299,7 +299,7 @@ func (crg chunkReaderGroup) getMany(ctx context.Context, eg *errgroup.Group, req return true, nil } -func (crg chunkReaderGroup) getManyCompressed(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, CompressedChunk), stats *Stats) (bool, error) { +func (crg chunkReaderGroup) getManyCompressed(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, ToChunker), stats *Stats) (bool, error) { for _, haver := range crg { remaining, err := haver.getManyCompressed(ctx, eg, reqs, found, stats) if err != nil { diff --git a/go/store/nbs/metadata.go b/go/store/nbs/metadata.go index 6f443efb0b5..efb0e2a6bd1 100644 --- a/go/store/nbs/metadata.go +++ b/go/store/nbs/metadata.go @@ -118,7 +118,7 @@ func GetStorageMetadata(path string) (StorageMetadata, error) { tableSpecInfo := manifest.GetTableSpecInfo(i) // If the oldgen/name exists, it's not an archive. If it exists with a .darc suffix, then it's an archive. - tfName := tableSpecInfo.GetName() + tfName := tableSpecInfo.GetFileName() fullPath := filepath.Join(oldgen, tfName) _, err := os.Stat(fullPath) if err == nil { diff --git a/go/store/nbs/nbs_metrics_wrapper.go b/go/store/nbs/nbs_metrics_wrapper.go index 1ca852da04d..d15a0c213cd 100644 --- a/go/store/nbs/nbs_metrics_wrapper.go +++ b/go/store/nbs/nbs_metrics_wrapper.go @@ -99,7 +99,7 @@ func (nbsMW *NBSMetricWrapper) PruneTableFiles(ctx context.Context) error { // GetManyCompressed gets the compressed Chunks with |hashes| from the store. On return, // |found| will have been fully sent all chunks which have been // found. Any non-present chunks will silently be ignored. -func (nbsMW *NBSMetricWrapper) GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, CompressedChunk)) error { +func (nbsMW *NBSMetricWrapper) GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, ToChunker)) error { atomic.AddInt32(&nbsMW.TotalChunkGets, int32(len(hashes))) return nbsMW.nbs.GetManyCompressed(ctx, hashes, found) } diff --git a/go/store/nbs/root_tracker_test.go b/go/store/nbs/root_tracker_test.go index f428f0817eb..eb4e2af7e78 100644 --- a/go/store/nbs/root_tracker_test.go +++ b/go/store/nbs/root_tracker_test.go @@ -404,7 +404,7 @@ func interloperWrite(fm *fakeManifest, p tablePersister, rootChunk []byte, chunk return hash.Hash{}, nil, err } - fm.set(constants.FormatLD1String, newLock, newRoot, []tableSpec{{src.hash(), uint32(len(chunks) + 1)}}, nil) + fm.set(constants.FormatLD1String, newLock, newRoot, []tableSpec{{typeNoms, src.hash(), uint32(len(chunks) + 1)}}, nil) if err = src.close(); err != nil { return [20]byte{}, nil, err diff --git a/go/store/nbs/store.go b/go/store/nbs/store.go index 7ddc44a001a..61b2ff5b51b 100644 --- a/go/store/nbs/store.go +++ b/go/store/nbs/store.go @@ -68,7 +68,6 @@ const ( defaultMaxTables = 256 defaultManifestCacheSize = 1 << 23 // 8MB - preflushChunkCount = 8 ) var ( @@ -86,7 +85,7 @@ func makeGlobalCaches() { type NBSCompressedChunkStore interface { chunks.ChunkStore - GetManyCompressed(context.Context, hash.HashSet, func(context.Context, CompressedChunk)) error + GetManyCompressed(context.Context, hash.HashSet, func(context.Context, ToChunker)) error } type NomsBlockStore struct { @@ -127,8 +126,10 @@ var _ chunks.ChunkStoreGarbageCollector = &NomsBlockStore{} const hasCacheSize = 100000 type Range struct { - Offset uint64 - Length uint32 + Offset uint64 + Length uint32 + DictOffset uint64 + DictLength uint32 } // ChunkJournal returns the ChunkJournal in use by this NomsBlockStore, or nil if no ChunkJournal is being used. @@ -144,16 +145,16 @@ func (nbs *NomsBlockStore) GetChunkLocationsWithPaths(ctx context.Context, hashe if err != nil { return nil, err } - toret := make(map[string]map[hash.Hash]Range, len(locs)) + toret := make(map[string]map[hash.Hash]Range, len(locs)) // NM4 for k, v := range locs { - toret[k.String()] = v + toret[k] = v } return toret, nil } -func (nbs *NomsBlockStore) GetChunkLocations(ctx context.Context, hashes hash.HashSet) (map[hash.Hash]map[hash.Hash]Range, error) { +func (nbs *NomsBlockStore) GetChunkLocations(ctx context.Context, hashes hash.HashSet) (map[string]map[hash.Hash]Range, error) { gr := toGetRecords(hashes) - ranges := make(map[hash.Hash]map[hash.Hash]Range) + ranges := make(map[string]map[hash.Hash]Range) fn := func(css chunkSourceSet) error { for _, cs := range css { @@ -161,8 +162,11 @@ func (nbs *NomsBlockStore) GetChunkLocations(ctx context.Context, hashes hash.Ha if err != nil { return err } + if len(rng) == 0 { + continue // NM4 - not sure why this wasn't here before.... + } - h := hash.Hash(cs.hash()) + h := cs.name() if m, ok := ranges[h]; ok { for k, v := range rng { m[k] = v @@ -259,7 +263,7 @@ func (nbs *NomsBlockStore) UpdateManifest(ctx context.Context, updates map[hash. for h, count := range updates { if _, ok := currSpecs[h]; !ok { addCount++ - contents.specs = append(contents.specs, tableSpec{h, count}) + contents.specs = append(contents.specs, tableSpec{typeNoms, h, count}) } } @@ -348,11 +352,11 @@ func (nbs *NomsBlockStore) UpdateManifestWithAppendix(ctx context.Context, updat var addCount int for h, count := range updates { if option == ManifestAppendixOption_Set { - appendixSpecs = append(appendixSpecs, tableSpec{h, count}) + appendixSpecs = append(appendixSpecs, tableSpec{typeNoms, h, count}) // NM4 sanity check. } else { if _, ok := currAppendixSpecs[h]; !ok { addCount++ - appendixSpecs = append(appendixSpecs, tableSpec{h, count}) + appendixSpecs = append(appendixSpecs, tableSpec{typeNoms, h, count}) // NM4 sanity check } } } @@ -473,12 +477,13 @@ func OverwriteStoreManifest(ctx context.Context, store *NomsBlockStore, root has } // Appendix table files should come first in specs for h, c := range appendixTableFiles { - s := tableSpec{name: h, chunkCount: c} + // NM4 - not sure on this one.... + s := tableSpec{fileType: typeNoms, hash: h, chunkCount: c} contents.appendix = append(contents.appendix, s) contents.specs = append(contents.specs, s) } for h, c := range tableFiles { - s := tableSpec{name: h, chunkCount: c} + s := tableSpec{fileType: typeNoms, hash: h, chunkCount: c} contents.specs = append(contents.specs, s) } contents.lock = generateLockHash(contents.root, contents.specs, contents.appendix, nil) @@ -889,7 +894,7 @@ func (nbs *NomsBlockStore) GetMany(ctx context.Context, hashes hash.HashSet, fou }) } -func (nbs *NomsBlockStore) GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, CompressedChunk)) error { +func (nbs *NomsBlockStore) GetManyCompressed(ctx context.Context, hashes hash.HashSet, found func(context.Context, ToChunker)) error { ctx, span := tracer.Start(ctx, "nbs.GetManyCompressed", trace.WithAttributes(attribute.Int("num_hashes", len(hashes)))) defer span.End() return nbs.getManyWithFunc(ctx, hashes, func(ctx context.Context, cr chunkReader, eg *errgroup.Group, reqs []getRecord, stats *Stats) (bool, error) { @@ -1295,7 +1300,7 @@ func (nbs *NomsBlockStore) updateManifest(ctx context.Context, current, last has filtered := make([]tableSpec, 0, len(specs)) for _, s := range specs { - if _, present := appendixSet[s.name]; !present { + if _, present := appendixSet[s.hash]; !present { filtered = append(filtered, s) } } @@ -1384,7 +1389,7 @@ func (tf tableFile) LocationPrefix() string { // FileID gets the id of the file func (tf tableFile) FileID() string { - return tf.info.GetName() + return tf.info.GetFileName() } // NumChunks returns the number of chunks in a table file @@ -1440,12 +1445,21 @@ func getTableFiles(css map[hash.Hash]chunkSource, contents manifestContents, num if numSpecs == 0 { return tableFiles, nil } + for i := 0; i < numSpecs; i++ { + // info := tableSpec{fileType: typeNoms, hash: hash.Hash{}, chunkCount: 0} + info := specFunc(contents, i) - cs, ok := css[info.name] + cs, ok := css[info.hash] if !ok { return nil, ErrSpecWithoutChunkSource } + + // Look a the type of cs, and set archive type is needed. + if _, ok := cs.(archiveChunkSource); ok { + info.fileType = typeArchive + } + tableFiles = append(tableFiles, newTableFile(cs, info)) } return tableFiles, nil @@ -1716,25 +1730,25 @@ func (i *markAndSweeper) SaveHashes(ctx context.Context, hashes []hash.Hash) err found := 0 var addErr error - err = i.src.GetManyCompressed(ctx, toVisit, func(ctx context.Context, cc CompressedChunk) { + err = i.src.GetManyCompressed(ctx, toVisit, func(ctx context.Context, tc ToChunker) { mu.Lock() defer mu.Unlock() if addErr != nil { return } found += 1 - if cc.IsGhost() { + if tc.IsGhost() { // Ghost chunks encountered on the walk can be left alone --- they // do not bring their dependencies, and because of how generational // store works, they will still be ghost chunks // in the store after the GC is finished. return } - addErr = i.gcc.addChunk(ctx, cc) + addErr = i.gcc.addChunk(ctx, tc) if addErr != nil { return } - c, err := cc.ToChunk() + c, err := tc.ToChunk() if err != nil { addErr = err return @@ -1781,7 +1795,7 @@ func (gcf gcFinalizer) AddChunksToStore(ctx context.Context) (chunks.HasManyFunc fileIdToNumChunks := tableSpecsToMap(gcf.specs) var addrs []hash.Hash for _, spec := range gcf.specs { - addrs = append(addrs, spec.name) + addrs = append(addrs, spec.hash) } f := func(ctx context.Context, hashes hash.HashSet) (hash.HashSet, error) { return gcf.nbs.hasManyInSources(addrs, hashes) diff --git a/go/store/nbs/table.go b/go/store/nbs/table.go index b487422d079..b0cc680b8cf 100644 --- a/go/store/nbs/table.go +++ b/go/store/nbs/table.go @@ -204,7 +204,7 @@ type chunkReader interface { // getManyCompressed sets getRecord.found to true, and calls |found| for each present getRecord query. // It returns true if any getRecord query was not found in this chunkReader. - getManyCompressed(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, CompressedChunk), stats *Stats) (bool, error) + getManyCompressed(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, ToChunker), stats *Stats) (bool, error) // count returns the chunk count for this chunkReader. count() (uint32, error) @@ -222,6 +222,10 @@ type chunkSource interface { // hash returns the hash address of this chunkSource. hash() hash.Hash + // name is the on disk short name for this chunkSource. Classically, this was a hash. Having files + // with suffixes (eg darc) was useful. + name() string + // opens a Reader to the first byte of the chunkData segment of this table. reader(context.Context) (io.ReadCloser, uint64, error) diff --git a/go/store/nbs/table_reader.go b/go/store/nbs/table_reader.go index 3ff059fb480..416843d731c 100644 --- a/go/store/nbs/table_reader.go +++ b/go/store/nbs/table_reader.go @@ -38,6 +38,14 @@ import ( // Do not read more than 128MB at a time. const maxReadSize = 128 * 1024 * 1024 +type ToChunker interface { + Hash() hash.Hash + ToChunk() (chunks.Chunk, error) + FullCompressedChunkLen() uint32 + IsEmpty() bool + IsGhost() bool +} + // CompressedChunk represents a chunk of data in a table file which is still compressed via snappy. type CompressedChunk struct { // H is the hash of the chunk @@ -53,6 +61,8 @@ type CompressedChunk struct { ghost bool } +var _ ToChunker = CompressedChunk{} + // NewCompressedChunk creates a CompressedChunk func NewCompressedChunk(h hash.Hash, buff []byte) (CompressedChunk, error) { dataLen := uint64(len(buff)) - checksumSize @@ -114,6 +124,10 @@ func (cmp CompressedChunk) CompressedSize() int { return len(cmp.CompressedData) } +func (cmp CompressedChunk) FullCompressedChunkLen() uint32 { + return uint32(len(cmp.FullCompressedChunk)) +} + var EmptyCompressedChunk CompressedChunk func init() { @@ -313,10 +327,10 @@ var _ chunkReader = tableReader{} func (tr tableReader) readCompressedAtOffsets( ctx context.Context, rb readBatch, - found func(context.Context, CompressedChunk), + found func(context.Context, ToChunker), stats *Stats, ) error { - return tr.readAtOffsetsWithCB(ctx, rb, stats, func(ctx context.Context, cmp CompressedChunk) error { + return tr.readAtOffsetsWithCB(ctx, rb, stats, func(ctx context.Context, cmp ToChunker) error { found(ctx, cmp) return nil }) @@ -328,7 +342,7 @@ func (tr tableReader) readAtOffsets( found func(context.Context, *chunks.Chunk), stats *Stats, ) error { - return tr.readAtOffsetsWithCB(ctx, rb, stats, func(ctx context.Context, cmp CompressedChunk) error { + return tr.readAtOffsetsWithCB(ctx, rb, stats, func(ctx context.Context, cmp ToChunker) error { chk, err := cmp.ToChunk() if err != nil { @@ -344,7 +358,7 @@ func (tr tableReader) readAtOffsetsWithCB( ctx context.Context, rb readBatch, stats *Stats, - cb func(ctx context.Context, cmp CompressedChunk) error, + cb func(ctx context.Context, cmp ToChunker) error, ) error { readLength := rb.End() - rb.Start() buff := make([]byte, readLength) @@ -391,7 +405,7 @@ func (tr tableReader) getMany( err = tr.getManyAtOffsets(ctx, eg, offsetRecords, found, stats) return remaining, err } -func (tr tableReader) getManyCompressed(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, CompressedChunk), stats *Stats) (bool, error) { +func (tr tableReader) getManyCompressed(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, ToChunker), stats *Stats) (bool, error) { // Pass #1: Iterate over |reqs| and |tr.prefixes| (both sorted by address) and build the set // of table locations which must be read in order to satisfy the getMany operation. offsetRecords, remaining, err := tr.findOffsets(reqs) @@ -402,7 +416,7 @@ func (tr tableReader) getManyCompressed(ctx context.Context, eg *errgroup.Group, return remaining, err } -func (tr tableReader) getManyCompressedAtOffsets(ctx context.Context, eg *errgroup.Group, offsetRecords offsetRecSlice, found func(context.Context, CompressedChunk), stats *Stats) error { +func (tr tableReader) getManyCompressedAtOffsets(ctx context.Context, eg *errgroup.Group, offsetRecords offsetRecSlice, found func(context.Context, ToChunker), stats *Stats) error { return tr.getManyAtOffsetsWithReadFunc(ctx, eg, offsetRecords, stats, func( ctx context.Context, rb readBatch, diff --git a/go/store/nbs/table_set.go b/go/store/nbs/table_set.go index 185743199a0..50440d1331f 100644 --- a/go/store/nbs/table_set.go +++ b/go/store/nbs/table_set.go @@ -203,7 +203,7 @@ func (ts tableSet) getMany(ctx context.Context, eg *errgroup.Group, reqs []getRe return f(ts.novel) && err == nil && f(ts.upstream), err } -func (ts tableSet) getManyCompressed(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, CompressedChunk), stats *Stats) (remaining bool, err error) { +func (ts tableSet) getManyCompressed(ctx context.Context, eg *errgroup.Group, reqs []getRecord, found func(context.Context, ToChunker), stats *Stats) (remaining bool, err error) { f := func(css chunkSourceSet) bool { for _, haver := range css { remaining, err = haver.getManyCompressed(ctx, eg, reqs, found, stats) @@ -392,10 +392,10 @@ func (ts tableSet) rebase(ctx context.Context, specs []tableSpec, stats *Stats) specs = make([]tableSpec, 0, len(orig)) seen := map[hash.Hash]struct{}{} for _, spec := range orig { - if _, ok := seen[spec.name]; ok { + if _, ok := seen[spec.hash]; ok { continue } - seen[spec.name] = struct{}{} + seen[spec.hash] = struct{}{} // keep specs in order to play nicely with // manifest appendix optimization specs = append(specs, spec) @@ -423,7 +423,7 @@ func (ts tableSet) rebase(ctx context.Context, specs []tableSpec, stats *Stats) upstream := make(chunkSourceSet, len(specs)) for _, s := range specs { // clone tables that we have already opened - if cs, ok := ts.upstream[s.name]; ok { + if cs, ok := ts.upstream[s.hash]; ok { cl, err := cs.clone() if err != nil { _ = eg.Wait() @@ -441,7 +441,7 @@ func (ts tableSet) rebase(ctx context.Context, specs []tableSpec, stats *Stats) // open missing tables in parallel spec := s eg.Go(func() error { - cs, err := ts.p.Open(ctx, spec.name, spec.chunkCount, stats) // NM4 - spec.name is the tf/arch name. + cs, err := ts.p.Open(ctx, spec.hash, spec.chunkCount, stats) if err != nil { return err } @@ -480,8 +480,9 @@ func (ts tableSet) toSpecs() ([]tableSpec, error) { if err != nil { return nil, err } else if cnt > 0 { + // NM4 - New to choose between classic or archive here. h := src.hash() - tableSpecs = append(tableSpecs, tableSpec{h, cnt}) + tableSpecs = append(tableSpecs, tableSpec{typeNoms, h, cnt}) } } for _, src := range ts.upstream { @@ -491,11 +492,12 @@ func (ts tableSet) toSpecs() ([]tableSpec, error) { } else if cnt <= 0 { return nil, errors.New("no upstream chunks") } + // NM4 - New to choose between classic or archive here. h := src.hash() - tableSpecs = append(tableSpecs, tableSpec{h, cnt}) + tableSpecs = append(tableSpecs, tableSpec{typeNoms, h, cnt}) } sort.Slice(tableSpecs, func(i, j int) bool { - return bytes.Compare(tableSpecs[i].name[:], tableSpecs[j].name[:]) < 0 + return bytes.Compare(tableSpecs[i].hash[:], tableSpecs[j].hash[:]) < 0 }) return tableSpecs, nil } diff --git a/go/store/nbs/table_set_test.go b/go/store/nbs/table_set_test.go index b7d54cbd092..82cae91759c 100644 --- a/go/store/nbs/table_set_test.go +++ b/go/store/nbs/table_set_test.go @@ -238,7 +238,7 @@ func TestTableSetClosesOpenedChunkSourcesOnErr(t *testing.T) { p.sourcesToFail[a] = true } once = false - specs = append(specs, tableSpec{a, 1}) + specs = append(specs, tableSpec{typeNoms, a, 1}) } ts := newTableSet(p, q) diff --git a/integration-tests/bats/archive-test-repo/noms/LOCK b/integration-tests/bats/archive-test-repo/noms/LOCK new file mode 100644 index 00000000000..e69de29bb2d diff --git a/integration-tests/bats/archive-test-repo/noms/manifest b/integration-tests/bats/archive-test-repo/noms/manifest new file mode 100644 index 00000000000..f53699ef53f --- /dev/null +++ b/integration-tests/bats/archive-test-repo/noms/manifest @@ -0,0 +1 @@ +5:__DOLT__:2o11dvovtgf84gvaap9use1dfhfqq185:t03ii2bn1d8actv3f1deos6kiiukqvuq:2o11dvovtgf84gvaap9use1dfhfqq185:v3qdaqu9aeuq4ppg26ad8smbg6kutf1o:2 \ No newline at end of file diff --git a/integration-tests/bats/archive-test-repo/noms/oldgen/1jm54h3oulp0k7shca3keiob4tj82rcd.darc b/integration-tests/bats/archive-test-repo/noms/oldgen/1jm54h3oulp0k7shca3keiob4tj82rcd.darc new file mode 100644 index 00000000000..88fa1084bc2 Binary files /dev/null and b/integration-tests/bats/archive-test-repo/noms/oldgen/1jm54h3oulp0k7shca3keiob4tj82rcd.darc differ diff --git a/integration-tests/bats/archive-test-repo/noms/oldgen/LOCK b/integration-tests/bats/archive-test-repo/noms/oldgen/LOCK new file mode 100644 index 00000000000..e69de29bb2d diff --git a/integration-tests/bats/archive-test-repo/noms/oldgen/manifest b/integration-tests/bats/archive-test-repo/noms/oldgen/manifest new file mode 100644 index 00000000000..9476d9a3700 --- /dev/null +++ b/integration-tests/bats/archive-test-repo/noms/oldgen/manifest @@ -0,0 +1 @@ +5:__DOLT__:q8n06g3ttdtq9lnajmifu87na546rn6i:00000000000000000000000000000000:q8n06g3ttdtq9lnajmifu87na546rn6i:1jm54h3oulp0k7shca3keiob4tj82rcd:417:s760v0u1amamtr6o852pmjob6sfqosgr:500 \ No newline at end of file diff --git a/integration-tests/bats/archive-test-repo/noms/oldgen/s760v0u1amamtr6o852pmjob6sfqosgr.darc b/integration-tests/bats/archive-test-repo/noms/oldgen/s760v0u1amamtr6o852pmjob6sfqosgr.darc new file mode 100644 index 00000000000..088c192064a Binary files /dev/null and b/integration-tests/bats/archive-test-repo/noms/oldgen/s760v0u1amamtr6o852pmjob6sfqosgr.darc differ diff --git a/integration-tests/bats/archive-test-repo/noms/v3qdaqu9aeuq4ppg26ad8smbg6kutf1o b/integration-tests/bats/archive-test-repo/noms/v3qdaqu9aeuq4ppg26ad8smbg6kutf1o new file mode 100644 index 00000000000..4eb7de7179b Binary files /dev/null and b/integration-tests/bats/archive-test-repo/noms/v3qdaqu9aeuq4ppg26ad8smbg6kutf1o differ diff --git a/integration-tests/bats/archive-test-repo/repo_state.json b/integration-tests/bats/archive-test-repo/repo_state.json new file mode 100755 index 00000000000..32f2d6197d5 --- /dev/null +++ b/integration-tests/bats/archive-test-repo/repo_state.json @@ -0,0 +1,6 @@ +{ + "head": "refs/heads/main", + "remotes": {}, + "backups": {}, + "branches": {} +} \ No newline at end of file diff --git a/integration-tests/bats/archive.bats b/integration-tests/bats/archive.bats index 0e31e7b0aea..09554f95ba1 100755 --- a/integration-tests/bats/archive.bats +++ b/integration-tests/bats/archive.bats @@ -143,19 +143,56 @@ mutations_and_gc_statement() { [ "$commits" -eq "66" ] } -@test "archive: archive backup no go" { - dolt sql -q "$(mutations_and_gc_statement)" - dolt archive - - dolt backup add bac1 file://../bac1 - run dolt backup sync bac1 - - [ "$status" -eq 1 ] - [[ "$output" =~ "archive files present" ]] || false +@test "archive: can clone archived repository" { + mkdir -p remote/.dolt + mkdir cloned + + # Copy the archive test repo to remote directory + cp -R $BATS_TEST_DIRNAME/archive-test-repo/* remote/.dolt + cd remote + + port=$( definePORT ) + + remotesrv --http-port $port --grpc-port $port --repo-mode & + remotesrv_pid=$! + [[ "$remotesrv_pid" -gt 0 ]] || false + + cd ../cloned + run dolt clone http://localhost:$port/test-org/test-repo repo1 + [ "$status" -eq 0 ] + cd repo1 + + # Verify we can read data + run dolt sql -q 'select sum(j) from tbl;' + [[ "$status" -eq 0 ]] || false + [[ "$output" =~ "20100" ]] || false + + kill $remotesrv_pid + wait $remotesrv_pid || : + remotesrv_pid="" + + ## The above test is the setup for the next test - so we'll stick both in here. + ## This tests cloning from a clone. Archive files are generally in oldgen, but not the case with a fresh clone. + cd ../../ + mkdir clone2 + + cd cloned/repo1 # start the server using the clone from above. + port=$( definePORT ) + remotesrv --http-port $port --grpc-port $port --repo-mode & + remotesrv_pid=$! + [[ "$remotesrv_pid" -gt 0 ]] || false + + cd ../../clone2 + run dolt clone http://localhost:$port/test-org/test-repo repo2 + [ "$status" -eq 0 ] + cd repo2 + + run dolt sql -q 'select sum(j) from tbl;' + [[ "$status" -eq 0 ]] || false + [[ "$output" =~ "20100" ]] || false - # currently the cli and stored procedures are different code paths. - run dolt sql -q "call dolt_backup('sync', 'bac1')" - [ "$status" -eq 1 ] - # NM4 - TODO. This message is cryptic, but plumbing the error through is awkward. - [[ "$output" =~ "Archive chunk source" ]] || false + teardown_common + kill $remotesrv_pid + wait $remotesrv_pid || : + remotesrv_pid="" } diff --git a/proto/dolt/services/remotesapi/v1alpha1/chunkstore.proto b/proto/dolt/services/remotesapi/v1alpha1/chunkstore.proto index 519bd616b03..04ff5804567 100644 --- a/proto/dolt/services/remotesapi/v1alpha1/chunkstore.proto +++ b/proto/dolt/services/remotesapi/v1alpha1/chunkstore.proto @@ -89,6 +89,8 @@ message RangeChunk { bytes hash = 1; uint64 offset = 2; uint32 length = 3; + uint64 dictionary_offset = 4; + uint32 dictionary_length = 5; } message HttpGetRange {