Annotation of libaitio/src/sarray.c, revision 1.3

1.3     ! misho       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.2.2.1 2011/05/03 15:44:58 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: */
1.2       misho      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:        assert(parr);
                     94:        if (!parr)
                     95:                return;
                     96: 
                     97:        for (i = 0; i < (*parr)->sarr_siz; i++)
                     98:                if ((*parr)->sarr_data[i]) {
                     99:                        free((*parr)->sarr_data[i]);
                    100:                        (*parr)->sarr_data[i] = NULL;
                    101:                }
                    102: 
                    103:        if ((*parr)->sarr_data)
                    104:                free((*parr)->sarr_data);
                    105:        free(*parr);
                    106:        *parr = NULL;
                    107: }
                    108: 
                    109: /*
                    110:  * io_sarrVacuum() - Vacuum dynamic split-order array, empty segments will be freed
                    111:  * @arr = Array
                    112:  * return: -1 error, >-1 freed segments
                    113:  */
                    114: int
                    115: io_sarrVacuum(sarr_t * __restrict arr)
                    116: {
                    117:        register int i, j;
                    118:        int cx = 0;
                    119:        sarr_seg_t seg;
                    120: 
                    121:        assert(arr);
                    122:        if (!arr)
                    123:                return -1;
                    124: 
                    125:        for (i = 0; i < arr->sarr_siz; i++)
                    126:                if (arr->sarr_data[i]) {
                    127:                        for (j = 0, seg = arr->sarr_data[i]; j < arr->sarr_seg; j++)
                    128:                                if (seg[j])
                    129:                                        break;
                    130:                        if (j == arr->sarr_seg) {
                    131:                                free(arr->sarr_data[i]);
                    132:                                arr->sarr_data[i] = NULL;
                    133:                                cx++;
                    134:                        }
                    135:                }
                    136: 
                    137:        return cx;
                    138: }
                    139: 
                    140: /*
                    141:  * io_sarrGrow() - Grow/Shrink dynamic split-order array, Use with care when it shrink!!!
                    142:  * @arr = Array
                    143:  * @newNumItems = Number of Items
                    144:  * return: -1 error, 0 ok
                    145:  */
                    146: int
                    147: io_sarrGrow(sarr_t * __restrict arr, int newNumItems)
                    148: {
                    149:        sarr_seg_t *data;
                    150:        int seg, n = 0;
                    151:        register int i;
                    152: 
                    153:        assert(arr);
                    154:        if (!arr)
                    155:                return -1;
                    156: 
                    157:        arr->sarr_num = newNumItems;
                    158:        seg = newNumItems / arr->sarr_seg + 1;
                    159:        if (arr->sarr_siz == seg)
                    160:                return n;
                    161:        if (arr->sarr_siz < seg)
                    162:                n = seg - arr->sarr_siz;
                    163:        else
                    164:                for (i = seg; i < arr->sarr_siz; i++)
                    165:                        if (arr->sarr_data[i])
                    166:                                free(arr->sarr_data[i]);
                    167: 
                    168:        arr->sarr_siz = seg;
                    169:        data = realloc(arr->sarr_data, arr->sarr_siz * sizeof(sarr_seg_t));
                    170:        if (!data) {
                    171:                LOGERR;
                    172:                return -1;
                    173:        } else
                    174:                arr->sarr_data = data;
                    175:        memset(arr->sarr_data + (arr->sarr_siz - n), 0, n * sizeof(sarr_seg_t));
                    176: 
                    177:        return 0;
                    178: }
                    179: 
                    180: /*
                    181:  * io_sarrGet() - Get element from dynamic split-order array
                    182:  * @arr = Array
                    183:  * @idx = Index (warning 1st element is at position 1)
                    184:  * return: NULL not found, !=NULL element
                    185:  */
                    186: inline void *
                    187: io_sarrGet(sarr_t * __restrict arr, u_int idx)
                    188: {
                    189:        void *ret = NULL;
                    190:        sarr_seg_t seg;
                    191: 
                    192:        assert(arr);
                    193:        if (!arr || idx < 1 || arr->sarr_num < idx)
                    194:                return ret;
                    195: 
                    196:        seg = arr->sarr_data[idx / arr->sarr_seg];
                    197:        if (seg)
                    198:                ret = seg[idx % arr->sarr_seg];
                    199: 
                    200:        return ret;
                    201: }
                    202: 
                    203: /*
                    204:  * io_sarrGet2() - Always get element from dynamic split-order array
                    205:  *     Function automatic grow array. Good use for Hash tables! 
                    206:  * @arr = Array
                    207:  * @idx = Index (warning 1st element is at position 1)
                    208:  * return: NULL not found, !=NULL element
                    209:  */
                    210: void *
                    211: io_sarrGet2(sarr_t * __restrict arr, u_int idx)
                    212: {
                    213:        assert(arr);
                    214:        if (!arr || idx < 1)
                    215:                return NULL;
                    216:        if (arr->sarr_num < idx)
                    217:                if (io_sarrGrow(arr, idx))
                    218:                        return NULL;
                    219:        return io_sarrGet(arr, idx);
                    220: }
                    221: 
                    222: /*
                    223:  * io_sarrSet() - Set element to dynamic split-order array
                    224:  * @arr = Array
                    225:  * @idx = Index (warning 1st element is at position 1)
                    226:  * @data = Value
                    227:  * return: NULL error or empty, !=NULL old value in element
                    228:  */
                    229: inline void *
                    230: io_sarrSet(sarr_t * __restrict arr, u_int idx, void *data)
                    231: {
                    232:        void *ret = NULL;
                    233:        sarr_seg_t seg;
                    234:        register int pos;
                    235: 
                    236:        assert(arr);
                    237:        if (!arr || idx < 1 || arr->sarr_num < idx)
                    238:                return ret;
                    239: 
                    240:        seg = arr->sarr_data[idx / arr->sarr_seg];
                    241:        if (!seg) {
                    242:                seg = calloc(arr->sarr_seg, sizeof(void*));
                    243:                if (!seg) {
                    244:                        LOGERR;
                    245:                        return ret;
                    246:                } else
                    247:                        memset(seg, 0, arr->sarr_seg * sizeof(void*));
                    248:                arr->sarr_data[idx / arr->sarr_seg] = seg;
                    249:        }
                    250: 
                    251:        pos = idx % arr->sarr_seg;
                    252:        ret = seg[pos];
                    253:        seg[pos] = data;
                    254: 
                    255:        return ret;
                    256: }

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