[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