1 (load "bbtree-test-util.lisp")
4 #-sb-thread
(invoke-restart 'run-tests
::skip-file
) ;; some of the symbols below disappear
6 (import 'sb-thread
::(avlnode-key avlnode-data avlnode-left avlnode-right
8 avl-insert avl-delete avl-find
9 avl-balance-factor avl-count
))
11 (defun tree-to-dot (tree output
)
12 (with-open-file (stream output
:direction
:output
:if-exists
:supersede
)
13 (format stream
"digraph G {
14 node [shape=record];~%")
15 (named-let recurse
((node tree
))
17 (let ((key (avlnode-key node
)))
18 (format stream
"node~d [label=\"~d\"];~%" key key
)
19 (awhen (avlnode-left node
)
20 (format stream
"node~d:sw -> node~d;~%" key
(avlnode-key it
))
22 (awhen (avlnode-right node
)
23 (format stream
"node~d:se -> node~d;~%" key
(avlnode-key it
))
25 (format stream
"}~%"))
28 (defun avl-verify-invariants (tree)
29 ;; ensure that it's a search tree
30 (named-let recurse
((node tree
) (min most-negative-fixnum
) (max most-positive-fixnum
))
32 (let ((key (avlnode-key node
)))
33 (assert (<= min key max
))
34 (recurse (avlnode-left node
) min
(1- key
))
35 (recurse (avlnode-right node
) (1+ key
) max
))))
36 ;; and as balanced as required
37 (named-let recurse
((node tree
))
39 (unless (<= -
1 (avl-balance-factor node
) +1)
40 (error "balance invariant failed on node ~d. b=~d~%"
41 (avlnode-key node
) (avl-balance-factor node
)))
42 (recurse (avlnode-left node
))
43 (recurse (avlnode-right node
)))))
45 (defun random-operations (n-trials n-ops print
46 &aux
(keys (make-array 5000 :fill-pointer
0))
48 (dotimes (iter n-trials
)
50 (format t
"Trial ~d " iter
)
52 (let (tree (prev-op :delete
))
53 (setf (fill-pointer keys
) 0)
55 for event from
0 repeat n-ops do
56 (assert (= (avl-count tree
) (length keys
)))
62 (let ((ct (length keys
)))
69 (when (and (eq op
:delete
) (zerop (length keys
)))
73 (write-char (if (eq op
:insert
) #\
+ #\-
)))
76 (flet ((new-key () (random most-positive-fixnum
)))
77 (let ((key (new-key)))
78 (loop while
(avl-find key tree
)
79 do
(setq key
(new-key)))
80 (push `(:insert .
,key
) events
)
81 (setq tree
(avl-insert tree key
(- key
)))
82 (vector-push-extend key keys
))))
84 (let* ((i (random (length keys
)))
86 (push `(:delete .
,key
) events
)
87 (setq tree
(avl-delete key tree
))
88 (assert (not (avl-find key tree
)))
89 (setf (aref keys i
) (aref keys
(1- (length keys
))))
90 (decf (fill-pointer keys
)))))
91 (avl-verify-invariants tree
)
92 (dotimes (i (length keys
))
93 (let* ((key (aref keys i
))
94 (node (avl-find key tree
)))
95 (unless (and node
(= (avlnode-data node
) (- key
)))
96 (error "failed to find ~s~%" key
)))))))
98 (format t
" ~d keys~%" (length keys
)))))
100 (test-util:with-test
(:name
:avltree-random-tester
)
101 (random-operations 10 10 nil
)
102 (random-operations 10 200 nil
))
104 (defun test-avlfind-inexact (n-nodes n-iterations
)
105 (bbtree-test:test-find-inexact-macro avl-insert avl-find
<= avl-find
>= avlnode-key
))
107 (test-util:with-test
(:name
:avl-find-inexact
)
108 (bbtree-test:exercise-find-inexact
'test-avlfind-inexact
))