Exemple #1
0
        public async Task Encode(ReadOnlyMemory<byte>[] sources, int[] index, Memory<byte>[] repairs, int packetLength, int concurrency = 1, CancellationToken token = default)
        {
            if (sources == null) throw new ArgumentNullException(nameof(sources));
            if (repairs == null) throw new ArgumentNullException(nameof(repairs));
            if (index == null) throw new ArgumentNullException(nameof(index));

            await Enumerable.Range(0, repairs.Length).ForEachAsync(row =>
            {
                return Task.Run(() =>
                {
                    token.ThrowIfCancellationRequested();

                    // *remember* indices start at 0, k starts at 1.
                    if (index[row] < _k)
                    {
                        // < k, systematic so direct copy.
                        BytesOperations.Copy(sources[index[row]].Span, repairs[row].Span, packetLength);
                    }
                    else
                    {
                        // index[row] >= k && index[row] < n
                        int pos = index[row] * _k;
                        BytesOperations.Zero(repairs[row].Span.Slice(packetLength));

                        for (int col = 0; col < _k; col++)
                        {
                            token.ThrowIfCancellationRequested();

                            ReadSolomonMath.AddMul(sources[col].Span, repairs[row].Span, _encMatrix[pos + col], packetLength);
                        }
                    }
                });
            }, concurrency, token, false);
        }
Exemple #2
0
 public ReedSolomon8(int k, int n, BufferPool bufferPool)
 {
     _k = k;
     _n = n;
     _bufferPool = bufferPool;
     _encMatrix = ReadSolomonMath.CreateEncodeMatrix(k, n);
 }
Exemple #3
0
        public async Task Decode(Memory<byte>[] packets, int[] index, int packetLength, int concurrency = 1, CancellationToken token = default)
        {
            if (packets == null) throw new ArgumentNullException(nameof(packets));
            if (index == null) throw new ArgumentNullException(nameof(index));

            Shuffle(packets, index, _k);

            var decMatrix = ReadSolomonMath.CreateDecodeMatrix(_encMatrix, index, _k, _n);

            // do the actual decoding..
            var tempPackets = new byte[_k][];

            await Enumerable.Range(0, _k).ForEachAsync(row =>
            {
                return Task.Run(() =>
                {
                    token.ThrowIfCancellationRequested();

                    if (index[row] >= _k)
                    {
                        tempPackets[row] = _bufferPool.GetArrayPool().Rent(packetLength);
                        BytesOperations.Zero(tempPackets[row].AsSpan(0, packetLength));

                        for (int col = 0; col < _k; col++)
                        {
                            token.ThrowIfCancellationRequested();

                            ReadSolomonMath.AddMul(packets[col].Span, tempPackets[row], decMatrix[row * _k + col], packetLength);
                        }
                    }
                });
            }, concurrency, token, false);

            token.ThrowIfCancellationRequested();

            // move pkts to their final destination
            for (int row = 0; row < _k; row++)
            {
                if (index[row] >= _k)
                {
                    // only copy those actually decoded.
                    BytesOperations.Copy(tempPackets[row], packets[row].Span, packetLength);
                    index[row] = row;
                    _bufferPool.GetArrayPool().Return(tempPackets[row]);
                }
            }
        }
Exemple #4
0
 internal static void LoadPureUnsafeMethods()
 {
     ReadSolomonMath.LoadPureUnsafeMethods();
 }
Exemple #5
0
 internal static void LoadNativeMethods()
 {
     ReadSolomonMath.LoadNativeMethods();
 }