Annotation of libaitio/src/sarray.c, revision 1.4.2.2
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 $
1.4.2.2 ! misho 6: * $Id: sarray.c,v 1.4.2.1 2011/08/31 12:29:32 misho Exp $
1.3 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:
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:
1.4 misho 93: if (!parr || !*parr)
1.2 misho 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: /*
1.4.2.2 ! misho 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: /*
1.2 misho 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: assert(arr);
143: if (!arr)
144: return -1;
145:
146: for (i = 0; i < arr->sarr_siz; i++)
147: if (arr->sarr_data[i]) {
148: for (j = 0, seg = arr->sarr_data[i]; j < arr->sarr_seg; j++)
149: if (seg[j])
150: break;
151: if (j == arr->sarr_seg) {
152: free(arr->sarr_data[i]);
153: arr->sarr_data[i] = NULL;
154: cx++;
155: }
156: }
157:
158: return cx;
159: }
160:
161: /*
162: * io_sarrGrow() - Grow/Shrink dynamic split-order array, Use with care when it shrink!!!
163: * @arr = Array
164: * @newNumItems = Number of Items
165: * return: -1 error, 0 ok
166: */
167: int
168: io_sarrGrow(sarr_t * __restrict arr, int newNumItems)
169: {
170: sarr_seg_t *data;
171: int seg, n = 0;
172: register int i;
173:
174: assert(arr);
175: if (!arr)
176: return -1;
177:
178: arr->sarr_num = newNumItems;
179: seg = newNumItems / arr->sarr_seg + 1;
180: if (arr->sarr_siz == seg)
181: return n;
182: if (arr->sarr_siz < seg)
183: n = seg - arr->sarr_siz;
184: else
185: for (i = seg; i < arr->sarr_siz; i++)
186: if (arr->sarr_data[i])
187: free(arr->sarr_data[i]);
188:
189: arr->sarr_siz = seg;
190: data = realloc(arr->sarr_data, arr->sarr_siz * sizeof(sarr_seg_t));
191: if (!data) {
192: LOGERR;
193: return -1;
194: } else
195: arr->sarr_data = data;
196: memset(arr->sarr_data + (arr->sarr_siz - n), 0, n * sizeof(sarr_seg_t));
197:
198: return 0;
199: }
200:
201: /*
202: * io_sarrGet() - Get element from dynamic split-order array
203: * @arr = Array
204: * @idx = Index (warning 1st element is at position 1)
205: * return: NULL not found, !=NULL element
206: */
207: inline void *
208: io_sarrGet(sarr_t * __restrict arr, u_int idx)
209: {
210: void *ret = NULL;
211: sarr_seg_t seg;
212:
213: assert(arr);
214: if (!arr || idx < 1 || arr->sarr_num < idx)
215: return ret;
216:
217: seg = arr->sarr_data[idx / arr->sarr_seg];
218: if (seg)
219: ret = seg[idx % arr->sarr_seg];
220:
221: return ret;
222: }
223:
224: /*
225: * io_sarrGet2() - Always get element from dynamic split-order array
226: * Function automatic grow array. Good use for Hash tables!
227: * @arr = Array
228: * @idx = Index (warning 1st element is at position 1)
229: * return: NULL not found, !=NULL element
230: */
231: void *
232: io_sarrGet2(sarr_t * __restrict arr, u_int idx)
233: {
234: assert(arr);
235: if (!arr || idx < 1)
236: return NULL;
237: if (arr->sarr_num < idx)
238: if (io_sarrGrow(arr, idx))
239: return NULL;
240: return io_sarrGet(arr, idx);
241: }
242:
243: /*
244: * io_sarrSet() - Set element to dynamic split-order array
245: * @arr = Array
246: * @idx = Index (warning 1st element is at position 1)
247: * @data = Value
248: * return: NULL error or empty, !=NULL old value in element
249: */
250: inline void *
251: io_sarrSet(sarr_t * __restrict arr, u_int idx, void *data)
252: {
253: void *ret = NULL;
254: sarr_seg_t seg;
255: register int pos;
256:
257: assert(arr);
258: if (!arr || idx < 1 || arr->sarr_num < idx)
259: return ret;
260:
261: seg = arr->sarr_data[idx / arr->sarr_seg];
262: if (!seg) {
263: seg = calloc(arr->sarr_seg, sizeof(void*));
264: if (!seg) {
265: LOGERR;
266: return ret;
267: } else
268: memset(seg, 0, arr->sarr_seg * sizeof(void*));
269: arr->sarr_data[idx / arr->sarr_seg] = seg;
270: }
271:
272: pos = idx % arr->sarr_seg;
273: ret = seg[pos];
274: seg[pos] = data;
275:
276: return ret;
277: }
1.4 misho 278:
279: /*
280: * io_sarr2array() - Convert from split-order array to dynamic array
281: * @sa = split array
282: * @sarrFree = after convert split array !=0 will be destroyed sarray
283: * return: NULL error or != NULL new array
284: */
285: array_t *
286: io_sarr2array(sarr_t ** __restrict sa, int sarrFree)
287: {
288: array_t *arr = NULL;
289: int el;
290: register int i;
291:
292: assert(sa && *sa);
293: if (!sa || !*sa)
294: return NULL;
295:
296: el = io_sarrSize(*sa);
297: arr = io_arrayInit(el);
298: if (!arr)
299: return NULL;
300:
301: for (i = 0; i < el; i++)
302: io_arraySet(arr, i, io_sarrGet(*sa, i + 1));
303:
304: if (sarrFree) {
305: free(*sa);
306: *sa = NULL;
307: }
308: return arr;
309: }
310:
311: /*
312: * io_array2sarr() - Convert from dynamic array to split-order array
313: * @a = array
314: * @segLen = Length of segment
315: * @arrFree = after convert array !=0 will be destroyed
316: * return: NULL error or != NULL new sarr
317: */
318: sarr_t *
319: io_array2sarr(array_t ** __restrict a, int segLen, int arrFree)
320: {
321: sarr_t *sa = NULL;
322: int el;
323: register int i;
324:
325: assert(a && *a);
326: if (!a || !*a)
327: return NULL;
328:
329: el = io_arraySize(*a);
330: sa = io_sarrInit(el, segLen);
331: if (!sa)
332: return NULL;
333:
334: for (i = 0; i < el; i++)
335: io_sarrSet(sa, i + 1, io_arrayGet(*a, i));
336:
337: if (arrFree) {
338: free(*a);
339: *a = NULL;
340: }
341: return sa;
342: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>