mirror of
git://git.code.sf.net/p/sbcl/sbcl
synced 2026-09-10 07:26:40 -04:00
Improve and fix BBtree tests
Don't use 0 as a key
This commit is contained in:
parent
93886596f1
commit
5d49acca77
|
|
@ -1,3 +1,4 @@
|
||||||
|
(load "bbtree-test-util.lisp")
|
||||||
(use-package "SB-INT")
|
(use-package "SB-INT")
|
||||||
|
|
||||||
#-sb-thread (invoke-restart 'run-tests::skip-file) ;; some of the symbols below disappear
|
#-sb-thread (invoke-restart 'run-tests::skip-file) ;; some of the symbols below disappear
|
||||||
|
|
@ -100,57 +101,8 @@ node [shape=record];~%")
|
||||||
(random-operations 10 10 nil)
|
(random-operations 10 10 nil)
|
||||||
(random-operations 10 200 nil))
|
(random-operations 10 200 nil))
|
||||||
|
|
||||||
;; TOD: perform this test on the red-black trees as well.
|
(defun test-avlfind-inexact (n-nodes n-iterations)
|
||||||
(defun test-find-inexact (n-nodes n-iterations)
|
(bbtree-test:test-find-inexact-macro avl-insert avl-find<= avl-find>= avlnode-key))
|
||||||
(let (integers)
|
|
||||||
;; Generate N random integers
|
|
||||||
(dotimes (i n-nodes)
|
|
||||||
(loop
|
|
||||||
(let ((val (random 1000)))
|
|
||||||
(unless (member val integers)
|
|
||||||
(push val integers)
|
|
||||||
(return)))))
|
|
||||||
(setq integers (coerce integers 'vector))
|
|
||||||
(dotimes (i n-iterations)
|
|
||||||
;; Try many different shuffles of the insertion order because each
|
|
||||||
;; potentially yields a different tree.
|
|
||||||
(test-util:shuffle integers)
|
|
||||||
;; Convert a tree
|
|
||||||
(let ((tree nil))
|
|
||||||
(dotimes (i (length integers))
|
|
||||||
(setq tree (avl-insert tree (svref integers i) (svref integers i))))
|
|
||||||
(setq integers (sort integers #'<))
|
|
||||||
(dotimes (i (length integers))
|
|
||||||
(let ((this (svref integers i))
|
|
||||||
(pred (if (> i 0) (svref integers (1- i))))
|
|
||||||
(succ (if (< i (1- (length integers))) (svref integers (1+ i)))))
|
|
||||||
;; THIS should be found exactly
|
|
||||||
(let ((answer (avl-find<= this tree)))
|
|
||||||
(assert (eql (avlnode-key answer) this)))
|
|
||||||
(let ((answer (avl-find>= this tree)))
|
|
||||||
(assert (eql (avlnode-key answer) this)))
|
|
||||||
;; find this node by a smaller key using FIND>=
|
|
||||||
(unless (eql pred (1- this))
|
|
||||||
(assert (eql (avlnode-key (avl-find>= (1- this) tree)) this)))
|
|
||||||
;; find this node by a larger key using FIND<=
|
|
||||||
(unless (eql succ (1+ this))
|
|
||||||
(assert (eql (avlnode-key (avl-find<= (1+ this) tree)) this)))
|
|
||||||
;; check the boundary case of FIND<= and/or find the predecessor
|
|
||||||
(let ((answer (avl-find<= (1- this) tree)))
|
|
||||||
(if pred
|
|
||||||
(assert (eql (avlnode-key answer) pred))
|
|
||||||
(assert (not answer))))
|
|
||||||
;; check the boundary case of FIND>= and/or find the successor
|
|
||||||
(let ((answer (avl-find>= (1+ this) tree)))
|
|
||||||
(if succ
|
|
||||||
(assert (eql (avlnode-key answer) succ))
|
|
||||||
(assert (not answer))))))))))
|
|
||||||
|
|
||||||
(test-util:with-test (:name :find-inexact)
|
(test-util:with-test (:name :avl-find-inexact)
|
||||||
(loop for n-nodes from 1 to 20
|
(bbtree-test:exercise-find-inexact 'test-avlfind-inexact))
|
||||||
do (test-find-inexact n-nodes
|
|
||||||
(case n-nodes
|
|
||||||
(1 1)
|
|
||||||
(2 4)
|
|
||||||
(3 10)
|
|
||||||
(t 100)))))
|
|
||||||
|
|
|
||||||
62
tests/bbtree-test-util.lisp
Normal file
62
tests/bbtree-test-util.lisp
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
|
||||||
|
(defpackage "BBTREE-TEST"
|
||||||
|
(:use :cl)
|
||||||
|
(:export #:test-find-inexact-macro
|
||||||
|
#:exercise-find-inexact))
|
||||||
|
|
||||||
|
;;;; Tests of two different kinds of balanced binary trees
|
||||||
|
|
||||||
|
(defmacro bbtree-test:test-find-inexact-macro (insertion-fun find<=-fun find>=-fun node-key)
|
||||||
|
`(let (integers)
|
||||||
|
;; Generate N random integers
|
||||||
|
(dotimes (i n-nodes)
|
||||||
|
(loop
|
||||||
|
(let ((val (+ 5 (random 1000))))
|
||||||
|
(unless (member val integers)
|
||||||
|
(push val integers)
|
||||||
|
(return)))))
|
||||||
|
(setq integers (coerce integers 'vector))
|
||||||
|
(dotimes (i n-iterations)
|
||||||
|
;; Try many different shuffles of the insertion order because each
|
||||||
|
;; potentially yields a different tree.
|
||||||
|
(test-util:shuffle integers)
|
||||||
|
;; Convert a tree
|
||||||
|
(let ((tree nil))
|
||||||
|
(dotimes (i (length integers))
|
||||||
|
(setq tree (,insertion-fun tree (svref integers i) (svref integers i))))
|
||||||
|
(setq integers (sort integers #'<))
|
||||||
|
(dotimes (i (length integers))
|
||||||
|
(let ((this (svref integers i))
|
||||||
|
(pred (if (> i 0) (svref integers (1- i))))
|
||||||
|
(succ (if (< i (1- (length integers))) (svref integers (1+ i)))))
|
||||||
|
;; THIS should be found exactly
|
||||||
|
(let ((answer (,find<=-fun this tree)))
|
||||||
|
(assert (eql (,node-key answer) this)))
|
||||||
|
(let ((answer (,find>=-fun this tree)))
|
||||||
|
(assert (eql (,node-key answer) this)))
|
||||||
|
;; find this node by a smaller key using FIND>=
|
||||||
|
(unless (eql pred (1- this))
|
||||||
|
(assert (eql (,node-key (,find>=-fun (1- this) tree)) this)))
|
||||||
|
;; find this node by a larger key using FIND<=
|
||||||
|
(unless (eql succ (1+ this))
|
||||||
|
(assert (eql (,node-key (,find<=-fun (1+ this) tree)) this)))
|
||||||
|
;; check the boundary case of FIND<= and/or find the predecessor
|
||||||
|
(let ((answer (,find<=-fun (1- this) tree)))
|
||||||
|
(if pred
|
||||||
|
(assert (eql (,node-key answer) pred))
|
||||||
|
(assert (not answer))))
|
||||||
|
;; check the boundary case of FIND>= and/or find the successor
|
||||||
|
(let ((answer (,find>=-fun (1+ this) tree)))
|
||||||
|
(if succ
|
||||||
|
(assert (eql (,node-key answer) succ))
|
||||||
|
(assert (not answer))))))))))
|
||||||
|
|
||||||
|
(defun bbtree-test:exercise-find-inexact (fun)
|
||||||
|
(loop for n-nodes from 1 to 20
|
||||||
|
do (funcall fun n-nodes
|
||||||
|
(case n-nodes
|
||||||
|
(1 1)
|
||||||
|
(2 4)
|
||||||
|
(3 10)
|
||||||
|
(t 100)))))
|
||||||
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
(("aprof.impure.lisp"
|
(("aprof.impure.lisp"
|
||||||
"src/code/aprof.lisp"
|
"src/code/aprof.lisp"
|
||||||
"src/code/shaketree.lisp")
|
"src/code/shaketree.lisp")
|
||||||
|
("avltree.pure.lisp" "bbtree-test-util.lisp")
|
||||||
("bit-vector.impure.lisp" "contrib/sb-posix.fasl")
|
("bit-vector.impure.lisp" "contrib/sb-posix.fasl")
|
||||||
("case.pure.lisp" "tests/case-test.lisp")
|
("case.pure.lisp" "tests/case-test.lisp")
|
||||||
("chill.test.sh"
|
("chill.test.sh"
|
||||||
|
|
@ -53,6 +54,7 @@
|
||||||
("octets.pure.lisp"
|
("octets.pure.lisp"
|
||||||
"tests/data/compile-file-pos.lisp"
|
"tests/data/compile-file-pos.lisp"
|
||||||
"tests/data/compile-file-pos-utf16be.lisp")
|
"tests/data/compile-file-pos-utf16be.lisp")
|
||||||
|
("redblack.pure.lisp" "bbtree-test-util.lisp")
|
||||||
("run-program.impure.lisp" "contrib/sb-posix.fasl")
|
("run-program.impure.lisp" "contrib/sb-posix.fasl")
|
||||||
("signals.impure.lisp" "contrib/sb-posix.fasl")
|
("signals.impure.lisp" "contrib/sb-posix.fasl")
|
||||||
("stream.impure.lisp" "contrib/sb-posix.fasl")
|
("stream.impure.lisp" "contrib/sb-posix.fasl")
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
color-of left right
|
color-of left right
|
||||||
node-key node-value data
|
node-key node-value data
|
||||||
find= find<=))
|
find= find<=))
|
||||||
|
(load "bbtree-test-util.lisp")
|
||||||
|
|
||||||
(defun verify-invariants (root print)
|
(defun verify-invariants (root print)
|
||||||
(unless root
|
(unless root
|
||||||
|
|
@ -211,3 +212,10 @@
|
||||||
(dotimes (i n-items)
|
(dotimes (i n-items)
|
||||||
(setq tree (redblack:insert tree i i)))
|
(setq tree (redblack:insert tree i i)))
|
||||||
tree)
|
tree)
|
||||||
|
|
||||||
|
(defun test-rb-find-inexact (n-nodes n-iterations)
|
||||||
|
(bbtree-test:test-find-inexact-macro redblack:insert
|
||||||
|
find<= redblack:find>= node-key))
|
||||||
|
|
||||||
|
(test-util:with-test (:name :rb-find-inexact)
|
||||||
|
(bbtree-test:exercise-find-inexact 'test-rb-find-inexact))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue