说说循环缓存区的数据查找

说说循环缓存区的数据查找

循环队列的实现大多情况下是为了对数据进行拼接于数据查找提取,本博客内容为如何通过循环缓冲区支持多种数据的查找提取
抽象数据结构定义如下:
1、根据数据特征进行提取抽象,同一类数据一般具有标准的头,故根据数据的特征提取出了如下数据结构;

typedef struct {
	unsigned int data_type;
	char data_head[40];
	unsigned int data_head_len;
} DataInfo_t;

结合博客Ring Buffer的常规用法与高级用法(一)循环缓存区的数据结构,定义除如下的数据结构
循环队列的数据结构定义如下:

typedef struct {
	unsigned int in;
	unsigned int out;
	unsigned int size;
	char *buf;
	unsigned int data_head_max_len;
	DataInfo_t *support_data_list;
	unsigned int support_data_list_num;
} RingFifo_t;

接下来直接上一段的demo伪代码:

typedef enum {
	TEST_ONE = 1,
	TEST_TWO,
} TestDate_t;

#define TEST_ONE_HEAD "one"
#define TEST_TWO_HEAD "two"

DataInfo_t test_support_list[] = {
	{TEST_ONE,
	TEST_ONE_HEAD,	(sizeof(TEST_ONE_HEAD)-1),
	},
	{TEST_TWO,
	TEST_TWO_HEAD,	(sizeof(TEST_TWO_HEAD)-1),
	},
};

以下是使用选择排序法实现的升降序排列函数,当然大家也可以使用别的排序方法实现升降序排列的功能

typedef enum {
	DESECENDING_ORDER= 1, //降序
	ASCENDING_ORDER, //升序
} OrderType_t;

void select_sort(DataInfo_t *a, int l, OrderType_t order_type)//a为数组地址,l为数组长度。
{
    int i, j;
    DataInfo_t v;
    //排序主体
    for(i = 0; i < l - 1; i ++)
        for(j = i+1; j < l; j ++)
        {
        	if(DESECENDING_ORDER == order_type) { 
        	    //升序
	            if(a[i] > a[j])//如前面的比后面的大,则交换。
	            {
	                v = a[i];
	                a[i] = a[j];
	                a[j] = v;
	            }
	         } else {
	            //降序
	   	        if(a[i] < a[j])//如前面的比后面的小,则交换。
	            {
	                v = a[i];
	                a[i] = a[j];
	                a[j] = v;
	            }      
	        }
        }
    }
}

关于循环队列的使用请参照本人博客:Ring Buffer的常规用法与高级用法(一)的详细讲解

int FindDateIinit(RingFifo_t *ringfifo_p, int ring_buf_size, 
DataInfo_t *support_list, int support_list_num)
{
	ringfifo_p->in = 0;
	ringfifo_p->out = 0;
	ringfifo_p->size = ring_buf_size;
	ringfifo_p->buf = (char *)molloc(ring_buf_size); //分配循环缓存区
	memset(ringfifo_p->buf, 0, ring_buf_size)
	//分配支持查找数据列表的存储空间大小
	ringfifo_p->support_data_list = (DataInfo_t *)molloc(support_list_num * sizeof(DataInfo_t));
	ringfifo_p->support_data_list_num = support_list_num;
	memcpy(ringfifo_p->support_data_list, support_list, support_list_num * sizeof(DataInfo_t));
	//将支持查找的数据列表根据数据头的长度进行降序排队,避免先查找短数据头的数据;
	select_sort(ringfifo_p->support_data_list, support_list_num , DESECENDING_ORDER)/
	ringfifo_p->data_head_max_len = ringfifo_p->support_data_list[0].data_head_len);
}

以下函数为实现支持多种数据查找的循环缓存区的核心,基本的实现原理为遍历循环缓存区内的数据,依次与支持查找列表中的数据头进行匹配,匹配上则认为查找到了对应的数据(注意:为什么要降支持列表的按照数头的长度降序排列,是因为如果较长的数据头内包含,较短是数据头内容,时可能出现查找失败错误);当然具体的数据包提取还应该按照对应的数据格式进行完整性校验,完整性校验通过在进行数据提取。

int GetdataPacket(RingFifo_t *ringfifo_p, char *data_buf, int data_buf_size, int *data_real_len)
{
	int len = 0;
	int i = 0, j = 0, k = 0; 
	
	len = GetRingBufferLen(ringfifo_p);
	if(len < ringfifo_p->data_head_max_len) {
		return -1;
	} 
	
	for(j = 0; j < len ; ==j) {
		for(i = 0; i < ringfifo_p->support_data_list_num; ++i) {
			for(k = 0; k < ringfifo_p->support_data_list[i].data_head_len; ++k) {
				if(ringfifo_p->buf[(out + j) % ringfifo_p->size] != 
				ringfifo_p->support_data_list[i].data_head[k]) 
				{
					break;
				}
			}
			if(k == ringfifo_p->support_data_list[i].data_head_len) {
				//查找道数据包头;
				switch(ringfifo_p->support_data_list[i].data_type) {
					case TEST_ONE :
						//具体数据包的提取按照对应的数据格式,以及循环缓冲区的数据读取具体实现
						return GetdataPacketTestOne();
					case TEST_TWO :
						//具体数据包的提取按照对应的数据格式,以及循环缓冲区的数据读取具体实现
						return GetdataPacketTestTwo();
					default:
						return -2;
				}
			}
		}
	}
	return -1;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值