Annotation of libelwix/src/sarray.c, revision 1.4

1.1       misho       1: /*************************************************************************
                      2: * (C) 2011 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
                      3: *  by Michael Pounov <misho@elwix.org>
                      4: *
                      5: * $Author: misho $
1.4     ! misho       6: * $Id: sarray.c,v 1.3.20.1 2015/06/25 00:36:48 misho Exp $
1.1       misho       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: 
1.4     ! misho      15: Copyright 2004 - 2015
1.1       misho      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:  */
1.2       misho     205: void *
1.1       misho     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:  */
1.2       misho     248: void *
1.1       misho     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>