File:
[ELWIX - Embedded LightWeight unIX -] /
libaitio /
src /
Attic /
sarray.c
Revision
1.6:
download - view:
text,
annotated -
select for diffs -
revision graph
Thu Mar 29 01:31:34 2012 UTC (12 years, 4 months ago) by
misho
Branches:
MAIN
CVS tags:
io3_1,
io2_8,
io2_7,
io2_6,
IO3_0,
IO2_7,
IO2_6,
IO2_5,
HEAD
version 2.5
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.6 2012/03/29 01:31:34 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, 2012
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: *
52: * @numItems = Number of Items
53: * @segLen = Length of segment
54: * return: NULL error, != NULL allocated memory for array
55: */
56: inline sarr_t *
57: io_sarrInit(int numItems, int segLen)
58: {
59: sarr_t *arr = NULL;
60:
61: if (segLen < 1)
62: return NULL;
63:
64: arr = malloc(sizeof(sarr_t));
65: if (!arr) {
66: LOGERR;
67: return NULL;
68: }
69:
70: arr->sarr_num = numItems;
71: arr->sarr_seg = segLen;
72: arr->sarr_siz = numItems / segLen + 1;
73: arr->sarr_data = calloc(arr->sarr_siz, sizeof(sarr_seg_t));
74: if (!arr->sarr_data) {
75: LOGERR;
76: free(arr);
77: return NULL;
78: } else
79: memset(arr->sarr_data, 0, arr->sarr_siz * sizeof(sarr_seg_t));
80:
81: return arr;
82: }
83:
84: /*
85: * io_sarrDestroy() - Free all data in dynamic split-order array and Destroy array
86: *
87: * @parr = Array
88: * return: none
89: */
90: inline void
91: io_sarrDestroy(sarr_t ** __restrict parr)
92: {
93: register int i;
94:
95: if (!parr || !*parr)
96: return;
97:
98: for (i = 0; i < (*parr)->sarr_siz; i++)
99: if ((*parr)->sarr_data[i]) {
100: free((*parr)->sarr_data[i]);
101: (*parr)->sarr_data[i] = NULL;
102: }
103:
104: if ((*parr)->sarr_data)
105: free((*parr)->sarr_data);
106: free(*parr);
107: *parr = NULL;
108: }
109:
110: /*
111: * io_sarrCopy() Copy source split array to destination split array
112: *
113: * @dest = Destination split array, after use free with io_sarrDestroy()
114: * @src = Source split array
115: * return: -1 error; >0 count of destination split array
116: */
117: int
118: io_sarrCopy(sarr_t ** __restrict dest, sarr_t * __restrict src)
119: {
120: assert(dest);
121: assert(src);
122: if (!dest || !src)
123: return -1;
124:
125: *dest = io_sarrInit(io_sarrSize(src), io_sarrSeg(src));
126: if (!*dest)
127: return -1;
128:
129: memcpy((*dest)->sarr_data, src->sarr_data, (*dest)->sarr_siz * sizeof(sarr_seg_t));
130: return io_sarrSize(*dest);
131: }
132:
133: /*
134: * io_sarrVacuum() - Vacuum dynamic split-order array, empty segments will be freed
135: *
136: * @arr = Array
137: * return: -1 error, >-1 freed segments
138: */
139: int
140: io_sarrVacuum(sarr_t * __restrict arr)
141: {
142: register int i, j;
143: int cx = 0;
144: sarr_seg_t seg;
145:
146: if (!arr)
147: return -1;
148:
149: for (i = 0; i < arr->sarr_siz; i++)
150: if (arr->sarr_data[i]) {
151: for (j = 0, seg = arr->sarr_data[i]; j < arr->sarr_seg; j++)
152: if (seg[j])
153: break;
154: if (j == arr->sarr_seg) {
155: free(arr->sarr_data[i]);
156: arr->sarr_data[i] = NULL;
157: cx++;
158: }
159: }
160:
161: return cx;
162: }
163:
164: /*
165: * io_sarrGrow() - Grow/Shrink dynamic split-order array, Use with care when it shrink!!!
166: *
167: * @arr = Array
168: * @newNumItems = Number of Items
169: * return: -1 error, 0 ok
170: */
171: int
172: io_sarrGrow(sarr_t * __restrict arr, int newNumItems)
173: {
174: sarr_seg_t *data;
175: int seg, n = 0;
176: register int i;
177:
178: if (!arr)
179: return -1;
180:
181: arr->sarr_num = newNumItems;
182: seg = newNumItems / arr->sarr_seg + 1;
183: if (arr->sarr_siz == seg)
184: return n;
185: if (arr->sarr_siz < seg)
186: n = seg - arr->sarr_siz;
187: else
188: for (i = seg; i < arr->sarr_siz; i++)
189: if (arr->sarr_data[i])
190: free(arr->sarr_data[i]);
191:
192: arr->sarr_siz = seg;
193: data = realloc(arr->sarr_data, arr->sarr_siz * sizeof(sarr_seg_t));
194: if (!data) {
195: LOGERR;
196: return -1;
197: } else
198: arr->sarr_data = data;
199: memset(arr->sarr_data + (arr->sarr_siz - n), 0, n * sizeof(sarr_seg_t));
200:
201: return 0;
202: }
203:
204: /*
205: * io_sarrGet() - Get element from dynamic split-order array
206: *
207: * @arr = Array
208: * @idx = Index (warning 1st element is at position 1)
209: * return: NULL not found, !=NULL element
210: */
211: inline void *
212: io_sarrGet(sarr_t * __restrict arr, u_int idx)
213: {
214: void *ret = NULL;
215: sarr_seg_t seg;
216:
217: if (!arr || idx < 1 || arr->sarr_num < idx)
218: return ret;
219:
220: seg = arr->sarr_data[idx / arr->sarr_seg];
221: if (seg)
222: ret = seg[idx % arr->sarr_seg];
223:
224: return ret;
225: }
226:
227: /*
228: * io_sarrGet2() - Always get element from dynamic split-order array
229: * Function automatic grow array. Good use for Hash tables!
230: *
231: * @arr = Array
232: * @idx = Index (warning 1st element is at position 1)
233: * return: NULL not found, !=NULL element
234: */
235: void *
236: io_sarrGet2(sarr_t * __restrict arr, u_int idx)
237: {
238: if (!arr || idx < 1)
239: return NULL;
240: if (arr->sarr_num < idx)
241: if (io_sarrGrow(arr, idx))
242: return NULL;
243: return io_sarrGet(arr, idx);
244: }
245:
246: /*
247: * io_sarrSet() - Set element to dynamic split-order array
248: *
249: * @arr = Array
250: * @idx = Index (warning 1st element is at position 1)
251: * @data = Value
252: * return: NULL error or empty, !=NULL old value in element
253: */
254: inline void *
255: io_sarrSet(sarr_t * __restrict arr, u_int idx, void *data)
256: {
257: void *ret = NULL;
258: sarr_seg_t seg;
259: register int pos;
260:
261: if (!arr || idx < 1 || arr->sarr_num < idx)
262: return ret;
263:
264: seg = arr->sarr_data[idx / arr->sarr_seg];
265: if (!seg) {
266: seg = calloc(arr->sarr_seg, sizeof(void*));
267: if (!seg) {
268: LOGERR;
269: return ret;
270: } else
271: memset(seg, 0, arr->sarr_seg * sizeof(void*));
272: arr->sarr_data[idx / arr->sarr_seg] = seg;
273: }
274:
275: pos = idx % arr->sarr_seg;
276: ret = seg[pos];
277: seg[pos] = data;
278:
279: return ret;
280: }
281:
282: /*
283: * io_sarr2array() - Convert from split-order array to dynamic array
284: *
285: * @sa = split array
286: * @sarrFree = after convert split array !=0 will be destroyed sarray
287: * return: NULL error or != NULL new array
288: */
289: array_t *
290: io_sarr2array(sarr_t ** __restrict sa, int sarrFree)
291: {
292: array_t *arr = NULL;
293: int el;
294: register int i;
295:
296: assert(sa && *sa);
297: if (!sa || !*sa)
298: return NULL;
299:
300: el = io_sarrSize(*sa);
301: arr = io_arrayInit(el);
302: if (!arr)
303: return NULL;
304:
305: for (i = 0; i < el; i++)
306: io_arraySet(arr, i, io_sarrGet(*sa, i + 1));
307:
308: if (sarrFree) {
309: free(*sa);
310: *sa = NULL;
311: }
312: return arr;
313: }
314:
315: /*
316: * io_array2sarr() - Convert from dynamic array to split-order array
317: *
318: * @a = array
319: * @segLen = Length of segment
320: * @arrFree = after convert array !=0 will be destroyed
321: * return: NULL error or != NULL new sarr
322: */
323: sarr_t *
324: io_array2sarr(array_t ** __restrict a, int segLen, int arrFree)
325: {
326: sarr_t *sa = NULL;
327: int el;
328: register int i;
329:
330: assert(a && *a);
331: if (!a || !*a)
332: return NULL;
333:
334: el = io_arraySize(*a);
335: sa = io_sarrInit(el, segLen);
336: if (!sa)
337: return NULL;
338:
339: for (i = 0; i < el; i++)
340: io_sarrSet(sa, i + 1, io_arrayGet(*a, i));
341:
342: if (arrFree) {
343: free(*a);
344: *a = NULL;
345: }
346: return sa;
347: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>