物聯網安全himqtt防火牆數據結構之ringbuffer環形緩衝區

 

物聯網安全himqtt防火牆數據結構之ringbuffer環形緩衝區git

 

  隨着5G的普及,物聯網安全顯得特別重要,himqtt是首款完整源碼的高性能MQTT物聯網防火牆 - MQTT Application FireWallC語言編寫,採用epoll模式支持IoT數十萬的高併發鏈接,而且兼容ModSecurity部分規則。 代碼很是優秀,很是值得收藏和學習,今天筆者就從結合himqtt的源碼來進行ringbuffer數據結構分析,主要特色是速度快。github

 

1、 ringBuffer 介紹

  ringBuffer 稱做環形緩衝,也有叫 circleBuffer Linux內核也大量使用了這種數據結構。就是取內存中一塊連續的區域用做環形緩衝區的數據存儲區。這塊連續的存儲會被反覆使用,向 ringBuffer 寫入數據老是從寫指針的位置開始,如寫到實際存儲區的末尾尚未寫完,則將剩餘的數據從存儲區的頭開始寫;從該 ringBuffer 讀出數據也是從讀指針的位置開始,如讀到實際存儲區的末尾尚未讀完,則從存儲區的頭開始讀剩下的數據。算法

 

 

ringBuffer 優勢

 

1Ring Buffer 比鏈表要快,由於它是數組,並且有一個容易預測的訪問模式。這很不錯,對 CPU 高速緩存友好 (CPU-cache-friendly)-數據能夠在硬件層面預加載到高速緩存,所以 CPU 不須要常常回到主內存 RAM 裏去尋找 Ring Buffer 的下一條數據。數組

2Ring Buffer 是一個數組,你能夠預先分配內存,並保持數組元素永遠有效。這意味着內存垃圾收集(GC)在這種狀況下幾乎什麼也不用作。此外,也不像鏈表那樣每增長一條數據都要建立對象-當這些數據從鏈表裏刪除時,這些對象都要被清理掉。緩存

 總之就是內存處理速度特別快,特別適合高併發、大量的請求安全

3、ringBuffer 代碼實現

首先在github上下載himqtt的源碼:https://github.com/qq4108863/himqtt數據結構

找到src目錄下的ringbuffer.cringbuffer.h文件。併發

 

一、ringBuffer 的結構體app

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;

 

 

二、建立 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;

}

   

三、清空 ringBuffer 函數

void

ringbuffer_cleanup(ringbuffer *rb)

{

int x;

for (x=0; x < rb->num_slots; x++) {

free(rb->slots[x].data);

}

free(rb->slots);

}

 

四、讀數據函數

char *

ringbuffer_read_next(ringbuffer *rb, int * length)

{

assert(rb->used);

*length = rb->head->left;

return rb->head->ptr;

}

 

五、寫數據函數

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這類物聯網防火牆就提出了很高的要求,因此算法和數據結構設計就很是重要。

相關文章
相關標籤/搜索