Symbol.st
changeset 356 6c5ce0e1e7a8
parent 345 cf2301210c47
child 370 20f04d9b371b
--- a/Symbol.st	Fri May 19 15:33:11 1995 +0200
+++ b/Symbol.st	Wed May 24 14:44:58 1995 +0200
@@ -21,7 +21,7 @@
 COPYRIGHT (c) 1988 by Claus Gittinger
 	      All Rights Reserved
 
-$Header: /cvs/stx/stx/libbasic/Symbol.st,v 1.23 1995-05-16 17:09:21 claus Exp $
+$Header: /cvs/stx/stx/libbasic/Symbol.st,v 1.24 1995-05-24 12:44:31 claus Exp $
 '!
 
 !Symbol class methodsFor:'documentation'!
@@ -42,7 +42,7 @@
 
 version
 "
-$Header: /cvs/stx/stx/libbasic/Symbol.st,v 1.23 1995-05-16 17:09:21 claus Exp $
+$Header: /cvs/stx/stx/libbasic/Symbol.st,v 1.24 1995-05-24 12:44:31 claus Exp $
 "
 !
 
@@ -285,6 +285,58 @@
     ^ true
 ! !
 
+!Symbol methodsFor:'comparing'!
+
+identityHash
+    "interned symbols can return a better hash key"
+
+%{  /* NOCONTEXT */
+
+    REGISTER int g, val;
+    REGISTER unsigned char *cp, *cp0;
+    int l;
+
+    if (__Class(self) == Symbol) {
+	val = _GET_HASH(self);
+	/*
+	 * only do it, if I have no standard hash key
+	 * assigned.
+	 */
+	if (val == 0) {
+	    cp = _stringVal(self);
+	    l = _stringSize(self);
+        
+	    /*
+	     * this is the dragon-book algorithm
+	     *
+	     * the algorithm hashes pretty good:
+	     *   with (currently) 9963 symbols in the system,
+	     *   there are only about 200 hash key collisions.
+	     *   where the maximum collision count in these 200
+	     *   is 3. This means, that in most situations,
+	     *   a single probe will find the right element in
+	     *   a symbol-hashed collection.
+	     */
+	    val = 0;
+	    for (cp0 = cp, cp += l - 1; cp >= cp0; cp--) {
+		val = (val << 5) + (*cp & 0x1F);
+		if (g = (val & 0x3E000000))
+		    val ^= g >> 25 /* 23 */ /* 25 */;
+		val &= 0x3FFFFFFF;
+	    }
+
+	    if (l) {
+		l |= 1; 
+		val = (val * l) & 0x3FFFFFFF;
+	    }
+
+	    RETURN ( _MKSMALLINT(val) );
+	}
+     }
+%}.
+     ^ super identityHash
+! !
+
 !Symbol methodsFor:'system primitives'!
 
 become:anotherObject