diff --git a/collects/data/private/ordered-dict.rkt b/collects/data/private/ordered-dict.rkt new file mode 100644 index 0000000000..3248e37ace --- /dev/null +++ b/collects/data/private/ordered-dict.rkt @@ -0,0 +1,56 @@ +#lang racket/base +(require racket/dict + racket/contract/base + unstable/prop-contract) + +(define-values (prop:ordered-dict ordered-dict? ordered-dict-ref) + (make-struct-type-property 'ordered-dict #f)) + +(define extreme-contract + (->i ([d ordered-dict?]) + [_ (d) (or/c #f (dict-iter-contract d))])) + +(define search-contract + (->i ([d ordered-dict?] + [k (d) (dict-key-contract d)]) + [_ (d) (or/c #f (dict-iter-contract d))])) + +(define prop:ordered-dict-contract + (let ([e extreme-contract] + [s search-contract]) + (vector-immutable/c e ;; iterate-min + e ;; iterate-max + s ;; iterate-least/>? + s ;; iterate-least/>=? + s ;; iterate-greatest/? d k) + (appd d 2 k)) +(define (dict-iterate-least/>=? d k) + (appd d 3 k)) +(define (dict-iterate-greatest/ any/c boolean?)] + [dict-iterate-min extreme-contract] + [dict-iterate-max extreme-contract] + [dict-iterate-least/>? search-contract] + [dict-iterate-least/>=? search-contract] + [dict-iterate-greatest/ key (define (skip-list-iterate-least/>? s key) (let* ([head (skip-list-head s)] [= key @@ -256,7 +257,21 @@ Levels are indexed starting at 1, as in the paper. [? + skip-list-iterate-least/>=? + skip-list-iterate-greatest/ procedure? procedure? skip-list?)] [skip-list? (-> any/c boolean?)] @@ -310,6 +331,12 @@ Levels are indexed starting at 1, as in the paper. (-> skip-list? any/c (or/c skip-list-iter? #f))] [skip-list-iterate-least/>=? (-> skip-list? any/c (or/c skip-list-iter? #f))] + + [skip-list-iterate-min + (-> skip-list? (or/c skip-list-iter? #f))] + [skip-list-iterate-max + (-> skip-list? (or/c skip-list-iter? #f))] + [skip-list-iterate-set-key! (-> skip-list? skip-list-iter? any/c any)] [skip-list-iterate-set-value! diff --git a/collects/data/splay-tree.rkt b/collects/data/splay-tree.rkt index efa00e208c..4b976c9f08 100644 --- a/collects/data/splay-tree.rkt +++ b/collects/data/splay-tree.rkt @@ -1,7 +1,8 @@ #lang racket/base (require racket/match racket/dict - racket/contract) + racket/contract + "private/ordered-dict.rkt") ;; ======== Raw splay tree ======== @@ -403,44 +404,6 @@ Options ;; ======== -(struct splay-tree ([root #:mutable] [size #:mutable] cmp tx) - #:transparent - #:property prop:dict/contract - (list (vector-immutable splay-tree-ref - splay-tree-set! - #f ;; set - splay-tree-remove! - #f ;; remove - splay-tree-count - splay-tree-iterate-first - splay-tree-iterate-next - splay-tree-iterate-key - splay-tree-iterate-value) - (vector-immutable any/c - any/c - splay-tree-iter? - #f #f #f))) - -(struct splay-tree* splay-tree (key-c value-c) - #:transparent - #:property prop:dict/contract - (list (vector-immutable splay-tree-ref - splay-tree-set! - #f ;; set - splay-tree-remove! - #f ;; remove - splay-tree-count - splay-tree-iterate-first - splay-tree-iterate-next - splay-tree-iterate-key - splay-tree-iterate-value) - (vector-immutable any/c - any/c - splay-tree-iter? - (lambda (s) (splay-tree*-key-c s)) - (lambda (s) (splay-tree*-value-c s)) - #f))) - (define-syntax-rule (mkcmp ]))) @@ -467,11 +430,6 @@ In an integer splay tree, keys can be stored relative to their parent nodes. (define (splay-tree-with-adjust? s) (splay-tree-tx s)) -(define (key-c s) - (if (splay-tree*? s) (splay-tree*-key-c s) any/c)) -(define (val-c s) - (if (splay-tree*? s) (splay-tree*-value-c s) any/c)) - ;; ======== ;; Order-based search @@ -499,6 +457,15 @@ In an integer splay tree, keys can be stored relative to their parent nodes. (define (splay-tree-iterate-least/>? s key) (extreme 'splay-tree-iterate-least/>? s key '(>) has-next? find-next)) +(define (splay-tree-iterate-min s) + (splay-tree-iterate-first s)) +(define (splay-tree-iterate-max s) + (match s + [(splay-tree root size cmp tx) + (let-values ([(ok? root) (find-max tx root)]) + (set-splay-tree-root! s root) + (if ok? (splay-tree-iter (node-key root)) #f))])) + ;; ======== ;; snapshot @@ -517,6 +484,57 @@ In an integer splay tree, keys can be stored relative to their parent nodes. ;; ======== +(define (key-c s) + (if (splay-tree*? s) (splay-tree*-key-c s) any/c)) +(define (val-c s) + (if (splay-tree*? s) (splay-tree*-value-c s) any/c)) + +(define dict-methods + (vector-immutable splay-tree-ref + splay-tree-set! + #f ;; set + splay-tree-remove! + #f ;; remove + splay-tree-count + splay-tree-iterate-first + splay-tree-iterate-next + splay-tree-iterate-key + splay-tree-iterate-value)) + +(define ordered-dict-methods + (vector-immutable splay-tree-iterate-min + splay-tree-iterate-max + splay-tree-iterate-least/>? + splay-tree-iterate-least/>=? + splay-tree-iterate-greatest/* ((-> any/c any/c any) (-> any/c any/c any)) @@ -572,4 +590,9 @@ In an integer splay tree, keys can be stored relative to their parent nodes. [splay-tree-iterate-least/>? (->i ([s splay-tree?] [k (s) (key-c s)]) [_ (or/c splay-tree-iter? #f)])] + [splay-tree-iterate-min + (-> splay-tree? (or/c splay-tree-iter? #f))] + [splay-tree-iterate-max + (-> splay-tree? (or/c splay-tree-iter? #f))] + [splay-tree-iter? (-> any/c boolean?)]) diff --git a/collects/racket/dict.rkt b/collects/racket/dict.rkt index be1b562f72..7da317e3bd 100644 --- a/collects/racket/dict.rkt +++ b/collects/racket/dict.rkt @@ -228,4 +228,8 @@ in-dict in-dict-keys in-dict-values - in-dict-pairs) + in-dict-pairs + + dict-key-contract + dict-value-contract + dict-iter-contract) diff --git a/collects/tests/data/ordered-dict.rkt b/collects/tests/data/ordered-dict.rkt index 55d026f931..12b2e4e35e 100644 --- a/collects/tests/data/ordered-dict.rkt +++ b/collects/tests/data/ordered-dict.rkt @@ -2,28 +2,13 @@ (require rackunit racket/dict data/skip-list - data/splay-tree) + data/splay-tree + data/private/ordered-dict) ;; Tests for ordered dictionaries ;; - skip-list ;; - splay-tree -(define (it-least/>? d k) - (cond [(skip-list? d) (skip-list-iterate-least/>? d k)] - [(splay-tree? d) (splay-tree-iterate-least/>? d k)])) - -(define (it-least/>=? d k) - (cond [(skip-list? d) (skip-list-iterate-least/>=? d k)] - [(splay-tree? d) (splay-tree-iterate-least/>=? d k)])) - -(define (it-greatest/i (it-least/>? d k0)] - [l>=i (it-least/>=? d k0)] - [gi (dict-iterate-least/>? d k0)] + [l>=i (dict-iterate-least/>=? d k0)] + [g (and l>i (dict-iterate-key d l>i))] [l>= (and l>=i (dict-iterate-key d l>=i))] [g< (and g