--- libaitio/src/Attic/sarray.c 2011/05/03 08:39:14 1.1 +++ libaitio/src/Attic/sarray.c 2011/05/03 15:41:00 1.2 @@ -0,0 +1,211 @@ +#include "global.h" + + +/* + * io_sarrInit() - Create and initialize dynamic split-order array + * @numItems = Number of Items + * @segLen = Length of segment + * return: NULL error, != NULL allocated memory for array + */ +inline sarr_t * +io_sarrInit(int numItems, int segLen) +{ + sarr_t *arr = NULL; + + if (segLen < 1) + return NULL; + + arr = malloc(sizeof(sarr_t)); + if (!arr) { + LOGERR; + return NULL; + } + + arr->sarr_num = numItems; + arr->sarr_seg = segLen; + arr->sarr_siz = numItems / segLen + 1; + arr->sarr_data = calloc(arr->sarr_siz, sizeof(sarr_seg_t)); + if (!arr->sarr_data) { + LOGERR; + free(arr); + return NULL; + } else + memset(arr->sarr_data, 0, arr->sarr_siz * sizeof(sarr_seg_t)); + + return arr; +} + +/* + * io_sarrDestroy() - Free all data in dynamic split-order array and Destroy array + * @parr = Array + * return: none + */ +inline void +io_sarrDestroy(sarr_t ** __restrict parr) +{ + register int i; + + assert(parr); + if (!parr) + return; + + for (i = 0; i < (*parr)->sarr_siz; i++) + if ((*parr)->sarr_data[i]) { + free((*parr)->sarr_data[i]); + (*parr)->sarr_data[i] = NULL; + } + + if ((*parr)->sarr_data) + free((*parr)->sarr_data); + free(*parr); + *parr = NULL; +} + +/* + * io_sarrVacuum() - Vacuum dynamic split-order array, empty segments will be freed + * @arr = Array + * return: -1 error, >-1 freed segments + */ +int +io_sarrVacuum(sarr_t * __restrict arr) +{ + register int i, j; + int cx = 0; + sarr_seg_t seg; + + assert(arr); + if (!arr) + return -1; + + for (i = 0; i < arr->sarr_siz; i++) + if (arr->sarr_data[i]) { + for (j = 0, seg = arr->sarr_data[i]; j < arr->sarr_seg; j++) + if (seg[j]) + break; + if (j == arr->sarr_seg) { + free(arr->sarr_data[i]); + arr->sarr_data[i] = NULL; + cx++; + } + } + + return cx; +} + +/* + * io_sarrGrow() - Grow/Shrink dynamic split-order array, Use with care when it shrink!!! + * @arr = Array + * @newNumItems = Number of Items + * return: -1 error, 0 ok + */ +int +io_sarrGrow(sarr_t * __restrict arr, int newNumItems) +{ + sarr_seg_t *data; + int seg, n = 0; + register int i; + + assert(arr); + if (!arr) + return -1; + + arr->sarr_num = newNumItems; + seg = newNumItems / arr->sarr_seg + 1; + if (arr->sarr_siz == seg) + return n; + if (arr->sarr_siz < seg) + n = seg - arr->sarr_siz; + else + for (i = seg; i < arr->sarr_siz; i++) + if (arr->sarr_data[i]) + free(arr->sarr_data[i]); + + arr->sarr_siz = seg; + data = realloc(arr->sarr_data, arr->sarr_siz * sizeof(sarr_seg_t)); + if (!data) { + LOGERR; + return -1; + } else + arr->sarr_data = data; + memset(arr->sarr_data + (arr->sarr_siz - n), 0, n * sizeof(sarr_seg_t)); + + return 0; +} + +/* + * io_sarrGet() - Get element from dynamic split-order array + * @arr = Array + * @idx = Index (warning 1st element is at position 1) + * return: NULL not found, !=NULL element + */ +inline void * +io_sarrGet(sarr_t * __restrict arr, u_int idx) +{ + void *ret = NULL; + sarr_seg_t seg; + + assert(arr); + if (!arr || idx < 1 || arr->sarr_num < idx) + return ret; + + seg = arr->sarr_data[idx / arr->sarr_seg]; + if (seg) + ret = seg[idx % arr->sarr_seg]; + + return ret; +} + +/* + * io_sarrGet2() - Always get element from dynamic split-order array + * Function automatic grow array. Good use for Hash tables! + * @arr = Array + * @idx = Index (warning 1st element is at position 1) + * return: NULL not found, !=NULL element + */ +void * +io_sarrGet2(sarr_t * __restrict arr, u_int idx) +{ + assert(arr); + if (!arr || idx < 1) + return NULL; + if (arr->sarr_num < idx) + if (io_sarrGrow(arr, idx)) + return NULL; + return io_sarrGet(arr, idx); +} + +/* + * io_sarrSet() - Set element to dynamic split-order array + * @arr = Array + * @idx = Index (warning 1st element is at position 1) + * @data = Value + * return: NULL error or empty, !=NULL old value in element + */ +inline void * +io_sarrSet(sarr_t * __restrict arr, u_int idx, void *data) +{ + void *ret = NULL; + sarr_seg_t seg; + register int pos; + + assert(arr); + if (!arr || idx < 1 || arr->sarr_num < idx) + return ret; + + seg = arr->sarr_data[idx / arr->sarr_seg]; + if (!seg) { + seg = calloc(arr->sarr_seg, sizeof(void*)); + if (!seg) { + LOGERR; + return ret; + } else + memset(seg, 0, arr->sarr_seg * sizeof(void*)); + arr->sarr_data[idx / arr->sarr_seg] = seg; + } + + pos = idx % arr->sarr_seg; + ret = seg[pos]; + seg[pos] = data; + + return ret; +}