合并算法

编写该算法解决的是,在tcp报文里面有很多的块,需要合并成一整块进行处理。使用的是递归

 

#include 
#include 
#include 
#include 
#include "list.h"

typedef unsigned int uint32;
#define HERE 	printf("HERE: %s %d\n", __FUNCTION__,__LINE__)

#define debug 
#define debug2 printf

#ifndef min
#define	min(a, b)	((a) < (b) ? (a) : (b))
#define	max(a,b) (((a)>(b))?(a):(b))
#endif

struct buff_fragment {
	struct list_head list;
	unsigned int start;
	unsigned int end;//[start, end)
};


int merging(struct buff_fragment *fa, struct buff_fragment *fb)
{
	int fa_len = fa->end - fa->start;
	int fb_len = fb->end - fb->start;
	int dist = fa_len + fb_len;
	int diff;
	int fb_is_rear = 0;

	if (fb->end >= fa->end) {
		diff = fb->end - fa->start;
		fb_is_rear = 1;
	} else {
		diff = fa->end - fb->start;
	}

	if (diff <= dist) {
		fa->start = min(fa->start, fb->start);
		fa->end = max(fa->end, fb->end);
		debug2("merging start=%d, end=%d\n", fa->start, fa->end);
		return 0;
	}

	return fb_is_rear?1:2;		
}

int dpi_merge_fragment(struct list_head *head, uint32 start, uint32 end)
{
	struct buff_fragment *fa, *temp;
	struct buff_fragment *prev = NULL;;
	int rc;

	struct buff_fragment *fb = malloc(sizeof(struct buff_fragment));
	fb->start = start;
	fb->end = end;

	debug2("dpi_merge_fragment: start = %u, end = %u\n", start, end);
	
	if (!fb)
		return -1;
	
	if (list_empty(head)) {
		list_add(&fb->list, head);
		return 0;
	}

	list_for_each_entry(fa, head, list) {
		if (fa->end < fb->start) {
			prev = fa;
			continue;
		}
		
		rc = merging(fa, fb);
		if (0 == rc)  {
			list_del(&fa->list);
			start = fa->start;
			end = fa->end;
			free(fa);
			free(fb);
			return dpi_merge_fragment(head, start, end);
		}
		break;
	}

	if (!prev) {
		HERE;
		list_add(&fb->list, head);
		return 0;
	} 

	if (rc == 1) {
		HERE;
		list_add(&fb->list, &fa->list);
	} else {
		HERE;
		list_add(&fb->list, &prev->list);
	}
	return 0;
}

void dpi_show_fragment(struct list_head *head)
{
	struct buff_fragment *fa;
	int id = 0;
	
	debug2("dpi_show_fragment\n");
	list_for_each_entry(fa, head, list) {
		debug2("fa[%d]->start=%d, end=%d\n", id++, fa->start, fa->end);
	}
}

LIST_HEAD(fhead);

struct buff_fragment data[]={
	{.start = 1,.end = 6},
	{.start = 5,.end = 10},
	{.start = 14,.end = 19},	
	{.start = 13,.end = 14},	
	{.start = 3,.end = 13},
	{.start = 100,.end = 200},
	{.start = 50,.end = 70},
};

int main(void)
{
	int i =0;
	
	for (;i< (sizeof(data) / sizeof(struct buff_fragment)); i++) {
		dpi_merge_fragment(&fhead, data[i].start, data[i].end);	
	}
	
	dpi_show_fragment(&fhead);
        
    return 0;
}


 

你可能感兴趣的:(算法)