- (etypecase x
- (fixnum (sxhash x)) ; through DEFTRANSFORM
- (integer (sb!bignum:sxhash-bignum x))
- (single-float (sxhash x)) ; through DEFTRANSFORM
- (double-float (sxhash x)) ; through DEFTRANSFORM
- #!+long-float (long-float (error "stub: no LONG-FLOAT"))
- (ratio (let ((result 127810327))
- (declare (type fixnum result))
- (mixf result (sxhash-number (numerator x)))
- (mixf result (sxhash-number (denominator x)))
- result))
- (complex (let ((result 535698211))
- (declare (type fixnum result))
- (mixf result (sxhash-number (realpart x)))
- (mixf result (sxhash-number (imagpart x)))
- result))))
- (sxhash-recurse (x &optional (depthoid +max-hash-depthoid+))
- (declare (type index depthoid))
- (typecase x
- (list
- (if (plusp depthoid)
- (mix (sxhash-recurse (car x) (1- depthoid))
- (sxhash-recurse (cdr x) (1- depthoid)))
- 261835505))
- (instance
- (if (typep x 'structure-object)
- (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))
- (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))
- (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))
- (t 42))))
- (sxhash-recurse x)))
+ (etypecase x
+ (fixnum (sxhash x)) ; through DEFTRANSFORM
+ (integer (sb!bignum:sxhash-bignum x))
+ (single-float (sxhash x)) ; through DEFTRANSFORM
+ (double-float (sxhash x)) ; through DEFTRANSFORM
+ #!+long-float (long-float (error "stub: no LONG-FLOAT"))
+ (ratio (let ((result 127810327))
+ (declare (type fixnum result))
+ (mixf result (sxhash-number (numerator x)))
+ (mixf result (sxhash-number (denominator x)))
+ result))
+ (complex (let ((result 535698211))
+ (declare (type fixnum result))
+ (mixf result (sxhash-number (realpart x)))
+ (mixf result (sxhash-number (imagpart x)))
+ result))))
+ (sxhash-recurse (x depthoid)
+ (declare (type index depthoid))
+ (typecase x
+ ;; we test for LIST here, rather than CONS, because the
+ ;; type test for CONS is in fact the test for
+ ;; LIST-POINTER-LOWTAG followed by a negated test for
+ ;; NIL. If we're going to have to test for NIL anyway,
+ ;; we might as well do it explicitly and pick off the
+ ;; answer. -- CSR, 2004-07-14
+ (list
+ (if (null x)
+ (sxhash x) ; through DEFTRANSFORM
+ (if (plusp depthoid)
+ (mix (sxhash-recurse (car x) (1- depthoid))
+ (sxhash-recurse (cdr x) (1- depthoid)))
+ 261835505)))
+ (instance
+ (if (pathnamep x)
+ ;; Pathnames are EQUAL if all the components are EQUAL, so
+ ;; we hash all of the components of a pathname together.
+ (let ((hash (sxhash-recurse (pathname-host x) depthoid)))
+ (mixf hash (sxhash-recurse (pathname-device x) depthoid))
+ (mixf hash (sxhash-recurse (pathname-directory x) depthoid))
+ (mixf hash (sxhash-recurse (pathname-name x) depthoid))
+ (mixf hash (sxhash-recurse (pathname-type x) depthoid))
+ ;; Hash :NEWEST the same as NIL because EQUAL for
+ ;; pathnames assumes that :newest and nil are equal.
+ (let ((version (%pathname-version x)))
+ (mixf hash (sxhash-recurse (if (eq version :newest)
+ nil
+ version)
+ depthoid))))
+ (if (or (typep x 'structure-object) (typep x 'condition))
+ (logxor 422371266
+ (sxhash ; through DEFTRANSFORM
+ (classoid-name
+ (layout-classoid (%instance-layout x)))))
+ (sxhash-instance x))))
+ (symbol (sxhash x)) ; through DEFTRANSFORM
+ (array
+ (typecase x
+ (simple-string (sxhash x)) ; through DEFTRANSFORM
+ (string (%sxhash-substring x))
+ (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 %VECTOR-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 +max-hash-depthoid+)))