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

随着5G的普及,物联网安全显得特别重要,himqtt是首款完整源码的高性能MQTT物联网防火墙 - MQTT Application FireWall,C语言编写,采用epoll模式支持IoT数十万的高并发连接,并且兼容ModSecurity部分规则。 代码非常优秀,非常值得收藏和学习,今天笔者就从结合himqtt的源码来进行ringbuffer数据结构分析,主要特点是速度快。

一、 ringBuffer 介绍
ringBuffer 称作环形缓冲,也有叫 circleBuffer 的,Linux内核也大量使用了这种数据结构。就是取内存中一块连续的区域用作环形缓冲区的数据存储区。这块连续的存储会被反复使用,向 ringBuffer 写入数据总是从写指针的位置开始,如写到实际存储区的末尾还没有写完,则将剩余的数据从存储区的头开始写;从该 ringBuffer 读出数据也是从读指针的位置开始,如读到实际存储区的末尾还没有读完,则从存储区的头开始读剩下的数据。
在这里插入图片描述

二、 ringBuffer 优点

1、Ring Buffer 比链表要快,因为它是数组,而且有一个容易预测的访问模式。这很不错,对 CPU 高速缓存友好 (CPU-cache-friendly)-数据可以在硬件层面预加载到高速缓存,因此 CPU 不需要经常回到主内存 RAM 里去寻找 Ring Buffer 的下一条数据。
2、Ring Buffer 是一个数组,你可以预先分配内存,并保持数组元素永远有效。这意味着内存垃圾收集(GC)在这种情况下几乎什么也不用做。此外,也不像链表那样每增加一条数据都要创建对象-当这些数据从链表里删除时,这些对象都要被清理掉。

总之就是内存处理速度特别快,特别适合高并发、大量的请求。
三、ringBuffer 代码实现
首先在github上下载himqtt的源码:https://github.com/qq4108863/himqtt
找到src目录下的ringbuffer.c和ringbuffer.h文件。

1、ringBuffer 的结构体

typedef struct bufent {
    char *data;
    char *ptr;
    size_t left;
    struct bufent *next;
} bufent;

typedef struct ringbuffer {
    bufent *slots;
    bufent *head; // reads from the head
    bufent *tail; // writes to the tail
    char   *buf; 
    int used;
    int num_slots;
    int data_len;
    size_t bytes_written;
} ringbuffer;

2、创建 ringBuffer 函数

void
ringbuffer_init(ringbuffer *rb, int num_slots, int data_len)
{
	rb->num_slots = num_slots ?: DEF_RING_SLOTS;
	rb->data_len = data_len ?: DEF_RING_DATA_LEN;
	rb->slots = malloc(rb->num_slots * sizeof(rb->slots[0]));
	AN(rb->slots);

	rb->head = &rb->slots[0];
	rb->tail = &rb->slots[0];
	int x;
	for (x=0; x < rb->num_slots; x++) {
		rb->slots[x].next = &(rb->slots[(x + 1) % rb->num_slots]);
		rb->slots[x].data = malloc(rb->data_len);
		AN(rb->slots[x].data);
	}
	rb->used = 0;
	rb->bytes_written = 0;
}

3、清空 ringBuffer 函数

void
ringbuffer_cleanup(ringbuffer *rb)
{
	int x;
	for (x=0; x < rb->num_slots; x++) {
		free(rb->slots[x].data);
	}
	free(rb->slots);
}

4、读数据函数

char *
ringbuffer_read_next(ringbuffer *rb, int * length)
{
	assert(rb->used);
	*length = rb->head->left;
	return rb->head->ptr;
}

5、写数据函数

void
ringbuffer_write_append(ringbuffer *rb, int length)
{
	assert(rb->used < rb->num_slots);

	rb->used++;

	rb->tail->ptr = rb->tail->data;
	rb->tail->left = length;
	rb->tail = rb->tail->next;
}

如果仅仅有一个读用户和一个写用户,那么不需要添加互斥保护机制就可以保证数据的正确性。如果有多个读写用户访问环形缓冲区,那么必须添加互斥保护机制来确保多个用户互斥访问环形缓冲区。
Ringbuffer特别适合一个读,一个写的高速场景。5G 时代就是大量的设备会联网,并且持续通信,对himqtt这类物联网防火墙就提出了很高的要求,所以算法和数据结构设计就非常重要。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值