func (x *XRS) retrieveRS(vects [][]byte, dpHas []int) (err error) {
	half := len(vects[0]) / 2
	for _, h := range dpHas {
		if h > x.RS.DataNum {  
			xs := x.XORSet[h]
			xv := make([][]byte, len(xs)+1)
			xv[0] = vects[h][half:]  
			for i, ai := range xs {
				xv[i+1] = vects[ai][:half]
			}
			xor.Encode(vects[h][half:], xv)
		}
	}
	return
}
retrieveRS retrieves b_parity_vects(if has) to RS codes
by XOR itself and a_vects in XORSet.
package xrs
import (
	"errors"
	"fmt"
	rs "github.com/templexxx/reedsolomon"
	xor "github.com/templexxx/xorsimd"
)
type XRS struct {
	RS *rs.RS
	XORSet map[int][]int
}
func New(dataNum, parityNum int) (x *XRS, err error) {
	if parityNum == 1 {
		err = errors.New("illegal parity")
		return
	}
	r, err := rs.New(dataNum, parityNum)
	if err != nil {
		return
	}
	xs := make(map[int][]int)
	makeXORSet(dataNum, parityNum, xs)
	x = &XRS{RS: r, XORSet: xs}
	return
}
func makeXORSet(d, p int, m map[int][]int) {
	for i := d + 1; i < d+p; i++ {
		m[i] = make([]int, 0)
	}
	j := d + 1
	for i := 0; i < d; i++ {
		if j > d+p-1 {
			j = d + 1
		}
		m[j] = append(m[j], i)
		j++
	}
	for k, v := range m {
		if len(v) == 0 {
			delete(m, k)
		}
	}
}
func (x *XRS) Encode(vects [][]byte) (err error) {
	err = checkSize(vects[0])
	if err != nil {
		return
	}
	size := len(vects[0])
	err = x.RS.Encode(vects)
	if err != nil {
		return
	}
	half := size / 2
	for bi, xs := range x.XORSet {
		xv := make([][]byte, len(xs)+1)
		xv[0] = vects[bi][half:]
		for j, ai := range xs {
			xv[j+1] = vects[ai][:half]
		}
		xor.Encode(vects[bi][half:], xv)
	}
	return
}
func checkSize(vect []byte) error {
	size := len(vect)
	if size&1 != 0 {
		return fmt.Errorf("vect size not even: %d", size)
	}
	return nil
}
func (x *XRS) GetNeedVects(needReconst int) (aNeed, bNeed []int, err error) {
	d := x.RS.DataNum
	if needReconst < 0 || needReconst >= d {
		err = fmt.Errorf("illegal data index: %d", needReconst)
		return
	}
	bNeed = make([]int, 2)
	bNeed[0] = d  
	xs := x.XORSet
	for i, s := range xs {
		if isIn(needReconst, s) {
			bNeed[1] = i
			break
		}
	}
	for _, i := range xs[bNeed[1]] {
		if i != needReconst {
			aNeed = append(aNeed, i)
		}
	}
	return
}
func (x *XRS) ReconstOne(vects [][]byte, needReconst int) (err error) {
	err = checkSize(vects[0])
	if err != nil {
		return
	}
	aNeed, bNeed, err := x.GetNeedVects(needReconst)
	if err != nil {
		return
	}
	bVects := make([][]byte, len(vects))
	half := len(vects[0]) / 2
	for i, v := range vects {
		bVects[i] = v[half:]
	}
	d := x.RS.DataNum
	bDPHas := make([]int, d)
	for i := 0; i < d; i++ {
		bDPHas[i] = i
	}
	bDPHas[needReconst] = d  
	bi := bNeed[1]  
	bRS := make([]byte, half)
	bVects[bi] = bRS
	err = x.RS.Reconst(bVects, bDPHas, []int{needReconst, bi})
	if err != nil {
		return
	}
	xorV := make([][]byte, len(aNeed)+2)
	xorV[0] = vects[bi][half:]
	xorV[1] = bRS
	for i, ai := range aNeed {
		xorV[i+2] = vects[ai][:half]
	}
	xor.Encode(vects[needReconst][:half], xorV)
	return
}
func (x *XRS) Reconst(vects [][]byte, dpHas, needReconst []int) (err error) {
	if len(needReconst) == 1 && needReconst[0] < x.RS.DataNum {
		return x.ReconstOne(vects, needReconst[0])
	}
	err = checkSize(vects[0])
	if err != nil {
		return
	}
	half := len(vects[0]) / 2
	aVects := make([][]byte, len(vects))
	for i := range vects {
		aVects[i] = vects[i][:half]
	}
	aLost := make([]int, 0)
	for i := 0; i < x.RS.DataNum+x.RS.ParityNum; i++ {
		if !isIn(i, dpHas) {
			aLost = append(aLost, i)
		}
	}
	err = x.RS.Reconst(aVects, dpHas, aLost)
	if err != nil {
		return
	}
	err = x.retrieveRS(vects, dpHas)
	if err != nil {
		return
	}
	bVects := make([][]byte, len(vects))
	for i := range vects {
		bVects[i] = vects[i][half:]
	}
	err = x.RS.Reconst(bVects, dpHas, needReconst)
	if err != nil {
		return
	}
	d := x.RS.DataNum
	_, pn := rs.SplitNeedReconst(d, needReconst)
	if len(pn) != 0 {
		if len(pn) == 1 && pn[0] == d {
			return nil
		}
		for _, i := range pn {
			if i != d {
				xs := x.XORSet[i]
				xv := make([][]byte, len(xs)+1)
				xv[0] = vects[i][half:]
				for j, ai := range xs {
					xv[j+1] = vects[ai][:half]
				}
				xor.Encode(vects[i][half:], xv)
			}
		}
	}
	return nil
}