Raymond Toy pushed to branch issue-240-set-diff-with-hash-table at cmucl / cmucl
Commits:
-
96e66071
by Raymond Toy at 2023-07-26T18:59:10-07:00
-
7ab5d243
by Raymond Toy at 2023-07-26T19:00:59-07:00
2 changed files:
Changes:
| ... | ... | @@ -746,7 +746,7 @@ |
| 746 | 746 | |
| 747 | 747 | ;; The minimum length of a list before we can use a hashtable. This
|
| 748 | 748 | ;; was determined experimentally.
|
| 749 | -(defconstant +min-list-length-for-hashtable+
|
|
| 749 | +(defparameter *min-list-length-for-hashtable*
|
|
| 750 | 750 | 15)
|
| 751 | 751 | |
| 752 | 752 | ;; Convert a list to a hashtable. The hashtable does not handle
|
| ... | ... | @@ -767,7 +767,7 @@ |
| 767 | 767 | ;; If the list is too short, the hashtable makes things
|
| 768 | 768 | ;; slower. We also need to balance memory usage.
|
| 769 | 769 | (let ((len (length list)))
|
| 770 | - (when (< len +min-list-length-for-hashtable+)
|
|
| 770 | + (when (< len *min-list-length-for-hashtable*)
|
|
| 771 | 771 | (return-from list-to-hashtable nil))
|
| 772 | 772 | (let ((hashtable (make-hash-table :test hash-test :size len)))
|
| 773 | 773 | (dolist (item list)
|
| ... | ... | @@ -855,7 +855,7 @@ |
| 855 | 855 | (cond (hashtable
|
| 856 | 856 | ;; list2 was placed in hash table.
|
| 857 | 857 | (let ((res nil))
|
| 858 | - (dolist (item list1)
|
|
| 858 | + (doli st (item list1)
|
|
| 859 | 859 | (unless (nth-value 1 (gethash (apply-key key item) hashtable))
|
| 860 | 860 | (push item res)))
|
| 861 | 861 | res))
|
| ... | ... | @@ -72,3 +72,20 @@ |
| 72 | 72 | (set-difference '("a" "b" "b" "C")
|
| 73 | 73 | '("c" "D" "e" "f" "g" "h")
|
| 74 | 74 | :test #'equalp))))
|
| 75 | + |
|
| 76 | +;; Simple test that we handle a key correctly
|
|
| 77 | +(define-test set-diff.hash-eql-with-key
|
|
| 78 | + (let ((lisp::*min-list-length-for-hashtable* 2))
|
|
| 79 | + (assert-equal '((3 "b") (2 "b"))
|
|
| 80 | + (set-difference '((1 "a") (2 "b") (3 "b"))
|
|
| 81 | + '((1 "a") (4 "c") (5 "d"))
|
|
| 82 | + :key #'first))))
|
|
| 83 | + |
|
| 84 | +(define-test set-diff.test-and-test-not
|
|
| 85 | + (assert-error 'simple-error
|
|
| 86 | + (set-difference '(1 2)
|
|
| 87 | + '(3 4)
|
|
| 88 | + :test 'eql
|
|
| 89 | + :test-not 'eql)))
|
|
| 90 | + |
|
| 91 | + |