Exemple #1
0
        public List <IByteBuffer> decode(FecPacket pkt)
        {
            if (pkt.Flag == Fec.typeParity)
            {
                Snmp.snmp.FECParityShards++;
            }
            else
            {
                Snmp.snmp.FECDataShards++;
            }

            int n         = rx.Count - 1;
            int insertIdx = 0;

            for (int i = n; i >= 0; i--)
            {
                //去重
                if (pkt.Seqid == rx[i].Seqid)
                {
                    Snmp.snmp.FECRepeatDataShards++;
                    pkt.release();
                    return(null);
                }

                if (pkt.Seqid > rx[i].Seqid)
                {
                    // insertion
                    insertIdx = i + 1;
                    break;
                }
            }

            //插入 rx中
            if (insertIdx == n + 1)
            {
                this.rx.Add(pkt);
            }
            else
            {
                rx.Insert(insertIdx, pkt);
            }

            //所有消息列表中的第一个包
            // shard range for current packet
            long shardBegin = pkt.Seqid - pkt.Seqid % shardSize;
            long shardEnd   = shardBegin + shardSize - 1;

            //rx数组中的第一个包
            // max search range in ordered queue for current shard
            int searchBegin = (int)(insertIdx - pkt.Seqid % shardSize);

            if (searchBegin < 0)
            {
                searchBegin = 0;
            }

            int searchEnd = searchBegin + shardSize - 1;

            if (searchEnd >= rx.Count)
            {
                searchEnd = rx.Count - 1;
            }

            List <IByteBuffer> result = null;

            if (searchEnd - searchBegin + 1 >= dataShards)
            {
                //当前包组的已收到的包数量
                int numshard = 0;
                //当前包组中属于数据包的数量
                int numDataShard = 0;
                //搜到第一个包在搜索行中的位置
                int first = 0;
                //收到的最大包的字节长度
                int maxlen = 0;

                // zero cache
                IByteBuffer[] shards     = decodeCache;
                bool[]        shardsflag = flagCache;
                for (int i = 0; i < shards.Length; i++)
                {
                    shards[i]     = null;
                    shardsflag[i] = false;
                }

                for (int i = searchBegin; i <= searchEnd; i++)
                {
                    FecPacket fecPacket = rx[i];
                    long      seqid     = fecPacket.Seqid;
                    if (seqid > shardEnd)
                    {
                        break;
                    }
                    if (seqid < shardBegin)
                    {
                        continue;
                    }
                    shards[(int)(seqid % shardSize)]     = fecPacket.Data;
                    shardsflag[(int)(seqid % shardSize)] = true;
                    numshard++;
                    if (fecPacket.Flag == Fec.typeData)
                    {
                        numDataShard++;
                    }

                    if (numshard == 1)
                    {
                        first = i;
                    }

                    if (fecPacket.Data.ReadableBytes > maxlen)
                    {
                        maxlen = fecPacket.Data.ReadableBytes;
                    }
                }

                if (numDataShard == dataShards)
                {
                    freeRange(first, numshard, rx);
                }
                else if (numshard >= dataShards)
                {
                    for (int i = 0; i < shards.Length; i++)
                    {
                        IByteBuffer shard = shards[i];
                        //如果数据不存在 用0填充起来
                        if (shard == null)
                        {
                            shards[i] = zeros.Copy(0, maxlen);
                            shards[i].SetWriterIndex(maxlen);
                            continue;
                        }

                        int left = maxlen - shard.ReadableBytes;
                        if (left > 0)
                        {
                            shard.WriteBytes(this.zeros, left);
                            zeros.ResetReaderIndex();
//                            zeros.resetReaderIndex();
                        }
                    }

                    codec.decodeMissing(shards, shardsflag, 0, maxlen);
                    result = new List <IByteBuffer>(this.dataShards);
                    for (int i = 0; i < shardSize; i++)
                    {
                        if (shardsflag[i])
                        {
                            continue;
                        }

                        IByteBuffer byteBufs = shards[i];
                        //释放构建的parityShards内存
                        if (i >= dataShards)
                        {
                            byteBufs.Release();
                            continue;
                        }

                        int packageSize = byteBufs.ReadShort();
                        if (byteBufs.ReadableBytes < packageSize)
                        {
////                            System.out.println("bytebuf长度: " + byteBufs.writerIndex() + " 读出长度" + packageSize);
//                            byte[] bytes = new byte[byteBufs.writerIndex()];
//                            byteBufs.getBytes(0, bytes);
//                            for (byte aByte :
//                            bytes) {
//                                System.out.print("[" + aByte + "] ");
//                            }
                            Snmp.snmp.FECErrs++;
                        }
                        else
                        {
                            Snmp.snmp.FECRecovered++;
                        }

                        //去除fec头标记的消息体长度2字段
                        byteBufs = byteBufs.Slice(Fec.fecDataSize, packageSize);
                        //int packageSize =byteBufs.readUnsignedShort();
                        //byteBufs = byteBufs.slice(0,packageSize);
                        result.Add(byteBufs);
                        Snmp.snmp.FECRecovered++;
                        //int packageSize =byteBufs.getUnsignedShort(0);
                        ////判断长度
                        //if(byteBufs.writerIndex()-Fec.fecHeaderSizePlus2>=packageSize&&packageSize>0)
                        //{
                        //    byteBufs = byteBufs.slice(Fec.fecHeaderSizePlus2,packageSize);
                        //    result.add(byteBufs);
                        //    Snmp.snmp.FECRecovered.incrementAndGet();
                        //}else{
                        //    System.out.println("bytebuf长度: "+byteBufs.writerIndex()+" 读出长度"+packageSize);
                        //    byte[] bytes = new byte[byteBufs.writerIndex()];
                        //    byteBufs.getBytes(0,bytes);
                        //    for (byte aByte : bytes) {
                        //        System.out.print("["+aByte+"] ");
                        //    }
                        //    Snmp.snmp.FECErrs.incrementAndGet();
                        //}
                    }

                    freeRange(first, numshard, rx);
                }
            }

            if (rx.Count > rxlimit)
            {
                if (rx[0].Flag == Fec.typeData)
                {
                    Snmp.snmp.FECShortShards++;
                }

                freeRange(0, 1, rx);
            }

            return(result);
        }