#include #include #include #include #include "main.h" #include "list.h" #include "index.h" #define DEBUG_INDEX static index_item_t* newIndexItem(int key, void *data) { index_item_t *new; new = malloc( sizeof(index_item_t) ); new->key = key; new->data = data; return new; } #ifdef DEBUG_INDEX static void printIndexItem(index_item_t *p) { printf("key = %d data = %p\n", p->key, p->data); } static void printListIndexItem(list_t *list) { int i; printf("list :\n"); printf("------------------\n"); for( i = 0 ; i < list->count ; i++ ) { index_item_t *this; this = (index_item_t *)list->list[i]; printIndexItem(this); } } static void checkList(list_t *list) { int i; int prev; int this; //return; if( list->count == 0 ) { printf("nothing\n"); return; } prev = ( (index_item_t *) list->list[0] )->key; for( i = 1 ; i < list->count ; i++ ) { this = ( (index_item_t *) list->list[i] )->key; if( prev >= this ) { printListIndexItem(list); assert( ! "error" ); } prev = this; } } #endif static void destroyIndexItem(index_item_t *p) { free(p); } list_t* newIndex() { return newList(); } void addToIndex(list_t *list, int key, void *data) { #ifdef DEBUG_INDEX int count = 0; #endif index_item_t *item; index_item_t *this; int min, max, point; int len; item = newIndexItem(key, data); len = list->count; min = 0; max = len-1; for(;;) { point = min + ( max - min ) / 2; #ifdef DEBUG_INDEX if( ++count == len*5 ) { printf("CICLIC ERROR\n"); printIndexItem(item); printf("-------------------\n"); printListIndexItem(list); assert( 0 ); } #endif if( max < 0 ) { insList(list, 0, item); #ifdef DEBUG_INDEX checkList(list); #endif return; } if( min >= len ) { addList(list, item); #ifdef DEBUG_INDEX checkList(list); #endif return; } this = (index_item_t *)list->list[point]; /* printf("min = %d max = %d point = %d len = %d offset = %d\n", min, max, point, len, offset); */ if( min > max ) { insList(list, point, item); #ifdef DEBUG_INDEX checkList(list); #endif return; } if( item->key > this->key ) { min = point + 1; continue; } if( item->key < this->key ) { max = point - 1; continue; } } } static int getOffsetFromIndex(list_t *list, int key) { index_item_t *this; int min, max, point, len; len = list->count; if( len == 0 ) { return -1; } min = 0; max = len-1; for(;;) { point = min + ( max - min ) / 2; if( max < 0 || point >= len || max < min ) { return -1; } this = (index_item_t *)list->list[point]; /* printf("min = %d max = %d point = %d len = %d offset = %d\n", min, max, point, len, offset); */ if( key == this->key ) { return point; } if( key > this->key ) { min = point + 1; continue; } if( key < this->key ) { max = point - 1; continue; } } } void* getFromIndex(list_t *list, int key) { int offset; offset = getOffsetFromIndex(list, key); if( offset != -1 ) { index_item_t *this; this = list->list[offset]; return this->data; } return NULL; } void delFromIndex(list_t *list, int key) { int offset; offset = getOffsetFromIndex(list, key); if( offset != -1 ) { delListItem(list, offset, destroyIndexItem); } } void delFromIndexWithObject(list_t *list, int key, void *f) { int offset; offset = getOffsetFromIndex(list, key); if( offset != -1 ) { index_item_t *this; void (*fce)(void *p); this = list->list[offset]; fce = f; fce(this); delListItem(list, offset, destroyIndexItem); } } void actionIndexWithObject(list_t *list, void *f) { int i; for( i = 0 ; i < list->count ; i++) { index_item_t *this; void (*fce)(void *p); this = list->list[i]; fce = f; fce(this); } } void destroyIndex(list_t *list) { destroyListItem(list, destroyIndexItem); } void destroyIndexWithObject(list_t *list, void *f) { actionIndexWithObject(list, f); destroyListItem(list, destroyIndexItem); }