环形缓冲区(Circular Buffer 或 Ring Buffer)是一种数据结构,它在逻辑上形成一个闭环。这种结构非常适用于需要固定大小的缓冲区的情况,如音频处理、网络通信、实时数据传输等。环形缓冲区的主要特点和用途包括:

固定大小:环形缓冲区的大小在创建时确定,并且在其生命周期内保持不变。

高效的数据插入和移除:在环形缓冲区中添加或移除元素(通常是在头部添加,在尾部移除)是非常高效的,因为这些操作不需要移动缓冲区中的其他元素。

循环覆盖:当缓冲区填满时,新添加的元素将覆盖最早添加的元素。这使得环形缓冲区非常适用于处理流式数据,其中只关心最近的数据。

无需动态内存分配:由于环形缓冲区的大小是固定的,因此在初始化后不需要额外的内存分配。

下面是C#中一个泛型环形缓冲区的实现

// LiteRingBuffer 是一个泛型类,用于存储类型为 T 的数据
public class LiteRingBuffer<T> : IEnumerable<T>
{ // _elements 数组用于存储环形缓冲区的元素
private readonly T[] _elements; // _start 和 _end 分别表示缓冲区中第一个和最后一个元素的索引
private int _start;
private int _end; // _count 表示缓冲区中当前元素的数量
private int _count; // _capacity 表示缓冲区的最大容量
private readonly int _capacity; // 索引器,用于访问缓冲区中的元素。它将索引 i 映射到环形缓冲区的正确位置
public T this[int i] => _elements[(_start + i) % _capacity]; // 构造函数,初始化环形缓冲区的大小
public LiteRingBuffer(int count)
{
_elements = new T[count];
_capacity = count;
} // Add 方法用于向缓冲区添加新元素
public void Add(T element)
{
if(_count == _capacity)
throw new ArgumentException(); // 如果缓冲区已满,则抛出异常
_elements[_end] = element; // 将元素添加到_end指向的位置
_end = (_end + 1) % _capacity; // 更新_end索引
_count++; // 增加元素数量
} // FastClear 方法用于快速清空缓冲区
public void FastClear()
{
_start = 0;
_end = 0;
_count = 0;
} // Count 属性返回缓冲区中的元素数量
public int Count => _count; // First 属性返回缓冲区中的第一个元素
public T First => _elements[_start]; // Last 属性返回缓冲区中的最后一个元素
public T Last => _elements[(_start+_count-1)%_capacity]; // IsFull 属性指示缓冲区是否已满
public bool IsFull => _count == _capacity; // RemoveFromStart 方法从缓冲区的开始移除指定数量的元素
public void RemoveFromStart(int count)
{
if(count > _capacity || count > _count)
throw new ArgumentException(); // 如果请求移除的元素数量不合法,则抛出异常
_start = (_start + count) % _capacity; // 更新_start索引
_count -= count; // 减少元素数量
} // GetEnumerator 方法提供了遍历缓冲区的方法
public IEnumerator<T> GetEnumerator()
{
int counter = _start;
while (counter != _end)
{
yield return _elements[counter];
counter = (counter + 1) % _capacity;
}
} // IEnumerable 接口的实现,用于集合的迭代
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}

