前言:

A circular buffer, cyclic buffer or ring buffer is a data structure that uses a single, fixed-size buffer as if it were connected end-to-end. This structure lends itself easily to buffering data streams.

Uses

The useful property of a circular buffer is that it does not need to have its elements shuffled around [重新排列]when one is consumed. (If a non-circular buffer were used then it would be necessary to shift all elements when one is consumed.) In other words, the circular buffer is well-suited[非常合适] as a FIFO [先进先出]buffer while a standard, non-circular buffer is well suited as a LIFO [后进后出]buffer.

Circular buffering makes a good implementation strategy for a queue that has fixed maximum size. Should a maximum size be adopted [被采用]for a queue, then a circular buffer is a completely ideal implementation; all queue operations are constant time. However, expanding a circular buffer requires shifting memory, which is comparatively[相对来说] costly. For arbitrarily expanding queues[可随意扩展的], a linked list approach[链表] may be preferred instead.

[本文作者franklin注解]环形buffer 应用于固定的块场合,一旦固定,这块内存就是专用,所以,不具备扩展性.

In some situations, overwriting [可覆盖性]circular buffer can be used, e.g. in multimedia. If the buffer is used as the bounded [有界性,有限制] buffer in the producer-consumer problem then it is probably desired for the producer (e.g., an audio generator) to overwrite old data if the consumer (e.g., the sound card) is unable to momentarily keep up. Also, the LZ77 family of lossless data compression algorithms operates on the assumption that strings seen more recently in a data stream are more likely to occur soon in the stream. Implementations store the most recent data in a circular buffer.

How it works

A circular buffer first starts empty and of some predefined length. For example, this is a 7-element buffer:

Assume that a 1 is written into the middle of the buffer (exact starting location does not matter in a circular buffer):

Then assume that two more elements are added — 2 & 3 — which get appended after the 1:

If two elements are then removed from the buffer, the oldest values inside the buffer are removed. The two elements removed, in this case, are 1 & 2, leaving the buffer with just a 3:

If the buffer has 7 elements then it is completely full:

A consequence of the circular buffer is that when it is full and a subsequent write is performed, then it starts overwriting the oldest data. In this case, two more elements — A & B — are added and they overwrite the 3 & 4:

[本文作者franklin注解][当环形buffer满的时候,后续写入数据将覆盖前面数据]

Alternatively[或者], the routines that manage the buffer could prevent overwriting the data and return an error or raise[根本就是设计成不能写入] an exception. Whether or not data is overwritten is up to the semantics of the buffer routines or the application using the circular buffer.

Finally, if two elements are now removed then what would be returned is not 3 & 4 but 5 & 6 because A & B overwrote the 3 & the 4 yielding the buffer with:

Circular buffer mechanics

What is not shown in the example above is the mechanics of how the circular buffer is managed.

Start/end pointers (head/tail)[edit]

Generally, a circular buffer requires four pointers:

  • one to the actual buffer in memory
  • one to the buffer end in memory (or alternately[代替]: the size of the buffer)
  • one to point to the start of valid data (or alternately: amount of data written to the buffer)
  • one to point to the end of valid data (or alternately: amount of data read from the buffer)

Alternatively[或者], a fixed-length buffer with two integers to keep track of indices can be used in languages that do not have pointers.

[没有指针也可以的]

Taking a couple of examples from above. (While there are numerous[庞大的] ways to label the pointers and exact semantics[精确到语意]can vary, this is one way to do it.)

This image shows a partially[部分] full buffer:

This image shows a full buffer with two elements having been overwritten:

What to note about the second one is that after each element is overwritten then the start pointer is incremented as well.

Difficulties

Full / Empty Buffer Distinction

A small disadvantage of relying on pointers or relative indices of the start and end of data is, that in the case the buffer is entirely full, both pointers point to the same element:

This is exactly the same situation as when the buffer is empty:

[最常见的问题是,buffer的满和空的判别]

To solve this confusion there are a number of solutions:

  • Always keep one slot open.
  • Use a fill count to distinguish the two cases.
  • Use an extra mirroring bit to distinguish the two cases.
  • Use read and write counts to get the fill count from.
  • Use absolute indices.
  • Record last operation.

Always Keep One Slot Open [最简单有效的解决办法就是保持最后一个单元不写]

This design always keeps one slot unallocated. A full buffer has at most  slots. If both pointers refer to the same slot, the buffer is empty. If the end (write) pointer refers to the slot preceding the one referred to by the start (read) pointer, the buffer is full.

The advantage is:

  • The solution is simple and robust.

The disadvantages are:

  • One slot is lost, so it is a bad compromise when the buffer size is small or the slot is big or is implemented in hardware.
  • The full test requires a modulo operation

ref:

http://en.wikipedia.org/wiki/Circular_buffer

http://lmax-exchange.github.io/disruptor/

