[asterisk-commits] murf: branch group/newcdr r74474 - in /team/group/newcdr: apps/ cel/ channels...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jul 10 15:50:08 CDT 2007


Author: murf
Date: Tue Jul 10 15:50:07 2007
New Revision: 74474

URL: http://svn.digium.com/view/asterisk?view=rev&rev=74474
Log:
Brought this back up to date; compiles again; some event_subscribe calls were added and needed to be updated, and localtime calls updated, mainly. Some bad formatting fixed. A few files were forgotten to be added. Some .h files seem to have been added to trunk, but were not rightly handled somehow by svn.

Added:
    team/group/newcdr/channels/busy.h   (with props)
    team/group/newcdr/channels/ringtone.h   (with props)
    team/group/newcdr/include/asterisk/hashtab.h   (with props)
    team/group/newcdr/main/hashtab.c   (with props)
Modified:
    team/group/newcdr/apps/app_queue.c
    team/group/newcdr/cel/cel_csv.c
    team/group/newcdr/cel/cel_manager.c
    team/group/newcdr/cel/cel_odbc.c
    team/group/newcdr/cel/cel_pgsql.c
    team/group/newcdr/cel/cel_radius.c
    team/group/newcdr/cel/cel_sqlite.c
    team/group/newcdr/cel/cel_tds.c
    team/group/newcdr/main/cel.c
    team/group/newcdr/main/pbx.c

Modified: team/group/newcdr/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/group/newcdr/apps/app_queue.c?view=diff&rev=74474&r1=74473&r2=74474
==============================================================================
--- team/group/newcdr/apps/app_queue.c (original)
+++ team/group/newcdr/apps/app_queue.c Tue Jul 10 15:50:07 2007
@@ -4832,7 +4832,7 @@
 	res |= ast_custom_function_register(&queuemembercount_function);
 	res |= ast_custom_function_register(&queuememberlist_function);
 	res |= ast_custom_function_register(&queuewaitingcount_function);
-	if (!(device_state_sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE, device_state_cb, NULL, AST_EVENT_IE_END)))
+	if (!(device_state_sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE, device_state_cb, "AppQueue Device state", NULL, AST_EVENT_IE_END)))
 		res = -1;
 
 	return res ? AST_MODULE_LOAD_DECLINE : 0;

Modified: team/group/newcdr/cel/cel_csv.c
URL: http://svn.digium.com/view/asterisk/team/group/newcdr/cel/cel_csv.c?view=diff&rev=74474&r1=74473&r2=74474
==============================================================================
--- team/group/newcdr/cel/cel_csv.c (original)
+++ team/group/newcdr/cel/cel_csv.c Tue Jul 10 15:50:07 2007
@@ -193,7 +193,7 @@
 	if (usegmtime) {
 		gmtime_r(&t,&tm);
 	} else {
-		localtime_r(&t,&tm);
+		ast_localtime(&t,&tm,NULL);
 	}
 	strftime(tmp, sizeof(tmp), DATE_FORMAT, &tm);
 	return append_string(buf, tmp, bufsize);

Modified: team/group/newcdr/cel/cel_manager.c
URL: http://svn.digium.com/view/asterisk/team/group/newcdr/cel/cel_manager.c?view=diff&rev=74474&r1=74473&r2=74474
==============================================================================
--- team/group/newcdr/cel/cel_manager.c (original)
+++ team/group/newcdr/cel/cel_manager.c Tue Jul 10 15:50:07 2007
@@ -126,7 +126,7 @@
 	peer = ast_event_get_ie_str(event, AST_EVENT_IE_CEL_PEER);
 
 	t = eventtime;
-	localtime_r(&t, &timeresult);
+	ast_localtime(&t, &timeresult,NULL);
 	strftime(strStartTime, sizeof(strStartTime), DATE_FORMAT, &timeresult);
 	
 	manager_event(EVENT_FLAG_CALL, "CEL",

Modified: team/group/newcdr/cel/cel_odbc.c
URL: http://svn.digium.com/view/asterisk/team/group/newcdr/cel/cel_odbc.c?view=diff&rev=74474&r1=74473&r2=74474
==============================================================================
--- team/group/newcdr/cel/cel_odbc.c (original)
+++ team/group/newcdr/cel/cel_odbc.c Tue Jul 10 15:50:07 2007
@@ -129,7 +129,7 @@
 	if (usegmtime) 
 		gmtime_r(&eventtime,&tm);
 	else
-		localtime_r(&eventtime,&tm);
+		ast_localtime(&eventtime,&tm,NULL);
 
 	ast_mutex_lock(&odbc_lock);
 	strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);

Modified: team/group/newcdr/cel/cel_pgsql.c
URL: http://svn.digium.com/view/asterisk/team/group/newcdr/cel/cel_pgsql.c?view=diff&rev=74474&r1=74473&r2=74474
==============================================================================
--- team/group/newcdr/cel/cel_pgsql.c (original)
+++ team/group/newcdr/cel/cel_pgsql.c Tue Jul 10 15:50:07 2007
@@ -113,7 +113,7 @@
 
 	ast_mutex_lock(&pgsql_lock);
 
-	localtime_r(&eventtime,&tm);
+	ast_localtime(&eventtime,&tm,NULL);
 	strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
 
 	if ((!connected) && pghostname && pgdbuser && pgpassword && pgdbname) {

Modified: team/group/newcdr/cel/cel_radius.c
URL: http://svn.digium.com/view/asterisk/team/group/newcdr/cel/cel_radius.c?view=diff&rev=74474&r1=74473&r2=74474
==============================================================================
--- team/group/newcdr/cel/cel_radius.c (original)
+++ team/group/newcdr/cel/cel_radius.c Tue Jul 10 15:50:07 2007
@@ -156,7 +156,7 @@
 	if (ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME))
 		gmtime_r(&(eventtime), &tm);
 	else
