ring buffer

#include <stdio.h>
#include <string.h>
#include <malloc.h>

//因此使用ring buffer关键因素是数据缓冲区、数据缓冲区长度、head索引、tail索引
typedef struct {
    char *buff;
    int length;
    int head;
    int tail;
}ring_buffer_t;

//创建、初始化ring buffer
ring_buffer_t *ring_buffer_create_init(int ring_buffer_length)
{
    ring_buffer_t *tmp_ring_buffer = (ring_buffer_t *)malloc(sizeof(ring_buffer_t));
    tmp_ring_buffer->buff = (char *)malloc(ring_buffer_length);
    memset(tmp_ring_buffer->buff, 0, ring_buffer_length);
    tmp_ring_buffer->head = 0;
    tmp_ring_buffer->tail = 0;
    tmp_ring_buffer->length = ring_buffer_length;
    return tmp_ring_buffer;
}

//判断当前有无数据可读,用于读操作前的判断
//如果当前要写入的位置和可读位置相同,则判定无数据可读
bool ring_buffer_empty(ring_buffer_t *ring_buffer)
{
    return (ring_buffer->head == ring_buffer->tail);
}

//判断当前ring buffer是否满了,用于写操作前的判断
//如果要写的位置紧挨在可读位置后面,则判定为满
bool ring_buffer_full(ring_buffer_t *ring_buffer)
{
    int tmp_len = ring_buffer->head - ring_buffer->tail;
    if((-1 == tmp_len) || (ring_buffer->length -1 == tmp_len)){
        return true;
    }else{
        return false;
    }
}

//写一个字节到ring buffer,如果ring buffer满了head、tail递增,覆盖旧数据
void write_ring_buffer_byte(ring_buffer_t *ring_buffer, char data)
{
    //此处控制如果有写入操作后,当写快于读时,head和tail也不会相等,即不会判断无数据可读
    if(ring_buffer_full(ring_buffer)){
        ring_buffer->tail++;
        if(ring_buffer->tail == ring_buffer->length){
            ring_buffer->tail = 0;
        }
    }
    ring_buffer->buff[ring_buffer->head] = data;
    ring_buffer->head++;
    if(ring_buffer->head == ring_buffer->length){
	    ring_buffer->head = 0;
    }
}

//读一个字节
int read_ring_buffer_byte(ring_buffer_t *ring_buffer, char *data)
{
    if(ring_buffer_empty(ring_buffer)){
        return -1;
    }
    *data = ring_buffer->buff[ring_buffer->tail];
    ring_buffer->tail++;
    if(ring_buffer->tail == ring_buffer->length){
	    ring_buffer->tail = 0;
    }
    return 0;
}

//写buffer时即一个个字节写
void write_ring_buffer_data(ring_buffer_t *ring_buffer, char *data, int size)
{
    for(int i = 0;i < size;i++){
        write_ring_buffer_byte(ring_buffer, *(data + i));
	//printf("[%s]data:[%s]\n", __func__, ring_buffer->buff);
    }
}

//读buffer时即一个个字节读
int read_ring_buffer_data(ring_buffer_t *ring_buffer, char *data, int size)
{
    for(int i = 0; i < size; i++){
        if(-1 == read_ring_buffer_byte(ring_buffer, data + i)){
	    return -1;
	}
	//printf("[%s]read data:[%s]\n", __func__, data);
    }
    return 0;
}

//测试程序
void main(void)
{
    int i;
    char tmp_write[40] = "abcdefghijklmnopquio";
    char tmp_read[40] = {0};
    ring_buffer_t *ring_buffer = ring_buffer_create_init(20);  //10、50

#if 0
    for(i = 0;i < strlen(tmp_write); i++){
        write_ring_buffer_byte(ring_buffer, *(tmp_write + i));
	printf("write_buff:[%s]\n", ring_buffer->buff);
    }
    for(i = 0;i < 20; i++){
        read_ring_buffer_byte(ring_buffer, tmp_read+i);
	printf("read_buff:[%s]\n", tmp_read);
    }
#endif
    write_ring_buffer_data(ring_buffer, tmp_write, strlen(tmp_write));
    printf("write data:[%s]\n", ring_buffer->buff);
    read_ring_buffer_data(ring_buffer, tmp_read, sizeof(tmp_read));
    printf("read_buff:[%s]\n", tmp_read);
}

环形存储(ring buffer):一个头尾相连的buffer,根据head索引确定写入位置,根据tail索引确定读出位置,读写时head、tail索引各自递增,不够空间且有新数据要写入时,覆盖旧数据。
下图演示了创建/初始化长度12、写4bytes数据、读2bytes数据时,ring buffer的head、tail索引变化情况。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值