@@ -36,8 +36,32 @@ type decodeNode struct {
36
36
decodeIndex []byte
37
37
}
38
38
39
- func (c * Code ) getDecode (errList []byte ) * decodeNode {
40
- node := c .decode .getDecode (errList , 0 , byte (c .M ))
39
+ func newDecodeNode (errList []byte , m byte ) * decodeNode {
40
+ return & decodeNode {
41
+ children : make ([]* decodeNode , m - errList [0 ]),
42
+ mutex : & sync.Mutex {},
43
+ }
44
+ }
45
+
46
+ func (n * decodeNode ) getDecode (errList []byte , parent , m byte ) (node * decodeNode ) {
47
+ n .mutex .Lock ()
48
+ node = n .children [errList [0 ]- parent ]
49
+ if node == nil {
50
+ node = newDecodeNode (errList , m )
51
+ }
52
+ n .mutex .Unlock ()
53
+ if len (errList ) > 1 {
54
+ return node .getDecode (errList [1 :], errList [0 ]+ 1 , m )
55
+ }
56
+ return node
57
+ }
58
+
59
+ func (c * Code ) getDecode (errList []byte , cache bool ) (node * decodeNode ) {
60
+ if cache {
61
+ node = c .decode .getDecode (errList , 0 , byte (c .M ))
62
+ } else {
63
+ node = newDecodeNode (errList , byte (c .M ))
64
+ }
41
65
42
66
node .mutex .Lock ()
43
67
defer node .mutex .Unlock ()
@@ -64,23 +88,6 @@ func (c *Code) getDecode(errList []byte) *decodeNode {
64
88
return node
65
89
}
66
90
67
- func (n * decodeNode ) getDecode (errList []byte , parent , m byte ) * decodeNode {
68
- n .mutex .Lock ()
69
- node := n .children [errList [0 ]- parent ]
70
- if node == nil {
71
- node = & decodeNode {
72
- children : make ([]* decodeNode , m - errList [0 ]),
73
- mutex : & sync.Mutex {},
74
- }
75
- n .children [errList [0 ]- parent ] = node
76
- }
77
- n .mutex .Unlock ()
78
- if len (errList ) > 1 {
79
- return node .getDecode (errList [1 :], errList [0 ]+ 1 , m )
80
- }
81
- return node
82
- }
83
-
84
91
// Constructor for creating a new erasure coding scheme. M is the total
85
92
// number of shards output by the encoding. K is the number of shards
86
93
// that can recreate any data that was encoded. Size is the size of the
@@ -120,14 +127,14 @@ func NewCode(m int, k int, size int) *Code {
120
127
// The data buffer to encode must be of the length Size given in the constructor.
121
128
// The returned encoded buffer is (M-K)*Shard length, since the first Size bytes
122
129
// of the encoded data is just the original data due to the identity matrix.
123
- func (c * Code ) Encode (data []byte ) []byte {
130
+ func (c * Code ) Encode (data []byte ) ( encoded []byte ) {
124
131
if len (data ) != c .K * c .ShardLength {
125
132
panic ("Data to encode is not the proper size" )
126
133
}
127
134
// Since the first k rows of the encode matrix is actually the identity matrix
128
135
// we only need to encode the last m-k shards of the data and append
129
136
// them to the original data
130
- encoded : = make ([]byte , (c .M - c .K )* (c .ShardLength ))
137
+ encoded = make ([]byte , (c .M - c .K )* (c .ShardLength ))
131
138
C .ec_encode_data (C .int (c .ShardLength ), C .int (c .K ), C .int (c .M - c .K ), (* C .uchar )(& c .galoisTables [0 ]), (* C .uchar )(& data [0 ]), (* C .uchar )(& encoded [0 ]))
132
139
// return append(data, encoded...)
133
140
return encoded
@@ -136,19 +143,20 @@ func (c *Code) Encode(data []byte) []byte {
136
143
// Data buffer to decode must be of the (M/K)*Size given in the constructor.
137
144
// The error list must contain M-K values, corresponding to the shards
138
145
// with errors (eg. [0, 2, 4, 6]).
146
+ // Cache stores the decode matrices in a trie, enabling a faster decode
147
+ // with a memory tradeoff.
139
148
// The returned decoded data is the orignal data of length Size
140
- func (c * Code ) Decode (encoded []byte , errList []byte ) []byte {
149
+ func (c * Code ) Decode (encoded []byte , errList []byte , cache bool ) ( recovered []byte ) {
141
150
if len (encoded ) != c .M * c .ShardLength {
142
151
panic ("Data to decode is not the proper size" )
143
152
}
144
153
if len (errList ) > c .M - c .K {
145
154
panic ("Too many errors, cannot decode" )
146
155
}
147
- recovered := []byte {}
148
156
if len (errList ) == 0 {
149
157
recovered = append (recovered , encoded [:c .K * c .ShardLength ]... )
150
158
} else {
151
- node := c .getDecode (errList )
159
+ node := c .getDecode (errList , cache )
152
160
153
161
for i := 0 ; i < c .K ; i ++ {
154
162
recovered = append (recovered , encoded [(int (node .decodeIndex [i ])* c .ShardLength ):int (node .decodeIndex [i ]+ 1 )* c .ShardLength ]... )
0 commit comments