ET---Circularbuffer学习笔记

Circularbuffer学习笔记

请大家关注我的微博:@NormanLin_BadPixel坏像素


因为这是LandlordsCore作者3.0对TBuffer进行的修改,如果有兴趣的话,大家可以去看看我之前写的TBuffer学习笔记,里面可能会比较详细。 而且这篇里如果有TBuffer里讲过的,我会一笔带过。


public int ChunkSize = 8192;

private readonly Queue<byte[]> bufferQueue = new Queue<byte[]>();

private readonly Queue<byte[]> bufferCache = new Queue<byte[]>();

public int LastIndex { get; set; }

public int FirstIndex { get; set; }

private byte[] lastBuffer;

TBuffer有一些类似的地方,也有不同的。最明显的,就是取消了LinkedList的使用,看来作者发现了我们其实并没有用到LinkedList的特征,快速的插入。因为我们一般只会取出缓冲区的首位,和往末位插入新的数据,应对这样的需求,Queue就已经符合要求了。Queue是一个先进先出的队列,不用我多说了吧?

至于lastBuffer这个变量,我们从Queue当中获取首位数据很方便,但是没法获取末位的数据,所以这里特意分配一块内存给末位的数据区块,方便操作。

至于bufferCache是干什么的?我们结合后面的AddLast来看看。

public void AddLast()
{
    byte[] buffer;
    if (this.bufferCache.Count > 0)
    {
        buffer = this.bufferCache.Dequeue();
    }
    else
    {
        buffer = new byte[ChunkSize];
    }
    this.bufferQueue.Enqueue(buffer);
    this.lastBuffer = buffer;
}

我们发现,如果我们要向bufferQueue中添加新的数据区块的时候,会先判断bufferQueue中有没有数据区块,如果有的话,则从bufferQueue当中取出一个数据区块进队bufferQueue。其实这是一个类似对象池的设计,为了优化内存的调用,避免多次new一片新的内存。而bufferCache中的数据区块,应该就是从bufferQueue当中出队并已经没有用的数据区块了。在TBuffer当中我们是直接释让这部分内存垃圾回收了,而这里,我们自己对它们进行了回收,并且进行再利用。牛逼

public void RemoveFirst()
{
    this.bufferCache.Enqueue(bufferQueue.Dequeue());
}

这段就是对数据区块的回收了,不用当心我们没有对进队的数据区块进行“清空”,因为我们以LastIndex自己控制游标位置,这些旧的数据会被新的数据所覆盖的。

获取首位数据区块跟末尾区块的方法我就不说了,聪明的大家一眼就能看懂。这里顺便提一下,Queue.Peek() 方法只会返回队列的第一位但是并不会让它从队列中移除。Dequeue才会移除。

/// <summary>
/// 从stream流写到CircularBuffer中
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
public async Task<int> WriteAsync(Stream stream)

作者的注释很详细了。从stream流写到CircularBuffer中。我们发现,新的3.0代码在这块运用了Stream。大家可以了解一下。就是文件读写的数据流。

Stream.ReadAsync : 从当前流异步读取字节序列,并将流中的位置提升读取的字节数。

public override int Read(byte[] buffer, int offset, int count)

这段代码,跟TBuffer里面的RecvFrom(byte[] buffer) 方法的作用是一样的,从这个缓冲区中获取数据。不过这里多了两个参数,offset跟cout,调用更加灵活了。

public void Write(byte[] buffer)

这段代码,跟TBuffer里面的SendTo(byte[] buffer) 是一样的,往缓冲区里写入新的数据,带过。

除此之外,这里也提供了有offset跟count参数的写入方法

public override void Write(byte[] buffer, int offset, int count)

不过这里的offset指的是buffer的offset。

注意的是,这些带offset跟count的Read和Write都是重写的方法。

并且,重写了一些方法,让CanReadCanWrite始终返回true,而CanSeek始终返回false

结束语

就是因为程序员的追求,才让代码越来越难看,也越来越优雅。————Norman林

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值