[PATCH] Increase Numhash precision

Alexander Malysh <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
Hi list,

attached patch increase Numhash precision from 9,18 to 19,38 on  
32,64bit respectively.
This is possible by using C99 standard type long long.

Please review and vote.

Thanks,
Alex
numhash-long-long.patch (application/octet-stream, 7.4 KB)
diff --git a/gw/numhash.c b/gw/numhash.c
index 9e1eec6..196c0cb 100644
--- a/gw/numhash.c
+++ b/gw/numhash.c
@@ -98,7 +98,7 @@ struct numhash_table {
 };	/* Numhash */
 
 struct numhash_number {
-  long			key;		/* (hopefully) unique key */
+  long long			key;		/* (hopefully) unique key */
   struct numhash_number	*next;		/* next in hash table, if any */
 };
 
@@ -114,7 +114,7 @@ struct numhashes {
 };	/* Multitable */
 
 
-static int	precision = 9;		/* the precision (last numbers) used */
+static int	precision = 19;		/* the precision (last numbers) used */
 
 /*
  * add new item (number) to hash table
@@ -139,8 +139,8 @@ static int add_item(Numhash *table, struct numhash_number *nro)
     return 0;
 
 duplicate:
-    warning(0, "Duplicate number %ld!", nro->key); 
-    return -1;	
+    warning(0, "Duplicate number %lld!", nro->key);
+    return -1;
 }
 
 /* Add a new number to number list and hash
@@ -156,12 +156,12 @@ static int numhash_add_number(Numhash *table, char *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;
 }
 
@@ -173,7 +173,7 @@ 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) {
@@ -194,13 +194,15 @@ static Numhash *numhash_init(int max_numbers, int hash_size)
     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;
+    if (sizeof(long long) >= 16)
+        precision = 38;
+    else if (sizeof(long long) >= 8)
+        precision = 19;
 
     return ntable;
 }
@@ -215,14 +217,14 @@ static Numhash *numhash_init(int max_numbers, int hash_size)
 
 int numhash_find_number(Numhash *table, Octstr *nro)
 {
-    long key = numhash_get_key(nro);
+    long 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)
+int numhash_find_key(Numhash *table, long long key)
 {
     struct numhash_number *ptr;
 
@@ -236,31 +238,34 @@ int numhash_find_key(Numhash *table, long key)
 
 
 
-long numhash_get_key(Octstr *nro)
+long long numhash_get_key(Octstr *nro)
 {
-    long key;
+    long long key;
+
     if (!nro) return -1;
-  
+
     if (octstr_len(nro) > precision)
-	key = atoi(octstr_get_cstr(nro) + octstr_len(nro) -precision);
+        key = strtoll(octstr_get_cstr(nro) + octstr_len(nro) - precision, (char**) NULL, 10);
     else
-	key = atoi(octstr_get_cstr(nro));
+        key = strtoll(octstr_get_cstr(nro), (char**) NULL, 10);
 
     return key;
 }
 
 
-long numhash_get_char_key(char *nro)
+long long numhash_get_char_key(char *nro)
 {
     int len;
-    long key;
+    long long key;
+
     if (!nro) return -1;
+
     len = strlen(nro);
-    
+
     if (len > precision)
-	key = atoi(nro + len -precision);
+        key = strtoll(nro + len - precision, (char**) NULL, 10);
     else
-	key = atoi(nro);
+        key = strtoll(nro, (char**) NULL, 10);
 
     return key;
 }
@@ -284,7 +289,7 @@ double numhash_hash_fill(Numhash *table, int *longest)
     for (i=0; i < table->hash_size; i++)
 	if (table->hash[i]) {
 	    tot++;
-	    ptr = table->hash[i]; 
+	    ptr = table->hash[i];
 	    for (l=0; ptr->next; ptr = ptr->next)
 		l++;
 	    if (l > max)
@@ -304,24 +309,24 @@ int numhash_size(Numhash *table)
 }
 
 
-Numhash *numhash_create(char *seek_url)
+Numhash *numhash_create(const char *seek_url)
 {
     int		loc, lines = 0;
     List	*request_headers, *reply_headers;
     Octstr	*url, *final_url, *reply_body;
     Octstr	*type, *charset;
-    
-    char    *data, *ptr, numbuf[100];
+
+    char *data, *ptr, numbuf[100];
     int		status;
     Numhash	*table;
 
     url = octstr_create(seek_url);
-    request_headers = gwlist_create();
+    request_headers = http_create_empty_headers();
     status = http_get_real(HTTP_METHOD_GET, url, request_headers, &final_url,
 			    &reply_headers, &reply_body);
     octstr_destroy(url);
     octstr_destroy(final_url);
-    gwlist_destroy(request_headers, NULL);
+    http_destroy_headers(request_headers);
 
     if (status != HTTP_OK) {
 	http_destroy_headers(reply_headers);
@@ -332,7 +337,7 @@ Numhash *numhash_create(char *seek_url)
     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'"
@@ -341,7 +346,7 @@ Numhash *numhash_create(char *seek_url)
         return NULL;
     }
     octstr_destroy(type);
-    
+
     ptr = data = octstr_get_cstr(reply_body);
     while(*ptr) {
 	if (*ptr == '\n') lines++;
@@ -354,7 +359,7 @@ Numhash *numhash_create(char *seek_url)
     /* 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))
@@ -379,7 +384,7 @@ Numhash *numhash_create(char *seek_url)
 	}
 	data = ptr+1;	/* next row... */
     }
