/usr/share/racket/collects/data/queue.rkt is in racket-common 6.1-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | #lang racket/base
(require racket/contract/base
(for-syntax racket/base
unstable/wrapc))
;; A Queue contains a linked list with mutable cdrs, holding two pointers
;; to the head and the tail -- where items are pulled from the head and
;; pushed on the tail. It is not thread safe: mutating a queue from
;; different threads can break it.
(struct queue (head tail length) #:mutable
#:property prop:sequence (λ (q) (in-queue q)))
;; (Note: uses #f for `head' to mark an empty queue, but in those cases
;; the tail will be set to #f too, to avoid holding on to values that
;; should be collected.)
(struct link (value [tail #:mutable]))
(define (make-queue) (queue #f #f 0))
(define (queue-empty? q) (not (queue-head q)))
(define (non-empty-queue? v) (and (queue? v) (queue-head v) #t))
(define (enqueue! q v)
(unless (queue? q) (raise-type-error enqueue! "queue" 0 q))
(let ([new (link v #f)])
(if (queue-head q)
(set-link-tail! (queue-tail q) new)
(set-queue-head! q new))
(set-queue-tail! q new)
(set-queue-length! q (+ (queue-length q) 1))))
(define (enqueue-front! q v)
(unless (queue? q) (raise-type-error enqueue! "enqueue-front!" 0 q))
(define fr (queue-head q))
(cond
[fr
(set-queue-head! q (link v fr))]
[else
(define k (link v #f))
(set-queue-head! q k)
(set-queue-tail! q k)])
(set-queue-length! q (+ (queue-length q) 1)))
(define (dequeue! q)
(unless (queue? q) (raise-type-error dequeue! "queue" 0 q))
(let ([old (queue-head q)])
(unless old (raise-type-error 'dequeue! "non-empty queue" 0 q))
(cond
[(eq? old (queue-tail q))
(set-queue-tail! q #f)
(set-queue-head! q #f)]
[else
(set-queue-head! q (link-tail old))])
(set-queue-length! q (- (queue-length q) 1))
(link-value old)))
(define (queue->list q) (for/list ([e (in-queue q)]) e))
;; queue->vector could be implemented as (list->vector (queue->list q))
;; but this is somewhat slow. a direct translation between queue's and
;; vector's should be fast so the ideal situation is not to use a list
;; as an intermediate data structure.
;; maybe add the elements to a gvector and use gvector->vector?
(define (queue-filter! q pred?)
(unless (queue-empty? q)
(let loop ([prev #f]
[curr (queue-head q)]
[i 0])
(cond
[(not curr)
(set-queue-tail! q prev)
(set-queue-length! q i)]
[else
(define passed? (pred? (link-value curr)))
(cond
[passed?
(loop curr (link-tail curr) (+ i 1))]
[else
(define tl (link-tail curr))
(if prev
(set-link-tail! prev tl)
(set-queue-head! q tl))
(loop prev tl i)])]))))
(define (in-queue q)
(make-do-sequence
(λ ()
(values
link-value
link-tail
(queue-head q)
link?
#f #f))))
(define-sequence-syntax in-queue*
(lambda () #'in-queue)
(lambda (stx)
(syntax-case stx ()
([(var) (in-queue* queue-expression)]
(with-syntax ([queue-expression/c (wrap-expr/c #'queue? #'queue-expression
#:macro #'in-queue*)])
#'[(var)
(:do-in ([(queue) queue-expression/c])
(void) ;; handled by contract
([link (queue-head queue)])
link
([(var) (link-value link)])
#t
#t
((link-tail link)))]))
([(var ...) (in-queue* queue-expression)]
#f))))
;; --- contracts ---
(define queue/c queue?)
(define nonempty-queue/c non-empty-queue?)
(provide/contract
[queue/c flat-contract?]
[nonempty-queue/c flat-contract?]
[queue? (-> any/c boolean?)]
[non-empty-queue? (-> any/c boolean?)]
[make-queue (-> queue?)]
[queue-empty? (-> queue? boolean?)]
[queue-length (-> queue? exact-nonnegative-integer?)]
[queue->list (-> queue? (listof any/c))]
[queue-filter! (-> queue? (-> any/c any/c) void?)])
(provide enqueue! enqueue-front!
dequeue! (rename-out [in-queue* in-queue]))
|