diff -r 2d96938a5081 -r 6c5ce0e1e7a8 Symbol.st --- 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