File:  [ELWIX - Embedded LightWeight unIX -] / libelwix / src / sarray.c
Revision 1.4: download - view: text, annotated - select for diffs - revision graph
Thu Jun 25 17:53:50 2015 UTC (8 years, 10 months ago) by misho
Branches: MAIN
CVS tags: elwix5_9, elwix5_8, elwix5_7, elwix5_6, elwix5_5, elwix5_4, elwix5_3, elwix5_2, elwix5_12, elwix5_11, elwix5_10, elwix5_1, elwix5_0, elwix4_9, elwix4_8, elwix4_7, elwix4_6, elwix4_5, elwix4_4, elwix4_3, elwix4_26, elwix4_25, elwix4_24, elwix4_23, elwix4_22, elwix4_21, elwix4_20, elwix4_2, elwix4_19, elwix4_18, elwix4_17, elwix4_16, elwix4_15, elwix4_14, elwix4_13, elwix4_12, elwix4_11, elwix4_10, elwix4_1, elwix3_9, elwix3_8, HEAD, ELWIX5_9, ELWIX5_8, ELWIX5_7, ELWIX5_6, ELWIX5_5, ELWIX5_4, ELWIX5_3, ELWIX5_2, ELWIX5_11, ELWIX5_10, ELWIX5_1, ELWIX5_0, ELWIX4_9, ELWIX4_8, ELWIX4_7, ELWIX4_6, ELWIX4_5, ELWIX4_4, ELWIX4_3, ELWIX4_26, ELWIX4_25, ELWIX4_24, ELWIX4_23, ELWIX4_22, ELWIX4_21, ELWIX4_20, ELWIX4_2, ELWIX4_19, ELWIX4_18, ELWIX4_17, ELWIX4_16, ELWIX4_15, ELWIX4_14, ELWIX4_13, ELWIX4_12, ELWIX4_11, ELWIX4_10, ELWIX4_1, ELWIX4_0, ELWIX3_8, ELWIX3_7
version 3.7

    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 2015/06/25 17:53:50 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 - 2015
   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:  * sarr_Init() - Create and initialize dynamic split-order array
   51:  *
   52:  * @numItems = Number of Items
   53:  * @segLen = Length of segment
   54:  * return: NULL error, != NULL allocated memory for array
   55:  */
   56: sarr_t *
   57: sarr_Init(int numItems, int segLen)
   58: {
   59: 	sarr_t *arr = NULL;
   60: 
   61: 	if (segLen < 1)
   62: 		return NULL;
   63: 
   64: 	arr = e_malloc(sizeof(sarr_t));
   65: 	if (!arr)
   66: 		return NULL;
   67: 
   68: 	arr->sarr_num = numItems;
   69: 	arr->sarr_seg = segLen;
   70: 	arr->sarr_siz = numItems / segLen + 1;
   71: 	arr->sarr_data = e_calloc(arr->sarr_siz, sizeof(sarr_seg_t));
   72: 	if (!arr->sarr_data) {
   73: 		e_free(arr);
   74: 		return NULL;
   75: 	} else
   76: 		memset(arr->sarr_data, 0, arr->sarr_siz * sizeof(sarr_seg_t));
   77: 
   78: 	return arr;
   79: }
   80: 
   81: /*
   82:  * sarr_Destroy() - Free all data in dynamic split-order array and Destroy array
   83:  *
   84:  * @parr = Array
   85:  * return: none
   86:  */
   87: void
   88: sarr_Destroy(sarr_t ** __restrict parr)
   89: {
   90: 	register int i;
   91: 
   92: 	if (!parr || !*parr)
   93: 		return;
   94: 
   95: 	for (i = 0; i < (*parr)->sarr_siz; i++)
   96: 		if ((*parr)->sarr_data[i]) {
   97: 			e_free((*parr)->sarr_data[i]);
   98: 			(*parr)->sarr_data[i] = NULL;
   99: 		}
  100: 
  101: 	if ((*parr)->sarr_data)
  102: 		e_free((*parr)->sarr_data);
  103: 	e_free(*parr);
  104: 	*parr = NULL;
  105: }
  106: 
  107: /*
  108:  * sarr_Copy() Copy source split array to destination split array
  109:  *
  110:  * @dest = Destination split array, after use free with sarr_Destroy()
  111:  * @src = Source split array
  112:  * return: -1 error; >0 count of destination split array
  113:  */
  114: int
  115: sarr_Copy(sarr_t ** __restrict dest, sarr_t * __restrict src)
  116: {
  117: 	if (!dest || !src)
  118: 		return -1;
  119: 
  120: 	*dest = sarr_Init(sarr_Size(src), sarr_Seg(src));
  121: 	if (!*dest)
  122: 		return -1;
  123: 
  124: 	memcpy((*dest)->sarr_data, src->sarr_data, (*dest)->sarr_siz * sizeof(sarr_seg_t));
  125: 	return sarr_Size(*dest);
  126: }
  127: 
  128: /*
  129:  * sarr_Vacuum() - Vacuum dynamic split-order array, empty segments will be freed
  130:  *
  131:  * @arr = Array
  132:  * return: -1 error, >-1 freed segments
  133:  */
  134: int
  135: sarr_Vacuum(sarr_t * __restrict arr)
  136: {
  137: 	register int i, j;
  138: 	int cx = 0;
  139: 	sarr_seg_t seg;
  140: 
  141: 	if (!arr)
  142: 		return -1;
  143: 
  144: 	for (i = 0; i < arr->sarr_siz; i++)
  145: 		if (arr->sarr_data[i]) {
  146: 			for (j = 0, seg = arr->sarr_data[i]; j < arr->sarr_seg; j++)
  147: 				if (seg[j])
  148: 					break;
  149: 			if (j == arr->sarr_seg) {
  150: 				e_free(arr->sarr_data[i]);
  151: 				arr->sarr_data[i] = NULL;
  152: 				cx++;
  153: 			}
  154: 		}
  155: 
  156: 	return cx;
  157: }
  158: 
  159: /*
  160:  * sarr_Grow() - Grow/Shrink dynamic split-order array, Use with care when it shrink!!!
  161:  *
  162:  * @arr = Array
  163:  * @newNumItems = Number of Items
  164:  * return: -1 error, 0 ok
  165:  */
  166: int
  167: sarr_Grow(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: 				e_free(arr->sarr_data[i]);
  186: 
  187: 	arr->sarr_siz = seg;
  188: 	data = e_realloc(arr->sarr_data, arr->sarr_siz * sizeof(sarr_seg_t));
  189: 	if (!data)
  190: 		return -1;
  191: 	else
  192: 		arr->sarr_data = data;
  193: 	memset(arr->sarr_data + (arr->sarr_siz - n), 0, n * sizeof(sarr_seg_t));
  194: 
  195: 	return 0;
  196: }
  197: 
  198: /*
  199:  * sarr_Get() - Get element from dynamic split-order array
  200:  *
  201:  * @arr = Array
  202:  * @idx = Index (warning 1st element is at position 1)
  203:  * return: NULL not found, !=NULL element
  204:  */
  205: void *
  206: sarr_Get(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:  * sarr_Get2() - Always get element from dynamic split-order array
  223:  *	Function automatic grow array. Good use for Hash tables! 
  224:  *
  225:  * @arr = Array
  226:  * @idx = Index (warning 1st element is at position 1)
  227:  * return: NULL not found, !=NULL element
  228:  */
  229: void *
  230: sarr_Get2(sarr_t * __restrict arr, u_int idx)
  231: {
  232: 	if (!arr || idx < 1)
  233: 		return NULL;
  234: 	if (arr->sarr_num < idx)
  235: 		if (sarr_Grow(arr, idx))
  236: 			return NULL;
  237: 	return sarr_Get(arr, idx);
  238: }
  239: 
  240: /*
  241:  * sarr_Set() - Set element to dynamic split-order array
  242:  *
  243:  * @arr = Array
  244:  * @idx = Index (warning 1st element is at position 1)
  245:  * @data = Value
  246:  * return: NULL error or empty, !=NULL old value in element
  247:  */
  248: void *
  249: sarr_Set(sarr_t * __restrict arr, u_int idx, void *data)
  250: {
  251: 	void *ret = NULL;
  252: 	sarr_seg_t seg;
  253: 	register int pos;
  254: 
  255: 	if (!arr || idx < 1 || arr->sarr_num < idx)
  256: 		return ret;
  257: 
  258: 	seg = arr->sarr_data[idx / arr->sarr_seg];
  259: 	if (!seg) {
  260: 		seg = e_calloc(arr->sarr_seg, sizeof(void*));
  261: 		if (!seg)
  262: 			return ret;
  263: 		else
  264: 			memset(seg, 0, arr->sarr_seg * sizeof(void*));
  265: 		arr->sarr_data[idx / arr->sarr_seg] = seg;
  266: 	}
  267: 
  268: 	pos = idx % arr->sarr_seg;
  269: 	ret = seg[pos];
  270: 	seg[pos] = data;
  271: 
  272: 	return ret;
  273: }
  274: 
  275: /*
  276:  * sarr_sarr2array() - Convert from split-order array to dynamic array
  277:  *
  278:  * @sa = split array
  279:  * @sarrFree = after convert split array !=0 will be destroyed sarray
  280:  * return: NULL error or != NULL new array
  281:  */
  282: array_t *
  283: sarr_sarr2array(sarr_t ** __restrict sa, int sarrFree)
  284: {
  285: 	array_t *arr = NULL;
  286: 	int el;
  287: 	register int i;
  288: 
  289: 	if (!sa || !*sa)
  290: 		return NULL;
  291: 
  292: 	el = sarr_Size(*sa);
  293: 	arr = array_Init(el);
  294: 	if (!arr)
  295: 		return NULL;
  296: 
  297: 	for (i = 0; i < el; i++)
  298: 		array_Set(arr, i, sarr_Get(*sa, i + 1));
  299: 
  300: 	if (sarrFree) {
  301: 		e_free(*sa);
  302: 		*sa = NULL;
  303: 	}
  304: 	return arr;
  305: }
  306: 
  307: /*
  308:  * sarr_array2sarr() - Convert from dynamic array to split-order array
  309:  *
  310:  * @a = array
  311:  * @segLen = Length of segment
  312:  * @arrFree = after convert array !=0 will be destroyed
  313:  * return: NULL error or != NULL new sarr
  314:  */
  315: sarr_t *
  316: sarr_array2sarr(array_t ** __restrict a, int segLen, int arrFree)
  317: {
  318: 	sarr_t *sa = NULL;
  319: 	int el;
  320: 	register int i;
  321: 
  322: 	if (!a || !*a)
  323: 		return NULL;
  324: 
  325: 	el = array_Size(*a);
  326: 	sa = sarr_Init(el, segLen);
  327: 	if (!sa)
  328: 		return NULL;
  329: 
  330: 	for (i = 0; i < el; i++)
  331: 		sarr_Set(sa, i + 1, array_Get(*a, i));
  332: 
  333: 	if (arrFree) {
  334: 		e_free(*a);
  335: 		*a = NULL;
  336: 	}
  337: 	return sa;
  338: }

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