Skip to content

Commit a9de0e0

Browse files
author
Peter Collins
committed
Add cache as an option
1 parent 9e90b4b commit a9de0e0

File tree

2 files changed

+308
-34
lines changed

2 files changed

+308
-34
lines changed

Diff for: erasure.go

+32-24
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,32 @@ type decodeNode struct {
3636
decodeIndex []byte
3737
}
3838

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+
}
4165

4266
node.mutex.Lock()
4367
defer node.mutex.Unlock()
@@ -64,23 +88,6 @@ func (c *Code) getDecode(errList []byte) *decodeNode {
6488
return node
6589
}
6690

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-
8491
// Constructor for creating a new erasure coding scheme. M is the total
8592
// number of shards output by the encoding. K is the number of shards
8693
// 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 {
120127
// The data buffer to encode must be of the length Size given in the constructor.
121128
// The returned encoded buffer is (M-K)*Shard length, since the first Size bytes
122129
// 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) {
124131
if len(data) != c.K*c.ShardLength {
125132
panic("Data to encode is not the proper size")
126133
}
127134
// Since the first k rows of the encode matrix is actually the identity matrix
128135
// we only need to encode the last m-k shards of the data and append
129136
// 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))
131138
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]))
132139
// return append(data, encoded...)
133140
return encoded
@@ -136,19 +143,20 @@ func (c *Code) Encode(data []byte) []byte {
136143
// Data buffer to decode must be of the (M/K)*Size given in the constructor.
137144
// The error list must contain M-K values, corresponding to the shards
138145
// 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.
139148
// 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) {
141150
if len(encoded) != c.M*c.ShardLength {
142151
panic("Data to decode is not the proper size")
143152
}
144153
if len(errList) > c.M-c.K {
145154
panic("Too many errors, cannot decode")
146155
}
147-
recovered := []byte{}
148156
if len(errList) == 0 {
149157
recovered = append(recovered, encoded[:c.K*c.ShardLength]...)
150158
} else {
151-
node := c.getDecode(errList)
159+
node := c.getDecode(errList, cache)
152160

153161
for i := 0; i < c.K; i++ {
154162
recovered = append(recovered, encoded[(int(node.decodeIndex[i])*c.ShardLength):int(node.decodeIndex[i]+1)*c.ShardLength]...)

0 commit comments

Comments
 (0)