滑动窗口是日志模块重要的数据结构,用于日志发送接收以及日志索引查询,和组内同学讨论了的多线程安全的滑动窗口设计,有三种实现方案,写此文档记录下。
1.接口描述
滑动窗口内部使用数组,每个数组项的是一个结构体:
Structentry
{
Struct ValueNode *head;
Struct ValueNode *tail;
Int64_t cnt;
Int64_tstat;
}
由于在对同一项多次写入不同值的情况下,写入的多个值会以链表组织,head指向链表头,tail指向链表尾,cnt表明读取当前entry的引用计数,包括链表中所有节点。
StructValueNode的定义如下:
StructValueNode
{
Void *value
Struct ValueNode *next;
}
滑动窗口需要提供以下接口:
1. Init(int64_t size)
初始化滑动窗口,size 用于指明滑动窗口的大小。
2. set(int64_t id, const void*val)
set接口用于向滑动窗口中写入数据,id用于指明所写入数据的序号,val指向写入 的数据指针。对同一个id插入不同的值,会发生覆盖。
3. get(int64_t id, void* &val)
get接口用于从滑动窗口中读出数据,id用于指明所读数据的序号,val指向所读到 的数据的指针。
4. revert (int64_t id)
读取某一项结束时候,需要调用revert接口。
5. move_foward ()
move_foward用于将滑动窗口向前移动,对于移除滑动窗口的项,需要调用其revert 接口,将entry重置,方便后续复用此接口。
2方案一:读写锁保护start_id
方案一是并发度较低但思路比较简单的实现方案,此方案中,滑动窗口需要维护的成员变量:
1. size:此变量用于指明滑动窗口的大小;
2. sta