From 878d3609b28ab784abc21e8991cc7949c1ea0041 Mon Sep 17 00:00:00 2001 From: Chris Hanson <org/chris-hanson/cph> Date: Wed, 6 Oct 1993 21:17:13 +0000 Subject: [PATCH] Add type-checking of tree arguments and interrupt locking. Add new operations RB-TREE/KEY-LIST and RB-TREE/DATUM-LIST. --- v7/src/runtime/rbtree.scm | 171 +++++++++++++++++++++++++------------ v7/src/runtime/runtime.pkg | 4 +- v8/src/runtime/runtime.pkg | 4 +- 3 files changed, 124 insertions(+), 55 deletions(-) diff --git a/v7/src/runtime/rbtree.scm b/v7/src/runtime/rbtree.scm index b61820d4b..7ba0d96fa 100644 --- a/v7/src/runtime/rbtree.scm +++ b/v7/src/runtime/rbtree.scm @@ -1,6 +1,6 @@ #| -*-Scheme-*- -$Id: rbtree.scm,v 1.1 1993/10/05 07:17:24 cph Exp $ +$Id: rbtree.scm,v 1.2 1993/10/06 21:16:35 cph Exp $ Copyright (c) 1993 Massachusetts Institute of Technology @@ -67,6 +67,10 @@ MIT in each case. |# ((eq? key<? flo:<) (lambda (x y) (flo:< x y))) (else key<?)))) +(define-integrable (guarantee-rb-tree tree procedure) + (if (not (rb-tree? tree)) + (error:wrong-type-argument tree "red/black tree" procedure))) + (define-structure (node (constructor make-node (key datum))) key @@ -126,8 +130,10 @@ MIT in each case. |# (rotate+! tree x (-d d))) (define (rb-tree/insert! tree key datum) + (guarantee-rb-tree tree 'RB-TREE/INSERT!) (let ((key=? (tree-key=? tree)) - (key<? (tree-key<? tree))) + (key<? (tree-key<? tree)) + (interrupt-mask (set-interrupt-enables! interrupt-mask/gc-ok))) (let loop ((x (tree-root tree)) (y #f) (d #f)) (cond ((not x) (let ((z (make-node key datum))) @@ -139,7 +145,9 @@ MIT in each case. |# (insert-fixup! tree z))) ((key=? key (node-key x)) (set-node-datum! x datum)) ((key<? key (node-key x)) (loop (node-left x) x 'LEFT)) - (else (loop (node-right x) x 'RIGHT)))))) + (else (loop (node-right x) x 'RIGHT)))) + (set-interrupt-enables! interrupt-mask) + unspecific)) (define (insert-fixup! tree x) ;; Assumptions: X is red, and the only possible violation of the @@ -179,13 +187,17 @@ MIT in each case. |# tree)) (define (rb-tree/delete! tree key) + (guarantee-rb-tree tree 'RB-TREE/DELETE!) (let ((key=? (tree-key=? tree)) - (key<? (tree-key<? tree))) + (key<? (tree-key<? tree)) + (interrupt-mask (set-interrupt-enables! interrupt-mask/gc-ok))) (let loop ((x (tree-root tree))) (cond ((not x) unspecific) ((key=? key (node-key x)) (delete-node! tree x)) ((key<? key (node-key x)) (loop (node-left x))) - (else (loop (node-right x))))))) + (else (loop (node-right x))))) + (set-interrupt-enables! interrupt-mask) + unspecific)) (define (delete-node! tree z) (let ((z @@ -246,16 +258,23 @@ MIT in each case. |# (case-4 (get-link- u d))))))))))) (define (rb-tree/lookup tree key default) + (guarantee-rb-tree tree 'RB-TREE/LOOKUP) (let ((key=? (tree-key=? tree)) - (key<? (tree-key<? tree))) - (let loop ((x (tree-root tree))) - (cond ((not x) default) - ((key=? key (node-key x)) (node-datum x)) - ((key<? key (node-key x)) (loop (node-left x))) - (else (loop (node-right x))))))) + (key<? (tree-key<? tree)) + (interrupt-mask (set-interrupt-enables! interrupt-mask/gc-ok))) + (let ((result + (let loop ((x (tree-root tree))) + (cond ((not x) default) + ((key=? key (node-key x)) (node-datum x)) + ((key<? key (node-key x)) (loop (node-left x))) + (else (loop (node-right x))))))) + (set-interrupt-enables! interrupt-mask) + result))) (define (rb-tree/copy tree) - (let ((result (make-rb-tree (tree-key=? tree) (tree-key<? tree)))) + (guarantee-rb-tree tree 'RB-TREE/COPY) + (let ((result (make-rb-tree (tree-key=? tree) (tree-key<? tree))) + (interrupt-mask (set-interrupt-enables! interrupt-mask/gc-ok))) (set-tree-root! result (let loop ((node (tree-root tree)) (up #f)) @@ -266,59 +285,105 @@ MIT in each case. |# (set-node-left! node* (loop (node-left node) node*)) (set-node-right! node* (loop (node-right node) node*)) node*)))) + (set-interrupt-enables! interrupt-mask) result)) +(define (rb-tree/height tree) + (guarantee-rb-tree tree 'RB-TREE/HEIGHT) + (let ((interrupt-mask (set-interrupt-enables! interrupt-mask/gc-ok))) + (let ((result + (let loop ((node (tree-root tree))) + (if node + (+ 1 + (max (loop (node-left node)) + (loop (node-right node)))) + 0)))) + (set-interrupt-enables! interrupt-mask) + result))) + +(define (rb-tree/size tree) + (guarantee-rb-tree tree 'RB-TREE/SIZE) + (let ((interrupt-mask (set-interrupt-enables! interrupt-mask/gc-ok))) + (let ((result + (let loop ((node (tree-root tree))) + (if node + (+ 1 + (loop (node-left node)) + (loop (node-right node))) + 0)))) + (set-interrupt-enables! interrupt-mask) + result))) + +(define (rb-tree/empty? tree) + (guarantee-rb-tree tree 'RB-TREE/EMPTY?) + (not (tree-root tree))) + (define (rb-tree/equal? x y datum=?) - (let ((key=? (tree-key=? x))) - (and (eq? key=? (tree-key=? y)) - (let loop ((nx (first-node x)) (ny (first-node y))) - (if (not nx) - (not ny) - (and ny - (key=? (node-key nx) (node-key ny)) - (datum=? (node-datum nx) (node-datum ny)) - (loop (next-node nx) (next-node ny)))))))) + (guarantee-rb-tree x 'RB-TREE/EQUAL?) + (guarantee-rb-tree y 'RB-TREE/EQUAL?) + (let ((key=? (tree-key=? x)) + (interrupt-mask (set-interrupt-enables! interrupt-mask/gc-ok))) + (let ((result + (and (eq? key=? (tree-key=? y)) + (let loop ((nx (first-node x)) (ny (first-node y))) + (if (not nx) + (not ny) + (and ny + (key=? (node-key nx) (node-key ny)) + (datum=? (node-datum nx) (node-datum ny)) + (loop (next-node nx) (next-node ny)))))))) + (set-interrupt-enables! interrupt-mask) + result))) (define (rb-tree->alist tree) - (let loop ((node (first-node tree))) - (if node - (cons (cons (node-key node) (node-datum node)) - (loop (next-node node))) - '()))) + (guarantee-rb-tree tree 'RB-TREE->ALIST) + (let ((interrupt-mask (set-interrupt-enables! interrupt-mask/gc-ok))) + (let ((result + (let loop ((node (first-node tree))) + (if node + (cons (cons (node-key node) (node-datum node)) + (loop (next-node node))) + '())))) + (set-interrupt-enables! interrupt-mask) + result))) + +(define (rb-tree/key-list tree) + (guarantee-rb-tree tree 'RB-TREE/KEY-LIST) + (let ((interrupt-mask (set-interrupt-enables! interrupt-mask/gc-ok))) + (let ((result + (let loop ((node (first-node tree))) + (if node + (cons (node-key node) (loop (next-node node))) + '())))) + (set-interrupt-enables! interrupt-mask) + result))) + +(define (rb-tree/datum-list tree) + (guarantee-rb-tree tree 'RB-TREE/DATUM-LIST) + (let ((interrupt-mask (set-interrupt-enables! interrupt-mask/gc-ok))) + (let ((result + (let loop ((node (first-node tree))) + (if node + (cons (node-datum node) (loop (next-node node))) + '())))) + (set-interrupt-enables! interrupt-mask) + result))) (define (first-node tree) (and (tree-root tree) - (leftmost-node (tree-root tree)))) + (let loop ((x (tree-root tree))) + (if (node-left x) + (loop (node-left x)) + x)))) (define (next-node x) (if (node-right x) - (leftmost-node (node-right x)) + (let loop ((x (node-right x))) + (if (node-left x) + (loop (node-left x)) + x)) (let loop ((x x)) (let ((y (node-up x))) (if (and y (eq? x (node-right y))) (loop y) - y))))) - -(define (leftmost-node x) - (if (node-left x) - (leftmost-node (node-left x)) - x)) - -(define (rb-tree/height tree) - (let loop ((node (tree-root tree))) - (if node - (+ 1 - (max (loop (node-left node)) - (loop (node-right node)))) - 0))) - -(define (rb-tree/size tree) - (let loop ((node (tree-root tree))) - (if node - (+ 1 - (loop (node-left node)) - (loop (node-right node))) - 0))) - -(define (rb-tree/empty? tree) - (not (tree-root tree))) \ No newline at end of file + y))))) \ No newline at end of file diff --git a/v7/src/runtime/runtime.pkg b/v7/src/runtime/runtime.pkg index 26cca6e1a..23751390c 100644 --- a/v7/src/runtime/runtime.pkg +++ b/v7/src/runtime/runtime.pkg @@ -1,6 +1,6 @@ #| -*-Scheme-*- -$Id: runtime.pkg,v 14.196 1993/10/05 07:16:21 cph Exp $ +$Id: runtime.pkg,v 14.197 1993/10/06 21:17:13 cph Exp $ Copyright (c) 1988-1993 Massachusetts Institute of Technology @@ -2543,11 +2543,13 @@ MIT in each case. |# alist->rb-tree rb-tree->alist rb-tree/copy + rb-tree/datum-list rb-tree/delete! rb-tree/empty? rb-tree/equal? rb-tree/height rb-tree/insert! + rb-tree/key-list rb-tree/lookup rb-tree/size rb-tree? diff --git a/v8/src/runtime/runtime.pkg b/v8/src/runtime/runtime.pkg index 26cca6e1a..23751390c 100644 --- a/v8/src/runtime/runtime.pkg +++ b/v8/src/runtime/runtime.pkg @@ -1,6 +1,6 @@ #| -*-Scheme-*- -$Id: runtime.pkg,v 14.196 1993/10/05 07:16:21 cph Exp $ +$Id: runtime.pkg,v 14.197 1993/10/06 21:17:13 cph Exp $ Copyright (c) 1988-1993 Massachusetts Institute of Technology @@ -2543,11 +2543,13 @@ MIT in each case. |# alist->rb-tree rb-tree->alist rb-tree/copy + rb-tree/datum-list rb-tree/delete! rb-tree/empty? rb-tree/equal? rb-tree/height rb-tree/insert! + rb-tree/key-list rb-tree/lookup rb-tree/size rb-tree? -- 2.25.1