环形缓冲区 Ring Buffer 的实现的更多相关文章

  1. input子系统事件处理层(evdev)的环形缓冲区【转】

    在事件处理层(evdev.c)中结构体evdev_client定义了一个环形缓冲区(circular buffer),其原理是用数组的方式实现了一个先进先出的循环队列(circular queue), ...

  2. linux网络编程--Circular Buffer(Ring Buffer) 环形缓冲区的设计与实现【转】

    转自:https://blog.csdn.net/yusiguyuan/article/details/18368095 1. 应用场景 网络编程中有这样一种场景:需要应用程序代码一边从TCP/IP协 ...

  3. 一点公益商城开发系统模式Ring Buffer+

    一个队列如果只生产不消费肯定不行的,那么如何及时消费Ring Buffer的数据呢?简单的方案就是当Ring Buffer"写满"的时候一次性将数据"消费"掉. ...

  4. 使用Ring Buffer构建高性能的文件写入程序

    最近常收到SOD框架的朋友报告的SOD的SQL日志功能报错:文件句柄丢失.经过分析得知,这些朋友使用SOD框架开发了访问量比较大的系统,由于忘记关闭SQL日志功能所以出现了很高频率的日志写入操作,从而 ...

  5. dmesg---检查和控制内核的环形缓冲区

    dmesg命令被用于检查和控制内核的环形缓冲区.kernel会将开机信息存储在ring buffer中.您若是开机时来不及查看信息,可利用dmesg来查看.开机信息保存在/var/log/dmesg文 ...

  6. 物联网安全himqtt防火墙数据结构之ringbuffer环形缓冲区

    物联网安全himqtt防火墙数据结构之ringbuffer环形缓冲区 随着5G的普及,物联网安全显得特别重要,himqtt是首款完整源码的高性能MQTT物联网防火墙 - MQTT Applicatio ...

  7. linux device driver —— 环形缓冲区的实现

    还是没有接触到怎么控制硬件,但是在书里看到了一个挺巧妙的环形缓冲区实现. 此环形缓冲区实际为一个大小为bufsize的一维数组,有一个rp的读指针,一个wp的写指针. 在数据满时写进程会等待读进程读取 ...

  8. 环形缓冲区-模仿linux kfifo【转】

    转自:https://blog.csdn.net/vertor11/article/details/53741681 struct kfifo{ uint8_t *buffer; uint32_t i ...

  9. Linux内核跟踪之ring buffer的实现【转】

      转自:http://blog.chinaunix.net/uid-20543183-id-1930845.html ---------------------------------------- ...

  10. linux下C语言实现多线程通信—环形缓冲区,可用于生产者(producer)/消费者(consumer)【转】

    转自:http://blog.chinaunix.net/uid-28458801-id-4262445.html 操作系统:ubuntu10.04 前言:     在嵌入式开发中,只要是带操作系统的 ...

随机推荐

  1. java入门2..0

    java的运行原理 1.在本地磁盘中创建一个文本文件为Demo.java的源文件 2.在源文件中编写java代码如下: public class Demo public static void ,ma ...

  2. 《Pro Git》起步笔记

    @ 目录 什么是版本控制 本地版本控制系统 集中化的版本控制 分布式的版本控制系统 Git简史 Git是什么 安装Git 在Linux上安装 在Windows上安装 初次运行Git前的配置 用户信息 ...

  3. nflsoj 选数1 2 3

    5711 取数-1 状态表示:1维 集合:前 \(i\) 个数里面所有的选法和 属性:所有的选法和的最大值 状态计算:选或不选 选:\(f(i-1)+a_i\) 不选:\(f(i-1)\) #incl ...

  4. MIT 6.828 Lab实验记录 —— lab1 Booting PC

    实验参考信息 MIT 6.828 lab1 讲义地址 MIT 6.828 课程 Schedule MIT 6.828 lab 环境搭建参考 MIT 6.828 lab 工具guide Brennan' ...

  5. 一文解锁vue3中hooks的使用姿势

    vue3 中的 hooks 是什么? 简单来说如果你的函数中用到了诸如 ref,reactive,onMounted 等 vue 提供的 api 的话,那么它就是一个 hooks 函数,如果没用到它就 ...

  6. Mac SpringBoot项目 Gradle 7.3 转 Maven 手把手教学,包学会~

    导读 最近我手上有个使用Gradle构建的项目,国内使用Gradle的人相对较少.而且我也觉得Gradle的依赖管理方式有些复杂,让我感到有些困惑.因此,我想将项目转换为Maven构建方式.Maven ...

  7. Dami 本地过程调用框架(主打解耦),v0.24 发布

    Dami,专为本地多模块之间通讯解耦而设计(尤其是未知模块.隔离模块.领域模块).零依赖,特适合 DDD. 特点 结合 Bus 与 RPC 的概念,可作事件分发,可作接口调用,可作异步响应. 支持事务 ...

  8. 「atcoder - agc054c」Roughly Sorted

    link. 高妙题,我只会到构造下界那一步-- 构造下界比较容易,只需要注意到交换一次最多让序列向合法迫近一步即可.则答案下界为 \(\sum_i \max\{\left(\sum_{j < i ...

  9. 「sdoi2019 - D2T2」移动金币

    对 @command_block 没有 implementation 做法的细化.理论来说可以通过,但因为我实现得较劣无法通过.:( 把金币中的空隙看作石子,就是一个阶梯 Nim 的模型(有总共 \( ...

  10. Solution -「CF 1096E」The Top Scorer

    Description Link. 小明在打比赛,包括小明自己一共有 \(p\) 名选手参赛,每个人的得分是一个非负整数.最后的冠军是得分最高的人,如果得分最高的人有多个,就等概率从这些人中选一个当冠 ...