@@ -5,12 +5,15 @@ package erasurecode
5
5
#include <stdlib.h>
6
6
#include <liberasurecode/erasurecode.h>
7
7
#include <liberasurecode/erasurecode_helpers_ext.h>
8
- // shim to make dereferencing frags easier
9
- void * strArrayItem(char ** arr, int idx) { return arr[idx]; }
8
+ // shims to make working with frag arrays easier
9
+ char ** makeStrArray(int n) { return calloc(n, sizeof (char *)); }
10
+ void freeStrArray(char ** arr) { free(arr); }
11
+ void * getStrArrayItem(char ** arr, int idx) { return arr[idx]; }
12
+ void setStrArrayItem(char ** arr, int idx, unsigned char * val) { arr[idx] = (char *) val; }
10
13
// shims because the fragment headers use misaligned fields
11
14
uint64_t getOrigDataSize(struct fragment_header_s *header) { return header->meta.orig_data_size; }
12
15
uint32_t getBackendVersion(struct fragment_header_s *header) { return header->meta.backend_version; }
13
- ec_backend_id_t getBackendId (struct fragment_header_s *header) { return header->meta.backend_id; }
16
+ ec_backend_id_t getBackendID (struct fragment_header_s *header) { return header->meta.backend_id; }
14
17
uint32_t getECVersion(struct fragment_header_s *header) { return header->libec_version; }
15
18
*/
16
19
import "C"
@@ -74,30 +77,30 @@ func AvailableBackends() (avail []string) {
74
77
return
75
78
}
76
79
77
- type ErasureCodeParams struct {
80
+ type Params struct {
78
81
Name string
79
82
K int
80
83
M int
81
84
W int
82
85
HD int
83
86
}
84
87
85
- type ErasureCodeBackend struct {
86
- ErasureCodeParams
87
- libec_desc C.int
88
+ type Backend struct {
89
+ Params
90
+ libecDesc C.int
88
91
}
89
92
90
93
func BackendIsAvailable (name string ) bool {
91
- id , err := nameToId (name )
94
+ id , err := nameToID (name )
92
95
if err != nil {
93
96
return false
94
97
}
95
98
return C .liberasurecode_backend_available (id ) != 0
96
99
}
97
100
98
- func InitBackend (params ErasureCodeParams ) (ErasureCodeBackend , error ) {
99
- backend := ErasureCodeBackend {params , 0 }
100
- id , err := nameToId (backend .Name )
101
+ func InitBackend (params Params ) (Backend , error ) {
102
+ backend := Backend {params , 0 }
103
+ id , err := nameToID (backend .Name )
101
104
if err != nil {
102
105
return backend , err
103
106
}
@@ -109,110 +112,101 @@ func InitBackend(params ErasureCodeParams) (ErasureCodeBackend, error) {
109
112
ct : C .CHKSUM_CRC32 ,
110
113
})
111
114
if desc < 0 {
112
- return backend , errors .New (fmt .Sprintf (
113
- "instance_create() returned %v" , errToName (- desc )))
115
+ return backend , fmt .Errorf ("instance_create() returned %v" , errToName (- desc ))
114
116
}
115
- backend .libec_desc = desc
117
+ backend .libecDesc = desc
116
118
return backend , nil
117
119
}
118
120
119
- func (backend * ErasureCodeBackend ) Close () error {
120
- if backend .libec_desc == 0 {
121
+ func (backend * Backend ) Close () error {
122
+ if backend .libecDesc == 0 {
121
123
return errors .New ("backend already closed" )
122
124
}
123
- if rc := C .liberasurecode_instance_destroy (backend .libec_desc ); rc != 0 {
124
- return errors .New (fmt .Sprintf (
125
- "instance_destroy() returned %v" , errToName (- rc )))
125
+ if rc := C .liberasurecode_instance_destroy (backend .libecDesc ); rc != 0 {
126
+ return fmt .Errorf ("instance_destroy() returned %v" , errToName (- rc ))
126
127
}
127
- backend .libec_desc = 0
128
+ backend .libecDesc = 0
128
129
return nil
129
130
}
130
131
131
- func (backend * ErasureCodeBackend ) Encode (data []byte ) ([][]byte , error ) {
132
- var data_frags * * C.char
133
- var parity_frags * * C.char
134
- var frag_len C.uint64_t
135
- p_data := (* C .char )(unsafe .Pointer (& data [0 ]))
132
+ func (backend * Backend ) Encode (data []byte ) ([][]byte , error ) {
133
+ var dataFrags * * C.char
134
+ var parityFrags * * C.char
135
+ var fragLength C.uint64_t
136
+ pData := (* C .char )(unsafe .Pointer (& data [0 ]))
136
137
if rc := C .liberasurecode_encode (
137
- backend .libec_desc , p_data , C .uint64_t (len (data )),
138
- & data_frags , & parity_frags , & frag_len ); rc != 0 {
139
- return nil , errors .New (fmt .Sprintf (
140
- "encode() returned %v" , errToName (- rc )))
138
+ backend .libecDesc , pData , C .uint64_t (len (data )),
139
+ & dataFrags , & parityFrags , & fragLength ); rc != 0 {
140
+ return nil , fmt .Errorf ("encode() returned %v" , errToName (- rc ))
141
141
}
142
142
defer C .liberasurecode_encode_cleanup (
143
- backend .libec_desc , data_frags , parity_frags )
143
+ backend .libecDesc , dataFrags , parityFrags )
144
144
result := make ([][]byte , backend .K + backend .M )
145
145
for i := 0 ; i < backend .K ; i ++ {
146
- result [i ] = C .GoBytes (C .strArrayItem ( data_frags , C .int (i )), C .int (frag_len ))
146
+ result [i ] = C .GoBytes (C .getStrArrayItem ( dataFrags , C .int (i )), C .int (fragLength ))
147
147
}
148
148
for i := 0 ; i < backend .M ; i ++ {
149
- result [i + backend .K ] = C .GoBytes (C .strArrayItem ( parity_frags , C .int (i )), C .int (frag_len ))
149
+ result [i + backend .K ] = C .GoBytes (C .getStrArrayItem ( parityFrags , C .int (i )), C .int (fragLength ))
150
150
}
151
151
return result , nil
152
152
}
153
153
154
- func (backend * ErasureCodeBackend ) Decode (frags [][]byte ) ([]byte , error ) {
154
+ func (backend * Backend ) Decode (frags [][]byte ) ([]byte , error ) {
155
155
var data * C.char
156
- var data_len C.uint64_t
156
+ var dataLength C.uint64_t
157
157
if len (frags ) == 0 {
158
158
return nil , errors .New ("decoding requires at least one fragment" )
159
159
}
160
160
161
- c_frags := (* * C .char )(C .calloc (C .size_t (len (frags )), C .size_t (int (unsafe .Sizeof (data )))))
162
- defer C .free (unsafe .Pointer (c_frags ))
163
- base := uintptr (unsafe .Pointer (c_frags ))
161
+ cFrags := C .makeStrArray (C .int (len (frags )))
162
+ defer C .freeStrArray (cFrags )
164
163
for index , frag := range frags {
165
- ptr := (* * C .char )(unsafe .Pointer (base + uintptr (index )* unsafe .Sizeof (* c_frags )))
166
- * ptr = (* C .char )(unsafe .Pointer (& frag [0 ]))
164
+ C .setStrArrayItem (cFrags , C .int (index ), (* C .uchar )(& frag [0 ]))
167
165
}
168
166
169
167
if rc := C .liberasurecode_decode (
170
- backend .libec_desc , c_frags , C .int (len (frags )),
168
+ backend .libecDesc , cFrags , C .int (len (frags )),
171
169
C .uint64_t (len (frags [0 ])), C .int (1 ),
172
- & data , & data_len ); rc != 0 {
173
- return nil , errors .New (fmt .Sprintf (
174
- "decode() returned %v" , errToName (- rc )))
170
+ & data , & dataLength ); rc != 0 {
171
+ return nil , fmt .Errorf ("decode() returned %v" , errToName (- rc ))
175
172
}
176
- defer C .liberasurecode_decode_cleanup (backend .libec_desc , data )
177
- return C .GoBytes (unsafe .Pointer (data ), C .int (data_len )), nil
173
+ defer C .liberasurecode_decode_cleanup (backend .libecDesc , data )
174
+ return C .GoBytes (unsafe .Pointer (data ), C .int (dataLength )), nil
178
175
}
179
176
180
- func (backend * ErasureCodeBackend ) Reconstruct (frags [][]byte , frag_index int ) ([]byte , error ) {
177
+ func (backend * Backend ) Reconstruct (frags [][]byte , fragIndex int ) ([]byte , error ) {
181
178
if len (frags ) == 0 {
182
179
return nil , errors .New ("reconstruction requires at least one fragment" )
183
180
}
184
- frag_len := len (frags [0 ])
185
- data := make ([]byte , frag_len )
186
- p_data := (* C .char )(unsafe .Pointer (& data [0 ]))
181
+ fragLength := len (frags [0 ])
182
+ data := make ([]byte , fragLength )
183
+ pData := (* C .char )(unsafe .Pointer (& data [0 ]))
187
184
188
- c_frags := (* * C .char )(C .calloc (C .size_t (len (frags )), C .size_t (int (unsafe .Sizeof (p_data )))))
189
- defer C .free (unsafe .Pointer (c_frags ))
190
- base := uintptr (unsafe .Pointer (c_frags ))
185
+ cFrags := C .makeStrArray (C .int (len (frags )))
186
+ defer C .freeStrArray (cFrags )
191
187
for index , frag := range frags {
192
- ptr := (* * C .char )(unsafe .Pointer (base + uintptr (index )* unsafe .Sizeof (* c_frags )))
193
- * ptr = (* C .char )(unsafe .Pointer (& frag [0 ]))
188
+ C .setStrArrayItem (cFrags , C .int (index ), (* C .uchar )(& frag [0 ]))
194
189
}
195
190
196
191
if rc := C .liberasurecode_reconstruct_fragment (
197
- backend .libec_desc , c_frags , C .int (len (frags )),
198
- C .uint64_t (len (frags [0 ])), C .int (frag_index ), p_data ); rc != 0 {
199
- return nil , errors .New (fmt .Sprintf (
200
- "reconstruct_fragment() returned %v" , errToName (- rc )))
192
+ backend .libecDesc , cFrags , C .int (len (frags )),
193
+ C .uint64_t (len (frags [0 ])), C .int (fragIndex ), pData ); rc != 0 {
194
+ return nil , fmt .Errorf ("reconstruct_fragment() returned %v" , errToName (- rc ))
201
195
}
202
196
return data , nil
203
197
}
204
198
205
- func (backend * ErasureCodeBackend ) IsInvalidFragment (frag []byte ) bool {
206
- p_data := (* C .char )(unsafe .Pointer (& frag [0 ]))
207
- return 1 == C .is_invalid_fragment (backend .libec_desc , p_data )
199
+ func (backend * Backend ) IsInvalidFragment (frag []byte ) bool {
200
+ pData := (* C .char )(unsafe .Pointer (& frag [0 ]))
201
+ return 1 == C .is_invalid_fragment (backend .libecDesc , pData )
208
202
}
209
203
210
204
type FragmentInfo struct {
211
205
Index int
212
206
Size int
213
207
BackendMetadataSize int
214
208
OrigDataSize uint64
215
- BackendId C.ec_backend_id_t
209
+ BackendID C.ec_backend_id_t
216
210
BackendName string
217
211
BackendVersion Version
218
212
ErasureCodeVersion Version
@@ -221,14 +215,14 @@ type FragmentInfo struct {
221
215
222
216
func GetFragmentInfo (frag []byte ) FragmentInfo {
223
217
header := * (* C .struct_fragment_header_s )(unsafe .Pointer (& frag [0 ]))
224
- backendId := C .getBackendId (& header )
218
+ backendID := C .getBackendID (& header )
225
219
return FragmentInfo {
226
220
Index : int (header .meta .idx ),
227
221
Size : int (header .meta .size ),
228
222
BackendMetadataSize : int (header .meta .frag_backend_metadata_size ),
229
223
OrigDataSize : uint64 (C .getOrigDataSize (& header )),
230
- BackendId : backendId ,
231
- BackendName : idToName (backendId ),
224
+ BackendID : backendID ,
225
+ BackendName : idToName (backendID ),
232
226
BackendVersion : makeVersion (C .getBackendVersion (& header )),
233
227
ErasureCodeVersion : makeVersion (C .getECVersion (& header )),
234
228
IsValid : C .is_invalid_fragment_header ((* C .fragment_header_t )(& header )) == 0 ,
0 commit comments