CircleBuffer 是逻辑上呈环形的缓冲区 。 当缓冲区满了的时候可以让新的数据覆盖最旧的数据。
Glusterfs使用CircleBuffer来存储Afr的自修复日志。
CircleBuffer在 libglusterfs/src/circ-buff.c 中定义:
下面介绍下其关键函数 __cb_add_entry_buffer (buffer_t *buffer, void *item)
该函数负责添加一个buffer到环中:
//当环满了时候 if (buffer->used_len == buffer->size_buffer) { //w_index始终指向下一个写的位置 //如果这个位置不是空的,那么需要先释放空间 if (buffer->cb[buffer->w_index]) { ptr = buffer->cb[buffer->w_index]; if (ptr->data) { GF_FREE (ptr->data); ptr->data = NULL; GF_FREE (ptr); } buffer->cb[buffer->w_index] = NULL; ptr = NULL; } } //申请空间 buffer->cb[buffer->w_index] = GF_CALLOC (1, sizeof (circular_buffer_t), gf_common_mt_circular_buffer_t); if (!buffer->cb[buffer->w_index]) return -1; //data指针指向外部数据 buffer->cb[buffer->w_index]->data = item; //记录时间 ret = gettimeofday (&buffer->cb[buffer->w_index]->tv, NULL); if (ret == -1) gf_log_callingfn ("", GF_LOG_WARNING, "getting time of" "the day failed"); //计算下一个写位置,因为是环状的所以需要使用模运算 buffer->w_index++; buffer->w_index %= buffer->size_buffer - 1; //used_buffer size cannot be greater than the total buffer size //如果环未满,则已使用长度+1, 满了就不用加了。 if (buffer->used_len < buffer->size_buffer) buffer->used_len++; return buffer->w_index;
event-history.c封装了Circle-Buf来实现事件的历史记录功能。