contracts for gvector, skip-list
reorganized tests
This commit is contained in:
parent
50c408e872
commit
19be445d89
|
@ -6,23 +6,18 @@
|
||||||
racket/dict
|
racket/dict
|
||||||
racket/vector)
|
racket/vector)
|
||||||
|
|
||||||
(define make-gvector*
|
(define (make-gvector #:capacity [capacity 10])
|
||||||
(let ([make-gvector
|
(make-gvector (make-vector capacity #f) 0))
|
||||||
(lambda (#:capacity [capacity 10])
|
|
||||||
(make-gvector (make-vector capacity #f) 0))])
|
|
||||||
make-gvector))
|
|
||||||
|
|
||||||
(define gvector*
|
(define gvector*
|
||||||
(let ([gvector
|
(let ([gvector
|
||||||
(lambda init-elements
|
(lambda init-elements
|
||||||
(let ([gv (make-gvector*)])
|
(let ([gv (make-gvector)])
|
||||||
(apply gvector-add! gv init-elements)
|
(apply gvector-add! gv init-elements)
|
||||||
gv))])
|
gv))])
|
||||||
gvector))
|
gvector))
|
||||||
|
|
||||||
(define (check-index who index n set-to-add?)
|
(define (check-index who index n set-to-add?)
|
||||||
(unless (exact-nonnegative-integer? index)
|
|
||||||
(raise-type-error who "exact nonnegative integer" index))
|
|
||||||
(unless (< index n)
|
(unless (< index n)
|
||||||
(error who "index out of range ~a~a: ~s"
|
(error who "index out of range ~a~a: ~s"
|
||||||
(let ([max-index (if set-to-add? (- n 2) (- n 1))])
|
(let ([max-index (if set-to-add? (- n 2) (- n 1))])
|
||||||
|
@ -149,7 +144,7 @@
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[(_ (clause ...) . body)
|
[(_ (clause ...) . body)
|
||||||
(quasisyntax/loc stx
|
(quasisyntax/loc stx
|
||||||
(let ([gv (make-gvector*)])
|
(let ([gv (make-gvector)])
|
||||||
(for/fold/derived #,stx () (clause ...)
|
(for/fold/derived #,stx () (clause ...)
|
||||||
(call-with-values (lambda () . body)
|
(call-with-values (lambda () . body)
|
||||||
(lambda args (apply gvector-add! gv args) (values))))
|
(lambda args (apply gvector-add! gv args) (values))))
|
||||||
|
@ -159,25 +154,29 @@
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[(_ (clause ...) . body)
|
[(_ (clause ...) . body)
|
||||||
(quasisyntax/loc stx
|
(quasisyntax/loc stx
|
||||||
(let ([gv (make-gvector*)])
|
(let ([gv (make-gvector)])
|
||||||
(for*/fold/derived #,stx () (clause ...)
|
(for*/fold/derived #,stx () (clause ...)
|
||||||
(call-with-values (lambda () . body)
|
(call-with-values (lambda () . body)
|
||||||
(lambda args (apply gvector-add! gv args) (values))))
|
(lambda args (apply gvector-add! gv args) (values))))
|
||||||
gv))]))
|
gv))]))
|
||||||
|
|
||||||
(define-struct gvector (vec n)
|
(struct gvector (vec n)
|
||||||
#:mutable
|
#:mutable
|
||||||
#:property prop:dict
|
#:property prop:dict/contract
|
||||||
(vector gvector-ref
|
(list (vector-immutable gvector-ref
|
||||||
gvector-set!
|
gvector-set!
|
||||||
#f ;; set
|
#f ;; set
|
||||||
gvector-remove!
|
gvector-remove!
|
||||||
#f ;; remove
|
#f ;; remove
|
||||||
gvector-count
|
gvector-count
|
||||||
gvector-iterate-first
|
gvector-iterate-first
|
||||||
gvector-iterate-next
|
gvector-iterate-next
|
||||||
gvector-iterate-key
|
gvector-iterate-key
|
||||||
gvector-iterate-value)
|
gvector-iterate-value)
|
||||||
|
(vector-immutable exact-nonnegative-integer?
|
||||||
|
any/c
|
||||||
|
exact-nonnegative-integer?
|
||||||
|
#f #f #f))
|
||||||
#:property prop:equal+hash
|
#:property prop:equal+hash
|
||||||
(let ([equals
|
(let ([equals
|
||||||
(lambda (x y recursive-equal?)
|
(lambda (x y recursive-equal?)
|
||||||
|
@ -204,7 +203,7 @@
|
||||||
(-> any/c any)]
|
(-> any/c any)]
|
||||||
[rename gvector* gvector
|
[rename gvector* gvector
|
||||||
(->* () () #:rest any/c gvector?)]
|
(->* () () #:rest any/c gvector?)]
|
||||||
[rename make-gvector* make-gvector
|
[make-gvector
|
||||||
(->* () (#:capacity exact-positive-integer?) gvector?)]
|
(->* () (#:capacity exact-positive-integer?) gvector?)]
|
||||||
[gvector-ref
|
[gvector-ref
|
||||||
(->* (gvector? exact-nonnegative-integer?) (any/c) any)]
|
(->* (gvector? exact-nonnegative-integer?) (any/c) any)]
|
||||||
|
|
|
@ -282,17 +282,19 @@ Levels are indexed starting at 1, as in the paper.
|
||||||
(set-item-data! (skip-list-iter-item iter) value))
|
(set-item-data! (skip-list-iter-item iter) value))
|
||||||
|
|
||||||
(struct skip-list ([head #:mutable] [num-entries #:mutable] =? <?)
|
(struct skip-list ([head #:mutable] [num-entries #:mutable] =? <?)
|
||||||
#:property prop:dict
|
#:property prop:dict/contract
|
||||||
(vector skip-list-ref
|
(list (vector-immutable skip-list-ref
|
||||||
skip-list-set!
|
skip-list-set!
|
||||||
#f ;; set
|
#f ;; set
|
||||||
skip-list-remove!
|
skip-list-remove!
|
||||||
#f ;; remove
|
#f ;; remove
|
||||||
skip-list-count
|
skip-list-count
|
||||||
skip-list-iterate-first
|
skip-list-iterate-first
|
||||||
skip-list-iterate-next
|
skip-list-iterate-next
|
||||||
skip-list-iterate-key
|
skip-list-iterate-key
|
||||||
skip-list-iterate-value)
|
skip-list-iterate-value)
|
||||||
|
(vector-immutable any/c any/c skip-list-iter?
|
||||||
|
#f #f #f))
|
||||||
#:property prop:ordered-dict
|
#:property prop:ordered-dict
|
||||||
(vector-immutable skip-list-iterate-min
|
(vector-immutable skip-list-iterate-min
|
||||||
skip-list-iterate-max
|
skip-list-iterate-max
|
||||||
|
|
|
@ -200,6 +200,49 @@ In (values status nroot pside pnode):
|
||||||
(when B
|
(when B
|
||||||
(set-node-key! B (+ (node-key B) Kx))))]))
|
(set-node-key! B (+ (node-key B) Kx))))]))
|
||||||
|
|
||||||
|
#|
|
||||||
|
Top-down splay
|
||||||
|
|#
|
||||||
|
|
||||||
|
#|
|
||||||
|
(define (findt cmp tx k x scratch)
|
||||||
|
(if x
|
||||||
|
(findt* cmp tx k x scratch scratch scratch)
|
||||||
|
(values #f #f)))
|
||||||
|
|
||||||
|
(define (findt* cmp tx k t scratch l r)
|
||||||
|
(define-syntax-rule (assemble! t)
|
||||||
|
(set-node-right! l (node-left t))
|
||||||
|
(set-node-left! r (node-right t))
|
||||||
|
(set-node-left! t (node-right scratch))
|
||||||
|
(set-node-right! t (node-left scratch))
|
||||||
|
t)
|
||||||
|
(define-syntax-rule (continue t)
|
||||||
|
(findt* cmp tx k t scratch l r))
|
||||||
|
(define-syntax-rule (rotate&link cmpresult rl (node-A set-node-A!) (node-B set-node-B!))
|
||||||
|
(let ([tsub (node-A t)])
|
||||||
|
(cond [tsub
|
||||||
|
(let-values ([(continue? t)
|
||||||
|
(case (cmp k (node-key tsub))
|
||||||
|
((cmpresult)
|
||||||
|
(set-node-A! t (node-B tsub))
|
||||||
|
(set-node-B! tsub t)
|
||||||
|
(cond [(node-A tsub) (values #t tsub)]
|
||||||
|
[else (values #f tsub)])))])
|
||||||
|
(cond [continue?
|
||||||
|
(set-node-A! rl t)
|
||||||
|
(continue t)]
|
||||||
|
[else
|
||||||
|
(assemble! t)]))])))
|
||||||
|
(case (cmp k (node-key x))
|
||||||
|
((<)
|
||||||
|
(rotate&link < r (node-left set-node-left!) (node-right set-node-right!)))
|
||||||
|
((>)
|
||||||
|
(rotate&link > l (node-right set-node-right!) (node-left! set-node-left!)))
|
||||||
|
(else
|
||||||
|
(assemble t))))
|
||||||
|
|#
|
||||||
|
|
||||||
;; --------
|
;; --------
|
||||||
|
|
||||||
;; if left is node, new root is max(left)
|
;; if left is node, new root is max(left)
|
||||||
|
|
|
@ -9,11 +9,8 @@
|
||||||
;; - skip-list
|
;; - skip-list
|
||||||
;; - splay-tree
|
;; - splay-tree
|
||||||
|
|
||||||
(test-case "random keys and values"
|
(define (rand-test dicts ordered?)
|
||||||
(let ([hash (make-hash)]
|
(let ([hash (make-hash)])
|
||||||
[dicts (list (make-skip-list = <)
|
|
||||||
(make-splay-tree = <)
|
|
||||||
(make-integer-splay-tree #:adjust? #t))])
|
|
||||||
(for ([c (in-range 100)])
|
(for ([c (in-range 100)])
|
||||||
(let* ([k (- (random 2000) 1000)]
|
(let* ([k (- (random 2000) 1000)]
|
||||||
[v (- (random 2000) 1000)])
|
[v (- (random 2000) 1000)])
|
||||||
|
@ -27,29 +24,77 @@
|
||||||
(check-equal? vh vd (format "dict ~e, key = ~s, value = ~s, expected = ~s"
|
(check-equal? vh vd (format "dict ~e, key = ~s, value = ~s, expected = ~s"
|
||||||
d i vd vh)))))
|
d i vd vh)))))
|
||||||
|
|
||||||
|
(when ordered?
|
||||||
|
(for ([c (in-range 100)])
|
||||||
|
(let* ([k0 (- (random 2000) 1000)])
|
||||||
|
(for ([d dicts])
|
||||||
|
(let* ([has? (dict-has-key? d k0)]
|
||||||
|
[l>i (dict-iterate-least/>? d k0)]
|
||||||
|
[l>=i (dict-iterate-least/>=? d k0)]
|
||||||
|
[g<i (dict-iterate-greatest/<? d k0)]
|
||||||
|
[g<=i (dict-iterate-greatest/<=? d k0)]
|
||||||
|
[l> (and l>i (dict-iterate-key d l>i))]
|
||||||
|
[l>= (and l>=i (dict-iterate-key d l>=i))]
|
||||||
|
[g< (and g<i (dict-iterate-key d g<i))]
|
||||||
|
[g<= (and g<=i (dict-iterate-key d g<=i))])
|
||||||
|
(when has?
|
||||||
|
(check-equal? l>= g<= "has, should be same"))
|
||||||
|
(unless has?
|
||||||
|
(check-equal? l> l>= "not has, should be same")
|
||||||
|
(check-equal? g< g<= "not has, should be same"))
|
||||||
|
(when l> (check > l> k0))
|
||||||
|
(when l>= (check >= l>= k0))
|
||||||
|
(when g< (check < g< k0))
|
||||||
|
(when g<= (check <= g<= k0))
|
||||||
|
(for ([k (in-dict-keys d)])
|
||||||
|
(when (and l> (and (> k k0) (< k l>))) (error "l>"))
|
||||||
|
(when (and l>= (and (>= k k0) (< k l>=))) (error "l>="))
|
||||||
|
(when (and g< (and (< k k0) (> k g<))) (error "g<"))
|
||||||
|
(when (and g<= (and (<= k k0) (> k g<=))) (error "g<="))))))))))
|
||||||
|
|
||||||
|
(test-case "skip-list tests"
|
||||||
|
(rand-test (list (make-skip-list = <)) #t))
|
||||||
|
|
||||||
|
(test-case "splay-tree test"
|
||||||
|
(rand-test (list (make-splay-tree = <)) #t))
|
||||||
|
|
||||||
|
(test-case "int-splay-tree w adjust"
|
||||||
|
(rand-test (list (make-integer-splay-tree #:adjust? #t)) #t))
|
||||||
|
|
||||||
|
(provide rand-test)
|
||||||
|
|
||||||
|
#|
|
||||||
|
(define (splay-test splays _eh)
|
||||||
|
(let ([hash (make-hash)])
|
||||||
(for ([c (in-range 100)])
|
(for ([c (in-range 100)])
|
||||||
(let* ([k0 (- (random 2000) 1000)])
|
(let* ([k (- (random 2000) 1000)]
|
||||||
(for ([d dicts])
|
[v (- (random 2000) 1000)])
|
||||||
(let* ([has? (dict-has-key? d k0)]
|
(hash-set! hash k v)
|
||||||
[l>i (dict-iterate-least/>? d k0)]
|
(for ([d splays])
|
||||||
[l>=i (dict-iterate-least/>=? d k0)]
|
(splay-tree-set! d k v))))
|
||||||
[g<i (dict-iterate-greatest/<? d k0)]
|
|
||||||
[g<=i (dict-iterate-greatest/<=? d k0)]
|
(for ([i (in-range -1000 1000)])
|
||||||
[l> (and l>i (dict-iterate-key d l>i))]
|
(for ([d splays])
|
||||||
[l>= (and l>=i (dict-iterate-key d l>=i))]
|
(let ([vh (hash-ref hash i 'not-there)]
|
||||||
[g< (and g<i (dict-iterate-key d g<i))]
|
[vd (splay-tree-ref d i 'not-there)])
|
||||||
[g<= (and g<=i (dict-iterate-key d g<=i))])
|
(check-equal? vh vd (format "dict ~e, key = ~s, value = ~s, expected = ~s"
|
||||||
(when has?
|
d i vd vh)))))))
|
||||||
(check-equal? l>= g<= "has, should be same"))
|
|
||||||
(unless has?
|
(provide splay-test)
|
||||||
(check-equal? l> l>= "not has, should be same")
|
|
||||||
(check-equal? g< g<= "not has, should be same"))
|
(require (prefix-in ud: racket/private/dict)
|
||||||
(when l> (check > l> k0))
|
(prefix-in cd: racket/dict))
|
||||||
(when l>= (check >= l>= k0))
|
|
||||||
(when g< (check < g< k0))
|
(define-syntax-rule (htest *dict-set! *dict-ref)
|
||||||
(when g<= (check <= g<= k0))
|
(let ([h (make-hash)])
|
||||||
(for ([k (in-dict-keys d)])
|
(for ([c (in-range 100)])
|
||||||
(when (and l> (and (> k k0) (< k l>))) (error "l>"))
|
(*dict-set! h (- (random 2000) 1000) (- (random 2000) 1000)))
|
||||||
(when (and l>= (and (>= k k0) (< k l>=))) (error "l>="))
|
(for ([i (in-range -1000 1000)])
|
||||||
(when (and g< (and (< k k0) (> k g<))) (error "g<"))
|
(*dict-ref h i 'not-there))))
|
||||||
(when (and g<= (and (<= k k0) (> k g<=))) (error "g<=")))))))))
|
|
||||||
|
(define (ud-test) (htest ud:dict-set! ud:dict-ref))
|
||||||
|
(define (cd-test) (htest cd:dict-set! cd:dict-ref))
|
||||||
|
|
||||||
|
(provide ud-test
|
||||||
|
cd-test)
|
||||||
|
|#
|
||||||
|
|
Loading…
Reference in New Issue
Block a user