-    octstr_destroy(reply_body); 
+    octstr_destroy(reply_body);
 
     info(0, "Read from <%s> total of %ld numbers", seek_url, table->number_total);
     return table;
diff --git a/gw/numhash.h b/gw/numhash.h
index 5f7cc1b..944c843 100644
--- a/gw/numhash.h
+++ b/gw/numhash.h
@@ -61,10 +61,10 @@
  *
  * !!! NOTE NOTE NOTE !!!
  *
- * Phone number precision is limited according to sizeof(long)
+ * Phone number precision is limited according to sizeof(long long)
  * in host machine. that is usually either 32 or 64 bits. In a
- * case of 32 bit longs, only last 9 digits are checked, otherwise
- * last 18 digits. This means that in some places several numbers
+ * case of 32 bit longs, only last 19 digits are checked, otherwise
+ * last 38 digits. This means that in some places several numbers
  * might map to same hash entry, and thus some caution is needed
  * specially with telephone number black lists
  *
@@ -74,7 +74,7 @@
  *
  * MEMORY NEEDED:  (approximated)
  *
- * 2* (sizeof(long)+sizeof(void *)) bytes per number
+ * 2* (sizeof(long long)+sizeof(void *)) bytes per number
  */
 
 #ifndef NUMHASH_H
@@ -108,7 +108,7 @@ typedef struct numhash_table Numhash;
  *  +358 40 1234
  *  +358 40-1234 : Kalle Marjola
  */
-Numhash *numhash_create(char *url); 
+Numhash *numhash_create(const char *url); 
 
 /* destroy hash and all numbers in it */
 void numhash_destroy(Numhash *table);
@@ -118,11 +118,11 @@ void numhash_destroy(Numhash *table);
 int numhash_find_number(Numhash *table, Octstr *nro);
 				      
 /* if we already have the key */
-int numhash_find_key(Numhash *table, long key);		
+int numhash_find_key(Numhash *table, long long key);
 
 /* if we want to know the key */
-long numhash_get_key(Octstr *nro);
-long numhash_get_char_key(char *nro);
+long long numhash_get_key(Octstr *nro);
+long long numhash_get_char_key(char *nro);
 
 
 /* Return hash fill percent. If 'longest' != NULL, set as longest
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.