mirror of
git://git.code.sf.net/p/sbcl/sbcl
synced 2026-09-10 07:26:40 -04:00
68 lines
2.7 KiB
Common Lisp
68 lines
2.7 KiB
Common Lisp
(defstruct foo)
|
|
|
|
(with-test (:name :xset-hash-equal)
|
|
(let ((list `(sym ,(make-foo) 1 -12d0 4/3 #\z ,(ash 1 70)))
|
|
(a (sb-int:alloc-xset)))
|
|
(dolist (elt list)
|
|
(sb-int:add-to-xset elt a))
|
|
(sb-kernel::xset-generate-stable-hashes a)
|
|
(dotimes (i 10)
|
|
(let ((b (sb-int:alloc-xset)))
|
|
(dolist (elt (shuffle list))
|
|
(sb-int:add-to-xset elt b))
|
|
(sb-kernel::xset-generate-stable-hashes b)
|
|
(assert (sb-int:xset= a b))
|
|
(assert (= (sb-int:xset-elts-hash a)
|
|
(sb-int:xset-elts-hash b)))))))
|
|
|
|
(with-test (:name :xset-hash-numerics-better)
|
|
;; It was very easy to make xsets which collided on their hash if any
|
|
;; elements got assigned a stable hash. In such xsets, the non-pointer elements
|
|
;; could hash to themselves. This meant that any set of fixnums which summed
|
|
;; to the same as another set of fixnums might hash identically
|
|
(let ((str "hi")
|
|
(xset1 (sb-int:alloc-xset))
|
|
(xset2 (sb-int:alloc-xset)))
|
|
(dolist (e `(1 ,str 10)) (sb-int:add-to-xset e xset1))
|
|
(dolist (e `(8 3 ,str)) (sb-int:add-to-xset e xset2))
|
|
(sb-kernel::xset-generate-stable-hashes xset1)
|
|
(sb-kernel::xset-generate-stable-hashes xset2)
|
|
(assert (/= (sb-int:xset-elts-hash xset1) (sb-int:xset-elts-hash xset2)))))
|
|
|
|
(with-test (:name :xset-fast-union)
|
|
(let ((s1 (sb-int:alloc-xset))
|
|
(s2 (sb-int:alloc-xset)))
|
|
(sb-int:add-to-xset #\a s1)
|
|
(sb-int:add-to-xset #\b s1)
|
|
(sb-int:add-to-xset #\c s1)
|
|
(assert (eq (sb-int:xset-union s1 s2) s1))
|
|
(assert (eq (sb-int:xset-union s2 s1) s1))
|
|
(sb-int:add-to-xset #\b s2)
|
|
(assert (eq (sb-int:xset-union s1 s2) s1))
|
|
(assert (eq (sb-int:xset-union s2 s1) s1)))
|
|
(let ((s1 (sb-int:alloc-xset))
|
|
(s2 (sb-int:alloc-xset)))
|
|
(loop for i from (char-code #\a) to (char-code #\z)
|
|
do (sb-int:add-to-xset (code-char i) s1))
|
|
(sb-int:add-to-xset #\x s2)
|
|
(loop for i from 1 to 10
|
|
do (sb-int:add-to-xset (code-char i) s1))
|
|
(assert (listp (sb-kernel::xset-data s2)))
|
|
(let ((union1 (sb-int:xset-union s1 s2)))
|
|
(assert (= (sb-int:xset-count union1) (+ 26 10)))
|
|
(let ((union2 (sb-int:xset-union s2 s1))) ; had better commute
|
|
(assert (sb-int:xset= union1 union2))))))
|
|
|
|
(with-test (:name :xset-dedup-list-to-hash)
|
|
(let ((x (sb-int:alloc-xset)))
|
|
(dotimes (i 20)
|
|
(sb-int:add-to-xset i x))
|
|
(assert (listp (sb-kernel::xset-data x)))
|
|
(dotimes (i 20)
|
|
(sb-int:add-to-xset i x))
|
|
;; didn't upgrade to a hash-table
|
|
(assert (listp (sb-kernel::xset-data x)))
|
|
(sb-kernel::xset-generate-stable-hashes x)
|
|
;; doesn't affect representation of DATA slot
|
|
(assert (listp (sb-kernel::xset-data x)))))
|