version 1.1, 2011/05/03 08:39:14
|
version 1.2, 2011/05/03 15:41:00
|
Line 0
|
Line 1
|
|
#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; |
|
} |