File:  [ELWIX - Embedded LightWeight unIX -] / libaitio / src / Attic / sarray.c
Revision 1.2: download - view: text, annotated - select for diffs - revision graph
Tue May 3 15:41:00 2011 UTC (13 years, 2 months ago) by misho
Branches: MAIN
CVS tags: io1_9, IO1_8, HEAD
add new feature
split-order array

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>