Xplace_for_ICCAD/thirdparty/flute/dl.cpp
2022-10-20 22:46:17 +08:00

165 lines
3.4 KiB
C++

#include "dl.h"
#include <assert.h>
#include <stdio.h>
namespace Flute {
dl_t dl_alloc()
{
dl_t dl = (dl_t)malloc(sizeof(dl_s));
if (!dl) {
printf("Out of memory!!\n");
} else {
dl->first = dl->last = 0; dl->count = 0;
}
return dl;
}
void dl_delete(dl_t dl, dl_el *el)
{
if (dl->first == el) {
dl->first = el->next;
}
if (dl->last == el) {
dl->last = el->prev;
}
if (el->next) {
el->next->prev = el->prev;
}
if (el->prev) {
el->prev->next = el->next;
}
free(el); dl->count--;
}
void dl_clear(dl_t dl)
{
dl_el *el, *next;
if (dl->count > 0) {
for (el=dl->first; el; el=next) {
next = el->next;
free(el);
}
}
dl->first = dl->last = 0;
dl->count = 0;
}
void dl_concat(dl_t first_list, dl_t second_list)
{
if (first_list->count <= 0) {
*first_list = *second_list;
} else if (second_list->count > 0) {
first_list->last->next = second_list->first;
second_list->first->prev = first_list->last;
first_list->last = second_list->last;
first_list->count += second_list->count;
}
free(second_list);
}
static void dl_insertion_sort(dl_t dl, size_t el_size,
int(*compar)(void *, void *))
{
char *buf;
void *curr_d, *srch_d;
dl_el *curr, *srch;
if (dl_length(dl) <= 1) {
return;
}
buf = (char*)malloc(el_size);
for (curr=dl->first; curr!=dl->last; curr=curr->next) {
curr_d = (void*)(((dl_el*)curr)+1);
for (srch=dl->last; srch!=curr; srch=srch->prev) {
srch_d = (void*)(((dl_el*)srch)+1);
if (compar(curr_d, srch_d) > 0) {
memcpy((void*)buf, curr_d, el_size);
memcpy(curr_d, srch_d, el_size);
memcpy(srch_d, (void*)buf, el_size);
}
}
}
free(buf);
}
void dl_sort(dl_t dl, size_t el_size, int(*compar)(void *, void *))
{
dl_el *el, *first_head, *second_head;
dl_s first_list, second_list;
void *first_item, *second_item;
int i, len;
if (dl_length(dl) <= 25) {
dl_insertion_sort(dl, el_size, compar);
return;
}
len = dl_length(dl)/2;
for (i=0, el=dl->first; i<len; i++) {
el = el->next;
}
first_list.first = dl->first;
first_list.last = el->prev;
first_list.count = len;
first_list.last->next = 0;
second_list.first = el;
second_list.last = dl->last;
second_list.count = dl_length(dl)-len;
second_list.first->prev = 0;
dl_sort(&first_list, el_size, compar);
dl_sort(&second_list, el_size, compar);
/* in-place merging */
first_head = first_list.first;
second_head = second_list.first;
first_item = (void*)(((dl_el*)first_head)+1);
second_item = (void*)(((dl_el*)second_head)+1);
if (compar(first_item, second_item) <= 0) {
dl->first = el = first_head;
first_head = first_head->next;
} else {
dl->first = el = second_head;
second_head = second_head->next;
}
while (1) {
first_item = (void*)(((dl_el*)first_head)+1);
second_item = (void*)(((dl_el*)second_head)+1);
if (compar(first_item, second_item) <= 0) {
el->next = first_head;
first_head->prev = el;
el = first_head;
first_head = first_head->next;
if (!first_head) {
el->next = second_head;
second_head->prev = el;
dl->last = second_list.last;
break;
}
} else {
el->next = second_head;
second_head->prev = el;
el = second_head;
second_head = second_head->next;
if (!second_head) {
el->next = first_head;
first_head->prev = el;
dl->last = first_list.last;
break;
}
}
}
}
} // namespace Flute