-		localtime_r(&(eventtime), &tm);
+		ast_localtime(&(eventtime), &tm, NULL);
 	strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
 	if (!rc_avpair_add(rh, send, PW_AST_EVENT_TIME, timestr, strlen(timestr), VENDOR_CODE))
 		return -1;

Modified: team/group/newcdr/cel/cel_sqlite.c
URL: http://svn.digium.com/view/asterisk/team/group/newcdr/cel/cel_sqlite.c?view=diff&rev=74474&r1=74473&r2=74474
==============================================================================
--- team/group/newcdr/cel/cel_sqlite.c (original)
+++ team/group/newcdr/cel/cel_sqlite.c Tue Jul 10 15:50:07 2007
@@ -131,7 +131,7 @@
 	ast_mutex_lock(&sqlite_lock);
 
 	t = eventtime;
-	localtime_r(&t, &tm);
+	ast_localtime(&t, &tm, NULL);
 	strftime(startstr, sizeof(startstr), DATE_FORMAT, &tm);
 
 	for(count=0; count<5; count++) {

Modified: team/group/newcdr/cel/cel_tds.c
URL: http://svn.digium.com/view/asterisk/team/group/newcdr/cel/cel_tds.c?view=diff&rev=74474&r1=74473&r2=74474
==============================================================================
--- team/group/newcdr/cel/cel_tds.c (original)
+++ team/group/newcdr/cel/cel_tds.c Tue Jul 10 15:50:07 2007
@@ -321,7 +321,7 @@
 	/* To make sure we have date variable if not insert null to SQL */
 	if (t!=0)
 	{
-		localtime_r(&t, &tm);
+		ast_localtime(&t, &tm, NULL);
 		strftime(buf, 80, DATE_FORMAT, &tm);
 		sprintf(dateField, "'%s'", buf);
 	}

Added: team/group/newcdr/channels/busy.h
URL: http://svn.digium.com/view/asterisk/team/group/newcdr/channels/busy.h?view=auto&rev=74474
==============================================================================
--- team/group/newcdr/channels/busy.h (added)
+++ team/group/newcdr/channels/busy.h Tue Jul 10 15:50:07 2007
@@ -1,0 +1,55 @@
+/* busy.h: Generated from frequencies 480 and 620 
+   by gentone.  400 samples  */
+static short busy[400] = {
+	    0, 13697, 24766, 31109, 31585, 26222, 16198,  3569, 
+	-9162, -19575, -25812, -26935, -23069, -15322, -5493,  4339, 
+	12277, 16985, 17934, 15440, 10519,  4585,  -908, -4827, 
+	-6592, -6269, -4489, -2220,  -467,    30,  -983, -3203, 
+	-5839, -7844, -8215, -6301, -2035,  3975, 10543, 16141, 
+	19260, 18787, 14322,  6338, -3845, -14296, -22858, -27611, 
+	-27309, -21691, -11585,  1213, 14285, 25068, 31388, 31915, 
+	26457, 16010,  2568, -11282, -22885, -30054, -31509, -27120, 
+	-17908, -5805,  6760, 17379, 24147, 26028, 23020, 16094, 
+	 6931, -2478, -10279, -15136, -16474, -14538, -10253, -4949, 
+	    0,  3515,  5052,  4688,  3045,  1069,  -268,  -272, 
+	 1269,  3996,  7067,  9381,  9889,  7910,  3365, -3123, 
+	-10320, -16622, -20424, -20510, -16384, -8448,  2006, 13026, 
+	22383, 28040, 28613, 23696, 13996,  1232, -12193, -23670, 
+	-30918, -32459, -27935, -18190, -5103,  8795, 20838, 28764, 
+	31164, 27753, 19395,  7893, -4412, -15136, -22342, -24909, 
+	-22717, -16609, -8143,   780,  8361, 13272, 14909, 13455, 
+	 9758,  5067,   678, -2387, -3624, -3133, -1538,   224, 
+	 1209,   751, -1315, -4580, -8145, -10848, -11585, -9628, 
+	-4878,  2038,  9844, 16867, 21403, 22124, 18429, 10638, 
+	    0, -11524, -21643, -28211, -29702, -25561, -16364, -3737, 
+	 9946, 22044, 30180, 32733, 29182, 20210,  7573, -6269, 
+	-18655, -27259, -30558, -28117, -20645, -9807,  2148, 12878, 
+	20426, 23599, 22173, 16865,  9117,   731, -6552, -11426, 
+	-13269, -12216, -9050, -4941, -1118,  1460,  2335,  1635, 
+	    0, -1635, -2335, -1460,  1118,  4941,  9050, 12216, 
+	13269, 11426,  6552,  -731, -9117, -16865, -22173, -23599, 
+	-20426, -12878, -2148,  9807, 20645, 28117, 30558, 27259, 
+	18655,  6269, -7573, -20210, -29182, -32733, -30180, -22044, 
+	-9946,  3737, 16364, 25561, 29702, 28211, 21643, 11524, 
+	    0, -10638, -18429, -22124, -21403, -16867, -9844, -2038, 
+	 4878,  9628, 11585, 10848,  8145,  4580,  1315,  -751, 
+	-1209,  -224,  1538,  3133,  3624,  2387,  -678, -5067, 
+	-9758, -13455, -14909, -13272, -8361,  -780,  8143, 16609, 
+	22717, 24909, 22342, 15136,  4412, -7893, -19395, -27753, 
+	-31164, -28764, -20838, -8795,  5103, 18190, 27935, 32459, 
+	30918, 23670, 12193, -1232, -13996, -23696, -28613, -28040, 
+	-22383, -13026, -2006,  8448, 16384, 20510, 20424, 16622, 
+	10320,  3123, -3365, -7910, -9889, -9381, -7067, -3996, 
+	-1269,   272,   268, -1069, -3045, -4688, -5052, -3515, 
+	    0,  4949, 10253, 14538, 16474, 15136, 10279,  2478, 
+	-6931, -16094, -23020, -26028, -24147, -17379, -6760,  5805, 
+	17908, 27120, 31509, 30054, 22885, 11282, -2568, -16010, 
+	-26457, -31915, -31388, -25068, -14285, -1213, 11585, 21691, 
+	27309, 27611, 22858, 14296,  3845, -6338, -14322, -18787, 
+	-19260, -16141, -10543, -3975,  2035,  6301,  8215,  7844, 
+	 5839,  3203,   983,   -30,   467,  2220,  4489,  6269, 
+	 6592,  4827,   908, -4585, -10519, -15440, -17934, -16985, 
+	-12277, -4339,  5493, 15322, 23069, 26935, 25812, 19575, 
+	 9162, -3569, -16198, -26222, -31585, -31109, -24766, -13697, 
+	
+};

Propchange: team/group/newcdr/channels/busy.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/group/newcdr/channels/busy.h
------------------------------------------------------------------------------
    svn:keywords = Author Id Date Revision

Propchange: team/group/newcdr/channels/busy.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: team/group/newcdr/channels/ringtone.h
URL: http://svn.digium.com/view/asterisk/team/group/newcdr/channels/ringtone.h?view=auto&rev=74474
==============================================================================
--- team/group/newcdr/channels/ringtone.h (added)
+++ team/group/newcdr/channels/ringtone.h Tue Jul 10 15:50:07 2007
@@ -1,0 +1,30 @@
+/* ringtone.h: Generated from frequencies 440 and 480 
+   by gentone.  200 samples  */
+static short ringtone[200] = {
+	    0, 11581, 21659, 28927, 32445, 31764, 26981, 18727, 
+	 8084, -3559, -14693, -23875, -29927, -32083, -30088, -24228, 
+	-15290, -4453,  6864, 17195, 25212, 29902, 30693, 27526, 
+	20856, 11585,   944, -9673, -18899, -25560, -28837, -28357, 
+	-24244, -17089, -7868,  2192, 11780, 19667, 24872, 26779, 
+	25212, 20450, 13179,  4396, -4731, -13019, -19421, -23164, 
+	-23839, -21446, -16384, -9384, -1408,  6484, 13281, 18145, 
+	20517, 20182, 17286, 12301,  5951,  -887, -7314, -12519, 
+	-15886, -17068, -16017, -12983, -8458, -3109,  2327,  7142, 
+	10750, 12757, 13007, 11585,  8793,  5095,  1044, -2800, 
+	-5951, -8053, -8921, -8560, -7141, -4967, -2421,   104, 
+	 2260,  3791,  4567,  4589,  3977,  2941,  1733,   600, 
+	 -257,  -722,  -772,  -481,     0,   481,   772,   722, 
+	  257,  -600, -1733, -2941, -3977, -4589, -4567, -3791, 
+	-2260,  -104,  2421,  4967,  7141,  8560,  8921,  8053, 
+	 5951,  2800, -1044, -5095, -8793, -11585, -13007, -12757, 
+	-10750, -7142, -2327,  3109,  8458, 12983, 16017, 17068, 
+	15886, 12519,  7314,   887, -5951, -12301, -17286, -20182, 
+	-20517, -18145, -13281, -6484,  1408,  9384, 16384, 21446, 
+	23839, 23164, 19421, 13019,  4731, -4396, -13179, -20450, 
+	-25212, -26779, -24872, -19667, -11780, -2192,  7868, 17089, 
+	24244, 28357, 28837, 25560, 18899,  9673,  -944, -11585, 
+	-20856, -27526, -30693, -29902, -25212, -17195, -6864,  4453, 
+	15290, 24228, 30088, 32083, 29927, 23875, 14693,  3559, 
+	-8084, -18727, -26981, -31764, -32445, -28927, -21659, -11581, 
+	
+};

Propchange: team/group/newcdr/channels/ringtone.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/group/newcdr/channels/ringtone.h
------------------------------------------------------------------------------
    svn:keywords = Author Id Date Revision

Propchange: team/group/newcdr/channels/ringtone.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: team/group/newcdr/include/asterisk/hashtab.h
URL: http://svn.digium.com/view/asterisk/team/group/newcdr/include/asterisk/hashtab.h?view=auto&rev=74474
==============================================================================
--- team/group/newcdr/include/asterisk/hashtab.h (added)
+++ team/group/newcdr/include/asterisk/hashtab.h Tue Jul 10 15:50:07 2007
@@ -1,0 +1,210 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006, Digium, Inc.
+ *
+ * Steve Murphy <murf at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+#ifndef _ASTERISK_HASHTAB_H_
+#define _ASTERISK_HASHTAB_H_
+#define __USE_UNIX98 1 /* what on earth? */
+
+/* generic (perhaps overly so) hashtable implementation */
+
+/* notes:
+
+A hash table is a structure that allows for an exact-match search
+in O(1) (or close to that) time.
+
+The method: given: a set of {key,val} pairs. (at a minimum).
+            given: a hash function, which, given a the key,
+            will return an integer. Ideally, each key in the
+            set will have its own unique associated hash value.
+			This hash number will index into an array. "buckets"
+            are what the elements of this array are called. To
+            handle possible collisions in hash values, buckets can form a list.
+
+The key for a value must be contained in the value, or we won't
+be able to find it in the bucket list.
+
+This implementation is pretty generic, because:
+ 1. The value and key are expected to be in a structure
+    (along with other data, perhaps) and it's address is a "void *".
+ 2. The pointer to a compare function must be passed in at the
+    time of creation, and is stored in the hashtable.
+ 3. The pointer to a resize function, which returns 1 if the
+    hash table is to be grown. A default routine is provided
+    if the pointer is NULL, and uses the java hashtable metric
+    of a 75% load factor.
+ 4. The pointer to a "new size" function, which returns a preferable
+    new size for the hash table bucket array. By default, a function
+    is supplied which roughly doubles the size of the array, is provided.
+    This size should ideally be a prime number.
+ 5. The hashing function pointer must also be supplied. This function
+    must be written by the user to access the keys in the objects being
+    stored. Some helper functions that use a simple "mult by prime, add
+    the next char", sort of string hash, or a simple modulus of the hash
+    table size for ints, is provided; the user can use these simple
+    algorithms to generate a hash, or implement any other algorithms they
+    wish.
+*/
+
+struct ast_hashtab_bucket
+{
+	const void *object;                    /* whatever it is we are storing in this table */
+	struct ast_hashtab_bucket *next; /* a simple LL of buckets in hash collision */
+};
+
+struct ast_hashtab
+{
+	struct ast_hashtab_bucket **array;
+	int (*compare) (const void *a, const void *b);            /* a ptr to func that returns int, and take two void* ptrs, compares them, 
+													 rets -1 if a < b; rets 0 if a==b; rets 1 if a>b */
+	int (*newsize) (struct ast_hashtab *tab);     /* a ptr to func that returns int, a new size for hash tab, based on curr_size */
+	int (*resize) (struct ast_hashtab *tab);      /* a function to decide whether this hashtable should be resized now */
+	int (*hash) (const void *obj, int modulus);         /* a hash func ptr for this table. Given a raw ptr to an obj, 
+													 it calcs a hash. The modulus will be the hashtab size */
+	int hash_tab_size;                            /* the size of the bucket array */
+	int hash_tab_elements;                        /* the number of objects currently stored in the table */
+	int largest_bucket_size;                      /* a stat on the health of the table */
+	int resize_count;                             /* a count of the number of times this table has been
+													 resized */
+	int do_locking;                               /* if 1, use locks to guarantee safety of insertions/deletions */
+	/* this spot reserved for the proper lock storage */
+	ast_rwlock_t lock;                                /* is this as good as it sounds? */
+};
+
+struct ast_hashtab_iter              /* an iterator for traversing the buckets */
+{
+	struct ast_hashtab *tab;
+	int bucket_num;
+	struct ast_hashtab_bucket *curr;
+};
+
+
+/* some standard, default routines for general use */
+
+int isPrime(int num); /* this one is handy for sizing the hash table, tells if num is prime or not */
+
+int ast_hashtab_compare_strings(const void *a, const void *b); /* assumes a and b are char * and returns 0 if they match */
+
+
+int ast_hashtab_compare_strings_nocase(const void *a, const void *b); /* assumes a & b are strings, returns 0 if they match (strcasecmp) */
+
+
+int ast_hashtab_compare_ints(const void *a, const void *b);  /* assumes a & b are int *, returns a != b */
+
+
+int ast_hashtab_compare_shorts(const void *a, const void *b);  /* assumes a & b are short *, returns a != b */
+
+
+int ast_hashtab_resize_java(struct ast_hashtab *tab); /* returns 1 if the table is 75% full or more */
+
+
+int ast_hashtab_resize_tight(struct ast_hashtab *tab); /* not yet specified; probably will return 1 if table is 100% full */
+
+
+int ast_hashtab_resize_none(struct ast_hashtab *tab); /* no resizing; always return 0 */
+
+
+int ast_hashtab_newsize_java(struct ast_hashtab *tab);  /* returns a prime number roughly 2x the current table size */
+
+
+int ast_hashtab_newsize_tight(struct ast_hashtab *tab); /* not yet specified, probably will return 1.5x the current table size */
+
+
+int ast_hashtab_newsize_none(struct ast_hashtab *tab); /* always return current size -- no resizing */
+
+
+int ast_hashtab_hash_string(const void *obj, int modulus); /* hashes a string to a number, mod is applied so it in the range 0 to mod-1 */
+
+
+int ast_hashtab_hash_string_nocase(const void *obj, int modulus);  /* upcases each char before using them for a hash */
+
+
+int ast_hashtab_hash_string_sax(const void *obj, int modulus); /* from Josh */
+
+
+int ast_hashtab_hash_int(const int num, int modulus);  /* right now, both these funcs are just result = num%modulus; */
+
+
+int ast_hashtab_hash_short(const short num, int modulus);
+
+
+struct ast_hashtab * ast_hashtab_create(int initial_buckets,
+					int (*compare)(const void *a, const void *b),        /* a func to compare two elements in the hash -- cannot be null  */
+					int (*resize)(struct ast_hashtab *),     /* a func to decide if the table needs to be resized, 
+										a NULL ptr here will cause a default to be used */
+					int (*newsize)(struct ast_hashtab *tab), /* a ptr to func that returns a new size of the array. 
+										A NULL will cause a default to be used */
+					int (*hash)(const void *obj, int modulus),     /* a func to do the hashing */
+					int do_locking );                        /* use locks to guarantee safety of iterators/insertion/deletion */
+
+
+	/* this func will free the hash table and all its memory. It
+	   doesn't touch the objects stored in it */
+void ast_hashtab_destroy( struct ast_hashtab *tab);
+
+
+	/* normally, you'd insert "safely" by checking to see if the element is
+	   already there; in this case, you must already have checked. If an element
+	   is already in the hashtable, that matches this one, most likely this one
+	   will be found first. */
+	/* will force a resize if the resize func returns 1 */
+	/* returns 1 on success, 0 if there's a problem */
+int ast_hashtab_insert_immediate(struct ast_hashtab *tab, const void *obj);
+
+	/* same as the above, but h is the hash index; won't hash to find the index */
+int ast_hashtab_insert_immediate_bucket(struct ast_hashtab *tab, const void *obj, int h);
+
+
+	/* check to see if the element is already there; insert only if
+	   it is not there.*/
+	/* will force a resize if the resize func returns 1 */
+	/* returns 1 on success, 0 if there's a problem, or it's already there. */
+int ast_hashtab_insert_safe(struct ast_hashtab *tab, const void *obj);
+
+
+	/* lookup this object in the hash table. return a ptr if found, or NULL if not */
+void * ast_hashtab_lookup(struct ast_hashtab *tab, const void *obj);
+
+	/* same as the above lookup, but sets h to the index if the lookup fails */
+void * ast_hashtab_lookup_bucket(struct ast_hashtab *tab, const void *obj, int *h);
+
+	/* returns key stats for the table */
+void ast_hashtab_get_stats( struct ast_hashtab *tab, int *biggest_bucket_size, int *resize_count, int *num_objects, int *num_buckets);
+
+	/* this function is called either internally, when the resize func returns 1, or
+	   externally by the user to force a resize of the hash table */
+void ast_hashtab_resize( struct ast_hashtab *tab);
+
+
+	/* returns an iterator */
+struct ast_hashtab_iter *ast_hashtab_start_traversal(struct ast_hashtab *tab);
+	/* end the traversal, free the iterator, unlock if necc. */
+void ast_hashtab_end_traversal(struct ast_hashtab_iter *it);
+
+	/* returns the next object in the list, advances iter one step */
+void *ast_hashtab_next(struct ast_hashtab_iter *it);
+
+
+
+	/* looks up the object; removes the corresponding bucket */
+void *ast_hashtab_remove_object_via_lookup(struct ast_hashtab *tab, void *obj);
+
+
+	/* looks up the object by hash and then comparing pts in bucket list instead of
+	   calling the compare routine; removes the bucket */
+void *ast_hashtab_remove_this_object(struct ast_hashtab *tab, void *obj);
+
+#endif

Propchange: team/group/newcdr/include/asterisk/hashtab.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/group/newcdr/include/asterisk/hashtab.h
------------------------------------------------------------------------------
    svn:keywords = Author Id Date Revision

Propchange: team/group/newcdr/include/asterisk/hashtab.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/group/newcdr/main/cel.c
URL: http://svn.digium.com/view/asterisk/team/group/newcdr/main/cel.c?view=diff&rev=74474&r1=74473&r2=74474
==============================================================================
--- team/group/newcdr/main/cel.c (original)
+++ team/group/newcdr/main/cel.c Tue Jul 10 15:50:07 2007
@@ -155,10 +155,10 @@
 	const char *applist;
 	int was_enabled;
 	int res=0;
+	enum ast_cel_eventtype et;
 
 	was_enabled = cel_enabled;
 	cel_enabled = 1;
-	enum ast_cel_eventtype et;
 	if (appset) {
 		/* a pre-existing hash table == destroy it */
 		/* first, free all the entries */
@@ -235,8 +235,8 @@
 				if (!track_event(CEL_APP_START) && !track_event(CEL_APP_END)) {
 					ast_log(LOG_ERROR, "An apps= config line, but not tracking APP events!\n");
 				} else {
+					int commacount = 0;
 					t1 = myapplist;
-					int commacount = 0;
 					t2 = t1;
 					while (t2) {
 						t2 = strchr(t2,',');
@@ -438,7 +438,7 @@
 		time_t t = tv.tv_sec;
 		if (t) {
 			struct tm tm;
-			localtime_r(&t, &tm);
+			ast_localtime(&t, &tm, NULL);
 			strftime(buf, bufsize, fmt, &tm);
 		}
 	}

Added: team/group/newcdr/main/hashtab.c
URL: http://svn.digium.com/view/asterisk/team/group/newcdr/main/hashtab.c?view=auto&rev=74474
==============================================================================
--- team/group/newcdr/main/hashtab.c (added)
+++ team/group/newcdr/main/hashtab.c Tue Jul 10 15:50:07 2007
@@ -1,0 +1,606 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006, Digium, Inc.
+ *
+ * Steve Murphy <murf at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+/*! \file
+ *  *
+ *   * \brief code to implement generic hash tables
+ *    *
+ *     * \author Steve Murphy <murf at digium.com>
+ *      */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision")
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stddef.h>
+
+#include "asterisk/lock.h"
+#include "asterisk/frame.h"
+#include "asterisk/logger.h"
+#include "asterisk/options.h"
+#include "asterisk/channel.h"
+#include "asterisk/cli.h"
+#include "asterisk/term.h"
+#include "asterisk/utils.h"
+#include "asterisk/threadstorage.h"
+#include "asterisk/linkedlists.h"
+#include "asterisk/hashtab.h"
+
+
+/* some standard, default routines for general use */
+
+int ast_hashtab_compare_strings(const void *a, const void *b)
+{
+	return strcmp((char*)a,(char*)b);
+}
+
+int ast_hashtab_compare_strings_nocase(const void *a, const void *b)
+{
+	return strcasecmp((const char*)a,(const char*)b);
+}
+
+int ast_hashtab_compare_ints(const void *a, const void *b)
+{
+	int ai = *((int*)a);
+	int bi = *((int*)b);
+	if (ai < bi)
+		return -1;
+	else if (ai==bi)
+		return 0;
+	else
+		return 1;
+}
+
+int ast_hashtab_compare_shorts(const void *a, const void *b)
+{
+	short as = *((short*)a);
+	short bs = *((short*)b);
+	if (as < bs)
+		return -1;
+	else if (as==bs)
+		return 0;
+	else
+		return 1;
+}
+
+int ast_hashtab_resize_java(struct ast_hashtab *tab)
+{
+	double loadfactor = (double)tab->hash_tab_elements / (double)tab->hash_tab_size;
+	if (loadfactor > 0.75)
+		return 1;
+	return 0;
+}
+
+int ast_hashtab_resize_tight(struct ast_hashtab *tab)
+{
+	
+	if (tab->hash_tab_elements > tab->hash_tab_size) /* this is quicker than division */
+		return 1;
+	return 0;
+}
+
+int ast_hashtab_resize_none(struct ast_hashtab *tab) /* always return 0 -- no resizing */
+{
+	return 0;
+}
+
+
+int isPrime(int num)
+{
+	int tnum,limit;
+	    
+	if ((num & 0x1) == 0) /* even number -- not prime */
+		return 0;
+		    
+    	/* Loop through ODD numbers starting with 3 */
+
+	tnum = 3;
+	limit = num;
+	while (tnum < limit)
+	{
+		if ((num%tnum) == 0) {
+			return 0;
+		}
+		/* really, we only need to check sqrt(num) numbers */
+		limit = num / tnum;
+		/* we only check odd numbers */
+		tnum = tnum+2;
+	}
+	/* if we made it thru the loop, the number is a prime */
+	return 1;
+}
+
+int ast_hashtab_newsize_java(struct ast_hashtab *tab)
+{
+	int i = (tab->hash_tab_size<<1); /* multiply by two */
+	while (!isPrime(i))
+		i++;
+	return i;
+}
+
+int ast_hashtab_newsize_tight(struct ast_hashtab *tab)
+{
+	int x = (tab->hash_tab_size<<1);
+	int i = (tab->hash_tab_size+x);
+	while (!isPrime(i))
+		i++;
+	return i;
+}
+
+int ast_hashtab_newsize_none(struct ast_hashtab *tab) /* always return current size -- no resizing */
+{
+	return tab->hash_tab_size;
+}
+
+int ast_hashtab_hash_string(const void *obj, int modulus)
+{
+	unsigned char *str = (unsigned char*)obj;
+	unsigned int total;
+
+	for (total=0; *str; str++)
+	{
+		unsigned int tmp = total;
+		total <<= 1; /* multiply by 2 */
+		total += tmp; /* multiply by 3 */
+		total <<= 2; /* multiply by 12 */
+		total += tmp; /* multiply by 13 */
+		
+		total += ((unsigned int)(*str));
+	}
+	return (total % modulus);
+}
+
+int ast_hashtab_hash_string_sax(const void *obj, int modulus) /* from Josh */
+{
+	unsigned char *str = (unsigned char*)obj;
+	unsigned int total, c = 0;
+
+	while ((c = *str++))
+		total ^= ( total << 5 ) + ( total >> 2 ) + ( total << 10) + c;
+
+	return (total % modulus);
+}
+
+int ast_hashtab_hash_string_nocase(const void *obj, int modulus)
+{
+	unsigned char *str = (unsigned char*)obj;
+	unsigned int total;
+
+	for (total=0; *str; str++)
+	{
+		unsigned int tmp = total;
+		unsigned int charval = toupper(*str);
+
+		/* hopefully, the following is faster than multiplication by 7 */
+		/* why do I go to this bother? A good compiler will do this 
+		   anyway, if I say total *= 13 */
+		/* BTW, tried *= 7, and it doesn't do as well in spreading things around! */
+		total <<= 1; /* multiply by 2 */
+		total += tmp; /* multiply by 3 */
+		total <<= 2; /* multiply by 12 */
+		total += tmp; /* multiply by 13 */
+		
+		total += (charval);
+	}
+	return (total % modulus);
+}
+
+int ast_hashtab_hash_int(const int x, int modulus)
+{
+	return (x % modulus);
+}
+
+int ast_hashtab_hash_short(const short x, int modulus)
+{
+	/* hmmmm.... modulus is best < 65535 !! */
+	return (x % modulus);
+}
+
+struct ast_hashtab * ast_hashtab_create(int initial_buckets,
+										int (*compare)(const void *a, const void *b), /* a func to compare two elements in the hash -- cannot be null  */
+										int (*resize)(struct ast_hashtab *), /* a func to decide if the table needs to be resized, a NULL ptr here will cause a default to be used */
+										int (*newsize)(struct ast_hashtab *tab), /* a ptr to func that returns a new size of the array. A NULL will cause a default to be used */
+										int (*hash)(const void *obj, int modulus), /* a func to do the hashing */
+										int do_locking ) /* use locks to guarantee safety of iterators/insertion/deletion -- real simpleminded right now */
+{
+	struct ast_hashtab *ht = ast_calloc(1,sizeof(struct ast_hashtab));
+	while (!isPrime(initial_buckets)) /* make sure this is prime */
+		initial_buckets++;
+	ht->array = ast_calloc(initial_buckets,sizeof(struct ast_hashtab_bucket*));
+	ht->hash_tab_size = initial_buckets;
+	ht->compare = compare;
+	ht->resize = resize;
+	ht->newsize = newsize;
+	ht->hash = hash;
+	ht->do_locking = do_locking;
+	if (do_locking)
+		ast_rwlock_init(&ht->lock);
+	if (!ht->resize)
+		ht->resize = ast_hashtab_resize_java;
+	if (!ht->newsize)
+		ht->newsize = ast_hashtab_newsize_java;
+	return ht;
+}
+
+void ast_hashtab_destroy( struct ast_hashtab *tab)
+{
+	/* this func will free the hash table and all its memory. It
+	   doesn't touch the objects stored in it */
+	if (tab->do_locking)
+		ast_rwlock_wrlock(&tab->lock);
+	if (tab) {
+		
+		if (tab->array) {
+			/* go thru and destroy the buckets */
+			int i;
+			for (i=0;i<tab->hash_tab_size;i++) {
+				struct ast_hashtab_bucket *b = tab->array[i];
+				struct ast_hashtab_bucket *N;
+				while (b) {
+					N = b->next;
+					b->next = 0; /* don't leave dead pointers laying about */
+					free(b);
+					b = N;
+				}
+				tab->array[i] = 0; /* don't leave dead pointers laying about */
+			}
+			
+			free(tab->array);
+		}
+		if (tab->do_locking) {
+			ast_rwlock_unlock(&tab->lock);
+			ast_rwlock_destroy(&tab->lock);
+		}
+		free(tab);
+	}
+}
+
+int ast_hashtab_insert_immediate(struct ast_hashtab *tab, const void *obj)
+{
+	/* normally, you'd insert "safely" by checking to see if the element is
+	   already there; in this case, you must already have checked. If an element
+	   is already in the hashtable, that matches this one, most likely this one
+	   will be found first, but.... */
+
+	/* will force a resize if the resize func returns 1 */
+	/* returns 1 on success, 0 if there's a problem */
+	int h;
+	int c;
+	struct ast_hashtab_bucket *b;
+	
+	if (!tab || !obj)
+		return 0;
+	if (tab->do_locking)
+		ast_rwlock_wrlock(&tab->lock);
+	h = (*tab->hash)(obj, tab->hash_tab_size);
+	for (c=0,b=tab->array[h];b;b=b->next) {
+		c++;
+	}
+	if (c+1 > tab->largest_bucket_size)
+		tab->largest_bucket_size = c+1;
+	b = ast_malloc(sizeof(struct ast_hashtab_bucket));
+	b->object = obj;
+	b->next = tab->array[h];
+	tab->array[h] = b;
+	tab->hash_tab_elements++;
+	if ((*tab->resize)(tab))
+		ast_hashtab_resize(tab);
+	if (tab->do_locking)
+		ast_rwlock_unlock(&tab->lock);
+	return 1;
+}
+
+int ast_hashtab_insert_immediate_bucket(struct ast_hashtab *tab, const void *obj, int h)
+{
+	/* normally, you'd insert "safely" by checking to see if the element is
+	   already there; in this case, you must already have checked. If an element
+	   is already in the hashtable, that matches this one, most likely this one
+	   will be found first, but.... */
+
+	/* will force a resize if the resize func returns 1 */
+	/* returns 1 on success, 0 if there's a problem */
+	int c;
+	struct ast_hashtab_bucket *b;
+	
+	if (!tab || !obj)
+		return 0;
+	if (tab->do_locking)
+		ast_rwlock_wrlock(&tab->lock);
+	
+	for (c=0,b=tab->array[h];b;b=b->next) {
+		c++;
+	}
+	if (c+1 > tab->largest_bucket_size)
+		tab->largest_bucket_size = c+1;
+	b = ast_malloc(sizeof(struct ast_hashtab_bucket));
+	b->object = obj;
+	b->next = tab->array[h];
+	tab->array[h] = b;
+	tab->hash_tab_elements++;
+	if ((*tab->resize)(tab))
+		ast_hashtab_resize(tab);
+	if (tab->do_locking)
+		ast_rwlock_unlock(&tab->lock);
+	return 1;
+}
+
+int ast_hashtab_insert_safe(struct ast_hashtab *tab, const void *obj)
+{
+	/* check to see if the element is already there; insert only if
+	   it is not there. */
+	/* will force a resize if the resize func returns 1 */
+	/* returns 1 on success, 0 if there's a problem, or it's already there. */
+	int bucket;
+	if (ast_hashtab_lookup_bucket(tab,obj,&bucket) == 0)
+	{
+		return ast_hashtab_insert_immediate_bucket(tab,obj,bucket);
+	}
+	return 0;
+}
+
+void * ast_hashtab_lookup(struct ast_hashtab *tab, const void *obj)
+{
+	/* lookup this object in the hash table. return a ptr if found, or NULL if not */
+	int h;
+	struct ast_hashtab_bucket *b;
+	if (!tab || !obj)
+		return 0;
+	
+	if (tab->do_locking)
+		ast_rwlock_rdlock(&tab->lock);
+	h = (*tab->hash)(obj, tab->hash_tab_size);
+	for(b=tab->array[h]; b; b=b->next) {
+		if( (*tab->compare)(obj,b->object) == 0 ) {
+			if (tab->do_locking)
+				ast_rwlock_unlock(&tab->lock);
+			return (void*)b->object; /* I can't touch obj in this func, but the outside world is welcome to */
+		}
+	}
+	if (tab->do_locking)
+		ast_rwlock_unlock(&tab->lock);
+
+	return 0;
+}
+
+void * ast_hashtab_lookup_bucket(struct ast_hashtab *tab, const void *obj, int *bucket)
+{
+	/* lookup this object in the hash table. return a ptr if found, or NULL if not */
+	int h;
+	struct ast_hashtab_bucket *b;
+	if (!tab || !obj)
+		return 0;
+	
+	if (tab->do_locking)
+		ast_rwlock_rdlock(&tab->lock);
+	h = (*tab->hash)(obj, tab->hash_tab_size);
+	for(b=tab->array[h]; b; b=b->next) {
+		if( (*tab->compare)(obj,b->object) == 0 ) {
+			if (tab->do_locking)
+				ast_rwlock_unlock(&tab->lock);
+			return (void*)b->object; /* I can't touch obj in this func, but the outside world is welcome to */
+		}
+	}
+	if (tab->do_locking)
+		ast_rwlock_unlock(&tab->lock);
+	*bucket = h;
+	return 0;
+}
+
+void ast_hashtab_get_stats( struct ast_hashtab *tab, int *biggest_bucket_size, int *resize_count, int *num_objects, int *num_buckets)
+{
+	/* returns key stats for the table */
+	if (tab->do_locking)
+		ast_rwlock_rdlock(&tab->lock);
+	*biggest_bucket_size = tab->largest_bucket_size;
+	*resize_count = tab->resize_count;
+	*num_objects = tab->hash_tab_elements;
+	*num_buckets = tab->hash_tab_size;
+	if (tab->do_locking)
+		ast_rwlock_unlock(&tab->lock);
+}
+
+/* the insert operation calls this, and is wrlock'd when it does. */
+/* if you want to call it, you should set the wrlock yourself */
+
+void ast_hashtab_resize( struct ast_hashtab *tab)
+{
+	/* this function is called either internally, when the resize func returns 1, or
+	   externally by the user to force a resize of the hash table */
+	int newsize = (*tab->newsize)(tab), i, h,c;
+	struct ast_hashtab_bucket *list = 0, *b,*bn;
+	
+	/* there's two ways to do this: 
+	   1. allocate a new array, and move the elements into it from the old table directly, then
+	      free the old table. faster, requires more mem.
+	   2. relink the buckets into a single long chain; free the old array. Then, allocate the
+          new table, and move the buckets in. slower, minimal mem requirements. 
+	*/
+	for (i=0;i<tab->hash_tab_size;i++) {
+		for (b=tab->array[i]; b; b=bn) {
+			bn = b->next;
+			b->next = list;
+			list = b;
+		}
+		tab->array[i] = 0; /* erase old ptrs */
+	}
+	free(tab->array);
+	tab->array = ast_calloc(newsize,sizeof(struct ast_hashtab_bucket *));
+	/* now sort the buckets into their rightful new slots */
+	tab->resize_count++;
+	tab->hash_tab_size = newsize;
+	tab->largest_bucket_size = 0;
+
+	for (b=list;b;b=bn)
+	{
+		bn = b->next;
+		h = (*tab->hash)(b->object, tab->hash_tab_size);
+		b->next = tab->array[h];
+		tab->array[h] = b;
+	}
+	list = 0;
+	/* recalc the largest bucket size */
+	for (i=0;i<tab->hash_tab_size;i++) {
+		c=0;
+		for (b=tab->array[i]; b; b=b->next) {
+			c++;
+		}
+		if( c > tab->largest_bucket_size )
+			tab->largest_bucket_size = c;
+	}
+}
+
+struct ast_hashtab_iter *ast_hashtab_start_traversal(struct ast_hashtab *tab)
+{
+	/* returns an iterator */
+	struct ast_hashtab_iter *it = ast_malloc(sizeof(struct ast_hashtab_iter));
+	it->bucket_num = 0;
+	
+	it->curr = tab->array[0];
+	it->tab = tab;
+	if (tab->do_locking)
+		ast_rwlock_rdlock(&tab->lock);
+	return it;
+}
+
+void ast_hashtab_end_traversal(struct ast_hashtab_iter *it)
+{
+	if (it->tab->do_locking)
+		ast_rwlock_unlock(&it->tab->lock);
+	free(it);
+}
+
+void *ast_hashtab_next(struct ast_hashtab_iter *it)
+{
+	/* returns the next object in the list, advances iter one step */
+	int num;
+
+	
+	if( it->curr && it->curr->next )  /* there's a next in the bucket list */
+	{
+		it->curr = it->curr->next;
+		return (void*)it->curr->object;
+	} else if( !it->curr && it->bucket_num == 0 ){ /* first call to this */
+		for(num=it->bucket_num; num<it->tab->hash_tab_size; num++)
+		{
+			if (it->tab->array[num]) {
+				it->bucket_num = num;
+				it->curr = it->tab->array[num];
+				return (void*)it->curr->object; /* inside the hash code, the obj's are untouchable, but outside... */
+			} else {
+				continue; /* try the next bucket */
+			}
+			return 0; /* nothing in the whole table! */
+		}
+	} else if (it->curr && !it->curr->next) {  /* end of a bucket chain */
+		it->bucket_num++;
+		for(num=it->bucket_num; num<it->tab->hash_tab_size; num++)
+		{
+			if (it->tab->array[num]) {
+				it->bucket_num = num;
+				it->curr = it->tab->array[num];
+				return (void*)it->curr->object; /* inside the hash code, the obj's are untouchable, but outside... */
+			} else {
+				continue; /* try the next bucket */
+			}
+			return 0; /* nothing in the whole table! */
+		}
+		
+	} else if (!it->curr && it->bucket_num != 0 ) { /* call me again, after the list is traversed? */
+		return 0;
+	}
+	
+	return 0;
+}
+
+void *ast_hashtab_remove_object_via_lookup(struct ast_hashtab *tab, void *obj)
+{
+	/* looks up the object; removes the corresponding bucket */
+	int h;
+	struct ast_hashtab_bucket *b,*last;
+
+	if (!tab || !obj)
+		return 0;
+	last = 0;
+	if (tab->do_locking)
+		ast_rwlock_wrlock(&tab->lock);
+	h = (*tab->hash)(obj, tab->hash_tab_size);
+	for(b=tab->array[h]; b; b=b->next)
+	{
+		const void *obj2;
+		

[... 84 lines stripped ...]



More information about the asterisk-commits mailing list