git-svn-id: https://websvn.glenux.net/svn/Upoc/alobe/trunk@1348 eaee96b3-f302-0410-b096-c6cfd47f7835
359 lines
7.8 KiB
C
359 lines
7.8 KiB
C
/* vim: set sw=4 ts=4 si et: */
|
|
|
|
#include "nodeset.h"
|
|
|
|
#define DEBUG_INSERT 0
|
|
#define DEBUG_MERGE 1
|
|
|
|
#define DEBUG (DEBUG_INSERT | DEBUG_MERGE)
|
|
|
|
/**
|
|
*
|
|
* LIST OPERATIONS
|
|
*
|
|
*/
|
|
|
|
NodeSetList_t nodesetlist_create(){
|
|
return NULL;
|
|
}
|
|
|
|
void nodesetlist_destroy(NodeSetList_t * list){
|
|
/* FIXME : delete all elements of the list with ptr */
|
|
NodeSetItem_t * ptr = *list;
|
|
if (ptr != NULL) {
|
|
if (ptr->next != NULL){
|
|
nodesetlist_destroy(&(ptr->next));
|
|
ptr->next = NULL;
|
|
} else {
|
|
// on est le dernier, on se détruit
|
|
nodesetitem_destroy(ptr); // DESTROY OK
|
|
}
|
|
}
|
|
}
|
|
|
|
bool nodesetlist_contains_node(NodeSetList_t list, nodeindex_t node_idx){
|
|
NodeSetItem_t * curptr = list;
|
|
bool answer = false;
|
|
while (curptr != NULL){
|
|
if (nodesetitem_contains_node(curptr, node_idx)) {
|
|
answer = true;
|
|
break;
|
|
}
|
|
curptr = curptr->next;
|
|
}
|
|
return answer;
|
|
}
|
|
|
|
NodeSetList_t nodesetlist_insert_node(NodeSetList_t list, nodeindex_t node_idx)
|
|
{
|
|
NodeSetList_t head = list;
|
|
/* on crée un élément pour le noeud */
|
|
NodeSetItem_t * item = nodesetitem_create_from_node(node_idx);
|
|
/*
|
|
* char * str = nodesetitem_tostr(item);
|
|
* printf("Created nodesetitem %s\n",str);
|
|
* free(str);
|
|
*/
|
|
head = nodesetlist_insert_item(head, item);
|
|
nodesetitem_destroy(item);
|
|
return head;
|
|
}
|
|
|
|
|
|
NodeSetList_t nodesetlist_insert_item(NodeSetList_t root,
|
|
NodeSetItem_t * item)
|
|
{
|
|
bool action_done = false;
|
|
NodeSetList_t head = root;
|
|
// on insere de façon triée...
|
|
NodeSetItem_t * prevptr = NULL;
|
|
NodeSetItem_t * curptr = root;
|
|
char * curstr = NULL;
|
|
char * itemstr = nodesetitem_tostr(item);
|
|
|
|
while(curptr != NULL){
|
|
|
|
curstr = nodesetitem_tostr(curptr);
|
|
|
|
if (nodesetitem_is_overlap(curptr, item)){
|
|
pDEBUG("OVERLAP %s vs %s\n", curstr, itemstr);
|
|
/* on fusionne les deux... cf SNAP*/
|
|
NodeSetItem_t * newptr =
|
|
nodesetitem_create_from_bounds(curptr, item);
|
|
|
|
curptr->minimum = newptr->minimum;
|
|
curptr->maximum = newptr->maximum;
|
|
|
|
/*
|
|
* char * str = nodesetitem_tostr(curptr);
|
|
* printf("=> %s\n",str);
|
|
* free(str);
|
|
*/
|
|
|
|
nodesetitem_destroy(newptr);
|
|
|
|
action_done = true;
|
|
break;
|
|
}
|
|
else if (nodesetitem_is_snap(curptr, item))
|
|
{
|
|
pDEBUG("SNAP %s vs %s\n", curstr, itemstr);
|
|
/* on fusionne les deux... cf OVERLAP*/
|
|
NodeSetItem_t * newptr =
|
|
nodesetitem_create_from_bounds(curptr, item);
|
|
|
|
curptr->minimum = newptr->minimum;
|
|
curptr->maximum = newptr->maximum;
|
|
|
|
/*
|
|
* char * str = nodesetitem_tostr(curptr);
|
|
* printf("=> %s\n",str);
|
|
* free(str);
|
|
*/
|
|
|
|
nodesetitem_destroy(newptr);
|
|
|
|
action_done = true;
|
|
break;
|
|
}
|
|
else if (curptr->minimum > item->maximum) {
|
|
/* alors on insère le noeud ici... */
|
|
NodeSetItem_t * newptr = nodesetitem_copy(item);
|
|
if (NULL == curptr->prev)
|
|
{ /* on est en tete de liste */
|
|
newptr->next = head;
|
|
if (head){ head->prev = newptr; }
|
|
head = newptr;
|
|
}
|
|
else
|
|
{ /* on est en milieu de liste */
|
|
prevptr->next = newptr;
|
|
newptr->prev = prevptr;
|
|
newptr->next = curptr;
|
|
curptr->prev = newptr;
|
|
}
|
|
|
|
action_done = true;
|
|
break;
|
|
} else {
|
|
pDEBUG("Rien en commun : %s vs %s\n", curstr, itemstr);
|
|
// on va ajouter à la fin ?
|
|
}
|
|
|
|
prevptr = curptr;
|
|
curptr = curptr->next;
|
|
|
|
free(curstr);
|
|
curstr = NULL;
|
|
}
|
|
if (head == NULL){
|
|
NodeSetItem_t * newptr = nodesetitem_copy(item);
|
|
head = newptr;
|
|
action_done = true;
|
|
}
|
|
|
|
if (!action_done){
|
|
pDEBUG("On ajoute %s a la fin de la nodesetlist\n",itemstr);
|
|
NodeSetItem_t * newptr = nodesetitem_copy(item);
|
|
if (NULL != prevptr) { prevptr->next = newptr; } // n'arrive jamais
|
|
newptr->prev = prevptr;
|
|
}
|
|
|
|
if (NULL != curstr) { free(curstr); }
|
|
if (NULL != itemstr) { free(itemstr); }
|
|
|
|
return head;
|
|
}
|
|
|
|
NodeSetList_t nodesetlist_merge(NodeSetList_t one, NodeSetList_t two){
|
|
NodeSetList_t result = nodesetlist_create();
|
|
|
|
NodeSetItem_t * curptr;
|
|
|
|
if (DEBUG_MERGE){
|
|
pDEBUG("MERGING NODESETLIST\n");
|
|
nodesetlist_display(one);
|
|
}
|
|
|
|
curptr = one;
|
|
while (curptr != NULL){
|
|
/*
|
|
* str = nodesetitem_tostr(curptr);
|
|
* printf("Copying... %s\n", str);
|
|
* free(str);
|
|
*/
|
|
result = nodesetlist_insert_item (result, curptr);
|
|
curptr = curptr->next;
|
|
}
|
|
|
|
if (DEBUG_MERGE){
|
|
pDEBUG("AND\n");
|
|
nodesetlist_display(two);
|
|
}
|
|
|
|
curptr = two;
|
|
while (curptr != NULL){
|
|
/*
|
|
* str = nodesetitem_tostr(curptr);
|
|
* printf("Copying... %s\n", str);
|
|
* free(str);
|
|
*/
|
|
result = nodesetlist_insert_item (result, curptr);
|
|
curptr = curptr->next;
|
|
}
|
|
|
|
if (DEBUG_MERGE){
|
|
pDEBUG("GIVES\n");
|
|
nodesetlist_display(result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void nodesetlist_display(NodeSetList_t list)
|
|
{
|
|
|
|
printf("NodeSetList = {\n");
|
|
NodeSetItem_t * curptr = list;
|
|
while(curptr != NULL){
|
|
char * set = nodesetitem_tostr(curptr);
|
|
printf("\t%s, \n",set);
|
|
free(set);
|
|
curptr = curptr->next;
|
|
}
|
|
printf("}\n");
|
|
}
|
|
|
|
/**
|
|
*
|
|
* ITEM OPERATIONS
|
|
*
|
|
*/
|
|
|
|
|
|
NodeSetItem_t * nodesetitem_create(){
|
|
NodeSetItem_t * node = (NodeSetItem_t *) malloc (sizeof(NodeSetItem_t));
|
|
node->next = NULL;
|
|
node->prev = NULL;
|
|
node->minimum = -1;
|
|
node->maximum = -1;
|
|
return node;
|
|
}
|
|
|
|
NodeSetItem_t * nodesetitem_create_from_node(nodeindex_t node_idx){
|
|
NodeSetItem_t * node = nodesetitem_create();
|
|
node->minimum = node_idx;
|
|
node->maximum = node_idx;
|
|
return node;
|
|
}
|
|
|
|
NodeSetItem_t * nodesetitem_copy(NodeSetItem_t * original){
|
|
NodeSetItem_t * result = nodesetitem_create();
|
|
result->minimum = original->minimum;
|
|
result->maximum = original->maximum;
|
|
return result;
|
|
}
|
|
|
|
void nodesetitem_destroy(NodeSetItem_t * root){
|
|
root->prev = NULL;
|
|
root->next = NULL;
|
|
free(root);
|
|
root = NULL;
|
|
}
|
|
|
|
|
|
bool nodesetitem_contains_node(NodeSetItem_t * item, nodeindex_t node_idx){
|
|
if ((item->minimum <= node_idx) && (item->maximum >= node_idx)){
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool nodesetitem_is_overlap(NodeSetItem_t * one, NodeSetItem_t * two){
|
|
bool answer = false;
|
|
if (
|
|
(
|
|
(one->minimum <= two->minimum) // om <= tm <= oM
|
|
&& (one->maximum >= two->minimum)
|
|
)
|
|
|| (
|
|
(one->minimum <= two->maximum) // om <= tM <= oM
|
|
&& (one->maximum >= two->maximum)
|
|
)
|
|
|| (
|
|
(two->minimum <= one->minimum) // tm <= om <= tM
|
|
&& (two->maximum >= one->minimum)
|
|
)
|
|
|| (
|
|
(two->minimum <= one->maximum) // tm <= oM <= tM
|
|
&& (two->maximum >= one->maximum)
|
|
)
|
|
)
|
|
{
|
|
answer = true;
|
|
|
|
}
|
|
return answer;
|
|
}
|
|
|
|
bool nodesetitem_is_snap(NodeSetItem_t * one, NodeSetItem_t * two){
|
|
bool answer = false;
|
|
if ((one->maximum + 1) == two->minimum){
|
|
answer = true;
|
|
} else if ((two->maximum +1) == one->minimum){
|
|
answer = true;
|
|
}
|
|
return answer;
|
|
}
|
|
|
|
char * nodesetitem_tostr(NodeSetItem_t * root){
|
|
char * str = (char *) malloc (sizeof(char) * 100);
|
|
sprintf(str,"[ %ld .. %ld ]", root->minimum, root->maximum);
|
|
return str;
|
|
}
|
|
|
|
NodeSetItem_t * nodesetitem_create_from_bounds(NodeSetItem_t * one,
|
|
NodeSetItem_t * two){
|
|
NodeSetItem_t * result;
|
|
result = nodesetitem_create();
|
|
result->minimum =
|
|
(one->minimum < two->minimum) ? (one->minimum) : (two->minimum);
|
|
result->maximum =
|
|
(one->maximum > two->maximum) ? (one->maximum) : (two->maximum);
|
|
|
|
/*
|
|
* char * str= nodesetitem_tostr(result);
|
|
* printf("CREATING FROM BOUNDS -> %s\n", str);
|
|
* free(str);
|
|
*/
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
NodeSetList_t nodesetlist_insert_edge(NodeSetList_t list,
|
|
nodeindex_t from,
|
|
nodeindex_t to)
|
|
{
|
|
NodeSetList_t head = list;
|
|
NodeSetItem_t * edgeset_from;
|
|
NodeSetItem_t * edgeset_to;
|
|
|
|
printf("INSERTING EDGE (%ld - %ld)\n",from, to);
|
|
|
|
if (NULL == list){
|
|
printf("Empty set");
|
|
edgeset_from = nodesetitem_create_from_node(from);
|
|
head = nodesetlist_insert_item(head, edgeset_from); /* edgeset_from may have been deleted */
|
|
|
|
edgeset_to = nodesetitem_create_from_node (to);
|
|
head = nodesetlist_insert_item(head, edgeset_to); /* edgeset_to may have been deleted */
|
|
} else {
|
|
#warning "NODESETLIST_INSERT_EDGE NOT IMPLEMENTED FOR LIST!=NULL"
|
|
}
|
|
return head;
|
|
}
|
|
|
|
#undef DEBUG_INSERT
|
|
#undef DEBUG_MERGE
|
|
#undef DEBUG
|