http://www.cnblogs.com/shanyou/archive/2013/02/04/2891300.html

Circular buffer相关推荐

  1. Boost:circular buffer的测试程序

    Boost:circular buffer的测试程序 实现功能 C++实现代码 实现功能 circular buffer的测试程序 C++实现代码 #include <boost/circula ...

  2. Ring Buffer (circular Buffer)环形缓冲区简介

    https://blog.csdn.net/langeldep/article/details/8888582 关于环形缓冲区的知识,请看这里 http://en.wikipedia.org/wiki ...

  3. Creating a Circular Buffer in C and C++

    https://embeddedartistry.com/blog/2017/4/6/circular-buffers-in-cc 读但没有pop出数据,修改tail指针的函数 void print_ ...

  4. SQL Server 环形缓冲区(Ring Buffer) -- 介绍

    SQL Server 环形缓冲区(Ring Buffer) -- 介绍 以下关于Ring Buffer的介绍转载自: http://zh.wikipedia.org/wiki/%E7%92%B0%E5 ...

  5. 圆形缓冲区(循环buffer)实现

    用法 圆形缓冲区的一个有用特性是:当一个数据元素被用掉后,其余数据元素不需要移动其存储位置.相反,一个非圆形缓冲区(例如一个普通的队列)在用掉一个数据元素后,其余数据元素需要向前搬移.换句话说,圆形缓 ...

  6. Muduo 设计与实现之一:Buffer 类的设计

    [开源访谈]Muduo 作者陈硕访谈实录 http://www.oschina.net/question/28_61182 开源访谈是开源中国推出的一系列针对国内优秀开源软件作者的访谈,以文字的方式记 ...

  7. 优秀的内存规划方法——环形缓冲区(ring buffer)

    目录 什么是环形缓冲区 使用环形buffer的好处 环形buffer的使用场景 进程间通信 网络IO 区分缓冲区是满或者是空 计数 保持一个存储单元为空 镜像指示位 buffer满了之后的操作 实时流 ...

  8. 网卡中的Ring buffer -- 解决 rx_resource_errors 丢包

    1.软硬件环境 硬件: 飞腾E2000Q 平台 软件: linux 4.19.246 2.问题现象 网卡在高速收包的过程中,出现 rx error , 细查是 rx_resource_errors  ...

  9. 操作系统常用词典(二)

    操作系统常用词典(二) USB(Universal Serial Bus):是连接计算机系统与外部设备的一种串口总线标准,也是一种输入输出接口的技术规范,被广泛地应用于个人电脑和移动设备等信息通讯产品 ...

最新文章

  1. lightgbm过去版本安装包_云顶手游10.13安装包,6月24日
  2. 不会这些搜索技巧,真别说你懂 GitHub!
  3. MVC系列框架之Struts存在的意义是什么?
  4. 由浅入深:自己动手开发模板引擎——置换型模板引擎(三)
  5. 原创 | 我被面试官给虐懵了,竟然是因为我不懂Spring中的@Configuration
  6. eye care staff
  7. IBatis.Net学习笔记(四)--再谈查询
  8. python创建项目包
  9. 用c语言实现单链表的初始化,建表,查找,求长度,插入,删除等操作,【YTU+2430+C语言习题+链表建立+插入+删除+输(5)...
  10. vivo C/C++工程师 HR视频面试问题总结20180807
  11. phpSysInfo监测服务器
  12. linux c 语言 errno 我个头,Linux错误代码:errno.h与返回值 -EINVAL
  13. 在数组中寻找出现次数超过数组长度一半的数
  14. OpenCV处理椒盐噪声以及提高对比度
  15. 机器学习 流式特征_Web服务与实时机器学习端点的流式传输
  16. python字符串输入拼接_20200930 024.字符串_转义字符_字符串拼接_字符串复制_input()获得键盘输入...
  17. java xheditor,xhEditor不能支持本map片上传,请问
  18. Calendar获取当天0点的时间戳
  19. 数论:快速傅里叶变换FFT题集
  20. FFmpeg —— 15.示例程序(九):音频编码器(PCM编码为MP3)

热门文章

  1. 阿里云ECS服务器部署HADOOP集群(三):ZooKeeper 完全分布式集群搭建
  2. java 手写 jvm高性能缓存
  3. C#函数(构造函数)的重载
  4. HTML网站右键禁用F12代码 屏蔽审查元素 防止修改页面代码
  5. C#LeetCode刷题之#28-实现strStr()(Implement strStr())
  6. python之质数判断
  7. erlang有前途吗_带有示例的Erlang概述
  8. c语言讲输入退回缓冲区_开始之前的结束-如何不退回输入错误的用户电子邮件...
  9. springMVC发送邮件
  10. android项目实战博学谷源码_阿里爆款SpringBoot项目实战PDF+源码+视频分享