Example #1
0
// Constructor for creating a new erasure coding scheme. M is the total
// number of shards output by the encoding.  K is the number of shards
// that can recreate any data that was encoded.  Size is the size of the
// byte array to encode.  It should be divisible by K as each shard
// will be Size / K in length.  The maximum value for K and M is 127.
func NewCode(m int, k int, size int) *Code {
	if m <= 0 || k <= 0 || k >= m || k > 127 || m > 127 || size < 0 {
		panic("Invalid erasure code params")
	}
	if size%k != 0 {
		panic("Size to encode is not divisable by k and therefore cannot be encoded into shards")
	}

	encodeMatrix := make([]byte, m*k)
	galoisTables := make([]byte, k*(m-k)*32)

	if k > 5 {
		C.gf_gen_cauchy1_matrix((*C.uchar)(&encodeMatrix[0]), C.int(m), C.int(k))
	} else {
		C.gf_gen_rs_matrix((*C.uchar)(&encodeMatrix[0]), C.int(m), C.int(k))
	}

	C.ec_init_tables(C.int(k), C.int(m-k), (*C.uchar)(&encodeMatrix[k*k]), (*C.uchar)(&galoisTables[0]))
	return &Code{
		M:            m,
		K:            k,
		ShardLength:  size / k,
		EncodeMatrix: encodeMatrix,
		galoisTables: galoisTables,
		decode: &decodeNode{
			children: make([]*decodeNode, m),
			mutex:    &sync.Mutex{},
		},
	}
}
Example #2
0
func (c *Code) getDecode(errList []byte, cache bool) (node *decodeNode) {
	if cache {
		node = c.decode.getDecode(errList, 0, byte(c.M))
	} else {
		node = newDecodeNode(errList, byte(c.M))
	}

	node.mutex.Lock()
	defer node.mutex.Unlock()
	if node.galoisTables == nil || node.decodeIndex == nil {
		node.galoisTables = make([]byte, c.K*c.M*32)
		node.decodeIndex = make([]byte, c.K)

		decodeMatrix := make([]byte, c.M*c.K)
		srcInErr := make([]byte, c.M)
		nErrs := len(errList)
		nSrcErrs := 0
		for _, err := range errList {
			srcInErr[err] = 1
			if int(err) < c.K {
				nSrcErrs++
			}
		}

		C.gf_gen_decode_matrix((*C.uchar)(&c.EncodeMatrix[0]), (*C.uchar)(&decodeMatrix[0]), (*C.uchar)(&node.decodeIndex[0]), (*C.uchar)(&errList[0]), (*C.uchar)(&srcInErr[0]), C.int(nErrs), C.int(nSrcErrs), C.int(c.K), C.int(c.M))

		C.ec_init_tables(C.int(c.K), C.int(nErrs), (*C.uchar)(&decodeMatrix[0]), (*C.uchar)(&node.galoisTables[0]))
	}

	return node
}