aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--weed/pb/volume_server.proto22
-rw-r--r--weed/pb/volume_server_pb/volume_server.pb.go344
-rw-r--r--weed/server/volume_grpc_copy.go62
-rw-r--r--weed/server/volume_grpc_erasure_coding.go82
-rw-r--r--weed/storage/erasure_coding/ec_encoder.go128
-rw-r--r--weed/storage/erasure_coding/ec_test.go106
6 files changed, 508 insertions, 236 deletions
diff --git a/weed/pb/volume_server.proto b/weed/pb/volume_server.proto
index b5ebe6bed..78d19b285 100644
--- a/weed/pb/volume_server.proto
+++ b/weed/pb/volume_server.proto
@@ -47,6 +47,13 @@ service VolumeServer {
rpc VolumeTailReceiver (VolumeTailReceiverRequest) returns (VolumeTailReceiverResponse) {
}
+ // erasure coding
+ rpc VolumeEcGenerateSlices (VolumeEcGenerateSlicesRequest) returns (VolumeEcGenerateSlicesResponse) {
+ }
+ rpc VolumeEcCopy (VolumeEcCopyRequest) returns (VolumeEcCopyResponse) {
+ }
+
+
}
//////////////////////////////////////////////////
@@ -190,6 +197,21 @@ message VolumeTailReceiverRequest {
message VolumeTailReceiverResponse {
}
+message VolumeEcGenerateSlicesRequest {
+ uint32 volume_id = 1;
+}
+message VolumeEcGenerateSlicesResponse {
+}
+
+message VolumeEcCopyRequest {
+ uint32 volume_id = 1;
+ string collection = 2;
+ repeated uint32 ec_indexes = 3;
+ string source_data_node = 5;
+}
+message VolumeEcCopyResponse {
+}
+
message ReadVolumeFileStatusRequest {
uint32 volume_id = 1;
}
diff --git a/weed/pb/volume_server_pb/volume_server.pb.go b/weed/pb/volume_server_pb/volume_server.pb.go
index 10bebc65e..e30e76947 100644
--- a/weed/pb/volume_server_pb/volume_server.pb.go
+++ b/weed/pb/volume_server_pb/volume_server.pb.go
@@ -43,6 +43,10 @@ It has these top-level messages:
VolumeTailSenderResponse
VolumeTailReceiverRequest
VolumeTailReceiverResponse
+ VolumeEcGenerateSlicesRequest
+ VolumeEcGenerateSlicesResponse
+ VolumeEcCopyRequest
+ VolumeEcCopyResponse
ReadVolumeFileStatusRequest
ReadVolumeFileStatusResponse
DiskStatus
@@ -766,6 +770,78 @@ func (m *VolumeTailReceiverResponse) String() string { return proto.C
func (*VolumeTailReceiverResponse) ProtoMessage() {}
func (*VolumeTailReceiverResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} }
+type VolumeEcGenerateSlicesRequest struct {
+ VolumeId uint32 `protobuf:"varint,1,opt,name=volume_id,json=volumeId" json:"volume_id,omitempty"`
+}
+
+func (m *VolumeEcGenerateSlicesRequest) Reset() { *m = VolumeEcGenerateSlicesRequest{} }
+func (m *VolumeEcGenerateSlicesRequest) String() string { return proto.CompactTextString(m) }
+func (*VolumeEcGenerateSlicesRequest) ProtoMessage() {}
+func (*VolumeEcGenerateSlicesRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} }
+
+func (m *VolumeEcGenerateSlicesRequest) GetVolumeId() uint32 {
+ if m != nil {
+ return m.VolumeId
+ }
+ return 0
+}
+
+type VolumeEcGenerateSlicesResponse struct {
+}
+
+func (m *VolumeEcGenerateSlicesResponse) Reset() { *m = VolumeEcGenerateSlicesResponse{} }
+func (m *VolumeEcGenerateSlicesResponse) String() string { return proto.CompactTextString(m) }
+func (*VolumeEcGenerateSlicesResponse) ProtoMessage() {}
+func (*VolumeEcGenerateSlicesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} }
+
+type VolumeEcCopyRequest struct {
+ VolumeId uint32 `protobuf:"varint,1,opt,name=volume_id,json=volumeId" json:"volume_id,omitempty"`
+ Collection string `protobuf:"bytes,2,opt,name=collection" json:"collection,omitempty"`
+ EcIndexes []uint32 `protobuf:"varint,3,rep,packed,name=ec_indexes,json=ecIndexes" json:"ec_indexes,omitempty"`
+ SourceDataNode string `protobuf:"bytes,5,opt,name=source_data_node,json=sourceDataNode" json:"source_data_node,omitempty"`
+}
+
+func (m *VolumeEcCopyRequest) Reset() { *m = VolumeEcCopyRequest{} }
+func (m *VolumeEcCopyRequest) String() string { return proto.CompactTextString(m) }
+func (*VolumeEcCopyRequest) ProtoMessage() {}
+func (*VolumeEcCopyRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{36} }
+
+func (m *VolumeEcCopyRequest) GetVolumeId() uint32 {
+ if m != nil {
+ return m.VolumeId
+ }
+ return 0
+}
+
+func (m *VolumeEcCopyRequest) GetCollection() string {
+ if m != nil {
+ return m.Collection
+ }
+ return ""
+}
+
+func (m *VolumeEcCopyRequest) GetEcIndexes() []uint32 {
+ if m != nil {
+ return m.EcIndexes
+ }
+ return nil
+}
+
+func (m *VolumeEcCopyRequest) GetSourceDataNode() string {
+ if m != nil {
+ return m.SourceDataNode
+ }
+ return ""
+}
+
+type VolumeEcCopyResponse struct {
+}
+
+func (m *VolumeEcCopyResponse) Reset() { *m = VolumeEcCopyResponse{} }
+func (m *VolumeEcCopyResponse) String() string { return proto.CompactTextString(m) }
+func (*VolumeEcCopyResponse) ProtoMessage() {}
+func (*VolumeEcCopyResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{37} }
+
type ReadVolumeFileStatusRequest struct {
VolumeId uint32 `protobuf:"varint,1,opt,name=volume_id,json=volumeId" json:"volume_id,omitempty"`
}
@@ -773,7 +849,7 @@ type ReadVolumeFileStatusRequest struct {
func (m *ReadVolumeFileStatusRequest) Reset() { *m = ReadVolumeFileStatusRequest{} }
func (m *ReadVolumeFileStatusRequest) String() string { return proto.CompactTextString(m) }
func (*ReadVolumeFileStatusRequest) ProtoMessage() {}
-func (*ReadVolumeFileStatusRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} }
+func (*ReadVolumeFileStatusRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{38} }
func (m *ReadVolumeFileStatusRequest) GetVolumeId() uint32 {
if m != nil {
@@ -796,7 +872,7 @@ type ReadVolumeFileStatusResponse struct {
func (m *ReadVolumeFileStatusResponse) Reset() { *m = ReadVolumeFileStatusResponse{} }
func (m *ReadVolumeFileStatusResponse) String() string { return proto.CompactTextString(m) }
func (*ReadVolumeFileStatusResponse) ProtoMessage() {}
-func (*ReadVolumeFileStatusResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} }
+func (*ReadVolumeFileStatusResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{39} }
func (m *ReadVolumeFileStatusResponse) GetVolumeId() uint32 {
if m != nil {
@@ -864,7 +940,7 @@ type DiskStatus struct {
func (m *DiskStatus) Reset() { *m = DiskStatus{} }
func (m *DiskStatus) String() string { return proto.CompactTextString(m) }
func (*DiskStatus) ProtoMessage() {}
-func (*DiskStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{36} }
+func (*DiskStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{40} }
func (m *DiskStatus) GetDir() string {
if m != nil {
@@ -907,7 +983,7 @@ type MemStatus struct {
func (m *MemStatus) Reset() { *m = MemStatus{} }
func (m *MemStatus) String() string { return proto.CompactTextString(m) }
func (*MemStatus) ProtoMessage() {}
-func (*MemStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{37} }
+func (*MemStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{41} }
func (m *MemStatus) GetGoroutines() int32 {
if m != nil {
@@ -993,6 +1069,10 @@ func init() {
proto.RegisterType((*VolumeTailSenderResponse)(nil), "volume_server_pb.VolumeTailSenderResponse")
proto.RegisterType((*VolumeTailReceiverRequest)(nil), "volume_server_pb.VolumeTailReceiverRequest")
proto.RegisterType((*VolumeTailReceiverResponse)(nil), "volume_server_pb.VolumeTailReceiverResponse")
+ proto.RegisterType((*VolumeEcGenerateSlicesRequest)(nil), "volume_server_pb.VolumeEcGenerateSlicesRequest")
+ proto.RegisterType((*VolumeEcGenerateSlicesResponse)(nil), "volume_server_pb.VolumeEcGenerateSlicesResponse")
+ proto.RegisterType((*VolumeEcCopyRequest)(nil), "volume_server_pb.VolumeEcCopyRequest")
+ proto.RegisterType((*VolumeEcCopyResponse)(nil), "volume_server_pb.VolumeEcCopyResponse")
proto.RegisterType((*ReadVolumeFileStatusRequest)(nil), "volume_server_pb.ReadVolumeFileStatusRequest")
proto.RegisterType((*ReadVolumeFileStatusResponse)(nil), "volume_server_pb.ReadVolumeFileStatusResponse")
proto.RegisterType((*DiskStatus)(nil), "volume_server_pb.DiskStatus")
@@ -1029,6 +1109,9 @@ type VolumeServerClient interface {
CopyFile(ctx context.Context, in *CopyFileRequest, opts ...grpc.CallOption) (VolumeServer_CopyFileClient, error)
VolumeTailSender(ctx context.Context, in *VolumeTailSenderRequest, opts ...grpc.CallOption) (VolumeServer_VolumeTailSenderClient, error)
VolumeTailReceiver(ctx context.Context, in *VolumeTailReceiverRequest, opts ...grpc.CallOption) (*VolumeTailReceiverResponse, error)
+ // erasure coding
+ VolumeEcGenerateSlices(ctx context.Context, in *VolumeEcGenerateSlicesRequest, opts ...grpc.CallOption) (*VolumeEcGenerateSlicesResponse, error)
+ VolumeEcCopy(ctx context.Context, in *VolumeEcCopyRequest, opts ...grpc.CallOption) (*VolumeEcCopyResponse, error)
}
type volumeServerClient struct {
@@ -1261,6 +1344,24 @@ func (c *volumeServerClient) VolumeTailReceiver(ctx context.Context, in *VolumeT
return out, nil
}
+func (c *volumeServerClient) VolumeEcGenerateSlices(ctx context.Context, in *VolumeEcGenerateSlicesRequest, opts ...grpc.CallOption) (*VolumeEcGenerateSlicesResponse, error) {
+ out := new(VolumeEcGenerateSlicesResponse)
+ err := grpc.Invoke(ctx, "/volume_server_pb.VolumeServer/VolumeEcGenerateSlices", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *volumeServerClient) VolumeEcCopy(ctx context.Context, in *VolumeEcCopyRequest, opts ...grpc.CallOption) (*VolumeEcCopyResponse, error) {
+ out := new(VolumeEcCopyResponse)
+ err := grpc.Invoke(ctx, "/volume_server_pb.VolumeServer/VolumeEcCopy", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
// Server API for VolumeServer service
type VolumeServerServer interface {
@@ -1283,6 +1384,9 @@ type VolumeServerServer interface {
CopyFile(*CopyFileRequest, VolumeServer_CopyFileServer) error
VolumeTailSender(*VolumeTailSenderRequest, VolumeServer_VolumeTailSenderServer) error
VolumeTailReceiver(context.Context, *VolumeTailReceiverRequest) (*VolumeTailReceiverResponse, error)
+ // erasure coding
+ VolumeEcGenerateSlices(context.Context, *VolumeEcGenerateSlicesRequest) (*VolumeEcGenerateSlicesResponse, error)
+ VolumeEcCopy(context.Context, *VolumeEcCopyRequest) (*VolumeEcCopyResponse, error)
}
func RegisterVolumeServerServer(s *grpc.Server, srv VolumeServerServer) {
@@ -1604,6 +1708,42 @@ func _VolumeServer_VolumeTailReceiver_Handler(srv interface{}, ctx context.Conte
return interceptor(ctx, in, info, handler)
}
+func _VolumeServer_VolumeEcGenerateSlices_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(VolumeEcGenerateSlicesRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(VolumeServerServer).VolumeEcGenerateSlices(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/volume_server_pb.VolumeServer/VolumeEcGenerateSlices",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(VolumeServerServer).VolumeEcGenerateSlices(ctx, req.(*VolumeEcGenerateSlicesRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _VolumeServer_VolumeEcCopy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(VolumeEcCopyRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(VolumeServerServer).VolumeEcCopy(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/volume_server_pb.VolumeServer/VolumeEcCopy",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(VolumeServerServer).VolumeEcCopy(ctx, req.(*VolumeEcCopyRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
var _VolumeServer_serviceDesc = grpc.ServiceDesc{
ServiceName: "volume_server_pb.VolumeServer",
HandlerType: (*VolumeServerServer)(nil),
@@ -1664,6 +1804,14 @@ var _VolumeServer_serviceDesc = grpc.ServiceDesc{
MethodName: "VolumeTailReceiver",
Handler: _VolumeServer_VolumeTailReceiver_Handler,
},
+ {
+ MethodName: "VolumeEcGenerateSlices",
+ Handler: _VolumeServer_VolumeEcGenerateSlices_Handler,
+ },
+ {
+ MethodName: "VolumeEcCopy",
+ Handler: _VolumeServer_VolumeEcCopy_Handler,
+ },
},
Streams: []grpc.StreamDesc{
{
@@ -1688,95 +1836,101 @@ var _VolumeServer_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("volume_server.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
- // 1436 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xc4, 0x58, 0x4b, 0x73, 0xd4, 0xc6,
- 0x13, 0xb7, 0xd8, 0xb5, 0xbd, 0xee, 0x5d, 0x9b, 0x65, 0x6c, 0xf0, 0x7a, 0x79, 0x19, 0xc1, 0x1f,
- 0x96, 0xc7, 0xdf, 0x10, 0xa8, 0x24, 0x24, 0x39, 0x24, 0x60, 0x92, 0x0a, 0x55, 0x01, 0xaa, 0x64,
- 0xa0, 0x92, 0x4a, 0xaa, 0x54, 0x63, 0xa9, 0x8d, 0x55, 0xd6, 0x4a, 0x42, 0x33, 0x72, 0x70, 0x2a,
- 0xb7, 0xe4, 0x13, 0xe4, 0x2b, 0xe4, 0xc6, 0x21, 0xd7, 0x7c, 0xaa, 0x7c, 0x82, 0x5c, 0x52, 0xf3,
- 0x90, 0x76, 0xf5, 0xf2, 0x8a, 0x70, 0xc8, 0x6d, 0xb6, 0xa7, 0xdf, 0xea, 0xee, 0xf9, 0xf5, 0xc2,
- 0xea, 0x61, 0xe8, 0x27, 0x63, 0xb4, 0x19, 0xc6, 0x87, 0x18, 0x6f, 0x45, 0x71, 0xc8, 0x43, 0xd2,
- 0xcf, 0x11, 0xed, 0x68, 0xd7, 0xbc, 0x0d, 0xe4, 0x21, 0xe5, 0xce, 0xfe, 0x23, 0xf4, 0x91, 0xa3,
- 0x85, 0xaf, 0x13, 0x64, 0x9c, 0x6c, 0x40, 0x67, 0xcf, 0xf3, 0xd1, 0xf6, 0x5c, 0x36, 0x30, 0x36,
- 0x5b, 0xa3, 0x25, 0x6b, 0x51, 0xfc, 0x7e, 0xec, 0x32, 0xf3, 0x19, 0xac, 0xe6, 0x04, 0x58, 0x14,
- 0x06, 0x0c, 0xc9, 0x7d, 0x58, 0x8c, 0x91, 0x25, 0x3e, 0x57, 0x02, 0xdd, 0xbb, 0x17, 0xb6, 0x8a,
- 0xb6, 0xb6, 0x32, 0x91, 0xc4, 0xe7, 0x56, 0xca, 0x6e, 0x7a, 0xd0, 0x9b, 0xbe, 0x20, 0xeb, 0xb0,
- 0xa8, 0x6d, 0x0f, 0x8c, 0x4d, 0x63, 0xb4, 0x64, 0x2d, 0x28, 0xd3, 0xe4, 0x0c, 0x2c, 0x30, 0x4e,
- 0x79, 0xc2, 0x06, 0x27, 0x36, 0x8d, 0xd1, 0xbc, 0xa5, 0x7f, 0x91, 0x35, 0x98, 0xc7, 0x38, 0x0e,
- 0xe3, 0x41, 0x4b, 0xb2, 0xab, 0x1f, 0x84, 0x40, 0x9b, 0x79, 0x3f, 0xe1, 0xa0, 0xbd, 0x69, 0x8c,
- 0x96, 0x2d, 0x79, 0x36, 0x17, 0x61, 0xfe, 0xcb, 0x71, 0xc4, 0x8f, 0xcc, 0x8f, 0x61, 0xf0, 0x92,
- 0x3a, 0x49, 0x32, 0x7e, 0x29, 0x7d, 0xdc, 0xde, 0x47, 0xe7, 0x20, 0x8d, 0xfd, 0x2c, 0x2c, 0x69,
- 0xcf, 0xb5, 0x07, 0xcb, 0x56, 0x47, 0x11, 0x1e, 0xbb, 0xe6, 0x17, 0xb0, 0x51, 0x21, 0xa8, 0x73,
- 0x70, 0x19, 0x96, 0x5f, 0xd1, 0x78, 0x97, 0xbe, 0x42, 0x3b, 0xa6, 0xdc, 0x0b, 0xa5, 0xb4, 0x61,
- 0xf5, 0x34, 0xd1, 0x12, 0x34, 0xf3, 0x7b, 0x18, 0xe6, 0x34, 0x84, 0xe3, 0x88, 0x3a, 0xbc, 0x89,
- 0x71, 0xb2, 0x09, 0xdd, 0x28, 0x46, 0xea, 0xfb, 0xa1, 0x43, 0x39, 0xca, 0x2c, 0xb4, 0xac, 0x69,
- 0x92, 0x79, 0x1e, 0xce, 0x56, 0x2a, 0x57, 0x0e, 0x9a, 0xf7, 0x0b, 0xde, 0x87, 0xe3, 0xb1, 0xd7,
- 0xc8, 0xb4, 0x79, 0xae, 0xe4, 0xb5, 0x94, 0xd4, 0x7a, 0x3f, 0x29, 0xdc, 0xfa, 0x48, 0x83, 0x24,
- 0x6a, 0xa4, 0xb8, 0xe8, 0x71, 0x2a, 0x9a, 0x69, 0x5e, 0x57, 0xc5, 0xb1, 0x1d, 0xfa, 0x3e, 0x3a,
- 0xdc, 0x0b, 0x83, 0x54, 0xed, 0x05, 0x00, 0x27, 0x23, 0xea, 0x52, 0x99, 0xa2, 0x98, 0x43, 0x18,
- 0x94, 0x45, 0xb5, 0xda, 0xb7, 0x06, 0x9c, 0x7e, 0xa0, 0x93, 0xa6, 0x0c, 0x37, 0xfa, 0x00, 0x79,
- 0x93, 0x27, 0x8a, 0x26, 0x8b, 0x1f, 0xa8, 0x55, 0xfa, 0x40, 0x82, 0x23, 0xc6, 0xc8, 0xf7, 0x1c,
- 0x2a, 0x55, 0xb4, 0xa5, 0x8a, 0x69, 0x12, 0xe9, 0x43, 0x8b, 0x73, 0x7f, 0x30, 0x2f, 0x6f, 0xc4,
- 0xd1, 0x1c, 0xc0, 0x99, 0xa2, 0xaf, 0x3a, 0x8c, 0x8f, 0x60, 0x5d, 0x51, 0x76, 0x8e, 0x02, 0x67,
- 0x47, 0x76, 0x43, 0xa3, 0xa4, 0xff, 0x6d, 0xc0, 0xa0, 0x2c, 0xa8, 0xab, 0xf8, 0x7d, 0x33, 0xf0,
- 0xae, 0xf1, 0x91, 0x8b, 0xd0, 0xe5, 0xd4, 0xf3, 0xed, 0x70, 0x6f, 0x8f, 0x21, 0x1f, 0x2c, 0x6c,
- 0x1a, 0xa3, 0xb6, 0x05, 0x82, 0xf4, 0x4c, 0x52, 0xc8, 0x75, 0xe8, 0x3b, 0xaa, 0x92, 0xed, 0x18,
- 0x0f, 0x3d, 0x26, 0x34, 0x2f, 0x4a, 0xc7, 0x4e, 0x3a, 0x69, 0x85, 0x2b, 0x32, 0x31, 0x61, 0xd9,
- 0x73, 0xdf, 0xd8, 0x72, 0x80, 0xc8, 0xf6, 0xef, 0x48, 0x6d, 0x5d, 0xcf, 0x7d, 0xf3, 0x95, 0xe7,
- 0xe3, 0x8e, 0x98, 0x02, 0x2f, 0xe1, 0x9c, 0x0a, 0xfe, 0x71, 0xe0, 0xc4, 0x38, 0xc6, 0x80, 0x53,
- 0x7f, 0x3b, 0x8c, 0x8e, 0x1a, 0x95, 0xc0, 0x06, 0x74, 0x98, 0x17, 0x38, 0x68, 0x07, 0x6a, 0x0c,
- 0xb5, 0xad, 0x45, 0xf9, 0xfb, 0x29, 0x33, 0x1f, 0xc2, 0xf9, 0x1a, 0xbd, 0x3a, 0xb3, 0x97, 0xa0,
- 0x27, 0x1d, 0x73, 0xc2, 0x80, 0x63, 0xc0, 0xa5, 0xee, 0x9e, 0xd5, 0x15, 0xb4, 0x6d, 0x45, 0x32,
- 0x3f, 0x00, 0xa2, 0x74, 0x3c, 0x09, 0x93, 0xa0, 0x59, 0x6b, 0x9e, 0x86, 0xd5, 0x9c, 0x88, 0xae,
- 0x8d, 0x7b, 0xb0, 0xa6, 0xc8, 0x2f, 0x82, 0x71, 0x63, 0x5d, 0xeb, 0x70, 0xba, 0x20, 0xa4, 0xb5,
- 0xdd, 0x4d, 0x8d, 0xe4, 0xdf, 0x89, 0x63, 0x95, 0x9d, 0x49, 0x3d, 0xc8, 0x3f, 0x15, 0xe6, 0x1f,
- 0x06, 0x9c, 0x4a, 0xc7, 0x48, 0xc3, 0xac, 0xbf, 0x63, 0xd9, 0xb5, 0x6a, 0xcb, 0xae, 0x3d, 0x29,
- 0xbb, 0x11, 0xf4, 0x59, 0x98, 0xc4, 0x0e, 0xda, 0x2e, 0xe5, 0xd4, 0x0e, 0x42, 0x17, 0x75, 0x55,
- 0xae, 0x28, 0xfa, 0x23, 0xca, 0xe9, 0xd3, 0xd0, 0x45, 0xf3, 0xf3, 0xf4, 0xa3, 0xe4, 0xbe, 0xe6,
- 0x75, 0x38, 0xe5, 0x53, 0xc6, 0x6d, 0x1a, 0x45, 0x18, 0xb8, 0x36, 0xe5, 0xa2, 0x24, 0x0c, 0x59,
- 0x12, 0x2b, 0xe2, 0xe2, 0x81, 0xa4, 0x3f, 0xe0, 0x4f, 0x99, 0xf9, 0x9b, 0x01, 0x27, 0x85, 0xac,
- 0x28, 0xc1, 0x46, 0xf1, 0xf6, 0xa1, 0x85, 0x6f, 0xb8, 0x0e, 0x54, 0x1c, 0xc9, 0x6d, 0x58, 0xd5,
- 0xb5, 0xee, 0x85, 0xc1, 0xa4, 0x0d, 0x5a, 0x52, 0x90, 0x4c, 0xae, 0xb2, 0x4e, 0xb8, 0x08, 0x5d,
- 0xc6, 0xc3, 0x28, 0xed, 0xaa, 0xb6, 0xea, 0x2a, 0x41, 0x52, 0x5d, 0x65, 0x7e, 0x08, 0xfd, 0x89,
- 0x4f, 0xcd, 0x2b, 0xf4, 0x17, 0x23, 0x1d, 0x3a, 0xcf, 0xa9, 0xe7, 0xef, 0x60, 0xe0, 0x62, 0xfc,
- 0x9e, 0x9d, 0x43, 0xee, 0xc0, 0x9a, 0xe7, 0xfa, 0x68, 0x73, 0x6f, 0x8c, 0x61, 0xc2, 0x6d, 0x86,
- 0x4e, 0x18, 0xb8, 0x2c, 0x8d, 0x4e, 0xdc, 0x3d, 0x57, 0x57, 0x3b, 0xea, 0xc6, 0xfc, 0x35, 0x9b,
- 0x60, 0xd3, 0x5e, 0x4c, 0xde, 0xe1, 0x00, 0x51, 0x28, 0xdc, 0x47, 0xea, 0x62, 0xac, 0xc3, 0xe8,
- 0x29, 0xe2, 0xd7, 0x92, 0x26, 0xf2, 0xa3, 0x99, 0x76, 0x43, 0xf7, 0x48, 0x7a, 0xd4, 0xb3, 0x40,
- 0x91, 0x1e, 0x86, 0xee, 0x91, 0x1c, 0x25, 0xcc, 0x96, 0x9f, 0xd8, 0xd9, 0x4f, 0x82, 0x03, 0xe9,
- 0x4d, 0xc7, 0xea, 0x7a, 0xec, 0x1b, 0xca, 0xf8, 0xb6, 0x20, 0x99, 0x7f, 0x1a, 0xb0, 0x31, 0x71,
- 0xc3, 0x42, 0x07, 0xbd, 0xc3, 0xff, 0x20, 0x1d, 0x42, 0x42, 0xd7, 0x72, 0x0e, 0x74, 0xe9, 0x72,
- 0x27, 0xea, 0x4e, 0x4f, 0x7c, 0x79, 0x23, 0x1f, 0xf4, 0x0a, 0xc7, 0x75, 0x8b, 0x7e, 0x0a, 0x67,
- 0x2d, 0xa4, 0xae, 0xe2, 0x90, 0x83, 0xb3, 0xf9, 0xe3, 0xf2, 0xd7, 0x09, 0x38, 0x57, 0x2d, 0xdc,
- 0xe4, 0x81, 0xf9, 0x0c, 0x86, 0xd9, 0x00, 0x17, 0xf1, 0x33, 0x4e, 0xc7, 0x51, 0x96, 0x01, 0x95,
- 0xa8, 0x75, 0x3d, 0xcd, 0x9f, 0xa7, 0xf7, 0x69, 0x1a, 0x4a, 0xd3, 0xbf, 0x55, 0x9a, 0xfe, 0xc2,
- 0x80, 0x4b, 0x79, 0x9d, 0x01, 0xd5, 0x26, 0xeb, 0x2e, 0xe5, 0x75, 0x06, 0x32, 0x61, 0x69, 0x60,
- 0x5e, 0x19, 0xd0, 0xfc, 0xd2, 0xc0, 0x79, 0x00, 0xdd, 0x43, 0x49, 0x90, 0xbe, 0x66, 0x4b, 0xaa,
- 0x83, 0x92, 0xa0, 0xb6, 0x91, 0x17, 0x6b, 0x1b, 0x39, 0x3f, 0xfb, 0x3a, 0x25, 0x9c, 0xf3, 0x2d,
- 0xc0, 0x23, 0x8f, 0x1d, 0xa8, 0x24, 0x8b, 0xc9, 0xe1, 0x7a, 0xb1, 0x86, 0x43, 0xe2, 0x28, 0x28,
- 0xd4, 0xf7, 0x75, 0xea, 0xc4, 0x51, 0x40, 0xe3, 0x84, 0xa1, 0xab, 0xb3, 0x23, 0xcf, 0x82, 0xb6,
- 0x17, 0x23, 0xea, 0x04, 0xc8, 0xb3, 0xf9, 0xbb, 0x01, 0x4b, 0x4f, 0x70, 0xac, 0x35, 0x5f, 0x00,
- 0x78, 0x15, 0xc6, 0x61, 0xc2, 0xbd, 0x00, 0xd5, 0xa0, 0x9b, 0xb7, 0xa6, 0x28, 0xff, 0xde, 0x8e,
- 0x84, 0xea, 0xe8, 0xef, 0xe9, 0x64, 0xca, 0xb3, 0xa0, 0xed, 0x23, 0x8d, 0x74, 0xfe, 0xe4, 0x59,
- 0x00, 0x7d, 0xc6, 0xa9, 0x73, 0x20, 0x93, 0xd5, 0xb6, 0xd4, 0x8f, 0xbb, 0x6f, 0x57, 0xa0, 0x37,
- 0x5d, 0xda, 0xe4, 0x07, 0xe8, 0x4e, 0x6d, 0x28, 0xe4, 0x4a, 0x79, 0x11, 0x29, 0x6f, 0x3c, 0xc3,
- 0xff, 0xcd, 0xe0, 0xd2, 0x8d, 0x31, 0x47, 0x02, 0x38, 0x55, 0xda, 0x00, 0xc8, 0x8d, 0xb2, 0x74,
- 0xdd, 0x7e, 0x31, 0xbc, 0xd9, 0x88, 0x37, 0xb3, 0xc7, 0x61, 0xb5, 0x02, 0xd2, 0x93, 0x5b, 0x33,
- 0xb4, 0xe4, 0xd6, 0x8a, 0xe1, 0xff, 0x1b, 0x72, 0x67, 0x56, 0x5f, 0x03, 0x29, 0xe3, 0x7d, 0x72,
- 0x73, 0xa6, 0x9a, 0xc9, 0x3e, 0x31, 0xbc, 0xd5, 0x8c, 0xb9, 0x36, 0x50, 0xb5, 0x09, 0xcc, 0x0c,
- 0x34, 0xb7, 0x6b, 0xcc, 0x0c, 0xb4, 0xb0, 0x5e, 0xcc, 0x91, 0x03, 0xe8, 0x17, 0xb7, 0x04, 0x72,
- 0xbd, 0x6e, 0x75, 0x2d, 0x2d, 0x21, 0xc3, 0x1b, 0x4d, 0x58, 0x33, 0x63, 0x08, 0x2b, 0x79, 0x24,
- 0x4f, 0xae, 0x95, 0xe5, 0x2b, 0xf7, 0x92, 0xe1, 0x68, 0x36, 0xe3, 0x74, 0x4c, 0x45, 0x74, 0x5f,
- 0x15, 0x53, 0xcd, 0xea, 0x50, 0x15, 0x53, 0xdd, 0xb2, 0x60, 0xce, 0x91, 0x9f, 0x53, 0xc8, 0x58,
- 0x40, 0xbd, 0x64, 0xab, 0x4e, 0x4d, 0x35, 0xec, 0x1e, 0xde, 0x6e, 0xcc, 0x9f, 0xda, 0xbe, 0x63,
- 0x88, 0x5e, 0x9f, 0x02, 0xbf, 0x55, 0xbd, 0x5e, 0x86, 0xd3, 0x55, 0xbd, 0x5e, 0x85, 0xa0, 0xe7,
- 0xc8, 0x2e, 0x2c, 0xe7, 0xe0, 0x30, 0xb9, 0x5a, 0x27, 0x99, 0x07, 0xd9, 0xc3, 0x6b, 0x33, 0xf9,
- 0x32, 0x1b, 0x76, 0x3a, 0xbd, 0xf4, 0xb8, 0xaa, 0x75, 0x2e, 0x3f, 0xaf, 0xae, 0xce, 0x62, 0xcb,
- 0x0c, 0x7c, 0x07, 0x30, 0x41, 0xaf, 0xe4, 0x72, 0x9d, 0xdc, 0xf4, 0xa7, 0xb8, 0x72, 0x3c, 0x53,
- 0xa6, 0xfa, 0x47, 0x58, 0xab, 0x7a, 0xe9, 0x49, 0x45, 0x17, 0x1e, 0x03, 0x27, 0x86, 0x5b, 0x4d,
- 0xd9, 0x33, 0xc3, 0x2f, 0xa0, 0x93, 0x62, 0x57, 0x72, 0xa9, 0x2c, 0x5d, 0xc0, 0xda, 0x43, 0xf3,
- 0x38, 0x96, 0xa9, 0x6a, 0x1a, 0xa7, 0x8d, 0x33, 0x01, 0x95, 0xf5, 0x8d, 0x53, 0x82, 0xbf, 0xf5,
- 0x8d, 0x53, 0xc6, 0xa8, 0xd2, 0xdc, 0xeb, 0x74, 0xaf, 0x98, 0xc6, 0x60, 0x95, 0x43, 0xb6, 0x0e,
- 0x62, 0x56, 0x0e, 0xd9, 0x7a, 0x58, 0x37, 0xb7, 0xbb, 0x20, 0xff, 0x07, 0xbc, 0xf7, 0x4f, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x5d, 0xbf, 0x08, 0x06, 0x1e, 0x14, 0x00, 0x00,
+ // 1534 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xc4, 0x58, 0xcb, 0x6f, 0xd4, 0xd6,
+ 0x1a, 0x8f, 0x99, 0xc9, 0xeb, 0x9b, 0x04, 0x86, 0x93, 0x90, 0x4c, 0x0c, 0x09, 0x83, 0xe1, 0xc2,
+ 0xf0, 0xb8, 0x81, 0x0b, 0xba, 0xf7, 0xd2, 0x87, 0xd4, 0x42, 0xa0, 0x6d, 0xa4, 0x02, 0x92, 0x03,
+ 0xa8, 0x55, 0x2b, 0x59, 0x27, 0xf6, 0x17, 0x62, 0xc5, 0x63, 0x1b, 0xfb, 0x38, 0x4d, 0xaa, 0x76,
+ 0xd5, 0xae, 0xba, 0xec, 0xb6, 0xcb, 0xee, 0xba, 0xe8, 0xb6, 0x7f, 0x55, 0xff, 0x82, 0x6e, 0xaa,
+ 0xf3, 0xb0, 0x67, 0xfc, 0xca, 0x98, 0x52, 0xa9, 0xbb, 0x33, 0xdf, 0xf9, 0x5e, 0xe7, 0xf3, 0xf7,
+ 0xfa, 0x0d, 0x2c, 0x1d, 0x06, 0x5e, 0x32, 0x44, 0x2b, 0xc6, 0xe8, 0x10, 0xa3, 0xcd, 0x30, 0x0a,
+ 0x58, 0x40, 0xba, 0x39, 0xa2, 0x15, 0xee, 0x1a, 0xb7, 0x81, 0x3c, 0xa4, 0xcc, 0xde, 0x7f, 0x84,
+ 0x1e, 0x32, 0x34, 0xf1, 0x75, 0x82, 0x31, 0x23, 0x6b, 0x30, 0xb7, 0xe7, 0x7a, 0x68, 0xb9, 0x4e,
+ 0xdc, 0xd3, 0xfa, 0xad, 0xc1, 0xbc, 0x39, 0xcb, 0x7f, 0x6f, 0x3b, 0xb1, 0xf1, 0x0c, 0x96, 0x72,
+ 0x02, 0x71, 0x18, 0xf8, 0x31, 0x92, 0xfb, 0x30, 0x1b, 0x61, 0x9c, 0x78, 0x4c, 0x0a, 0x74, 0xee,
+ 0x6e, 0x6c, 0x16, 0x6d, 0x6d, 0x66, 0x22, 0x89, 0xc7, 0xcc, 0x94, 0xdd, 0x70, 0x61, 0x61, 0xfc,
+ 0x82, 0xac, 0xc2, 0xac, 0xb2, 0xdd, 0xd3, 0xfa, 0xda, 0x60, 0xde, 0x9c, 0x91, 0xa6, 0xc9, 0x0a,
+ 0xcc, 0xc4, 0x8c, 0xb2, 0x24, 0xee, 0x9d, 0xea, 0x6b, 0x83, 0x69, 0x53, 0xfd, 0x22, 0xcb, 0x30,
+ 0x8d, 0x51, 0x14, 0x44, 0xbd, 0x96, 0x60, 0x97, 0x3f, 0x08, 0x81, 0x76, 0xec, 0x7e, 0x8d, 0xbd,
+ 0x76, 0x5f, 0x1b, 0x2c, 0x9a, 0xe2, 0x6c, 0xcc, 0xc2, 0xf4, 0xe3, 0x61, 0xc8, 0x8e, 0x8d, 0xff,
+ 0x43, 0xef, 0x25, 0xb5, 0x93, 0x64, 0xf8, 0x52, 0xf8, 0xb8, 0xb5, 0x8f, 0xf6, 0x41, 0xfa, 0xf6,
+ 0xf3, 0x30, 0xaf, 0x3c, 0x57, 0x1e, 0x2c, 0x9a, 0x73, 0x92, 0xb0, 0xed, 0x18, 0x1f, 0xc2, 0x5a,
+ 0x85, 0xa0, 0x8a, 0xc1, 0x65, 0x58, 0x7c, 0x45, 0xa3, 0x5d, 0xfa, 0x0a, 0xad, 0x88, 0x32, 0x37,
+ 0x10, 0xd2, 0x9a, 0xb9, 0xa0, 0x88, 0x26, 0xa7, 0x19, 0x5f, 0x80, 0x9e, 0xd3, 0x10, 0x0c, 0x43,
+ 0x6a, 0xb3, 0x26, 0xc6, 0x49, 0x1f, 0x3a, 0x61, 0x84, 0xd4, 0xf3, 0x02, 0x9b, 0x32, 0x14, 0x51,
+ 0x68, 0x99, 0xe3, 0x24, 0x63, 0x1d, 0xce, 0x57, 0x2a, 0x97, 0x0e, 0x1a, 0xf7, 0x0b, 0xde, 0x07,
+ 0xc3, 0xa1, 0xdb, 0xc8, 0xb4, 0x71, 0xa1, 0xe4, 0xb5, 0x90, 0x54, 0x7a, 0xdf, 0x29, 0xdc, 0x7a,
+ 0x48, 0xfd, 0x24, 0x6c, 0xa4, 0xb8, 0xe8, 0x71, 0x2a, 0x9a, 0x69, 0x5e, 0x95, 0xc9, 0xb1, 0x15,
+ 0x78, 0x1e, 0xda, 0xcc, 0x0d, 0xfc, 0x54, 0xed, 0x06, 0x80, 0x9d, 0x11, 0x55, 0xaa, 0x8c, 0x51,
+ 0x0c, 0x1d, 0x7a, 0x65, 0x51, 0xa5, 0xf6, 0x17, 0x0d, 0xce, 0x3d, 0x50, 0x41, 0x93, 0x86, 0x1b,
+ 0x7d, 0x80, 0xbc, 0xc9, 0x53, 0x45, 0x93, 0xc5, 0x0f, 0xd4, 0x2a, 0x7d, 0x20, 0xce, 0x11, 0x61,
+ 0xe8, 0xb9, 0x36, 0x15, 0x2a, 0xda, 0x42, 0xc5, 0x38, 0x89, 0x74, 0xa1, 0xc5, 0x98, 0xd7, 0x9b,
+ 0x16, 0x37, 0xfc, 0x68, 0xf4, 0x60, 0xa5, 0xe8, 0xab, 0x7a, 0xc6, 0xff, 0x60, 0x55, 0x52, 0x76,
+ 0x8e, 0x7d, 0x7b, 0x47, 0x54, 0x43, 0xa3, 0xa0, 0xff, 0xa1, 0x41, 0xaf, 0x2c, 0xa8, 0xb2, 0xf8,
+ 0x6d, 0x23, 0xf0, 0xa6, 0xef, 0x23, 0x17, 0xa1, 0xc3, 0xa8, 0xeb, 0x59, 0xc1, 0xde, 0x5e, 0x8c,
+ 0xac, 0x37, 0xd3, 0xd7, 0x06, 0x6d, 0x13, 0x38, 0xe9, 0x99, 0xa0, 0x90, 0xeb, 0xd0, 0xb5, 0x65,
+ 0x26, 0x5b, 0x11, 0x1e, 0xba, 0x31, 0xd7, 0x3c, 0x2b, 0x1c, 0x3b, 0x63, 0xa7, 0x19, 0x2e, 0xc9,
+ 0xc4, 0x80, 0x45, 0xd7, 0x39, 0xb2, 0x44, 0x03, 0x11, 0xe5, 0x3f, 0x27, 0xb4, 0x75, 0x5c, 0xe7,
+ 0xe8, 0x23, 0xd7, 0xc3, 0x1d, 0xde, 0x05, 0x5e, 0xc2, 0x05, 0xf9, 0xf8, 0x6d, 0xdf, 0x8e, 0x70,
+ 0x88, 0x3e, 0xa3, 0xde, 0x56, 0x10, 0x1e, 0x37, 0x4a, 0x81, 0x35, 0x98, 0x8b, 0x5d, 0xdf, 0x46,
+ 0xcb, 0x97, 0x6d, 0xa8, 0x6d, 0xce, 0x8a, 0xdf, 0x4f, 0x63, 0xe3, 0x21, 0xac, 0xd7, 0xe8, 0x55,
+ 0x91, 0xbd, 0x04, 0x0b, 0xc2, 0x31, 0x3b, 0xf0, 0x19, 0xfa, 0x4c, 0xe8, 0x5e, 0x30, 0x3b, 0x9c,
+ 0xb6, 0x25, 0x49, 0xc6, 0x7f, 0x80, 0x48, 0x1d, 0x4f, 0x82, 0xc4, 0x6f, 0x56, 0x9a, 0xe7, 0x60,
+ 0x29, 0x27, 0xa2, 0x72, 0xe3, 0x1e, 0x2c, 0x4b, 0xf2, 0x0b, 0x7f, 0xd8, 0x58, 0xd7, 0x2a, 0x9c,
+ 0x2b, 0x08, 0x29, 0x6d, 0x77, 0x53, 0x23, 0xf9, 0x39, 0x71, 0xa2, 0xb2, 0x95, 0xd4, 0x83, 0xfc,
+ 0xa8, 0x30, 0x7e, 0xd5, 0xe0, 0x6c, 0xda, 0x46, 0x1a, 0x46, 0xfd, 0x0d, 0xd3, 0xae, 0x55, 0x9b,
+ 0x76, 0xed, 0x51, 0xda, 0x0d, 0xa0, 0x1b, 0x07, 0x49, 0x64, 0xa3, 0xe5, 0x50, 0x46, 0x2d, 0x3f,
+ 0x70, 0x50, 0x65, 0xe5, 0x69, 0x49, 0x7f, 0x44, 0x19, 0x7d, 0x1a, 0x38, 0x68, 0x7c, 0x90, 0x7e,
+ 0x94, 0xdc, 0xd7, 0xbc, 0x0e, 0x67, 0x3d, 0x1a, 0x33, 0x8b, 0x86, 0x21, 0xfa, 0x8e, 0x45, 0x19,
+ 0x4f, 0x09, 0x4d, 0xa4, 0xc4, 0x69, 0x7e, 0xf1, 0x40, 0xd0, 0x1f, 0xb0, 0xa7, 0xb1, 0xf1, 0xa3,
+ 0x06, 0x67, 0xb8, 0x2c, 0x4f, 0xc1, 0x46, 0xef, 0xed, 0x42, 0x0b, 0x8f, 0x98, 0x7a, 0x28, 0x3f,
+ 0x92, 0xdb, 0xb0, 0xa4, 0x72, 0xdd, 0x0d, 0xfc, 0x51, 0x19, 0xb4, 0x84, 0x20, 0x19, 0x5d, 0x65,
+ 0x95, 0x70, 0x11, 0x3a, 0x31, 0x0b, 0xc2, 0xb4, 0xaa, 0xda, 0xb2, 0xaa, 0x38, 0x49, 0x56, 0x95,
+ 0xf1, 0x5f, 0xe8, 0x8e, 0x7c, 0x6a, 0x9e, 0xa1, 0xdf, 0x69, 0x69, 0xd3, 0x79, 0x4e, 0x5d, 0x6f,
+ 0x07, 0x7d, 0x07, 0xa3, 0xb7, 0xac, 0x1c, 0x72, 0x07, 0x96, 0x5d, 0xc7, 0x43, 0x8b, 0xb9, 0x43,
+ 0x0c, 0x12, 0x66, 0xc5, 0x68, 0x07, 0xbe, 0x13, 0xa7, 0xaf, 0xe3, 0x77, 0xcf, 0xe5, 0xd5, 0x8e,
+ 0xbc, 0x31, 0xbe, 0xcf, 0x3a, 0xd8, 0xb8, 0x17, 0xa3, 0x39, 0xec, 0x23, 0x72, 0x85, 0xfb, 0x48,
+ 0x1d, 0x8c, 0xd4, 0x33, 0x16, 0x24, 0xf1, 0x13, 0x41, 0xe3, 0xf1, 0x51, 0x4c, 0xbb, 0x81, 0x73,
+ 0x2c, 0x3c, 0x5a, 0x30, 0x41, 0x92, 0x1e, 0x06, 0xce, 0xb1, 0x68, 0x25, 0xb1, 0x25, 0x3e, 0xb1,
+ 0xbd, 0x9f, 0xf8, 0x07, 0xc2, 0x9b, 0x39, 0xb3, 0xe3, 0xc6, 0x9f, 0xd2, 0x98, 0x6d, 0x71, 0x92,
+ 0xf1, 0x9b, 0x06, 0x6b, 0x23, 0x37, 0x4c, 0xb4, 0xd1, 0x3d, 0xfc, 0x07, 0xc2, 0xc1, 0x25, 0x54,
+ 0x2e, 0xe7, 0x96, 0x2e, 0x95, 0xee, 0x44, 0xde, 0xa9, 0x8e, 0x2f, 0x6e, 0xc4, 0x40, 0xaf, 0x70,
+ 0x5c, 0x95, 0xe8, 0xfb, 0x69, 0x2b, 0x7b, 0x6c, 0x7f, 0x8c, 0x3e, 0x46, 0x94, 0xe1, 0x8e, 0xe7,
+ 0xda, 0xd8, 0x6c, 0xbc, 0xf4, 0x61, 0xa3, 0x4e, 0x5a, 0xe9, 0xff, 0x49, 0x4b, 0xfb, 0xc9, 0x63,
+ 0xfb, 0x6f, 0x6b, 0x02, 0xeb, 0x00, 0x68, 0x5b, 0xae, 0xef, 0xe0, 0x11, 0xf2, 0x60, 0xb5, 0x06,
+ 0x8b, 0xe6, 0x3c, 0xda, 0xdb, 0x92, 0xf0, 0x06, 0xf5, 0x9e, 0x35, 0xae, 0xd4, 0x39, 0xe5, 0xf5,
+ 0xbb, 0x70, 0xde, 0x44, 0xea, 0xc8, 0x3b, 0x31, 0x4e, 0x9a, 0x8f, 0xdc, 0xdf, 0x4f, 0xc1, 0x85,
+ 0x6a, 0xe1, 0x26, 0x63, 0xf7, 0x3d, 0xd0, 0xb3, 0xb1, 0xc6, 0xb3, 0x22, 0x66, 0x74, 0x18, 0x66,
+ 0x79, 0x21, 0xd3, 0x67, 0x55, 0xcd, 0xb8, 0xe7, 0xe9, 0x7d, 0x9a, 0x1c, 0xa5, 0x99, 0xd8, 0x2a,
+ 0xcd, 0x44, 0x6e, 0xc0, 0xa1, 0xac, 0xce, 0x80, 0x6c, 0x1e, 0xab, 0x0e, 0x65, 0x75, 0x06, 0x32,
+ 0x61, 0x61, 0x60, 0x5a, 0x1a, 0x50, 0xfc, 0xc2, 0xc0, 0x3a, 0x80, 0xea, 0x2c, 0x89, 0x9f, 0xce,
+ 0xf8, 0x79, 0xd9, 0x57, 0x12, 0xbf, 0xb6, 0xbd, 0xcd, 0xd6, 0xb6, 0xb7, 0x7c, 0x32, 0xcc, 0x95,
+ 0xb6, 0xbf, 0xcf, 0x00, 0x1e, 0xb9, 0xf1, 0x81, 0x0c, 0x32, 0xef, 0xa7, 0x8e, 0x1b, 0xa9, 0x25,
+ 0x91, 0x1f, 0x39, 0x85, 0x7a, 0x9e, 0x0a, 0x1d, 0x3f, 0x72, 0xc0, 0x90, 0xc4, 0xe8, 0xa8, 0xe8,
+ 0x88, 0x33, 0xa7, 0xed, 0x45, 0x88, 0x2a, 0x00, 0xe2, 0x6c, 0xfc, 0xac, 0xc1, 0xfc, 0x13, 0x1c,
+ 0x2a, 0xcd, 0x1b, 0x00, 0xaf, 0x82, 0x28, 0x48, 0x98, 0xeb, 0xa3, 0x6c, 0xff, 0xd3, 0xe6, 0x18,
+ 0xe5, 0xaf, 0xdb, 0x11, 0x00, 0x06, 0xbd, 0x3d, 0x15, 0x4c, 0x71, 0xe6, 0xb4, 0x7d, 0xa4, 0xa1,
+ 0x8a, 0x9f, 0x38, 0x73, 0xf8, 0x13, 0x33, 0x6a, 0x1f, 0x88, 0x60, 0xb5, 0x4d, 0xf9, 0xe3, 0xee,
+ 0x0f, 0x5d, 0x58, 0x18, 0x2f, 0x78, 0xf2, 0x25, 0x74, 0xc6, 0x70, 0x1b, 0xb9, 0x52, 0x86, 0x67,
+ 0x65, 0x1c, 0xa8, 0xff, 0x6b, 0x02, 0x97, 0x2a, 0x8c, 0x29, 0xe2, 0xc3, 0xd9, 0x12, 0x2e, 0x22,
+ 0x37, 0xca, 0xd2, 0x75, 0xa8, 0x4b, 0xbf, 0xd9, 0x88, 0x37, 0xb3, 0xc7, 0x60, 0xa9, 0x02, 0xe8,
+ 0x90, 0x5b, 0x13, 0xb4, 0xe4, 0xc0, 0x96, 0xfe, 0xef, 0x86, 0xdc, 0x99, 0xd5, 0xd7, 0x40, 0xca,
+ 0x28, 0x88, 0xdc, 0x9c, 0xa8, 0x66, 0x84, 0xb2, 0xf4, 0x5b, 0xcd, 0x98, 0x6b, 0x1f, 0x2a, 0xf1,
+ 0xd1, 0xc4, 0x87, 0xe6, 0x10, 0xd8, 0xc4, 0x87, 0x16, 0x40, 0xd7, 0x14, 0x39, 0x80, 0x6e, 0x11,
+ 0x3b, 0x91, 0xeb, 0x75, 0x80, 0xbe, 0x04, 0xcd, 0xf4, 0x1b, 0x4d, 0x58, 0x33, 0x63, 0x08, 0xa7,
+ 0xf3, 0xf8, 0x86, 0x5c, 0x2b, 0xcb, 0x57, 0xa2, 0x35, 0x7d, 0x30, 0x99, 0x71, 0xfc, 0x4d, 0x45,
+ 0xcc, 0x53, 0xf5, 0xa6, 0x1a, 0x40, 0x55, 0xf5, 0xa6, 0x3a, 0x08, 0x65, 0x4c, 0x91, 0x6f, 0xd2,
+ 0x45, 0xba, 0x80, 0x05, 0xc8, 0x66, 0x9d, 0x9a, 0x6a, 0x30, 0xa2, 0xdf, 0x6e, 0xcc, 0x9f, 0xda,
+ 0xbe, 0xa3, 0xf1, 0x5a, 0x1f, 0x83, 0x04, 0x55, 0xb5, 0x5e, 0x06, 0x19, 0x55, 0xb5, 0x5e, 0x85,
+ 0x2b, 0xa6, 0xc8, 0x2e, 0x2c, 0xe6, 0x40, 0x02, 0xb9, 0x5a, 0x27, 0x99, 0x87, 0x1e, 0xfa, 0xb5,
+ 0x89, 0x7c, 0x99, 0x0d, 0x2b, 0xed, 0x5e, 0xaa, 0x5d, 0xd5, 0x3a, 0x97, 0xef, 0x57, 0x57, 0x27,
+ 0xb1, 0x65, 0x06, 0x3e, 0x07, 0x18, 0xed, 0xf4, 0xe4, 0x72, 0x9d, 0xdc, 0xf8, 0xa7, 0xb8, 0x72,
+ 0x32, 0x53, 0xa6, 0xfa, 0x2b, 0x58, 0xae, 0x9a, 0xf4, 0xa4, 0xa2, 0x0a, 0x4f, 0x58, 0x27, 0xf4,
+ 0xcd, 0xa6, 0xec, 0x99, 0xe1, 0x17, 0x30, 0x97, 0x6e, 0xf4, 0xe4, 0x52, 0x59, 0xba, 0x80, 0x40,
+ 0x74, 0xe3, 0x24, 0x96, 0xb1, 0x6c, 0x1a, 0xa6, 0x85, 0x33, 0x5a, 0xb5, 0xeb, 0x0b, 0xa7, 0x04,
+ 0x0a, 0xea, 0x0b, 0xa7, 0xbc, 0xb9, 0x0b, 0x73, 0xaf, 0x53, 0xb4, 0x35, 0xbe, 0x99, 0x56, 0x36,
+ 0xd9, 0xba, 0xc5, 0xbb, 0xb2, 0xc9, 0xd6, 0x2f, 0xbb, 0x53, 0xe4, 0x5b, 0x58, 0xa9, 0x5e, 0x58,
+ 0x49, 0x6d, 0xf9, 0xd5, 0x2c, 0xc6, 0xfa, 0x9d, 0xe6, 0x02, 0xe5, 0x64, 0x97, 0xfb, 0x66, 0x7d,
+ 0xb2, 0xe7, 0x96, 0xe5, 0xfa, 0x64, 0x2f, 0xac, 0xad, 0x53, 0xbb, 0x33, 0xe2, 0xdf, 0xdf, 0x7b,
+ 0x7f, 0x06, 0x00, 0x00, 0xff, 0xff, 0x2f, 0xf9, 0x4c, 0xc9, 0x14, 0x16, 0x00, 0x00,
}
diff --git a/weed/server/volume_grpc_copy.go b/weed/server/volume_grpc_copy.go
index 6bb61dfba..7b681aa53 100644
--- a/weed/server/volume_grpc_copy.go
+++ b/weed/server/volume_grpc_copy.go
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"io"
+ "math"
"os"
"time"
@@ -49,37 +50,13 @@ func (vs *VolumeServer) VolumeCopy(ctx context.Context, req *volume_server_pb.Vo
volumeFileName = storage.VolumeFileName(volFileInfoResp.Collection, location.Directory, int(req.VolumeId))
// println("source:", volFileInfoResp.String())
-
- copyFileClient, err := client.CopyFile(ctx, &volume_server_pb.CopyFileRequest{
- VolumeId: req.VolumeId,
- Ext: ".idx",
- CompactionRevision: volFileInfoResp.CompactionRevision,
- StopOffset: volFileInfoResp.IdxFileSize,
- })
- if err != nil {
- return fmt.Errorf("failed to start copying volume %d idx file: %v", req.VolumeId, err)
- }
-
- idxFileName = volumeFileName + ".idx"
- err = writeToFile(copyFileClient, idxFileName, util.NewWriteThrottler(vs.compactionBytePerSecond))
- if err != nil {
- return fmt.Errorf("failed to copy volume %d idx file: %v", req.VolumeId, err)
- }
-
- copyFileClient, err = client.CopyFile(ctx, &volume_server_pb.CopyFileRequest{
- VolumeId: req.VolumeId,
- Ext: ".dat",
- CompactionRevision: volFileInfoResp.CompactionRevision,
- StopOffset: volFileInfoResp.DatFileSize,
- })
- if err != nil {
- return fmt.Errorf("failed to start copying volume %d dat file: %v", req.VolumeId, err)
+ // copy ecx file
+ if err:=vs.doCopyFile(ctx, client, req.VolumeId, volFileInfoResp.CompactionRevision, volFileInfoResp.IdxFileSize, volumeFileName, ".idx"); err!=nil{
+ return err
}
- datFileName = volumeFileName + ".dat"
- err = writeToFile(copyFileClient, datFileName, util.NewWriteThrottler(vs.compactionBytePerSecond))
- if err != nil {
- return fmt.Errorf("failed to copy volume %d dat file: %v", req.VolumeId, err)
+ if err:=vs.doCopyFile(ctx, client, req.VolumeId, volFileInfoResp.CompactionRevision, volFileInfoResp.DatFileSize, volumeFileName, ".dat"); err!=nil{
+ return err
}
return nil
@@ -109,6 +86,28 @@ func (vs *VolumeServer) VolumeCopy(ctx context.Context, req *volume_server_pb.Vo
}, err
}
+func (vs *VolumeServer) doCopyFile(ctx context.Context, client volume_server_pb.VolumeServerClient, vid uint32,
+ compactRevision uint32, stopOffset uint64, baseFileName, ext string) error {
+
+ copyFileClient, err := client.CopyFile(ctx, &volume_server_pb.CopyFileRequest{
+ VolumeId: vid,
+ Ext: ext,
+ CompactionRevision: compactRevision,
+ StopOffset: stopOffset,
+ })
+ if err != nil {
+ return fmt.Errorf("failed to start copying volume %d %s file: %v", vid, ext, err)
+ }
+
+ err = writeToFile(copyFileClient, baseFileName+ext, util.NewWriteThrottler(vs.compactionBytePerSecond))
+ if err != nil {
+ return fmt.Errorf("failed to copy volume %d %s file: %v", vid, ext, err)
+ }
+
+ return nil
+
+}
+
/**
only check the the differ of the file size
todo: maybe should check the received count and deleted count of the volume
@@ -175,6 +174,9 @@ func (vs *VolumeServer) ReadVolumeFileStatus(ctx context.Context, req *volume_se
return resp, nil
}
+// CopyFile client pulls the volume related file from the source server.
+// if req.CompactionRevision != math.MaxUint32, it ensures the compact revision is as expected
+// The copying still stop at req.StopOffset, but you can set it to math.MaxUint64 in order to read all data.
func (vs *VolumeServer) CopyFile(req *volume_server_pb.CopyFileRequest, stream volume_server_pb.VolumeServer_CopyFileServer) error {
v := vs.store.GetVolume(needle.VolumeId(req.VolumeId))
@@ -182,7 +184,7 @@ func (vs *VolumeServer) CopyFile(req *volume_server_pb.CopyFileRequest, stream v
return fmt.Errorf("not found volume id %d", req.VolumeId)
}
- if uint32(v.CompactionRevision) != req.CompactionRevision {
+ if uint32(v.CompactionRevision) != req.CompactionRevision && req.CompactionRevision != math.MaxUint32 {
return fmt.Errorf("volume %d is compacted", req.VolumeId)
}
diff --git a/weed/server/volume_grpc_erasure_coding.go b/weed/server/volume_grpc_erasure_coding.go
new file mode 100644
index 000000000..beda234f7
--- /dev/null
+++ b/weed/server/volume_grpc_erasure_coding.go
@@ -0,0 +1,82 @@
+package weed_server
+
+import (
+ "context"
+ "fmt"
+ "math"
+
+ "github.com/chrislusf/seaweedfs/weed/operation"
+ "github.com/chrislusf/seaweedfs/weed/pb/volume_server_pb"
+ "github.com/chrislusf/seaweedfs/weed/storage"
+ "github.com/chrislusf/seaweedfs/weed/storage/erasure_coding"
+ "github.com/chrislusf/seaweedfs/weed/storage/needle"
+)
+
+/*
+
+Steps to apply erasure coding to .dat .idx files
+0. ensure the volume is readonly
+1. client call VolumeEcGenerateSlices to generate the .ecx and .ec01~.ec14 files
+2. client ask master for possible servers to hold the ec files, at least 4 servers
+3. client call VolumeEcCopy on above target servers to copy ec files from the source server
+4. target servers report the new ec files to the master
+5. master stores vid -> [14]*DataNode
+6. client checks master. If all 14 slices are ready, delete the original .idx, .idx files
+
+ */
+
+// VolumeEcGenerateSlices generates the .ecx and .ec01 ~ .ec14 files
+func (vs *VolumeServer) VolumeEcGenerateSlices(ctx context.Context, req *volume_server_pb.VolumeEcGenerateSlicesRequest) (*volume_server_pb.VolumeEcGenerateSlicesResponse, error) {
+
+ v := vs.store.GetVolume(needle.VolumeId(req.VolumeId))
+ if v == nil {
+ return nil, fmt.Errorf("volume %d not found", req.VolumeId)
+ }
+ baseFileName := v.FileName()
+
+ // write .ecx file
+ if err := erasure_coding.WriteSortedEcxFile(baseFileName); err != nil {
+ return nil, fmt.Errorf("WriteSortedEcxFile %s: %v", baseFileName, err)
+ }
+
+ // write .ec01 ~ .ec14 files
+ if err := erasure_coding.WriteEcFiles(baseFileName); err != nil {
+ return nil, fmt.Errorf("WriteEcFiles %s: %v", baseFileName, err)
+ }
+
+
+ return &volume_server_pb.VolumeEcGenerateSlicesResponse{}, nil
+}
+
+// VolumeEcCopy copy the .ecx and some ec data slices
+func (vs *VolumeServer) VolumeEcCopy(ctx context.Context, req *volume_server_pb.VolumeEcCopyRequest) (*volume_server_pb.VolumeEcCopyResponse, error) {
+
+ location := vs.store.FindFreeLocation()
+ if location == nil {
+ return nil, fmt.Errorf("no space left")
+ }
+
+ baseFileName := storage.VolumeFileName(req.Collection, location.Directory, int(req.VolumeId))
+
+ err := operation.WithVolumeServerClient(req.SourceDataNode, vs.grpcDialOption, func(client volume_server_pb.VolumeServerClient) error {
+
+ // copy ecx file
+ if err:=vs.doCopyFile(ctx, client, req.VolumeId, math.MaxUint32, math.MaxUint64, baseFileName, ".ecx"); err!=nil{
+ return err
+ }
+
+ // copy ec data slices
+ for _, ecIndex := range req.EcIndexes {
+ if err:=vs.doCopyFile(ctx, client, req.VolumeId, math.MaxUint32, math.MaxUint64, baseFileName, erasure_coding.ToExt(int(ecIndex))); err!=nil{
+ return err
+ }
+ }
+
+ return nil
+ })
+ if err != nil {
+ return nil, fmt.Errorf("VolumeEcCopy volume %d: %v", req.VolumeId, err)
+ }
+
+ return &volume_server_pb.VolumeEcCopyResponse{}, nil
+}
diff --git a/weed/storage/erasure_coding/ec_encoder.go b/weed/storage/erasure_coding/ec_encoder.go
index 4b5205dee..f4aa17e9d 100644
--- a/weed/storage/erasure_coding/ec_encoder.go
+++ b/weed/storage/erasure_coding/ec_encoder.go
@@ -6,6 +6,9 @@ import (
"os"
"github.com/chrislusf/seaweedfs/weed/glog"
+ "github.com/chrislusf/seaweedfs/weed/storage"
+ "github.com/chrislusf/seaweedfs/weed/storage/needle_map"
+ "github.com/chrislusf/seaweedfs/weed/storage/types"
"github.com/klauspost/reedsolomon"
)
@@ -16,11 +19,66 @@ const (
ErasureCodingSmallBlockSize = 1024 * 1024 // 1MB
)
+// WriteSortedEcxFile generates .ecx file from existing .idx file
+// all keys are sorted in ascending order
+func WriteSortedEcxFile(baseFileName string) (e error) {
+
+ cm, err := readCompactMap(baseFileName)
+ if err != nil {
+ return fmt.Errorf("readCompactMap: %v", err)
+ }
+
+ ecxFile, err := os.OpenFile(baseFileName+".ecx", os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
+ if err != nil {
+ return fmt.Errorf("failed to open dat file: %v", err)
+ }
+ defer ecxFile.Close()
+
+ err = cm.AscendingVisit(func(value needle_map.NeedleValue) error {
+ bytes := value.ToBytes()
+ _, writeErr := ecxFile.Write(bytes)
+ return writeErr
+ })
+
+ if err != nil {
+ return fmt.Errorf("failed to open dat file: %v", err)
+ }
+
+ return nil
+}
+
+// WriteEcFiles generates .ec01 ~ .ec14 files
+func WriteEcFiles(baseFileName string) error {
+ return generateEcFiles(baseFileName, 256*1024, ErasureCodingLargeBlockSize, ErasureCodingSmallBlockSize)
+}
+
+func ToExt(ecIndex int) string {
+ return fmt.Sprintf(".ec%02d", ecIndex)
+}
+
+func generateEcFiles(baseFileName string, bufferSize int, largeBlockSize int64, smallBlockSize int64) error {
+ file, err := os.OpenFile(baseFileName+".dat", os.O_RDONLY, 0)
+ if err != nil {
+ return fmt.Errorf("failed to open dat file: %v", err)
+ }
+ defer file.Close()
+
+ fi, err := file.Stat()
+ if err != nil {
+ return fmt.Errorf("failed to stat dat file: %v", err)
+ }
+ err = encodeDatFile(fi.Size(), err, baseFileName, bufferSize, largeBlockSize, file, smallBlockSize)
+ if err != nil {
+ return fmt.Errorf("encodeDatFile: %v", err)
+ }
+ return nil
+}
+
func encodeData(file *os.File, enc reedsolomon.Encoder, startOffset, blockSize int64, buffers [][]byte, outputs []*os.File) error {
bufferSize := int64(len(buffers[0]))
- batchCount := blockSize/bufferSize
- if blockSize%bufferSize!=0 {
+ batchCount := blockSize / bufferSize
+ if blockSize%bufferSize != 0 {
glog.Fatalf("unexpected block size %d buffer size %d", blockSize, bufferSize)
}
@@ -34,10 +92,10 @@ func encodeData(file *os.File, enc reedsolomon.Encoder, startOffset, blockSize i
return nil
}
-func openEcFiles(baseFileName string, forRead bool) (files []*os.File, err error){
- for i := 0; i< DataShardsCount+ParityShardsCount; i++{
- fname := fmt.Sprintf("%s.ec%02d", baseFileName, i+1)
- openOption := os.O_TRUNC|os.O_CREATE|os.O_WRONLY
+func openEcFiles(baseFileName string, forRead bool) (files []*os.File, err error) {
+ for i := 0; i < DataShardsCount+ParityShardsCount; i++ {
+ fname := baseFileName + ToExt(i+1)
+ openOption := os.O_TRUNC | os.O_CREATE | os.O_WRONLY
if forRead {
openOption = os.O_RDONLY
}
@@ -50,15 +108,14 @@ func openEcFiles(baseFileName string, forRead bool) (files []*os.File, err error
return
}
-func closeEcFiles(files []*os.File){
- for _, f := range files{
+func closeEcFiles(files []*os.File) {
+ for _, f := range files {
if f != nil {
f.Close()
}
}
}
-
func encodeDataOneBatch(file *os.File, enc reedsolomon.Encoder, startOffset, blockSize int64, buffers [][]byte, outputs []*os.File) error {
// read data into buffers
@@ -90,3 +147,56 @@ func encodeDataOneBatch(file *os.File, enc reedsolomon.Encoder, startOffset, blo
return nil
}
+
+func encodeDatFile(remainingSize int64, err error, baseFileName string, bufferSize int, largeBlockSize int64, file *os.File, smallBlockSize int64) error {
+ var processedSize int64
+ enc, err := reedsolomon.New(DataShardsCount, ParityShardsCount)
+ if err != nil {
+ return fmt.Errorf("failed to create encoder: %v", err)
+ }
+ buffers := make([][]byte, DataShardsCount+ParityShardsCount)
+ outputs, err := openEcFiles(baseFileName, false)
+ defer closeEcFiles(outputs)
+ if err != nil {
+ return fmt.Errorf("failed to open dat file: %v", err)
+ }
+ for i, _ := range buffers {
+ buffers[i] = make([]byte, bufferSize)
+ }
+ for remainingSize > largeBlockSize*DataShardsCount {
+ err = encodeData(file, enc, processedSize, largeBlockSize, buffers, outputs)
+ if err != nil {
+ return fmt.Errorf("failed to encode large chunk data: %v", err)
+ }
+ remainingSize -= largeBlockSize * DataShardsCount
+ processedSize += largeBlockSize * DataShardsCount
+ }
+ for remainingSize > 0 {
+ encodeData(file, enc, processedSize, smallBlockSize, buffers, outputs)
+ if err != nil {
+ return fmt.Errorf("failed to encode small chunk data: %v", err)
+ }
+ remainingSize -= smallBlockSize * DataShardsCount
+ processedSize += smallBlockSize * DataShardsCount
+ }
+ return nil
+}
+
+func readCompactMap(baseFileName string) (*needle_map.CompactMap, error) {
+ indexFile, err := os.OpenFile(baseFileName+".idx", os.O_RDONLY, 0644)
+ if err != nil {
+ return nil, fmt.Errorf("cannot read Volume Index %s.idx: %v", baseFileName, err)
+ }
+ defer indexFile.Close()
+
+ cm := needle_map.NewCompactMap()
+ err = storage.WalkIndexFile(indexFile, func(key types.NeedleId, offset types.Offset, size uint32) error {
+ if !offset.IsZero() && size != types.TombstoneFileSize {
+ cm.Set(key, offset, size)
+ } else {
+ cm.Delete(key)
+ }
+ return nil
+ })
+ return cm, err
+}
diff --git a/weed/storage/erasure_coding/ec_test.go b/weed/storage/erasure_coding/ec_test.go
index d631471e9..625f4e9a6 100644
--- a/weed/storage/erasure_coding/ec_test.go
+++ b/weed/storage/erasure_coding/ec_test.go
@@ -7,7 +7,6 @@ import (
"os"
"testing"
- "github.com/chrislusf/seaweedfs/weed/storage"
"github.com/chrislusf/seaweedfs/weed/storage/needle_map"
"github.com/chrislusf/seaweedfs/weed/storage/types"
"github.com/klauspost/reedsolomon"
@@ -27,98 +26,20 @@ func TestEncodingDecoding(t *testing.T) {
t.Logf("generateEcFiles: %v", err)
}
- err = writeSortedEcxFiles(baseFileName)
+ err = WriteSortedEcxFile(baseFileName)
if err != nil {
- t.Logf("writeSortedEcxFiles: %v", err)
+ t.Logf("WriteSortedEcxFile: %v", err)
}
err = validateFiles(baseFileName)
if err != nil {
- t.Logf("writeSortedEcxFiles: %v", err)
+ t.Logf("WriteSortedEcxFile: %v", err)
}
removeGeneratedFiles(baseFileName)
}
-func generateEcFiles(baseFileName string, bufferSize int, largeBlockSize int64, smallBlockSize int64) error {
- file, err := os.OpenFile(baseFileName+".dat", os.O_RDONLY, 0)
- if err != nil {
- return fmt.Errorf("failed to open dat file: %v", err)
- }
- defer file.Close()
-
- fi, err := file.Stat()
- if err != nil {
- return fmt.Errorf("failed to stat dat file: %v", err)
- }
- err = encodeDatFile(fi.Size(), err, baseFileName, bufferSize, largeBlockSize, file, smallBlockSize)
- if err != nil {
- return fmt.Errorf("encodeDatFile: %v", err)
- }
- return nil
-}
-
-func encodeDatFile(remainingSize int64, err error, baseFileName string, bufferSize int, largeBlockSize int64, file *os.File, smallBlockSize int64) error {
- var processedSize int64
- enc, err := reedsolomon.New(DataShardsCount, ParityShardsCount)
- if err != nil {
- return fmt.Errorf("failed to create encoder: %v", err)
- }
- buffers := make([][]byte, DataShardsCount+ParityShardsCount)
- outputs, err := openEcFiles(baseFileName, false)
- defer closeEcFiles(outputs)
- if err != nil {
- return fmt.Errorf("failed to open dat file: %v", err)
- }
- for i, _ := range buffers {
- buffers[i] = make([]byte, bufferSize)
- }
- for remainingSize > largeBlockSize*DataShardsCount {
- err = encodeData(file, enc, processedSize, largeBlockSize, buffers, outputs)
- if err != nil {
- return fmt.Errorf("failed to encode large chunk data: %v", err)
- }
- remainingSize -= largeBlockSize * DataShardsCount
- processedSize += largeBlockSize * DataShardsCount
- }
- for remainingSize > 0 {
- encodeData(file, enc, processedSize, smallBlockSize, buffers, outputs)
- if err != nil {
- return fmt.Errorf("failed to encode small chunk data: %v", err)
- }
- remainingSize -= smallBlockSize * DataShardsCount
- processedSize += smallBlockSize * DataShardsCount
- }
- return nil
-}
-
-func writeSortedEcxFiles(baseFileName string) (e error) {
-
- cm, err := readCompactMap(baseFileName)
- if err != nil {
- return fmt.Errorf("readCompactMap: %v", err)
- }
-
- ecxFile, err := os.OpenFile(baseFileName+".ecx", os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
- if err != nil {
- return fmt.Errorf("failed to open dat file: %v", err)
- }
- defer ecxFile.Close()
-
- err = cm.AscendingVisit(func(value needle_map.NeedleValue) error {
- bytes := value.ToBytes()
- _, writeErr := ecxFile.Write(bytes)
- return writeErr
- })
-
- if err != nil {
- return fmt.Errorf("failed to open dat file: %v", err)
- }
-
- return nil
-}
-
func validateFiles(baseFileName string) error {
cm, err := readCompactMap(baseFileName)
if err != nil {
@@ -148,25 +69,6 @@ func validateFiles(baseFileName string) error {
return nil
}
-func readCompactMap(baseFileName string) (*needle_map.CompactMap, error) {
- indexFile, err := os.OpenFile(baseFileName+".idx", os.O_RDONLY, 0644)
- if err != nil {
- return nil, fmt.Errorf("cannot read Volume Index %s.idx: %v", baseFileName, err)
- }
- defer indexFile.Close()
-
- cm := needle_map.NewCompactMap()
- err = storage.WalkIndexFile(indexFile, func(key types.NeedleId, offset types.Offset, size uint32) error {
- if !offset.IsZero() && size != types.TombstoneFileSize {
- cm.Set(key, offset, size)
- } else {
- cm.Delete(key)
- }
- return nil
- })
- return cm, err
-}
-
func assertSame(datFile *os.File, datSize int64, ecFiles []*os.File, offset types.Offset, size uint32) error {
data, err := readDatFile(datFile, offset, size)
@@ -288,7 +190,7 @@ func removeGeneratedFiles(baseFileName string) {
fname := fmt.Sprintf("%s.ec%02d", baseFileName, i+1)
os.Remove(fname)
}
- os.Remove(baseFileName+".ecx")
+ os.Remove(baseFileName + ".ecx")
}
func TestLocateData(t *testing.T) {