File:
[ELWIX - Embedded LightWeight unIX -] /
libelwix /
src /
index.c
Revision
1.2:
download - view:
text,
annotated -
select for diffs -
revision graph
Thu Jan 6 15:13:01 2022 UTC (2 years, 8 months ago) by
misho
Branches:
MAIN
CVS tags:
elwix6_1,
elwix5_9,
elwix5_8,
elwix5_7,
elwix5_6,
elwix5_5,
elwix5_4,
elwix5_3,
elwix5_2,
elwix5_12,
elwix5_11,
elwix5_10,
elwix5_1,
HEAD,
ELWIX6_0,
ELWIX5_9,
ELWIX5_8,
ELWIX5_7,
ELWIX5_6,
ELWIX5_5,
ELWIX5_4,
ELWIX5_3,
ELWIX5_2,
ELWIX5_11,
ELWIX5_10,
ELWIX5_1,
ELWIX5_0
Version 5.0
1: /*************************************************************************
2: * (C) 2022 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
3: * by Michael Pounov <misho@elwix.org>
4: *
5: * $Author: misho $
6: * $Id: index.c,v 1.2 2022/01/06 15:13:01 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 - 2022
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: * index_Init() - Init index structure
51: *
52: * @idx = index, if it is NULL then it will be allocate
53: * return: NULL is error and !=NULL index ready for use
54: */
55: index_t *
56: index_Init(index_t * __restrict idx)
57: {
58: if (!idx) {
59: idx = e_malloc(sizeof(index_t));
60: if (!idx)
61: return NULL;
62: }
63: memset(idx, 0, sizeof(index_t));
64:
65: return idx;
66: }
67:
68: static inline void
69: index_FreeList(index_list_t __restrict lst)
70: {
71: index_list_t n, l = lst;
72:
73: while (l) {
74: n = l->il_next;
75: e_free(l);
76: l = n;
77: }
78: }
79:
80: /*
81: * index_FreeLists() - Free linked lists with data
82: *
83: * @idx = index
84: * return: none
85: */
86: void
87: index_FreeLists(index_t *idx)
88: {
89: register int i;
90:
91: for (i = 0; i < 65536; i++)
92: index_FreeList(idx->i_hash[i]);
93: memset(idx->i_hash, 0, sizeof idx->i_hash);
94: }
95:
96: /*
97: * index_Destroy() - Destroy index
98: *
99: * @idx = index
100: * return: none
101: */
102: void
103: index_Destroy(index_t **idx)
104: {
105: if (idx && *idx) {
106: index_FreeLists(*idx);
107: e_free(*idx);
108: *idx = NULL;
109: }
110: }
111:
112: /*
113: * index_getArray() - Get list behind key into array
114: *
115: * @idx = index
116: * @key = Hash value
117: * return: NULL is error and !=NULL allocated array. It must be free after use
118: */
119: array_t *
120: index_getArray(index_t *idx, u_short key)
121: {
122: array_t *arr = NULL;
123: index_list_t lst;
124: register int n = 0;
125:
126: if (!idx)
127: return NULL;
128:
129: for (n = 0, lst = index_getList(idx, key); lst; n++, lst = lst->il_next);
130: arr = array_Init(n);
131: if (!arr)
132: return NULL;
133: for (n = 0, lst = index_getList(idx, key); lst; n++, lst = lst->il_next)
134: array_Set(arr, n, lst);
135:
136: return arr;
137: }
138:
139: /*
140: * index_add() - Adds item to index hash
141: *
142: * @idx = index
143: * @key = hash key
144: * @data = data
145: * @datlen = data length
146: * @hash = return calculated hash of data
147: * return: -1 error or 0 ok
148: */
149: int
150: index_add(index_t *idx, u_short key, void *data, int datlen, u_int *hash)
151: {
152: index_list_t lst, item;
153:
154: if (!idx || !data)
155: return -1;
156:
157: item = e_malloc(sizeof(struct tagIndexList));
158: if (!item)
159: return -1;
160: else
161: memset(item, 0, sizeof(struct tagIndexList));
162:
163: lst = idx->i_hash[key];
164:
165: item->il_hash = crcAdler(data, datlen);
166: item->il_ptr = data;
167: item->il_len = datlen;
168: item->il_next = lst;
169: idx->i_hash[key] = item;
170:
171: if (hash)
172: *hash = item->il_hash;
173:
174: return 0;
175: }
176:
177: /*
178: * index_del() - Dels item from index hash
179: *
180: * @idx = index
181: * @key = hash key
182: * @data = data
183: * @datlen = data length
184: * return: -1 error, 0 nothing deleted and 1 item deleted
185: */
186: int
187: index_del(index_t *idx, u_short key, void *data, int datlen)
188: {
189: index_list_t lst, prev;
190: u_int hash;
191:
192: if (!idx || !data)
193: return -1;
194:
195: lst = idx->i_hash[key];
196: if (!lst)
197: return 0;
198:
199: hash = crcAdler(data, datlen);
200:
201: if (lst->il_len == datlen && lst->il_hash == hash) {
202: idx->i_hash[key] = lst->il_next;
203: e_free(lst);
204: return 1; /* deleted item */
205: } else {
206: prev = lst;
207: lst = lst->il_next;
208: }
209: while (lst) {
210: if (lst->il_len == datlen && lst->il_hash == hash) {
211: prev->il_next = lst->il_next;
212: e_free(lst);
213: return 1; /* deleted item */
214: } else {
215: prev = lst;
216: lst = lst->il_next;
217: }
218: }
219:
220: return 0;
221: }
222:
223: /*
224: * index_delList() - Delete list behind key
225: *
226: * @idx = index
227: * @key = Hash value
228: * return: -1 is error and 0 is ok
229: */
230: int
231: index_delList(index_t *idx, u_short key)
232: {
233: if (!idx)
234: return -1;
235:
236: index_FreeList(idx->i_hash[key]);
237: idx->i_hash[key] = NULL;
238: return 0;
239: }
240:
241: /*
242: * index_del2() - Dels item with index key and hash
243: *
244: * @idx = index
245: * @key = hash key
246: * @hash = calculated hash of item when its added to index
247: * return: -1 error, 0 nothing deleted and 1 item deleted
248: */
249: int
250: index_del2(index_t *idx, u_short key, u_int hash)
251: {
252: index_list_t lst, prev;
253:
254: if (!idx)
255: return -1;
256:
257: lst = idx->i_hash[key];
258: if (!lst)
259: return 0;
260:
261: if (lst->il_hash == hash) {
262: idx->i_hash[key] = lst->il_next;
263: e_free(lst);
264: return 1; /* deleted item */
265: } else {
266: prev = lst;
267: lst = lst->il_next;
268: }
269: while (lst) {
270: if (lst->il_hash == hash) {
271: prev->il_next = lst->il_next;
272: e_free(lst);
273: return 1; /* deleted item */
274: } else {
275: prev = lst;
276: lst = lst->il_next;
277: }
278: }
279:
280: return 0;
281: }
282:
283: /*
284: * index_get2() - Get item by key and hash
285: *
286: * @idx = index
287: * @key = hash key
288: * @hash = calculated hash of item when its added to index
289: * return: NULL error or not found and !=NULL returned item
290: */
291: index_list_t
292: index_get2(index_t *idx, u_short key, u_int hash)
293: {
294: index_list_t lst;
295:
296: if (!idx)
297: return NULL;
298:
299: lst = idx->i_hash[key];
300: if (!lst)
301: return NULL;
302:
303: while (lst)
304: if (lst->il_hash == hash)
305: break; /* found */
306: else
307: lst = lst->il_next;
308:
309: return lst;
310: }
311:
312: /*
313: * index_getVar() - Get item by key and hash as Var
314: *
315: * @idx = index
316: * @key = hash key
317: * @hash = calculated hash of item when its added to index
318: * return: NULL error or not found and !=NULL returned variable. Must be free after use!
319: */
320: ait_val_t *
321: index_getVar(index_t *idx, u_short key, u_int hash)
322: {
323: index_list_t lst;
324: ait_val_t *v = NULL;
325:
326: lst = index_get2(idx, key, hash);
327: if (!lst)
328: return NULL;
329:
330: v = ait_allocVar();
331: if (!v)
332: return NULL;
333:
334: AIT_SET_PTR(v, lst->il_ptr, lst->il_len);
335: return v;
336: }
337:
338: /*
339: * index_dump() - Debug routine about index hashes
340: *
341: * @idx = index
342: * return: none
343: */
344: void
345: index_dump(index_t *idx)
346: {
347: index_list_t lst;
348: register int i;
349:
350: for (i = 0; i < 65536; i++) {
351: lst = idx->i_hash[i];
352: while (lst) {
353: printf("index[%hu/0x%x]=%s length=%lu\n", (u_short) i, index_Hash(lst),
354: (const char*) index_Ptr(lst), index_Len(lst));
355: lst = lst->il_next;
356: }
357: }
358: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>