Annotation of libelwix/src/index.c, revision 1.2
1.2 ! misho 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.1.2.3 2022/01/05 23:03:40 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>