File:  [ELWIX - Embedded LightWeight unIX -] / libaitio / src / Attic / sarray.c
Revision 1.4.2.3: download - view: text, annotated - select for diffs - revision graph
Wed Aug 31 13:19:22 2011 UTC (12 years, 10 months ago) by misho
Branches: io2_1
Diff to: branchpoint 1.4: preferred, unified
removed some asserts

    1: /*************************************************************************
    2: * (C) 2011 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
    3: *  by Michael Pounov <misho@elwix.org>
    4: *
    5: * $Author: misho $
    6: * $Id: sarray.c,v 1.4.2.3 2011/08/31 13:19:22 misho Exp $
    7: *
    8: **************************************************************************
    9: The ELWIX and AITNET software is distributed under the following
   10: terms:
   11: 
   12: All of the documentation and software included in the ELWIX and AITNET
   13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
   14: 
   15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
   16: 	by Michael Pounov <misho@elwix.org>.  All rights reserved.
   17: 
   18: Redistribution and use in source and binary forms, with or without
   19: modification, are permitted provided that the following conditions
   20: are met:
   21: 1. Redistributions of source code must retain the above copyright
   22:    notice, this list of conditions and the following disclaimer.
   23: 2. Redistributions in binary form must reproduce the above copyright
   24:    notice, this list of conditions and the following disclaimer in the
   25:    documentation and/or other materials provided with the distribution.
   26: 3. All advertising materials mentioning features or use of this software
   27:    must display the following acknowledgement:
   28: This product includes software developed by Michael Pounov <misho@elwix.org>
   29: ELWIX - Embedded LightWeight unIX and its contributors.
   30: 4. Neither the name of AITNET nor the names of its contributors
   31:    may be used to endorse or promote products derived from this software
   32:    without specific prior written permission.
   33: 
   34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
   35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   37: ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   44: SUCH DAMAGE.
   45: */
   46: #include "global.h"
   47: 
   48: 
   49: /*
   50:  * io_sarrInit() - Create and initialize dynamic split-order array
   51:  * @numItems = Number of Items
   52:  * @segLen = Length of segment
   53:  * return: NULL error, != NULL allocated memory for array
   54:  */
   55: inline sarr_t *
   56: io_sarrInit(int numItems, int segLen)
   57: {
   58: 	sarr_t *arr = NULL;
   59: 
   60: 	if (segLen < 1)
   61: 		return NULL;
   62: 
   63: 	arr = malloc(sizeof(sarr_t));
   64: 	if (!arr) {
   65: 		LOGERR;
   66: 		return NULL;
   67: 	}
   68: 
   69: 	arr->sarr_num = numItems;
   70: 	arr->sarr_seg = segLen;
   71: 	arr->sarr_siz = numItems / segLen + 1;
   72: 	arr->sarr_data = calloc(arr->sarr_siz, sizeof(sarr_seg_t));
   73: 	if (!arr->sarr_data) {
   74: 		LOGERR;
   75: 		free(arr);
   76: 		return NULL;
   77: 	} else
   78: 		memset(arr->sarr_data, 0, arr->sarr_siz * sizeof(sarr_seg_t));
   79: 
   80: 	return arr;
   81: }
   82: 
   83: /*
   84:  * io_sarrDestroy() - Free all data in dynamic split-order array and Destroy array
   85:  * @parr = Array
   86:  * return: none
   87:  */
   88: inline void
   89: io_sarrDestroy(sarr_t ** __restrict parr)
   90: {
   91: 	register int i;
   92: 
   93: 	if (!parr || !*parr)
   94: 		return;
   95: 
   96: 	for (i = 0; i < (*parr)->sarr_siz; i++)
   97: 		if ((*parr)->sarr_data[i]) {
   98: 			free((*parr)->sarr_data[i]);
   99: 			(*parr)->sarr_data[i] = NULL;
  100: 		}
  101: 
  102: 	if ((*parr)->sarr_data)
  103: 		free((*parr)->sarr_data);
  104: 	free(*parr);
  105: 	*parr = NULL;
  106: }
  107: 
  108: /*
  109:  * io_sarrCopy() Copy source split array to destination split array
  110:  * @dest = Destination split array, after use free with io_sarrDestroy()
  111:  * @src = Source split array
  112:  * return: -1 error; >0 count of destination split array
  113:  */
  114: int
  115: io_sarrCopy(sarr_t ** __restrict dest, sarr_t * __restrict src)
  116: {
  117: 	assert(dest);
  118: 	assert(src);
  119: 	if (!dest || !src)
  120: 		return -1;
  121: 
  122: 	*dest = io_sarrInit(io_sarrSize(src), io_sarrSeg(src));
  123: 	if (!*dest)
  124: 		return -1;
  125: 
  126: 	memcpy((*dest)->sarr_data, src->sarr_data, (*dest)->sarr_siz * sizeof(sarr_seg_t));
  127: 	return io_sarrSize(*dest);
  128: }
  129: 
  130: /*
  131:  * io_sarrVacuum() - Vacuum dynamic split-order array, empty segments will be freed
  132:  * @arr = Array
  133:  * return: -1 error, >-1 freed segments
  134:  */
  135: int
  136: io_sarrVacuum(sarr_t * __restrict arr)
  137: {
  138: 	register int i, j;
  139: 	int cx = 0;
  140: 	sarr_seg_t seg;
  141: 
  142: 	if (!arr)
  143: 		return -1;
  144: 
  145: 	for (i = 0; i < arr->sarr_siz; i++)
  146: 		if (arr->sarr_data[i]) {
  147: 			for (j = 0, seg = arr->sarr_data[i]; j < arr->sarr_seg; j++)
  148: 				if (seg[j])
  149: 					break;
  150: 			if (j == arr->sarr_seg) {
  151: 				free(arr->sarr_data[i]);
  152: 				arr->sarr_data[i] = NULL;
  153: 				cx++;
  154: 			}
  155: 		}
  156: 
  157: 	return cx;
  158: }
  159: 
  160: /*
  161:  * io_sarrGrow() - Grow/Shrink dynamic split-order array, Use with care when it shrink!!!
  162:  * @arr = Array
  163:  * @newNumItems = Number of Items
  164:  * return: -1 error, 0 ok
  165:  */
  166: int
  167: io_sarrGrow(sarr_t * __restrict arr, int newNumItems)
  168: {
  169: 	sarr_seg_t *data;
  170: 	int seg, n = 0;
  171: 	register int i;
  172: 
  173: 	if (!arr)
  174: 		return -1;
  175: 
  176: 	arr->sarr_num = newNumItems;
  177: 	seg = newNumItems / arr->sarr_seg + 1;
  178: 	if (arr->sarr_siz == seg)
  179: 		return n;
  180: 	if (arr->sarr_siz < seg)
  181: 		n = seg - arr->sarr_siz;
  182: 	else
  183: 		for (i = seg; i < arr->sarr_siz; i++)
  184: 			if (arr->sarr_data[i])
  185: 				free(arr->sarr_data[i]);
  186: 
  187: 	arr->sarr_siz = seg;
  188: 	data = realloc(arr->sarr_data, arr->sarr_siz * sizeof(sarr_seg_t));
  189: 	if (!data) {
  190: 		LOGERR;
  191: 		return -1;
  192: 	} else
  193: 		arr->sarr_data = data;
  194: 	memset(arr->sarr_data + (arr->sarr_siz - n), 0, n * sizeof(sarr_seg_t));
  195: 
  196: 	return 0;
  197: }
  198: 
  199: /*
  200:  * io_sarrGet() - Get element from dynamic split-order array
  201:  * @arr = Array
  202:  * @idx = Index (warning 1st element is at position 1)
  203:  * return: NULL not found, !=NULL element
  204:  */
  205: inline void *
  206: io_sarrGet(sarr_t * __restrict arr, u_int idx)
  207: {
  208: 	void *ret = NULL;
  209: 	sarr_seg_t seg;
  210: 
  211: 	if (!arr || idx < 1 || arr->sarr_num < idx)
  212: 		return ret;
  213: 
  214: 	seg = arr->sarr_data[idx / arr->sarr_seg];
  215: 	if (seg)
  216: 		ret = seg[idx % arr->sarr_seg];
  217: 
  218: 	return ret;
  219: }
  220: 
  221: /*
  222:  * io_sarrGet2() - Always get element from dynamic split-order array
  223:  *	Function automatic grow array. Good use for Hash tables! 
  224:  * @arr = Array
  225:  * @idx = Index (warning 1st element is at position 1)
  226:  * return: NULL not found, !=NULL element
  227:  */
  228: void *
  229: io_sarrGet2(sarr_t * __restrict arr, u_int idx)
  230: {
  231: 	if (!arr || idx < 1)
  232: 		return NULL;
  233: 	if (arr->sarr_num < idx)
  234: 		if (io_sarrGrow(arr, idx))
  235: 			return NULL;
  236: 	return io_sarrGet(arr, idx);
  237: }
  238: 
  239: /*
  240:  * io_sarrSet() - Set element to dynamic split-order array
  241:  * @arr = Array
  242:  * @idx = Index (warning 1st element is at position 1)
  243:  * @data = Value
  244:  * return: NULL error or empty, !=NULL old value in element
  245:  */
  246: inline void *
  247: io_sarrSet(sarr_t * __restrict arr, u_int idx, void *data)
  248: {
  249: 	void *ret = NULL;
  250: 	sarr_seg_t seg;
  251: 	register int pos;
  252: 
  253: 	if (!arr || idx < 1 || arr->sarr_num < idx)
  254: 		return ret;
  255: 
  256: 	seg = arr->sarr_data[idx / arr->sarr_seg];
  257: 	if (!seg) {
  258: 		seg = calloc(arr->sarr_seg, sizeof(void*));
  259: 		if (!seg) {
  260: 			LOGERR;
  261: 			return ret;
  262: 		} else
  263: 			memset(seg, 0, arr->sarr_seg * sizeof(void*));
  264: 		arr->sarr_data[idx / arr->sarr_seg] = seg;
  265: 	}
  266: 
  267: 	pos = idx % arr->sarr_seg;
  268: 	ret = seg[pos];
  269: 	seg[pos] = data;
  270: 
  271: 	return ret;
  272: }
  273: 
  274: /*
  275:  * io_sarr2array() - Convert from split-order array to dynamic array
  276:  * @sa = split array
  277:  * @sarrFree = after convert split array !=0 will be destroyed sarray
  278:  * return: NULL error or != NULL new array
  279:  */
  280: array_t *
  281: io_sarr2array(sarr_t ** __restrict sa, int sarrFree)
  282: {
  283: 	array_t *arr = NULL;
  284: 	int el;
  285: 	register int i;
  286: 
  287: 	assert(sa && *sa);
  288: 	if (!sa || !*sa)
  289: 		return NULL;
  290: 
  291: 	el = io_sarrSize(*sa);
  292: 	arr = io_arrayInit(el);
  293: 	if (!arr)
  294: 		return NULL;
  295: 
  296: 	for (i = 0; i < el; i++)
  297: 		io_arraySet(arr, i, io_sarrGet(*sa, i + 1));
  298: 
  299: 	if (sarrFree) {
  300: 		free(*sa);
  301: 		*sa = NULL;
  302: 	}
  303: 	return arr;
  304: }
  305: 
  306: /*
  307:  * io_array2sarr() - Convert from dynamic array to split-order array
  308:  * @a = array
  309:  * @segLen = Length of segment
  310:  * @arrFree = after convert array !=0 will be destroyed
  311:  * return: NULL error or != NULL new sarr
  312:  */
  313: sarr_t *
  314: io_array2sarr(array_t ** __restrict a, int segLen, int arrFree)
  315: {
  316: 	sarr_t *sa = NULL;
  317: 	int el;
  318: 	register int i;
  319: 
  320: 	assert(a && *a);
  321: 	if (!a || !*a)
  322: 		return NULL;
  323: 
  324: 	el = io_arraySize(*a);
  325: 	sa = io_sarrInit(el, segLen);
  326: 	if (!sa)
  327: 		return NULL;
  328: 
  329: 	for (i = 0; i < el; i++)
  330: 		io_sarrSet(sa, i + 1, io_arrayGet(*a, i));
  331: 
  332: 	if (arrFree) {
  333: 		free(*a);
  334: 		*a = NULL;
  335: 	}
  336: 	return sa;
  337: }

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