编写该算法解决的是,在tcp报文里面有很多的块,需要合并成一整块进行处理。使用的是递归
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#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;
}