#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; }