123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- package reedsolomon
- import (
- "errors"
- "sync"
- )
- type inversionTree struct {
- mutex *sync.RWMutex
- root inversionNode
- }
- type inversionNode struct {
- matrix matrix
- children []*inversionNode
- }
- func newInversionTree(dataShards, parityShards int) inversionTree {
- identity, _ := identityMatrix(dataShards)
- root := inversionNode{
- matrix: identity,
- children: make([]*inversionNode, dataShards+parityShards),
- }
- return inversionTree{
- mutex: &sync.RWMutex{},
- root: root,
- }
- }
- func (t inversionTree) GetInvertedMatrix(invalidIndices []int) matrix {
-
- t.mutex.RLock()
- defer t.mutex.RUnlock()
-
-
- if len(invalidIndices) == 0 {
- return t.root.matrix
- }
-
-
- return t.root.getInvertedMatrix(invalidIndices, 0)
- }
- var errAlreadySet = errors.New("the root node identity matrix is already set")
- func (t inversionTree) InsertInvertedMatrix(invalidIndices []int, matrix matrix, shards int) error {
-
-
- if len(invalidIndices) == 0 {
- return errAlreadySet
- }
- if !matrix.IsSquare() {
- return errNotSquare
- }
-
- t.mutex.Lock()
- defer t.mutex.Unlock()
-
-
-
- t.root.insertInvertedMatrix(invalidIndices, matrix, shards, 0)
- return nil
- }
- func (n inversionNode) getInvertedMatrix(invalidIndices []int, parent int) matrix {
-
-
-
-
-
-
- firstIndex := invalidIndices[0]
- node := n.children[firstIndex-parent]
-
-
- if node == nil {
- return nil
- }
-
-
- if len(invalidIndices) > 1 {
-
-
-
- return node.getInvertedMatrix(invalidIndices[1:], firstIndex+1)
- }
-
-
-
-
- return node.matrix
- }
- func (n inversionNode) insertInvertedMatrix(invalidIndices []int, matrix matrix, shards, parent int) {
-
-
-
-
-
-
- firstIndex := invalidIndices[0]
- node := n.children[firstIndex-parent]
-
-
-
- if node == nil {
-
-
-
-
- node = &inversionNode{
- children: make([]*inversionNode, shards-firstIndex),
- }
-
-
- n.children[firstIndex-parent] = node
- }
-
-
-
- if len(invalidIndices) > 1 {
-
-
-
-
- node.insertInvertedMatrix(invalidIndices[1:], matrix, shards, firstIndex+1)
- } else {
-
-
- node.matrix = matrix
- }
- }
|