环形缓冲区(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. .NET Core多线 (5) 常见性能问题

    合集:.NET Core多线程温故知新 .NET Core多线程(1)Thread与Task .NET Core多线程(2)异步 - 上 .NET Core多线程(3)异步 - 下 .NET Core ...

  2. c++算法之离散化

    什么是离散化? 离散化,故离散数学,其中的"离散"就是不连续的意思.离散化可以保持原数值之间相对大小关系不变的情况下将其映射成正整数. 也就是给可能用到的数值按大小关系分配一个编号 ...

  3. 当小白遇到FullGC

    起初没有人在意这场GC,直到它影响到了每一天! 前言 本文记录了一次排查FullGC导致的TP99过高过程,介绍了一些排查时思路,线索以及工具的使用,希望能够帮助一些新手在排查问题没有很好的思路时,提 ...

  4. 【译】在 Visual Studio 中处理图像变得更容易了

    任何 Web.桌面或移动开发人员都经常使用图像.你可以从 C#.HTML.XAML.CSS.C++.TypeScript 甚至代码注释中引用它们.有些图像是本地的,有些存在于线上或网络共享中,而其他图 ...

  5. 吃透单调栈(2)——解两道Hard题:接雨水、柱状图中最大的矩形问题

    怎么想到要用单调栈的? 这类题目的数据通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置(寻找边界),此时我们就要想到可以用单调栈了. 42. 接雨水 这道题就是要求解每一 ...

  6. SpringBoot整合ueditor编辑器

    1.到ueditor编辑器官网下载jsp版(目前官网地址改为了GitHub)https://ueditor.baidu.com/website/download.html2.下载解压后复制到当前项目3 ...

  7. jenkins部署及gitlab联调

    jenkins部署及gitlab联调 目录 jenkins部署及gitlab联调 一.jenkins安装 1.环境优化 2.安装jdk java 环境 3.下载jenkins 4.启动Jenkins服 ...

  8. [Maven] maven插件系列之maven-shade-plugin

    [Maven] maven插件系列之maven-shade-plugin 1 插件简述/Plugin Overview 1.1 定义与目的/Definition & Goals Officia ...

  9. 文心一言 VS 讯飞星火 VS chatgpt (91)-- 算法导论8.3 4题

    四.用go语言,说明如何在 O(n) 时间内,对 0 到 $n^3-1$ 区间内的n个整数进行排序. 文心一言: 在 O(n) 时间内对 0 到 n^3-1 区间内的 n 个整数进行排序,可以使用基数 ...

  10. 深入解析HTTP请求:了解请求特征与报文格式的关键秘密

    引言 在上一章节中,我们详细探讨了超文本传输协议(HTTP)的基本概念,并且延伸讨论了HTTP请求响应的基本流程.在这个过程中,浏览器首先通过DNS解析来确定要访问的服务器的IP地址,然后与服务器建立 ...