summaryrefslogtreecommitdiff
path: root/test/src/fns-tests.el
diff options
context:
space:
mode:
authorAndrew G Cohen <cohen@andy.bu.edu>2022-03-10 09:30:00 +0800
committerAndrew G Cohen <cohen@andy.bu.edu>2022-04-04 07:43:11 +0800
commit9ff2f0be32be621a0a1953cac2d552afebafe226 (patch)
tree0be9c62c2e143e8dd00b14a090d73a4badd46eb2 /test/src/fns-tests.el
parente091bee8db9926716a3e7778275901696896cbdf (diff)
downloademacs-9ff2f0be32be621a0a1953cac2d552afebafe226.tar.gz
emacs-9ff2f0be32be621a0a1953cac2d552afebafe226.tar.bz2
emacs-9ff2f0be32be621a0a1953cac2d552afebafe226.zip
Replace list and vector sorting with TIMSORT algorithm
* src/Makefile.in (base_obj): Add sort.o. * src/deps.mk (fns.o): Add sort.c. * src/lisp.h: Add prototypes for inorder, tim_sort. * src/sort.c: New file providing tim_sort. * src/fns.c: Remove prototypes for removed routines. (merge_vectors, sort_vector_inplace, sort_vector_copy): Remove. (sort_list, sort_vector): Use tim_sort. * test/src/fns-tests.el (fns-tests-sort): New sorting unit tests.
Diffstat (limited to 'test/src/fns-tests.el')
-rw-r--r--test/src/fns-tests.el70
1 files changed, 70 insertions, 0 deletions
diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el
index 723ef4c710f..5b252e184f0 100644
--- a/test/src/fns-tests.el
+++ b/test/src/fns-tests.el
@@ -204,6 +204,76 @@
[-1 2 3 4 5 5 7 8 9]))
(should (equal (sort (vector 9 5 2 -1 5 3 8 7 4) (lambda (x y) (> x y)))
[9 8 7 5 5 4 3 2 -1]))
+ ;; Sort a reversed list and vector.
+ (should (equal
+ (sort (reverse (number-sequence 1 1000)) (lambda (x y) (< x y)))
+ (number-sequence 1 1000)))
+ (should (equal
+ (sort (reverse (vconcat (number-sequence 1 1000)))
+ (lambda (x y) (< x y)))
+ (vconcat (number-sequence 1 1000))))
+ ;; Sort a constant list and vector.
+ (should (equal
+ (sort (make-vector 100 1) (lambda (x y) (> x y)))
+ (make-vector 100 1)))
+ (should (equal
+ (sort (append (make-vector 100 1) nil) (lambda (x y) (> x y)))
+ (append (make-vector 100 1) nil)))
+ ;; Sort a long list and vector with every pair reversed.
+ (let ((vec (make-vector 100000 nil))
+ (logxor-vec (make-vector 100000 nil)))
+ (dotimes (i 100000)
+ (aset logxor-vec i (logxor i 1))
+ (aset vec i i))
+ (should (equal
+ (sort logxor-vec (lambda (x y) (< x y)))
+ vec))
+ (should (equal
+ (sort (append logxor-vec nil) (lambda (x y) (< x y)))
+ (append vec nil))))
+ ;; Sort a list and vector with seven swaps.
+ (let ((vec (make-vector 100 nil))
+ (swap-vec (make-vector 100 nil)))
+ (dotimes (i 100)
+ (aset vec i (- i 50))
+ (aset swap-vec i (- i 50)))
+ (mapc (lambda (p)
+ (let ((tmp (elt swap-vec (car p))))
+ (aset swap-vec (car p) (elt swap-vec (cdr p)))
+ (aset swap-vec (cdr p) tmp)))
+ '((48 . 94) (75 . 77) (33 . 41) (92 . 52)
+ (10 . 96) (1 . 14) (43 . 81)))
+ (should (equal
+ (sort (copy-sequence swap-vec) (lambda (x y) (< x y)))
+ vec))
+ (should (equal
+ (sort (append swap-vec nil) (lambda (x y) (< x y)))
+ (append vec nil))))
+ ;; Check for possible corruption after GC.
+ (let* ((size 3000)
+ (complex-vec (make-vector size nil))
+ (vec (make-vector size nil))
+ (counter 0)
+ (my-counter (lambda ()
+ (if (< counter 500)
+ (cl-incf counter)
+ (setq counter 0)
+ (garbage-collect))))
+ (rand 1)
+ (generate-random
+ (lambda () (setq rand
+ (logand (+ (* rand 1103515245) 12345) 2147483647)))))
+ ;; Make a complex vector and its sorted version.
+ (dotimes (i size)
+ (let ((r (funcall generate-random)))
+ (aset complex-vec i (cons r "a"))
+ (aset vec i (cons r "a"))))
+ ;; Sort it.
+ (should (equal
+ (sort complex-vec
+ (lambda (x y) (funcall my-counter) (< (car x) (car y))))
+ (sort vec 'car-less-than-car))))
+ ;; Check for sorting stability.
(should (equal
(sort
(vector