Raymond Toy pushed to branch issue-240-set-diff-with-hash-table at cmucl / cmucl

Commits:

2 changed files:

Changes:

  • src/code/list.lisp
    ... ... @@ -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))
    

  • tests/sets.lisp
    ... ... @@ -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
    +