-
Notifications
You must be signed in to change notification settings - Fork 128
Expand file tree
/
Copy pathbuffers.pxi
More file actions
146 lines (114 loc) · 3.12 KB
/
buffers.pxi
File metadata and controls
146 lines (114 loc) · 3.12 KB
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
(ns pixie.buffers)
(defn acopy [src src-start dest dest-start len]
(loop [cnt 0]
(when (< cnt len)
(aset dest
(+ dest-start cnt)
(aget src (+ src-start cnt)))
(recur (inc cnt)))))
(defprotocol IMutableBuffer
(remove! [this])
(add! [this])
(full? [this]))
(defprotocol IResizableMutableBuffer
(add-unbounded! [this val])
(resize! [this new-size]))
(deftype RingBuffer [head tail length arr]
IMutableBuffer
(remove! [this]
(when-not (zero? length)
(let [x (aget arr tail)]
(aset arr tail nil)
(set-field! this :tail (int (rem (inc tail) (alength arr))))
(set-field! this :length (dec length))
x)))
(add! [this x]
(assert (< length (alength arr)))
(aset arr head x)
(set-field! this :head (int (rem (inc head) (alength arr))))
(set-field! this :length (inc length))
nil)
(full? [this]
(= length (alength arr)))
IResizableMutableBuffer
(resize! [this new-size]
(let [new-arr (make-array new-size)]
(cond
(< tail head)
(do (acopy arr tail new-arr 0 length)
(set-field! this :tail 0)
(set-field! this :head length)
(set-field! this :arr new-arr))
(> tail head)
(do (acopy arr tail new-arr 0 (- (alength arr) tail))
(acopy arr 0 new-arr (- (alength arr) tail) head)
(set-field! this :tail 0)
(set-field! this :head length)
(set-field! this :arr new-arr))
(full? this)
(do (acopy arr tail new-arr 0 length)
(set-field! this :tail 0)
(set-field! this :head length)
(set-field! this :arr new-arr))
:else
(do (set-field! this :tail 0)
(set-field! this :head 0)
(set-field! this :arr new-arr)))))
(add-unbounded! [this val]
(when (full? this)
(resize! this (* 2 length)))
(add! this val))
ICounted
(-count [this]
length))
(defn ring-buffer [size]
(assert (> size 0) "Can't create a ring buffer of size <= 0")
(->RingBuffer 0 0 0 (make-array size)))
(defn fixed-buffer [size]
(ring-buffer size))
(deftype DroppingBuffer [buf]
IMutableBuffer
(full? [this]
false)
(remove! [this]
(remove! buf))
(add! [this val]
(when-not (full? buf)
(add! buf val)))
ICounted
(-count [this]
(count buf)))
(defn dropping-buffer [size]
(->DroppingBuffer (ring-buffer size)))
(deftype SlidingBuffer [buf]
IMutableBuffer
(full? [this]
false)
(remove! [this]
(remove! buf))
(add! [this val]
(when (full? buf)
(remove! buf))
(add! buf val))
ICounted
(-count [this]
(count buf)))
(defn sliding-buffer [size]
(->SlidingBuffer (ring-buffer size)))
(defn empty-buffer? [buf]
(= (count buf) 0))
(deftype NullBuffer []
IMutableBuffer
(full? [this]
true)
ICounted
(-count [this] 0))
(def null-buffer (->NullBuffer))
(extend -reduce IMutableBuffer
(fn [buf f acc]
(loop [acc acc]
(if (reduced? acc)
@acc
(if (pos? (count buf))
(recur (f acc (remove! buf)))
acc)))))