📄 numhash.c
字号:
/* ==================================================================== * The Kannel Software License, Version 1.0 * * Copyright (c) 2001-2004 Kannel Group * Copyright (c) 1998-2001 WapIT Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Kannel Group (http://www.kannel.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Kannel" and "Kannel Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact org@kannel.org. * * 5. Products derived from this software may not be called "Kannel", * nor may "Kannel" appear in their name, without prior written * permission of the Kannel Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Kannel Group. For more information on * the Kannel Group, please see <http://www.kannel.org/>. * * Portions of this software are based upon software originally written at * WapIT Ltd., Helsinki, Finland for the Kannel project. */ /* * numhash.c * * NUMBER HASH functions * * functions to add a number to database/hash * and functions to retrieve them * * notes: read header file * * Kalle Marjola for project Kannel 1999-2000 */#include <stdlib.h>#include <string.h>#include <ctype.h>#include <errno.h>#include "gwlib/gwlib.h"#include "numhash.h"#define NUMHASH_AUTO_HASH -1/* set of pre-calculated prime numbers for hash generation... */static int primes[] = { 101, 503, 1009, 2003, 3001, 5003, 7001, 10007, 20011, 30011, 40009, 50021, 60013, 70001, 80021, 90001, 100003, 150001, 200003, 300007, 400009, 500009, 600011, 700001, 800011, 900001, 1000003, 1100009, 1200007, 1300021, 1400017, 1500007, 1600033, 1700021, 1800017, 1900009, 2000003, 3000017, 4000037, 5000111, 6000101, 7000127, 8000051, -1};struct numhash_table { struct numhash_number *numbers; long number_total; long table_size; struct numhash_number **hash; long hash_size;}; /* Numhash */struct numhash_number { long key; /* (hopefully) unique key */ struct numhash_number *next; /* next in hash table, if any */};struct nh_entry { Numhash *hash; struct nh_entry *next;}; struct numhashes { struct nh_entry *first; struct nh_entry *last;}; /* Multitable */static int precision = 9; /* the precision (last numbers) used *//* * add new item (number) to hash table */static int add_item(Numhash *table, struct numhash_number *nro){ if (table->hash[nro->key % table->hash_size]) { /* conflict */ struct numhash_number *ptr = table->hash[nro->key % table->hash_size]; if (ptr->key == nro->key) goto duplicate; while(ptr->next) { ptr = ptr->next; if (ptr->key == nro->key) goto duplicate; } ptr->next = nro; /* put as last of the linkage */ } else table->hash[nro->key % table->hash_size] = nro; return 0;duplicate: warning(0, "Duplicate number %ld!", nro->key); return -1; }/* Add a new number to number list and hash * Return 0 if all went ok, -1 if out of room */static int numhash_add_number(Numhash *table, char *nro){ struct numhash_number *newnro; if (table->number_total == table->table_size) { error(0, "Table limit %ld reached, cannot add %s!", table->table_size, nro); return -1; } newnro = &table->numbers[table->number_total++]; /* take the next free */ newnro->key = numhash_get_char_key(nro); newnro->next = NULL; add_item(table, newnro); return 0;}/* Init the number table and hash table with given sizes */static Numhash *numhash_init(int max_numbers, int hash_size){ Numhash *ntable = NULL; ntable = gw_malloc(sizeof(Numhash)); if (hash_size > 0) ntable->hash_size = hash_size; else if (hash_size == NUMHASH_AUTO_HASH) { int i; for(i=0 ; primes[i] > 0; i++) { ntable->hash_size = primes[i]; if (ntable->hash_size > max_numbers) break; } } else { gw_free(ntable); return NULL; } ntable->hash = gw_malloc(ntable->hash_size * sizeof(struct numhash_number *)); memset(ntable->hash, 0, sizeof(struct numhash_number *) * ntable->hash_size); ntable->table_size = max_numbers; ntable->numbers = gw_malloc(ntable->table_size * sizeof(struct numhash_number)); ntable->number_total = 0; /* set our accuracy according to the size of long int * Ok, we call this many times if we use multiple tables, but * that is not a problem... */ if (sizeof(long)>=8) precision = 18; else if (sizeof(long)>=4) precision = 9; return ntable;}/*------------------------------------------------------ * PUBLIC FUNCTIONS */int numhash_find_number(Numhash *table, Octstr *nro){ long key = numhash_get_key(nro); if (key<0) return key; return numhash_find_key(table, key);}int numhash_find_key(Numhash *table, long key){ struct numhash_number *ptr; ptr = table->hash[key % table->hash_size]; while (ptr) { if (ptr->key == key) return 1; ptr = ptr->next; } return 0; /* not found */}long numhash_get_key(Octstr *nro){ long key; if (!nro) return -1; if (octstr_len(nro) > precision) key = atoi(octstr_get_cstr(nro) + octstr_len(nro) -precision); else key = atoi(octstr_get_cstr(nro)); return key;}long numhash_get_char_key(char *nro){ int len; long key; if (!nro) return -1; len = strlen(nro); if (len > precision) key = atoi(nro + len -precision); else key = atoi(nro); return key;}void numhash_destroy(Numhash *table){ if (table == NULL) return; gw_free(table->numbers); gw_free(table->hash); gw_free(table);}double numhash_hash_fill(Numhash *table, int *longest){ int i, l, max = 0, tot = 0; struct numhash_number *ptr; for (i=0; i < table->hash_size; i++) if (table->hash[i]) { tot++; ptr = table->hash[i]; for (l=0; ptr->next; ptr = ptr->next) l++; if (l > max) max = l; } if (longest != NULL) *longest = max; return (double)(tot*100.0/(table->hash_size));}int numhash_size(Numhash *table){ return table->number_total;}Numhash *numhash_create(char *seek_url){ int loc, lines = 0; List *request_headers, *reply_headers; Octstr *url, *final_url, *reply_body; Octstr *type, *charset; unsigned char *data, *ptr, numbuf[100]; int status; Numhash *table; url = octstr_create(seek_url); request_headers = list_create(); status = http_get_real(HTTP_METHOD_GET, url, request_headers, &final_url, &reply_headers, &reply_body); octstr_destroy(url); octstr_destroy(final_url); list_destroy(request_headers, NULL); if (status != HTTP_OK) { http_destroy_headers(reply_headers); octstr_destroy(reply_body); error(0, "Cannot load numhash!"); return NULL; } http_header_get_content_type(reply_headers, &type, &charset); octstr_destroy(charset); http_destroy_headers(reply_headers); if (octstr_str_compare(type, "text/plain") != 0) { octstr_destroy(reply_body); error(0, "Strange content type <%s> for numhash - expecting 'text/plain'" ", operatiom fails", octstr_get_cstr(type)); octstr_destroy(type); return NULL; } octstr_destroy(type); ptr = data = octstr_get_cstr(reply_body); while(*ptr) { if (*ptr == '\n') lines++; ptr++; } debug("numhash", 0, "Total %d lines in %s", lines, seek_url); table = numhash_init(lines+10, NUMHASH_AUTO_HASH); /* automatic hash */ /* now, parse the number information */ lines = 0; while((ptr = strchr(data, '\n'))) { /* each line is ended with linefeed */ *ptr = '\0'; while(*data != '\0' && isspace(*data)) data++; if (*data != '#') { loc = 0; while (*data != '\0') { if (isdigit(*data)) numbuf[loc++] = *data; else if (*data == ' ' || *data == '+' || *data == '-') ; else break; data++; } if (loc) { numbuf[loc] = '\0'; numhash_add_number(table, numbuf); lines++; } else warning(0, "Corrupted line '%s'", data); } data = ptr+1; /* next row... */ } octstr_destroy(reply_body); info(0, "Read from <%s> total of %ld numbers", seek_url, table->number_total); return table;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -