mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2024-01-19 02:48:24 +00:00
adds VolumeEcGenerateSlices, VolumeEcCopy
This commit is contained in:
parent
ae499fd5aa
commit
fbbc74abb4
|
@ -47,6 +47,13 @@ service VolumeServer {
|
||||||
rpc VolumeTailReceiver (VolumeTailReceiverRequest) returns (VolumeTailReceiverResponse) {
|
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 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 {
|
message ReadVolumeFileStatusRequest {
|
||||||
uint32 volume_id = 1;
|
uint32 volume_id = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,10 @@ It has these top-level messages:
|
||||||
VolumeTailSenderResponse
|
VolumeTailSenderResponse
|
||||||
VolumeTailReceiverRequest
|
VolumeTailReceiverRequest
|
||||||
VolumeTailReceiverResponse
|
VolumeTailReceiverResponse
|
||||||
|
VolumeEcGenerateSlicesRequest
|
||||||
|
VolumeEcGenerateSlicesResponse
|
||||||
|
VolumeEcCopyRequest
|
||||||
|
VolumeEcCopyResponse
|
||||||
ReadVolumeFileStatusRequest
|
ReadVolumeFileStatusRequest
|
||||||
ReadVolumeFileStatusResponse
|
ReadVolumeFileStatusResponse
|
||||||
DiskStatus
|
DiskStatus
|
||||||
|
@ -766,6 +770,78 @@ func (m *VolumeTailReceiverResponse) String() string { return proto.C
|
||||||
func (*VolumeTailReceiverResponse) ProtoMessage() {}
|
func (*VolumeTailReceiverResponse) ProtoMessage() {}
|
||||||
func (*VolumeTailReceiverResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} }
|
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 {
|
type ReadVolumeFileStatusRequest struct {
|
||||||
VolumeId uint32 `protobuf:"varint,1,opt,name=volume_id,json=volumeId" json:"volume_id,omitempty"`
|
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) Reset() { *m = ReadVolumeFileStatusRequest{} }
|
||||||
func (m *ReadVolumeFileStatusRequest) String() string { return proto.CompactTextString(m) }
|
func (m *ReadVolumeFileStatusRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ReadVolumeFileStatusRequest) ProtoMessage() {}
|
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 {
|
func (m *ReadVolumeFileStatusRequest) GetVolumeId() uint32 {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
|
@ -796,7 +872,7 @@ type ReadVolumeFileStatusResponse struct {
|
||||||
func (m *ReadVolumeFileStatusResponse) Reset() { *m = ReadVolumeFileStatusResponse{} }
|
func (m *ReadVolumeFileStatusResponse) Reset() { *m = ReadVolumeFileStatusResponse{} }
|
||||||
func (m *ReadVolumeFileStatusResponse) String() string { return proto.CompactTextString(m) }
|
func (m *ReadVolumeFileStatusResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ReadVolumeFileStatusResponse) ProtoMessage() {}
|
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 {
|
func (m *ReadVolumeFileStatusResponse) GetVolumeId() uint32 {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
|
@ -864,7 +940,7 @@ type DiskStatus struct {
|
||||||
func (m *DiskStatus) Reset() { *m = DiskStatus{} }
|
func (m *DiskStatus) Reset() { *m = DiskStatus{} }
|
||||||
func (m *DiskStatus) String() string { return proto.CompactTextString(m) }
|
func (m *DiskStatus) String() string { return proto.CompactTextString(m) }
|
||||||
func (*DiskStatus) ProtoMessage() {}
|
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 {
|
func (m *DiskStatus) GetDir() string {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
|
@ -907,7 +983,7 @@ type MemStatus struct {
|
||||||
func (m *MemStatus) Reset() { *m = MemStatus{} }
|
func (m *MemStatus) Reset() { *m = MemStatus{} }
|
||||||
func (m *MemStatus) String() string { return proto.CompactTextString(m) }
|
func (m *MemStatus) String() string { return proto.CompactTextString(m) }
|
||||||
func (*MemStatus) ProtoMessage() {}
|
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 {
|
func (m *MemStatus) GetGoroutines() int32 {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
|
@ -993,6 +1069,10 @@ func init() {
|
||||||
proto.RegisterType((*VolumeTailSenderResponse)(nil), "volume_server_pb.VolumeTailSenderResponse")
|
proto.RegisterType((*VolumeTailSenderResponse)(nil), "volume_server_pb.VolumeTailSenderResponse")
|
||||||
proto.RegisterType((*VolumeTailReceiverRequest)(nil), "volume_server_pb.VolumeTailReceiverRequest")
|
proto.RegisterType((*VolumeTailReceiverRequest)(nil), "volume_server_pb.VolumeTailReceiverRequest")
|
||||||
proto.RegisterType((*VolumeTailReceiverResponse)(nil), "volume_server_pb.VolumeTailReceiverResponse")
|
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((*ReadVolumeFileStatusRequest)(nil), "volume_server_pb.ReadVolumeFileStatusRequest")
|
||||||
proto.RegisterType((*ReadVolumeFileStatusResponse)(nil), "volume_server_pb.ReadVolumeFileStatusResponse")
|
proto.RegisterType((*ReadVolumeFileStatusResponse)(nil), "volume_server_pb.ReadVolumeFileStatusResponse")
|
||||||
proto.RegisterType((*DiskStatus)(nil), "volume_server_pb.DiskStatus")
|
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)
|
CopyFile(ctx context.Context, in *CopyFileRequest, opts ...grpc.CallOption) (VolumeServer_CopyFileClient, error)
|
||||||
VolumeTailSender(ctx context.Context, in *VolumeTailSenderRequest, opts ...grpc.CallOption) (VolumeServer_VolumeTailSenderClient, error)
|
VolumeTailSender(ctx context.Context, in *VolumeTailSenderRequest, opts ...grpc.CallOption) (VolumeServer_VolumeTailSenderClient, error)
|
||||||
VolumeTailReceiver(ctx context.Context, in *VolumeTailReceiverRequest, opts ...grpc.CallOption) (*VolumeTailReceiverResponse, 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 {
|
type volumeServerClient struct {
|
||||||
|
@ -1261,6 +1344,24 @@ func (c *volumeServerClient) VolumeTailReceiver(ctx context.Context, in *VolumeT
|
||||||
return out, nil
|
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
|
// Server API for VolumeServer service
|
||||||
|
|
||||||
type VolumeServerServer interface {
|
type VolumeServerServer interface {
|
||||||
|
@ -1283,6 +1384,9 @@ type VolumeServerServer interface {
|
||||||
CopyFile(*CopyFileRequest, VolumeServer_CopyFileServer) error
|
CopyFile(*CopyFileRequest, VolumeServer_CopyFileServer) error
|
||||||
VolumeTailSender(*VolumeTailSenderRequest, VolumeServer_VolumeTailSenderServer) error
|
VolumeTailSender(*VolumeTailSenderRequest, VolumeServer_VolumeTailSenderServer) error
|
||||||
VolumeTailReceiver(context.Context, *VolumeTailReceiverRequest) (*VolumeTailReceiverResponse, 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) {
|
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)
|
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{
|
var _VolumeServer_serviceDesc = grpc.ServiceDesc{
|
||||||
ServiceName: "volume_server_pb.VolumeServer",
|
ServiceName: "volume_server_pb.VolumeServer",
|
||||||
HandlerType: (*VolumeServerServer)(nil),
|
HandlerType: (*VolumeServerServer)(nil),
|
||||||
|
@ -1664,6 +1804,14 @@ var _VolumeServer_serviceDesc = grpc.ServiceDesc{
|
||||||
MethodName: "VolumeTailReceiver",
|
MethodName: "VolumeTailReceiver",
|
||||||
Handler: _VolumeServer_VolumeTailReceiver_Handler,
|
Handler: _VolumeServer_VolumeTailReceiver_Handler,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MethodName: "VolumeEcGenerateSlices",
|
||||||
|
Handler: _VolumeServer_VolumeEcGenerateSlices_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "VolumeEcCopy",
|
||||||
|
Handler: _VolumeServer_VolumeEcCopy_Handler,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Streams: []grpc.StreamDesc{
|
Streams: []grpc.StreamDesc{
|
||||||
{
|
{
|
||||||
|
@ -1688,95 +1836,101 @@ var _VolumeServer_serviceDesc = grpc.ServiceDesc{
|
||||||
func init() { proto.RegisterFile("volume_server.proto", fileDescriptor0) }
|
func init() { proto.RegisterFile("volume_server.proto", fileDescriptor0) }
|
||||||
|
|
||||||
var fileDescriptor0 = []byte{
|
var fileDescriptor0 = []byte{
|
||||||
// 1436 bytes of a gzipped FileDescriptorProto
|
// 1534 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xc4, 0x58, 0x4b, 0x73, 0xd4, 0xc6,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xc4, 0x58, 0xcb, 0x6f, 0xd4, 0xd6,
|
||||||
0x13, 0xb7, 0xd8, 0xb5, 0xbd, 0xee, 0x5d, 0x9b, 0x65, 0x6c, 0xf0, 0x7a, 0x79, 0x19, 0xc1, 0x1f,
|
0x1a, 0x8f, 0x99, 0xc9, 0xeb, 0x9b, 0x04, 0x86, 0x93, 0x90, 0x4c, 0x0c, 0x09, 0x83, 0xe1, 0xc2,
|
||||||
0x96, 0xc7, 0xdf, 0x10, 0xa8, 0x24, 0x24, 0x39, 0x24, 0x60, 0x92, 0x0a, 0x55, 0x01, 0xaa, 0x64,
|
0xf0, 0xb8, 0x81, 0x0b, 0xba, 0xf7, 0xd2, 0x87, 0xd4, 0x42, 0xa0, 0x6d, 0xa4, 0x02, 0x92, 0x03,
|
||||||
0xa0, 0x92, 0x4a, 0xaa, 0x54, 0x63, 0xa9, 0x8d, 0x55, 0xd6, 0x4a, 0x42, 0x33, 0x72, 0x70, 0x2a,
|
0xa8, 0x55, 0x2b, 0x59, 0x27, 0xf6, 0x17, 0x62, 0xc5, 0x63, 0x1b, 0xfb, 0x38, 0x4d, 0xaa, 0x76,
|
||||||
0xb7, 0xe4, 0x13, 0xe4, 0x2b, 0xe4, 0xc6, 0x21, 0xd7, 0x7c, 0xaa, 0x7c, 0x82, 0x5c, 0x52, 0xf3,
|
0xd5, 0xae, 0xba, 0xec, 0xb6, 0xcb, 0xee, 0xba, 0xe8, 0xb6, 0x7f, 0x55, 0xff, 0x82, 0x6e, 0xaa,
|
||||||
0x90, 0x76, 0xf5, 0xf2, 0x8a, 0x70, 0xc8, 0x6d, 0xb6, 0xa7, 0xdf, 0xea, 0xee, 0xf9, 0xf5, 0xc2,
|
0xf3, 0xb0, 0x67, 0xfc, 0xca, 0x98, 0x52, 0xa9, 0xbb, 0x33, 0xdf, 0xf9, 0x5e, 0xe7, 0xf3, 0xf7,
|
||||||
0xea, 0x61, 0xe8, 0x27, 0x63, 0xb4, 0x19, 0xc6, 0x87, 0x18, 0x6f, 0x45, 0x71, 0xc8, 0x43, 0xd2,
|
0xfa, 0x0d, 0x2c, 0x1d, 0x06, 0x5e, 0x32, 0x44, 0x2b, 0xc6, 0xe8, 0x10, 0xa3, 0xcd, 0x30, 0x0a,
|
||||||
0xcf, 0x11, 0xed, 0x68, 0xd7, 0xbc, 0x0d, 0xe4, 0x21, 0xe5, 0xce, 0xfe, 0x23, 0xf4, 0x91, 0xa3,
|
0x58, 0x40, 0xba, 0x39, 0xa2, 0x15, 0xee, 0x1a, 0xb7, 0x81, 0x3c, 0xa4, 0xcc, 0xde, 0x7f, 0x84,
|
||||||
0x85, 0xaf, 0x13, 0x64, 0x9c, 0x6c, 0x40, 0x67, 0xcf, 0xf3, 0xd1, 0xf6, 0x5c, 0x36, 0x30, 0x36,
|
0x1e, 0x32, 0x34, 0xf1, 0x75, 0x82, 0x31, 0x23, 0x6b, 0x30, 0xb7, 0xe7, 0x7a, 0x68, 0xb9, 0x4e,
|
||||||
0x5b, 0xa3, 0x25, 0x6b, 0x51, 0xfc, 0x7e, 0xec, 0x32, 0xf3, 0x19, 0xac, 0xe6, 0x04, 0x58, 0x14,
|
0xdc, 0xd3, 0xfa, 0xad, 0xc1, 0xbc, 0x39, 0xcb, 0x7f, 0x6f, 0x3b, 0xb1, 0xf1, 0x0c, 0x96, 0x72,
|
||||||
0x06, 0x0c, 0xc9, 0x7d, 0x58, 0x8c, 0x91, 0x25, 0x3e, 0x57, 0x02, 0xdd, 0xbb, 0x17, 0xb6, 0x8a,
|
0x02, 0x71, 0x18, 0xf8, 0x31, 0x92, 0xfb, 0x30, 0x1b, 0x61, 0x9c, 0x78, 0x4c, 0x0a, 0x74, 0xee,
|
||||||
0xb6, 0xb6, 0x32, 0x91, 0xc4, 0xe7, 0x56, 0xca, 0x6e, 0x7a, 0xd0, 0x9b, 0xbe, 0x20, 0xeb, 0xb0,
|
0x6e, 0x6c, 0x16, 0x6d, 0x6d, 0x66, 0x22, 0x89, 0xc7, 0xcc, 0x94, 0xdd, 0x70, 0x61, 0x61, 0xfc,
|
||||||
0xa8, 0x6d, 0x0f, 0x8c, 0x4d, 0x63, 0xb4, 0x64, 0x2d, 0x28, 0xd3, 0xe4, 0x0c, 0x2c, 0x30, 0x4e,
|
0x82, 0xac, 0xc2, 0xac, 0xb2, 0xdd, 0xd3, 0xfa, 0xda, 0x60, 0xde, 0x9c, 0x91, 0xa6, 0xc9, 0x0a,
|
||||||
0x79, 0xc2, 0x06, 0x27, 0x36, 0x8d, 0xd1, 0xbc, 0xa5, 0x7f, 0x91, 0x35, 0x98, 0xc7, 0x38, 0x0e,
|
0xcc, 0xc4, 0x8c, 0xb2, 0x24, 0xee, 0x9d, 0xea, 0x6b, 0x83, 0x69, 0x53, 0xfd, 0x22, 0xcb, 0x30,
|
||||||
0xe3, 0x41, 0x4b, 0xb2, 0xab, 0x1f, 0x84, 0x40, 0x9b, 0x79, 0x3f, 0xe1, 0xa0, 0xbd, 0x69, 0x8c,
|
0x8d, 0x51, 0x14, 0x44, 0xbd, 0x96, 0x60, 0x97, 0x3f, 0x08, 0x81, 0x76, 0xec, 0x7e, 0x8d, 0xbd,
|
||||||
0x96, 0x2d, 0x79, 0x36, 0x17, 0x61, 0xfe, 0xcb, 0x71, 0xc4, 0x8f, 0xcc, 0x8f, 0x61, 0xf0, 0x92,
|
0x76, 0x5f, 0x1b, 0x2c, 0x9a, 0xe2, 0x6c, 0xcc, 0xc2, 0xf4, 0xe3, 0x61, 0xc8, 0x8e, 0x8d, 0xff,
|
||||||
0x3a, 0x49, 0x32, 0x7e, 0x29, 0x7d, 0xdc, 0xde, 0x47, 0xe7, 0x20, 0x8d, 0xfd, 0x2c, 0x2c, 0x69,
|
0x43, 0xef, 0x25, 0xb5, 0x93, 0x64, 0xf8, 0x52, 0xf8, 0xb8, 0xb5, 0x8f, 0xf6, 0x41, 0xfa, 0xf6,
|
||||||
0xcf, 0xb5, 0x07, 0xcb, 0x56, 0x47, 0x11, 0x1e, 0xbb, 0xe6, 0x17, 0xb0, 0x51, 0x21, 0xa8, 0x73,
|
0xf3, 0x30, 0xaf, 0x3c, 0x57, 0x1e, 0x2c, 0x9a, 0x73, 0x92, 0xb0, 0xed, 0x18, 0x1f, 0xc2, 0x5a,
|
||||||
0x70, 0x19, 0x96, 0x5f, 0xd1, 0x78, 0x97, 0xbe, 0x42, 0x3b, 0xa6, 0xdc, 0x0b, 0xa5, 0xb4, 0x61,
|
0x85, 0xa0, 0x8a, 0xc1, 0x65, 0x58, 0x7c, 0x45, 0xa3, 0x5d, 0xfa, 0x0a, 0xad, 0x88, 0x32, 0x37,
|
||||||
0xf5, 0x34, 0xd1, 0x12, 0x34, 0xf3, 0x7b, 0x18, 0xe6, 0x34, 0x84, 0xe3, 0x88, 0x3a, 0xbc, 0x89,
|
0x10, 0xd2, 0x9a, 0xb9, 0xa0, 0x88, 0x26, 0xa7, 0x19, 0x5f, 0x80, 0x9e, 0xd3, 0x10, 0x0c, 0x43,
|
||||||
0x71, 0xb2, 0x09, 0xdd, 0x28, 0x46, 0xea, 0xfb, 0xa1, 0x43, 0x39, 0xca, 0x2c, 0xb4, 0xac, 0x69,
|
0x6a, 0xb3, 0x26, 0xc6, 0x49, 0x1f, 0x3a, 0x61, 0x84, 0xd4, 0xf3, 0x02, 0x9b, 0x32, 0x14, 0x51,
|
||||||
0x92, 0x79, 0x1e, 0xce, 0x56, 0x2a, 0x57, 0x0e, 0x9a, 0xf7, 0x0b, 0xde, 0x87, 0xe3, 0xb1, 0xd7,
|
0x68, 0x99, 0xe3, 0x24, 0x63, 0x1d, 0xce, 0x57, 0x2a, 0x97, 0x0e, 0x1a, 0xf7, 0x0b, 0xde, 0x07,
|
||||||
0xc8, 0xb4, 0x79, 0xae, 0xe4, 0xb5, 0x94, 0xd4, 0x7a, 0x3f, 0x29, 0xdc, 0xfa, 0x48, 0x83, 0x24,
|
0xc3, 0xa1, 0xdb, 0xc8, 0xb4, 0x71, 0xa1, 0xe4, 0xb5, 0x90, 0x54, 0x7a, 0xdf, 0x29, 0xdc, 0x7a,
|
||||||
0x6a, 0xa4, 0xb8, 0xe8, 0x71, 0x2a, 0x9a, 0x69, 0x5e, 0x57, 0xc5, 0xb1, 0x1d, 0xfa, 0x3e, 0x3a,
|
0x48, 0xfd, 0x24, 0x6c, 0xa4, 0xb8, 0xe8, 0x71, 0x2a, 0x9a, 0x69, 0x5e, 0x95, 0xc9, 0xb1, 0x15,
|
||||||
0xdc, 0x0b, 0x83, 0x54, 0xed, 0x05, 0x00, 0x27, 0x23, 0xea, 0x52, 0x99, 0xa2, 0x98, 0x43, 0x18,
|
0x78, 0x1e, 0xda, 0xcc, 0x0d, 0xfc, 0x54, 0xed, 0x06, 0x80, 0x9d, 0x11, 0x55, 0xaa, 0x8c, 0x51,
|
||||||
0x94, 0x45, 0xb5, 0xda, 0xb7, 0x06, 0x9c, 0x7e, 0xa0, 0x93, 0xa6, 0x0c, 0x37, 0xfa, 0x00, 0x79,
|
0x0c, 0x1d, 0x7a, 0x65, 0x51, 0xa5, 0xf6, 0x17, 0x0d, 0xce, 0x3d, 0x50, 0x41, 0x93, 0x86, 0x1b,
|
||||||
0x93, 0x27, 0x8a, 0x26, 0x8b, 0x1f, 0xa8, 0x55, 0xfa, 0x40, 0x82, 0x23, 0xc6, 0xc8, 0xf7, 0x1c,
|
0x7d, 0x80, 0xbc, 0xc9, 0x53, 0x45, 0x93, 0xc5, 0x0f, 0xd4, 0x2a, 0x7d, 0x20, 0xce, 0x11, 0x61,
|
||||||
0x2a, 0x55, 0xb4, 0xa5, 0x8a, 0x69, 0x12, 0xe9, 0x43, 0x8b, 0x73, 0x7f, 0x30, 0x2f, 0x6f, 0xc4,
|
0xe8, 0xb9, 0x36, 0x15, 0x2a, 0xda, 0x42, 0xc5, 0x38, 0x89, 0x74, 0xa1, 0xc5, 0x98, 0xd7, 0x9b,
|
||||||
0xd1, 0x1c, 0xc0, 0x99, 0xa2, 0xaf, 0x3a, 0x8c, 0x8f, 0x60, 0x5d, 0x51, 0x76, 0x8e, 0x02, 0x67,
|
0x16, 0x37, 0xfc, 0x68, 0xf4, 0x60, 0xa5, 0xe8, 0xab, 0x7a, 0xc6, 0xff, 0x60, 0x55, 0x52, 0x76,
|
||||||
0x47, 0x76, 0x43, 0xa3, 0xa4, 0xff, 0x6d, 0xc0, 0xa0, 0x2c, 0xa8, 0xab, 0xf8, 0x7d, 0x33, 0xf0,
|
0x8e, 0x7d, 0x7b, 0x47, 0x54, 0x43, 0xa3, 0xa0, 0xff, 0xa1, 0x41, 0xaf, 0x2c, 0xa8, 0xb2, 0xf8,
|
||||||
0xae, 0xf1, 0x91, 0x8b, 0xd0, 0xe5, 0xd4, 0xf3, 0xed, 0x70, 0x6f, 0x8f, 0x21, 0x1f, 0x2c, 0x6c,
|
0x6d, 0x23, 0xf0, 0xa6, 0xef, 0x23, 0x17, 0xa1, 0xc3, 0xa8, 0xeb, 0x59, 0xc1, 0xde, 0x5e, 0x8c,
|
||||||
0x1a, 0xa3, 0xb6, 0x05, 0x82, 0xf4, 0x4c, 0x52, 0xc8, 0x75, 0xe8, 0x3b, 0xaa, 0x92, 0xed, 0x18,
|
0xac, 0x37, 0xd3, 0xd7, 0x06, 0x6d, 0x13, 0x38, 0xe9, 0x99, 0xa0, 0x90, 0xeb, 0xd0, 0xb5, 0x65,
|
||||||
0x0f, 0x3d, 0x26, 0x34, 0x2f, 0x4a, 0xc7, 0x4e, 0x3a, 0x69, 0x85, 0x2b, 0x32, 0x31, 0x61, 0xd9,
|
0x26, 0x5b, 0x11, 0x1e, 0xba, 0x31, 0xd7, 0x3c, 0x2b, 0x1c, 0x3b, 0x63, 0xa7, 0x19, 0x2e, 0xc9,
|
||||||
0x73, 0xdf, 0xd8, 0x72, 0x80, 0xc8, 0xf6, 0xef, 0x48, 0x6d, 0x5d, 0xcf, 0x7d, 0xf3, 0x95, 0xe7,
|
0xc4, 0x80, 0x45, 0xd7, 0x39, 0xb2, 0x44, 0x03, 0x11, 0xe5, 0x3f, 0x27, 0xb4, 0x75, 0x5c, 0xe7,
|
||||||
0xe3, 0x8e, 0x98, 0x02, 0x2f, 0xe1, 0x9c, 0x0a, 0xfe, 0x71, 0xe0, 0xc4, 0x38, 0xc6, 0x80, 0x53,
|
0xe8, 0x23, 0xd7, 0xc3, 0x1d, 0xde, 0x05, 0x5e, 0xc2, 0x05, 0xf9, 0xf8, 0x6d, 0xdf, 0x8e, 0x70,
|
||||||
0x7f, 0x3b, 0x8c, 0x8e, 0x1a, 0x95, 0xc0, 0x06, 0x74, 0x98, 0x17, 0x38, 0x68, 0x07, 0x6a, 0x0c,
|
0x88, 0x3e, 0xa3, 0xde, 0x56, 0x10, 0x1e, 0x37, 0x4a, 0x81, 0x35, 0x98, 0x8b, 0x5d, 0xdf, 0x46,
|
||||||
0xb5, 0xad, 0x45, 0xf9, 0xfb, 0x29, 0x33, 0x1f, 0xc2, 0xf9, 0x1a, 0xbd, 0x3a, 0xb3, 0x97, 0xa0,
|
0xcb, 0x97, 0x6d, 0xa8, 0x6d, 0xce, 0x8a, 0xdf, 0x4f, 0x63, 0xe3, 0x21, 0xac, 0xd7, 0xe8, 0x55,
|
||||||
0x27, 0x1d, 0x73, 0xc2, 0x80, 0x63, 0xc0, 0xa5, 0xee, 0x9e, 0xd5, 0x15, 0xb4, 0x6d, 0x45, 0x32,
|
0x91, 0xbd, 0x04, 0x0b, 0xc2, 0x31, 0x3b, 0xf0, 0x19, 0xfa, 0x4c, 0xe8, 0x5e, 0x30, 0x3b, 0x9c,
|
||||||
0x3f, 0x00, 0xa2, 0x74, 0x3c, 0x09, 0x93, 0xa0, 0x59, 0x6b, 0x9e, 0x86, 0xd5, 0x9c, 0x88, 0xae,
|
0xb6, 0x25, 0x49, 0xc6, 0x7f, 0x80, 0x48, 0x1d, 0x4f, 0x82, 0xc4, 0x6f, 0x56, 0x9a, 0xe7, 0x60,
|
||||||
0x8d, 0x7b, 0xb0, 0xa6, 0xc8, 0x2f, 0x82, 0x71, 0x63, 0x5d, 0xeb, 0x70, 0xba, 0x20, 0xa4, 0xb5,
|
0x29, 0x27, 0xa2, 0x72, 0xe3, 0x1e, 0x2c, 0x4b, 0xf2, 0x0b, 0x7f, 0xd8, 0x58, 0xd7, 0x2a, 0x9c,
|
||||||
0xdd, 0x4d, 0x8d, 0xe4, 0xdf, 0x89, 0x63, 0x95, 0x9d, 0x49, 0x3d, 0xc8, 0x3f, 0x15, 0xe6, 0x1f,
|
0x2b, 0x08, 0x29, 0x6d, 0x77, 0x53, 0x23, 0xf9, 0x39, 0x71, 0xa2, 0xb2, 0x95, 0xd4, 0x83, 0xfc,
|
||||||
0x06, 0x9c, 0x4a, 0xc7, 0x48, 0xc3, 0xac, 0xbf, 0x63, 0xd9, 0xb5, 0x6a, 0xcb, 0xae, 0x3d, 0x29,
|
0xa8, 0x30, 0x7e, 0xd5, 0xe0, 0x6c, 0xda, 0x46, 0x1a, 0x46, 0xfd, 0x0d, 0xd3, 0xae, 0x55, 0x9b,
|
||||||
0xbb, 0x11, 0xf4, 0x59, 0x98, 0xc4, 0x0e, 0xda, 0x2e, 0xe5, 0xd4, 0x0e, 0x42, 0x17, 0x75, 0x55,
|
0x76, 0xed, 0x51, 0xda, 0x0d, 0xa0, 0x1b, 0x07, 0x49, 0x64, 0xa3, 0xe5, 0x50, 0x46, 0x2d, 0x3f,
|
||||||
0xae, 0x28, 0xfa, 0x23, 0xca, 0xe9, 0xd3, 0xd0, 0x45, 0xf3, 0xf3, 0xf4, 0xa3, 0xe4, 0xbe, 0xe6,
|
0x70, 0x50, 0x65, 0xe5, 0x69, 0x49, 0x7f, 0x44, 0x19, 0x7d, 0x1a, 0x38, 0x68, 0x7c, 0x90, 0x7e,
|
||||||
0x75, 0x38, 0xe5, 0x53, 0xc6, 0x6d, 0x1a, 0x45, 0x18, 0xb8, 0x36, 0xe5, 0xa2, 0x24, 0x0c, 0x59,
|
0x94, 0xdc, 0xd7, 0xbc, 0x0e, 0x67, 0x3d, 0x1a, 0x33, 0x8b, 0x86, 0x21, 0xfa, 0x8e, 0x45, 0x19,
|
||||||
0x12, 0x2b, 0xe2, 0xe2, 0x81, 0xa4, 0x3f, 0xe0, 0x4f, 0x99, 0xf9, 0x9b, 0x01, 0x27, 0x85, 0xac,
|
0x4f, 0x09, 0x4d, 0xa4, 0xc4, 0x69, 0x7e, 0xf1, 0x40, 0xd0, 0x1f, 0xb0, 0xa7, 0xb1, 0xf1, 0xa3,
|
||||||
0x28, 0xc1, 0x46, 0xf1, 0xf6, 0xa1, 0x85, 0x6f, 0xb8, 0x0e, 0x54, 0x1c, 0xc9, 0x6d, 0x58, 0xd5,
|
0x06, 0x67, 0xb8, 0x2c, 0x4f, 0xc1, 0x46, 0xef, 0xed, 0x42, 0x0b, 0x8f, 0x98, 0x7a, 0x28, 0x3f,
|
||||||
0xb5, 0xee, 0x85, 0xc1, 0xa4, 0x0d, 0x5a, 0x52, 0x90, 0x4c, 0xae, 0xb2, 0x4e, 0xb8, 0x08, 0x5d,
|
0x92, 0xdb, 0xb0, 0xa4, 0x72, 0xdd, 0x0d, 0xfc, 0x51, 0x19, 0xb4, 0x84, 0x20, 0x19, 0x5d, 0x65,
|
||||||
0xc6, 0xc3, 0x28, 0xed, 0xaa, 0xb6, 0xea, 0x2a, 0x41, 0x52, 0x5d, 0x65, 0x7e, 0x08, 0xfd, 0x89,
|
0x95, 0x70, 0x11, 0x3a, 0x31, 0x0b, 0xc2, 0xb4, 0xaa, 0xda, 0xb2, 0xaa, 0x38, 0x49, 0x56, 0x95,
|
||||||
0x4f, 0xcd, 0x2b, 0xf4, 0x17, 0x23, 0x1d, 0x3a, 0xcf, 0xa9, 0xe7, 0xef, 0x60, 0xe0, 0x62, 0xfc,
|
0xf1, 0x5f, 0xe8, 0x8e, 0x7c, 0x6a, 0x9e, 0xa1, 0xdf, 0x69, 0x69, 0xd3, 0x79, 0x4e, 0x5d, 0x6f,
|
||||||
0x9e, 0x9d, 0x43, 0xee, 0xc0, 0x9a, 0xe7, 0xfa, 0x68, 0x73, 0x6f, 0x8c, 0x61, 0xc2, 0x6d, 0x86,
|
0x07, 0x7d, 0x07, 0xa3, 0xb7, 0xac, 0x1c, 0x72, 0x07, 0x96, 0x5d, 0xc7, 0x43, 0x8b, 0xb9, 0x43,
|
||||||
0x4e, 0x18, 0xb8, 0x2c, 0x8d, 0x4e, 0xdc, 0x3d, 0x57, 0x57, 0x3b, 0xea, 0xc6, 0xfc, 0x35, 0x9b,
|
0x0c, 0x12, 0x66, 0xc5, 0x68, 0x07, 0xbe, 0x13, 0xa7, 0xaf, 0xe3, 0x77, 0xcf, 0xe5, 0xd5, 0x8e,
|
||||||
0x60, 0xd3, 0x5e, 0x4c, 0xde, 0xe1, 0x00, 0x51, 0x28, 0xdc, 0x47, 0xea, 0x62, 0xac, 0xc3, 0xe8,
|
0xbc, 0x31, 0xbe, 0xcf, 0x3a, 0xd8, 0xb8, 0x17, 0xa3, 0x39, 0xec, 0x23, 0x72, 0x85, 0xfb, 0x48,
|
||||||
0x29, 0xe2, 0xd7, 0x92, 0x26, 0xf2, 0xa3, 0x99, 0x76, 0x43, 0xf7, 0x48, 0x7a, 0xd4, 0xb3, 0x40,
|
0x1d, 0x8c, 0xd4, 0x33, 0x16, 0x24, 0xf1, 0x13, 0x41, 0xe3, 0xf1, 0x51, 0x4c, 0xbb, 0x81, 0x73,
|
||||||
0x91, 0x1e, 0x86, 0xee, 0x91, 0x1c, 0x25, 0xcc, 0x96, 0x9f, 0xd8, 0xd9, 0x4f, 0x82, 0x03, 0xe9,
|
0x2c, 0x3c, 0x5a, 0x30, 0x41, 0x92, 0x1e, 0x06, 0xce, 0xb1, 0x68, 0x25, 0xb1, 0x25, 0x3e, 0xb1,
|
||||||
0x4d, 0xc7, 0xea, 0x7a, 0xec, 0x1b, 0xca, 0xf8, 0xb6, 0x20, 0x99, 0x7f, 0x1a, 0xb0, 0x31, 0x71,
|
0xbd, 0x9f, 0xf8, 0x07, 0xc2, 0x9b, 0x39, 0xb3, 0xe3, 0xc6, 0x9f, 0xd2, 0x98, 0x6d, 0x71, 0x92,
|
||||||
0xc3, 0x42, 0x07, 0xbd, 0xc3, 0xff, 0x20, 0x1d, 0x42, 0x42, 0xd7, 0x72, 0x0e, 0x74, 0xe9, 0x72,
|
0xf1, 0x9b, 0x06, 0x6b, 0x23, 0x37, 0x4c, 0xb4, 0xd1, 0x3d, 0xfc, 0x07, 0xc2, 0xc1, 0x25, 0x54,
|
||||||
0x27, 0xea, 0x4e, 0x4f, 0x7c, 0x79, 0x23, 0x1f, 0xf4, 0x0a, 0xc7, 0x75, 0x8b, 0x7e, 0x0a, 0x67,
|
0x2e, 0xe7, 0x96, 0x2e, 0x95, 0xee, 0x44, 0xde, 0xa9, 0x8e, 0x2f, 0x6e, 0xc4, 0x40, 0xaf, 0x70,
|
||||||
0x2d, 0xa4, 0xae, 0xe2, 0x90, 0x83, 0xb3, 0xf9, 0xe3, 0xf2, 0xd7, 0x09, 0x38, 0x57, 0x2d, 0xdc,
|
0x5c, 0x95, 0xe8, 0xfb, 0x69, 0x2b, 0x7b, 0x6c, 0x7f, 0x8c, 0x3e, 0x46, 0x94, 0xe1, 0x8e, 0xe7,
|
||||||
0xe4, 0x81, 0xf9, 0x0c, 0x86, 0xd9, 0x00, 0x17, 0xf1, 0x33, 0x4e, 0xc7, 0x51, 0x96, 0x01, 0x95,
|
0xda, 0xd8, 0x6c, 0xbc, 0xf4, 0x61, 0xa3, 0x4e, 0x5a, 0xe9, 0xff, 0x49, 0x4b, 0xfb, 0xc9, 0x63,
|
||||||
0xa8, 0x75, 0x3d, 0xcd, 0x9f, 0xa7, 0xf7, 0x69, 0x1a, 0x4a, 0xd3, 0xbf, 0x55, 0x9a, 0xfe, 0xc2,
|
0xfb, 0x6f, 0x6b, 0x02, 0xeb, 0x00, 0x68, 0x5b, 0xae, 0xef, 0xe0, 0x11, 0xf2, 0x60, 0xb5, 0x06,
|
||||||
0x80, 0x4b, 0x79, 0x9d, 0x01, 0xd5, 0x26, 0xeb, 0x2e, 0xe5, 0x75, 0x06, 0x32, 0x61, 0x69, 0x60,
|
0x8b, 0xe6, 0x3c, 0xda, 0xdb, 0x92, 0xf0, 0x06, 0xf5, 0x9e, 0x35, 0xae, 0xd4, 0x39, 0xe5, 0xf5,
|
||||||
0x5e, 0x19, 0xd0, 0xfc, 0xd2, 0xc0, 0x79, 0x00, 0xdd, 0x43, 0x49, 0x90, 0xbe, 0x66, 0x4b, 0xaa,
|
0xbb, 0x70, 0xde, 0x44, 0xea, 0xc8, 0x3b, 0x31, 0x4e, 0x9a, 0x8f, 0xdc, 0xdf, 0x4f, 0xc1, 0x85,
|
||||||
0x83, 0x92, 0xa0, 0xb6, 0x91, 0x17, 0x6b, 0x1b, 0x39, 0x3f, 0xfb, 0x3a, 0x25, 0x9c, 0xf3, 0x2d,
|
0x6a, 0xe1, 0x26, 0x63, 0xf7, 0x3d, 0xd0, 0xb3, 0xb1, 0xc6, 0xb3, 0x22, 0x66, 0x74, 0x18, 0x66,
|
||||||
0xc0, 0x23, 0x8f, 0x1d, 0xa8, 0x24, 0x8b, 0xc9, 0xe1, 0x7a, 0xb1, 0x86, 0x43, 0xe2, 0x28, 0x28,
|
0x79, 0x21, 0xd3, 0x67, 0x55, 0xcd, 0xb8, 0xe7, 0xe9, 0x7d, 0x9a, 0x1c, 0xa5, 0x99, 0xd8, 0x2a,
|
||||||
0xd4, 0xf7, 0x75, 0xea, 0xc4, 0x51, 0x40, 0xe3, 0x84, 0xa1, 0xab, 0xb3, 0x23, 0xcf, 0x82, 0xb6,
|
0xcd, 0x44, 0x6e, 0xc0, 0xa1, 0xac, 0xce, 0x80, 0x6c, 0x1e, 0xab, 0x0e, 0x65, 0x75, 0x06, 0x32,
|
||||||
0x17, 0x23, 0xea, 0x04, 0xc8, 0xb3, 0xf9, 0xbb, 0x01, 0x4b, 0x4f, 0x70, 0xac, 0x35, 0x5f, 0x00,
|
0x61, 0x61, 0x60, 0x5a, 0x1a, 0x50, 0xfc, 0xc2, 0xc0, 0x3a, 0x80, 0xea, 0x2c, 0x89, 0x9f, 0xce,
|
||||||
0x78, 0x15, 0xc6, 0x61, 0xc2, 0xbd, 0x00, 0xd5, 0xa0, 0x9b, 0xb7, 0xa6, 0x28, 0xff, 0xde, 0x8e,
|
0xf8, 0x79, 0xd9, 0x57, 0x12, 0xbf, 0xb6, 0xbd, 0xcd, 0xd6, 0xb6, 0xb7, 0x7c, 0x32, 0xcc, 0x95,
|
||||||
0x84, 0xea, 0xe8, 0xef, 0xe9, 0x64, 0xca, 0xb3, 0xa0, 0xed, 0x23, 0x8d, 0x74, 0xfe, 0xe4, 0x59,
|
0xb6, 0xbf, 0xcf, 0x00, 0x1e, 0xb9, 0xf1, 0x81, 0x0c, 0x32, 0xef, 0xa7, 0x8e, 0x1b, 0xa9, 0x25,
|
||||||
0x00, 0x7d, 0xc6, 0xa9, 0x73, 0x20, 0x93, 0xd5, 0xb6, 0xd4, 0x8f, 0xbb, 0x6f, 0x57, 0xa0, 0x37,
|
0x91, 0x1f, 0x39, 0x85, 0x7a, 0x9e, 0x0a, 0x1d, 0x3f, 0x72, 0xc0, 0x90, 0xc4, 0xe8, 0xa8, 0xe8,
|
||||||
0x5d, 0xda, 0xe4, 0x07, 0xe8, 0x4e, 0x6d, 0x28, 0xe4, 0x4a, 0x79, 0x11, 0x29, 0x6f, 0x3c, 0xc3,
|
0x88, 0x33, 0xa7, 0xed, 0x45, 0x88, 0x2a, 0x00, 0xe2, 0x6c, 0xfc, 0xac, 0xc1, 0xfc, 0x13, 0x1c,
|
||||||
0xff, 0xcd, 0xe0, 0xd2, 0x8d, 0x31, 0x47, 0x02, 0x38, 0x55, 0xda, 0x00, 0xc8, 0x8d, 0xb2, 0x74,
|
0x2a, 0xcd, 0x1b, 0x00, 0xaf, 0x82, 0x28, 0x48, 0x98, 0xeb, 0xa3, 0x6c, 0xff, 0xd3, 0xe6, 0x18,
|
||||||
0xdd, 0x7e, 0x31, 0xbc, 0xd9, 0x88, 0x37, 0xb3, 0xc7, 0x61, 0xb5, 0x02, 0xd2, 0x93, 0x5b, 0x33,
|
0xe5, 0xaf, 0xdb, 0x11, 0x00, 0x06, 0xbd, 0x3d, 0x15, 0x4c, 0x71, 0xe6, 0xb4, 0x7d, 0xa4, 0xa1,
|
||||||
0xb4, 0xe4, 0xd6, 0x8a, 0xe1, 0xff, 0x1b, 0x72, 0x67, 0x56, 0x5f, 0x03, 0x29, 0xe3, 0x7d, 0x72,
|
0x8a, 0x9f, 0x38, 0x73, 0xf8, 0x13, 0x33, 0x6a, 0x1f, 0x88, 0x60, 0xb5, 0x4d, 0xf9, 0xe3, 0xee,
|
||||||
0x73, 0xa6, 0x9a, 0xc9, 0x3e, 0x31, 0xbc, 0xd5, 0x8c, 0xb9, 0x36, 0x50, 0xb5, 0x09, 0xcc, 0x0c,
|
0x0f, 0x5d, 0x58, 0x18, 0x2f, 0x78, 0xf2, 0x25, 0x74, 0xc6, 0x70, 0x1b, 0xb9, 0x52, 0x86, 0x67,
|
||||||
0x34, 0xb7, 0x6b, 0xcc, 0x0c, 0xb4, 0xb0, 0x5e, 0xcc, 0x91, 0x03, 0xe8, 0x17, 0xb7, 0x04, 0x72,
|
0x65, 0x1c, 0xa8, 0xff, 0x6b, 0x02, 0x97, 0x2a, 0x8c, 0x29, 0xe2, 0xc3, 0xd9, 0x12, 0x2e, 0x22,
|
||||||
0xbd, 0x6e, 0x75, 0x2d, 0x2d, 0x21, 0xc3, 0x1b, 0x4d, 0x58, 0x33, 0x63, 0x08, 0x2b, 0x79, 0x24,
|
0x37, 0xca, 0xd2, 0x75, 0xa8, 0x4b, 0xbf, 0xd9, 0x88, 0x37, 0xb3, 0xc7, 0x60, 0xa9, 0x02, 0xe8,
|
||||||
0x4f, 0xae, 0x95, 0xe5, 0x2b, 0xf7, 0x92, 0xe1, 0x68, 0x36, 0xe3, 0x74, 0x4c, 0x45, 0x74, 0x5f,
|
0x90, 0x5b, 0x13, 0xb4, 0xe4, 0xc0, 0x96, 0xfe, 0xef, 0x86, 0xdc, 0x99, 0xd5, 0xd7, 0x40, 0xca,
|
||||||
0x15, 0x53, 0xcd, 0xea, 0x50, 0x15, 0x53, 0xdd, 0xb2, 0x60, 0xce, 0x91, 0x9f, 0x53, 0xc8, 0x58,
|
0x28, 0x88, 0xdc, 0x9c, 0xa8, 0x66, 0x84, 0xb2, 0xf4, 0x5b, 0xcd, 0x98, 0x6b, 0x1f, 0x2a, 0xf1,
|
||||||
0x40, 0xbd, 0x64, 0xab, 0x4e, 0x4d, 0x35, 0xec, 0x1e, 0xde, 0x6e, 0xcc, 0x9f, 0xda, 0xbe, 0x63,
|
0xd1, 0xc4, 0x87, 0xe6, 0x10, 0xd8, 0xc4, 0x87, 0x16, 0x40, 0xd7, 0x14, 0x39, 0x80, 0x6e, 0x11,
|
||||||
0x88, 0x5e, 0x9f, 0x02, 0xbf, 0x55, 0xbd, 0x5e, 0x86, 0xd3, 0x55, 0xbd, 0x5e, 0x85, 0xa0, 0xe7,
|
0x3b, 0x91, 0xeb, 0x75, 0x80, 0xbe, 0x04, 0xcd, 0xf4, 0x1b, 0x4d, 0x58, 0x33, 0x63, 0x08, 0xa7,
|
||||||
0xc8, 0x2e, 0x2c, 0xe7, 0xe0, 0x30, 0xb9, 0x5a, 0x27, 0x99, 0x07, 0xd9, 0xc3, 0x6b, 0x33, 0xf9,
|
0xf3, 0xf8, 0x86, 0x5c, 0x2b, 0xcb, 0x57, 0xa2, 0x35, 0x7d, 0x30, 0x99, 0x71, 0xfc, 0x4d, 0x45,
|
||||||
0x32, 0x1b, 0x76, 0x3a, 0xbd, 0xf4, 0xb8, 0xaa, 0x75, 0x2e, 0x3f, 0xaf, 0xae, 0xce, 0x62, 0xcb,
|
0xcc, 0x53, 0xf5, 0xa6, 0x1a, 0x40, 0x55, 0xf5, 0xa6, 0x3a, 0x08, 0x65, 0x4c, 0x91, 0x6f, 0xd2,
|
||||||
0x0c, 0x7c, 0x07, 0x30, 0x41, 0xaf, 0xe4, 0x72, 0x9d, 0xdc, 0xf4, 0xa7, 0xb8, 0x72, 0x3c, 0x53,
|
0x45, 0xba, 0x80, 0x05, 0xc8, 0x66, 0x9d, 0x9a, 0x6a, 0x30, 0xa2, 0xdf, 0x6e, 0xcc, 0x9f, 0xda,
|
||||||
0xa6, 0xfa, 0x47, 0x58, 0xab, 0x7a, 0xe9, 0x49, 0x45, 0x17, 0x1e, 0x03, 0x27, 0x86, 0x5b, 0x4d,
|
0xbe, 0xa3, 0xf1, 0x5a, 0x1f, 0x83, 0x04, 0x55, 0xb5, 0x5e, 0x06, 0x19, 0x55, 0xb5, 0x5e, 0x85,
|
||||||
0xd9, 0x33, 0xc3, 0x2f, 0xa0, 0x93, 0x62, 0x57, 0x72, 0xa9, 0x2c, 0x5d, 0xc0, 0xda, 0x43, 0xf3,
|
0x2b, 0xa6, 0xc8, 0x2e, 0x2c, 0xe6, 0x40, 0x02, 0xb9, 0x5a, 0x27, 0x99, 0x87, 0x1e, 0xfa, 0xb5,
|
||||||
0x38, 0x96, 0xa9, 0x6a, 0x1a, 0xa7, 0x8d, 0x33, 0x01, 0x95, 0xf5, 0x8d, 0x53, 0x82, 0xbf, 0xf5,
|
0x89, 0x7c, 0x99, 0x0d, 0x2b, 0xed, 0x5e, 0xaa, 0x5d, 0xd5, 0x3a, 0x97, 0xef, 0x57, 0x57, 0x27,
|
||||||
0x8d, 0x53, 0xc6, 0xa8, 0xd2, 0xdc, 0xeb, 0x74, 0xaf, 0x98, 0xc6, 0x60, 0x95, 0x43, 0xb6, 0x0e,
|
0xb1, 0x65, 0x06, 0x3e, 0x07, 0x18, 0xed, 0xf4, 0xe4, 0x72, 0x9d, 0xdc, 0xf8, 0xa7, 0xb8, 0x72,
|
||||||
0x62, 0x56, 0x0e, 0xd9, 0x7a, 0x58, 0x37, 0xb7, 0xbb, 0x20, 0xff, 0x07, 0xbc, 0xf7, 0x4f, 0x00,
|
0x32, 0x53, 0xa6, 0xfa, 0x2b, 0x58, 0xae, 0x9a, 0xf4, 0xa4, 0xa2, 0x0a, 0x4f, 0x58, 0x27, 0xf4,
|
||||||
0x00, 0x00, 0xff, 0xff, 0x5d, 0xbf, 0x08, 0x06, 0x1e, 0x14, 0x00, 0x00,
|
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,
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"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))
|
volumeFileName = storage.VolumeFileName(volFileInfoResp.Collection, location.Directory, int(req.VolumeId))
|
||||||
|
|
||||||
// println("source:", volFileInfoResp.String())
|
// println("source:", volFileInfoResp.String())
|
||||||
|
// copy ecx file
|
||||||
copyFileClient, err := client.CopyFile(ctx, &volume_server_pb.CopyFileRequest{
|
if err:=vs.doCopyFile(ctx, client, req.VolumeId, volFileInfoResp.CompactionRevision, volFileInfoResp.IdxFileSize, volumeFileName, ".idx"); err!=nil{
|
||||||
VolumeId: req.VolumeId,
|
return err
|
||||||
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"
|
if err:=vs.doCopyFile(ctx, client, req.VolumeId, volFileInfoResp.CompactionRevision, volFileInfoResp.DatFileSize, volumeFileName, ".dat"); err!=nil{
|
||||||
err = writeToFile(copyFileClient, idxFileName, util.NewWriteThrottler(vs.compactionBytePerSecond))
|
return err
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -109,6 +86,28 @@ func (vs *VolumeServer) VolumeCopy(ctx context.Context, req *volume_server_pb.Vo
|
||||||
}, err
|
}, 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
|
only check the the differ of the file size
|
||||||
todo: maybe should check the received count and deleted count of the volume
|
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
|
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 {
|
func (vs *VolumeServer) CopyFile(req *volume_server_pb.CopyFileRequest, stream volume_server_pb.VolumeServer_CopyFileServer) error {
|
||||||
|
|
||||||
v := vs.store.GetVolume(needle.VolumeId(req.VolumeId))
|
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)
|
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)
|
return fmt.Errorf("volume %d is compacted", req.VolumeId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
82
weed/server/volume_grpc_erasure_coding.go
Normal file
82
weed/server/volume_grpc_erasure_coding.go
Normal file
|
@ -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
|
||||||
|
}
|
|
@ -6,6 +6,9 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/chrislusf/seaweedfs/weed/glog"
|
"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"
|
"github.com/klauspost/reedsolomon"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,11 +19,66 @@ const (
|
||||||
ErasureCodingSmallBlockSize = 1024 * 1024 // 1MB
|
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 {
|
func encodeData(file *os.File, enc reedsolomon.Encoder, startOffset, blockSize int64, buffers [][]byte, outputs []*os.File) error {
|
||||||
|
|
||||||
bufferSize := int64(len(buffers[0]))
|
bufferSize := int64(len(buffers[0]))
|
||||||
batchCount := blockSize/bufferSize
|
batchCount := blockSize / bufferSize
|
||||||
if blockSize%bufferSize!=0 {
|
if blockSize%bufferSize != 0 {
|
||||||
glog.Fatalf("unexpected block size %d buffer size %d", blockSize, bufferSize)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func openEcFiles(baseFileName string, forRead bool) (files []*os.File, err error){
|
func openEcFiles(baseFileName string, forRead bool) (files []*os.File, err error) {
|
||||||
for i := 0; i< DataShardsCount+ParityShardsCount; i++{
|
for i := 0; i < DataShardsCount+ParityShardsCount; i++ {
|
||||||
fname := fmt.Sprintf("%s.ec%02d", baseFileName, i+1)
|
fname := baseFileName + ToExt(i+1)
|
||||||
openOption := os.O_TRUNC|os.O_CREATE|os.O_WRONLY
|
openOption := os.O_TRUNC | os.O_CREATE | os.O_WRONLY
|
||||||
if forRead {
|
if forRead {
|
||||||
openOption = os.O_RDONLY
|
openOption = os.O_RDONLY
|
||||||
}
|
}
|
||||||
|
@ -50,15 +108,14 @@ func openEcFiles(baseFileName string, forRead bool) (files []*os.File, err error
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func closeEcFiles(files []*os.File){
|
func closeEcFiles(files []*os.File) {
|
||||||
for _, f := range files{
|
for _, f := range files {
|
||||||
if f != nil {
|
if f != nil {
|
||||||
f.Close()
|
f.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func encodeDataOneBatch(file *os.File, enc reedsolomon.Encoder, startOffset, blockSize int64, buffers [][]byte, outputs []*os.File) error {
|
func encodeDataOneBatch(file *os.File, enc reedsolomon.Encoder, startOffset, blockSize int64, buffers [][]byte, outputs []*os.File) error {
|
||||||
|
|
||||||
// read data into buffers
|
// read data into buffers
|
||||||
|
@ -90,3 +147,56 @@ func encodeDataOneBatch(file *os.File, enc reedsolomon.Encoder, startOffset, blo
|
||||||
|
|
||||||
return nil
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/chrislusf/seaweedfs/weed/storage"
|
|
||||||
"github.com/chrislusf/seaweedfs/weed/storage/needle_map"
|
"github.com/chrislusf/seaweedfs/weed/storage/needle_map"
|
||||||
"github.com/chrislusf/seaweedfs/weed/storage/types"
|
"github.com/chrislusf/seaweedfs/weed/storage/types"
|
||||||
"github.com/klauspost/reedsolomon"
|
"github.com/klauspost/reedsolomon"
|
||||||
|
@ -27,98 +26,20 @@ func TestEncodingDecoding(t *testing.T) {
|
||||||
t.Logf("generateEcFiles: %v", err)
|
t.Logf("generateEcFiles: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = writeSortedEcxFiles(baseFileName)
|
err = WriteSortedEcxFile(baseFileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Logf("writeSortedEcxFiles: %v", err)
|
t.Logf("WriteSortedEcxFile: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = validateFiles(baseFileName)
|
err = validateFiles(baseFileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Logf("writeSortedEcxFiles: %v", err)
|
t.Logf("WriteSortedEcxFile: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
removeGeneratedFiles(baseFileName)
|
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 {
|
func validateFiles(baseFileName string) error {
|
||||||
cm, err := readCompactMap(baseFileName)
|
cm, err := readCompactMap(baseFileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -148,25 +69,6 @@ func validateFiles(baseFileName string) error {
|
||||||
return nil
|
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 {
|
func assertSame(datFile *os.File, datSize int64, ecFiles []*os.File, offset types.Offset, size uint32) error {
|
||||||
|
|
||||||
data, err := readDatFile(datFile, offset, size)
|
data, err := readDatFile(datFile, offset, size)
|
||||||
|
@ -288,7 +190,7 @@ func removeGeneratedFiles(baseFileName string) {
|
||||||
fname := fmt.Sprintf("%s.ec%02d", baseFileName, i+1)
|
fname := fmt.Sprintf("%s.ec%02d", baseFileName, i+1)
|
||||||
os.Remove(fname)
|
os.Remove(fname)
|
||||||
}
|
}
|
||||||
os.Remove(baseFileName+".ecx")
|
os.Remove(baseFileName + ".ecx")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLocateData(t *testing.T) {
|
func TestLocateData(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue