[asterisk-commits] nadi: branch nadi/trunk-cm r44332 - /team/nadi/trunk-cm/include/asterisk/hash.h

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Wed Oct 4 02:55:59 MST 2006


Author: nadi
Date: Wed Oct  4 04:55:57 2006
New Revision: 44332

URL: http://svn.digium.com/view/asterisk?rev=44332&view=rev
Log:
now using a double indexing strategy for collision resolution

Modified:
    team/nadi/trunk-cm/include/asterisk/hash.h

Modified: team/nadi/trunk-cm/include/asterisk/hash.h
URL: http://svn.digium.com/view/asterisk/team/nadi/trunk-cm/include/asterisk/hash.h?rev=44332&r1=44331&r2=44332&view=diff
==============================================================================
--- team/nadi/trunk-cm/include/asterisk/hash.h (original)
+++ team/nadi/trunk-cm/include/asterisk/hash.h Wed Oct  4 04:55:57 2006
@@ -45,6 +45,7 @@
 struct name {							\
 	struct {							\
 		char        _used;				\
+		size_t 		_next;				\
 		ktype       _key;				\
 		vtype       _val;				\
 	} *_data;							\
@@ -58,9 +59,10 @@
 #define __AST_HASH_NOLOCK(name, ktype, vtype)	\
 struct name {							\
 	struct {							\
+		char        _used;				\
+		size_t      _next;				\
 		ktype       _key;				\
 		vtype       _val;				\
-		char        _used;				\
 	} *_data;							\
 	size_t          _size;				\
 	size_t          _length;			\
@@ -89,6 +91,8 @@
 	(hash)->_size = (size);									\
 	(hash)->_hash_f = (hash_f);								\
 	(hash)->_eq_f = (eq_f);									\
+	for ((hash)->_length = (size); (hash)->_length; --(hash)->_length)	\
+		(hash)->_data[(hash)->_length - 1]._next = -1;		\
 } while (0)
 
 #define __AST_HASH_INIT(hash, size, hash_f, cmp)			\
@@ -98,16 +102,16 @@
 } while (0)
 
 #define AST_HASH_INIT_INT_NOLOCK(hash, size)				\
-	__AST_HASH_INIT_NOLOCK((hash), size, modolo_hash, eq_int)
+	__AST_HASH_INIT_NOLOCK((hash), (size), modolo_hash, eq_int)
 
 #define AST_HASH_INIT_INT(hash, size)						\
-	__AST_HASH_INIT((hash), size, modolo_hash, eq_int)
+	__AST_HASH_INIT((hash), (size), modolo_hash, eq_int)
 
 #define AST_HASH_INIT_STR_NOLOCK(hash, size)				\
-	__AST_HASH_INIT_NOLOCK((hash), size, joaat_hash, eq_str)
+	__AST_HASH_INIT_NOLOCK((hash), (size), joaat_hash, eq_str)
 
 #define AST_HASH_INIT_STR(hash, size)						\
-	__AST_HASH_INIT((hash), size, joaat_hash, eq_str)
+	__AST_HASH_INIT((hash), (size), joaat_hash, eq_str)
 
 
 
@@ -137,26 +141,51 @@
 	ast_mutex_unlock(&(hash)->_lock)
 
 
+#define __INSERT(hash, key, val, pos, prev)			\
+	hash->_data[pos]._key = key;					\
+	hash->_data[pos]._val = val;					\
+	hash->_data[pos]._used = 1;						\
+	if (prev > -1)									\
+		hash->_data[prev]._next = pos;				\
+	++hash->_length
 
 
 #define AST_HASH_INSERT_NOLOCK(hash, key, val)		\
 ({													\
 	int __pos = (hash)->_hash_f(key, (hash)->_size);\
-	int __end = __pos;								\
+ 	int __end;										\
+	int __prev = -1;								\
  	int __re = -1;									\
-	typeof(val) __valtmp = val;						\
-	if (AST_HASH_LOOKUP_NOLOCK((hash), (key), __valtmp))	\
+	int __goon = 0;									\
+	do {											\
+		if (!(hash)->_data[__pos]._used) {			\
+ 			__INSERT((hash), (key), (val), __pos, __prev);	\
+			__re = 0;								\
+			break;									\
+		}											\
+		if ((hash)->_eq_f((hash)->_data[__pos]._key, (key)))	\
+ 			break;									\
+ 		__prev = __pos;								\
+		if ((hash)->_data[__pos]._next > -1)		\
+			__pos = (hash)->_data[__pos]._next;		\
+		else {										\
+			__goon = 1;								\
+			break;									\
+		}											\
+	} while (1);									\
+	if (__goon) {									\
+		__end = __pos;								\
+		__pos = (__pos + 1) % (hash)->_size;		\
 		do {										\
 			if (!(hash)->_data[__pos]._used) {		\
-				(hash)->_data[__pos]._key = key;	\
-				(hash)->_data[__pos]._val = val;	\
-				(hash)->_data[__pos]._used = 1;		\
-				++(hash)->_length;					\
+				__INSERT((hash), (key), (val), __pos, __prev);	\
 				__re = 0;							\
 				break;								\
 			}										\
 			__pos = (__pos + 1) % (hash)->_size;	\
-		} while (__pos != __end);					\
+		}											\
+		while (__pos != __end);						\
+	}												\
 	__re;											\
 })
 
@@ -175,7 +204,6 @@
 #define AST_HASH_LOOKUP_NOLOCK(hash, key, val)	\
 ({												\
 	int _pos = (hash)->_hash_f(key, (hash)->_size);	\
-	int _end = _pos;							\
  	int _re = -1;								\
 	do {										\
 		if ((hash)->_data[_pos]._used &&		\
@@ -184,8 +212,8 @@
 			_re = 0;							\
  			break;								\
  		}										\
-		_pos = (_pos + 1) % (hash)->_size;		\
-	} while (_pos != _end);						\
+		_pos = (hash)->_data[_pos]._next;		\
+	} while (_pos > -1);						\
 	_re;										\
 })
 
@@ -204,16 +232,19 @@
 #define AST_HASH_REMOVE_NOLOCK(hash, key)		\
 do {											\
 	int _pos = (hash)->_hash_f((key), (hash)->_size);	\
-	int _end = _pos;							\
+	int _prev = -1;								\
 	do {										\
 		if ((hash)->_data[_pos]._used &&		\
 			(hash)->_eq_f((hash)->_data[_pos]._key, (key))) {	\
 			(hash)->_data[_pos]._used = 0;		\
+			if (_prev > -1)						\
+				(hash)->_data[_prev]._next = (hash)->_data[_pos]._next;	\
 			--(hash)->_length;					\
  			break;								\
  		}										\
-		_pos = (_pos + 1) % (hash)->_size;		\
-	} while (_pos != _end);						\
+		_prev = _pos;							\
+		_pos = (hash)->_data[_pos]._next;		\
+	} while (_pos > -1);						\
 } while (0)										\
 
 #define AST_HASH_REMOVE(hash, key)				\



More information about the asterisk-commits mailing list