X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fcode%2Ftarget-sxhash.lisp;h=0b65801e738c64a2384863f5f269dcc181579ca9;hb=a3ab89c1db0dd9bfb911532ca134be16f16c4c1b;hp=5fb976226b61a9144c08d80930b759adad32b472;hpb=f4a7d6c4a2a4f846ad353dddb922dd8967f998e5;p=sbcl.git diff --git a/src/code/target-sxhash.lisp b/src/code/target-sxhash.lisp index 5fb9762..0b65801 100644 --- a/src/code/target-sxhash.lisp +++ b/src/code/target-sxhash.lisp @@ -26,9 +26,9 @@ ;;; desiderata: ;;; * Non-commutativity keeps us from hashing e.g. #(1 5) to the ;;; same value as #(5 1), and ending up in real trouble in some -;;; special cases like bit vectors the way that CMUCL SXHASH 18b +;;; special cases like bit vectors the way that CMUCL 18b SXHASH ;;; does. (Under CMUCL 18b, SXHASH of any bit vector is 1..) -;;; * We'd like to scatter our hash values the entire possible range +;;; * We'd like to scatter our hash values over the entire possible range ;;; of values instead of hashing small or common key values (like ;;; 2 and NIL and #\a) to small FIXNUMs the way that the CMUCL 18b ;;; SXHASH function does, again helping to avoid pathologies like @@ -115,6 +115,9 @@ ;;;; the SXHASH function (defun sxhash (x) + ;; profiling SXHASH is hard, but we might as well try to make it go + ;; fast, in case it is the bottleneck somwhere. -- CSR, 2003-03-14 + (declare (optimize speed)) (labels ((sxhash-number (x) (etypecase x (fixnum (sxhash x)) ; through DEFTRANSFORM @@ -135,7 +138,7 @@ (sxhash-recurse (x &optional (depthoid +max-hash-depthoid+)) (declare (type index depthoid)) (typecase x - (list + (cons (if (plusp depthoid) (mix (sxhash-recurse (car x) (1- depthoid)) (sxhash-recurse (cdr x) (1- depthoid))) @@ -145,30 +148,28 @@ (logxor 422371266 (sxhash ; through DEFTRANSFORM (class-name (layout-class (%instance-layout x))))) - ;; Nice though it might be to return a nontrivial - ;; hash value for other instances (especially - ;; STANDARD-OBJECTs) there seems to be no good way - ;; to do so. We can't even do the CLASS-NAME trick - ;; (as used above for STRUCTURE-OBJECT) because - ;; then CHANGE-CLASS would cause SXHASH values to - ;; change, ouch! -- WHN recording wisdom of CSR - 309518995)) + (sxhash-instance x))) (symbol (sxhash x)) ; through DEFTRANSFORM (array (typecase x (simple-string (sxhash x)) ; through DEFTRANSFORM (string (%sxhash-substring x)) - (bit-vector (let ((result 410823708)) - (declare (type fixnum result)) - (dotimes (i (min depthoid (length x))) - (mixf result (aref x i))) - result)) + (simple-bit-vector (sxhash x)) ; through DEFTRANSFORM + (bit-vector + ;; FIXME: It must surely be possible to do better + ;; than this. The problem is that a non-SIMPLE + ;; BIT-VECTOR could be displaced to another, with a + ;; non-zero offset -- so that significantly more + ;; work needs to be done using the %RAW-BITS + ;; approach. This will probably do for now. + (sxhash-recurse (copy-seq x) depthoid)) (t (logxor 191020317 (sxhash (array-rank x)))))) (character (logxor 72185131 (sxhash (char-code x)))) ; through DEFTRANSFORM ;; general, inefficient case of NUMBER (number (sxhash-number x)) + (generic-function (sxhash-instance x)) (t 42)))) (sxhash-recurse x))) @@ -193,7 +194,7 @@ (array (array-psxhash key depthoid)) (hash-table (hash-table-psxhash key)) (structure-object (structure-object-psxhash key depthoid)) - (list (list-psxhash key depthoid)) + (cons (list-psxhash key depthoid)) (number (number-psxhash key)) (character (sxhash (char-upcase key))) (t (sxhash key))))