@@ -60,11 +60,16 @@ const DEFAULT_DEQUEUE_BLOCKSIZE = 1024
60
60
61
61
"""
62
62
Deque{T}
63
+ Deque{T}(blksize::Int) where T
63
64
64
- The Deque type implements a double-ended queue using a list of blocks.
65
- This data structure supports constant-time insertion/removal
66
- of elements at both ends of a sequence.
65
+ Constructs `Deque` object for elements of type `T`.
67
66
67
+ Parameters
68
+ ----------
69
+
70
+ `T::Type` Deque element data type.
71
+
72
+ `blksize::Int` Deque block size (in bytes). Default = 1024.
68
73
"""
69
74
mutable struct Deque{T}
70
75
nblocks:: Int
@@ -81,43 +86,54 @@ mutable struct Deque{T}
81
86
Deque {T} () where {T} = Deque {T} (DEFAULT_DEQUEUE_BLOCKSIZE)
82
87
end
83
88
84
- Base. isempty (q:: Deque ) = q. len == 0
85
- Base. length (q:: Deque ) = q. len
86
- num_blocks (q:: Deque ) = q. nblocks
89
+ """
90
+ isempty(d::Deque)
91
+
92
+ Verifies if deque `d` is empty.
93
+ """
94
+ Base. isempty (d:: Deque ) = d. len == 0
95
+
96
+ """
97
+ length(d::Deque)
98
+
99
+ Returns the number of elements in deque `d`.
100
+ """
101
+ Base. length (d:: Deque ) = d. len
102
+ num_blocks (d:: Deque ) = d. nblocks
87
103
Base. eltype (:: Type{Deque{T}} ) where T = T
88
104
89
105
"""
90
- first(q ::Deque)
106
+ first(d ::Deque)
91
107
92
- Returns the first element of the deque `q `.
108
+ Returns the first element of the deque `d `.
93
109
"""
94
- function Base. first (q :: Deque )
95
- isempty (q ) && throw (ArgumentError (" Deque must be non-empty" ))
96
- blk = q . head
110
+ function Base. first (d :: Deque )
111
+ isempty (d ) && throw (ArgumentError (" Deque must be non-empty" ))
112
+ blk = d . head
97
113
return blk. data[blk. front]
98
114
end
99
115
100
116
"""
101
- last(q ::Deque)
117
+ last(d ::Deque)
102
118
103
- Returns the last element of the deque `q `.
119
+ Returns the last element of the deque `d `.
104
120
"""
105
- function Base. last (q :: Deque )
106
- isempty (q ) && throw (ArgumentError (" Deque must be non-empty" ))
107
- blk = q . rear
121
+ function Base. last (d :: Deque )
122
+ isempty (d ) && throw (ArgumentError (" Deque must be non-empty" ))
123
+ blk = d . rear
108
124
return blk. data[blk. back]
109
125
end
110
126
111
127
112
128
# Iteration
113
129
114
130
struct DequeIterator{T}
115
- q :: Deque{T}
131
+ d :: Deque{T}
116
132
end
117
133
118
- Base. last (qi :: DequeIterator ) = last (qi . q )
134
+ Base. last (di :: DequeIterator ) = last (di . d )
119
135
120
- function Base. iterate (qi :: DequeIterator{T} , (cb, i) = (qi . q . head, qi . q . head. front)) where T
136
+ function Base. iterate (di :: DequeIterator{T} , (cb, i) = (di . d . head, di . d . head. front)) where T
121
137
i > cb. back && return nothing
122
138
x = cb. data[i]
123
139
132
148
133
149
# Backwards deque iteration
134
150
135
- function Base. iterate (qi :: Iterators.Reverse{<:Deque} , (cb, i) = (qi . itr. rear, qi . itr. rear. back))
151
+ function Base. iterate (di :: Iterators.Reverse{<:Deque} , (cb, i) = (di . itr. rear, di . itr. rear. back))
136
152
i < cb. front && return nothing
137
153
x = cb. data[i]
138
154
@@ -146,21 +162,21 @@ function Base.iterate(qi::Iterators.Reverse{<:Deque}, (cb, i) = (qi.itr.rear, qi
146
162
return (x, (cb, i))
147
163
end
148
164
149
- Base. iterate (q :: Deque{T} , s... ) where {T} = iterate (DequeIterator {T} (q ), s... )
165
+ Base. iterate (d :: Deque{T} , s... ) where {T} = iterate (DequeIterator {T} (d ), s... )
150
166
151
- Base. length (qi :: DequeIterator{T} ) where {T} = qi . q . len
167
+ Base. length (di :: DequeIterator{T} ) where {T} = di . d . len
152
168
153
- Base. collect (q :: Deque{T} ) where {T} = T[x for x in q ]
169
+ Base. collect (d :: Deque{T} ) where {T} = T[x for x in d ]
154
170
155
171
# Showing
156
172
157
- function Base. show (io:: IO , q :: Deque )
158
- print (io, " Deque [$(collect (q )) ]" )
173
+ function Base. show (io:: IO , d :: Deque )
174
+ print (io, " Deque [$(collect (d )) ]" )
159
175
end
160
176
161
- function Base. dump (io:: IO , q :: Deque )
162
- println (io, " Deque (length = $(q . len) , nblocks = $(q . nblocks) )" )
163
- cb:: DequeBlock = q . head
177
+ function Base. dump (io:: IO , d :: Deque )
178
+ println (io, " Deque (length = $(d . len) , nblocks = $(d . nblocks) )" )
179
+ cb:: DequeBlock = d . head
164
180
i = 1
165
181
while true
166
182
print (io, " block $i [$(cb. front) :$(cb. back) ] ==> " )
@@ -184,38 +200,38 @@ end
184
200
# Manipulation
185
201
186
202
"""
187
- empty!(q ::Deque{T})
203
+ empty!(d ::Deque{T}) where T
188
204
189
- Reset the deque.
205
+ Reset the deque `d` .
190
206
"""
191
- function Base. empty! (q :: Deque{T} ) where T
207
+ function Base. empty! (d :: Deque{T} ) where T
192
208
# release all blocks except the head
193
- if q . nblocks > 1
194
- cb:: DequeBlock{T} = q . rear
195
- while cb != q . head
209
+ if d . nblocks > 1
210
+ cb:: DequeBlock{T} = d . rear
211
+ while cb != d . head
196
212
empty! (cb. data)
197
213
cb = cb. prev
198
214
end
199
215
end
200
216
201
217
# clean the head block (but retain the block itself)
202
- reset! (q . head, 1 )
218
+ reset! (d . head, 1 )
203
219
204
220
# reset queue fields
205
- q . nblocks = 1
206
- q . len = 0
207
- q . rear = q . head
208
- return q
221
+ d . nblocks = 1
222
+ d . len = 0
223
+ d . rear = d . head
224
+ return d
209
225
end
210
226
211
227
212
228
"""
213
- push!(q ::Deque{T}, x)
229
+ push!(d ::Deque{T}, x) where T
214
230
215
- Add an element to the back
231
+ Add an element to the back of deque `d`.
216
232
"""
217
- function Base. push! (q :: Deque{T} , x) where T
218
- rear = q . rear
233
+ function Base. push! (d :: Deque{T} , x) where T
234
+ rear = d . rear
219
235
220
236
if isempty (rear)
221
237
rear. front = 1
@@ -225,24 +241,24 @@ function Base.push!(q::Deque{T}, x) where T
225
241
if rear. back < rear. capa
226
242
@inbounds rear. data[rear. back += 1 ] = convert (T, x)
227
243
else
228
- new_rear = rear_deque_block (T, q . blksize)
244
+ new_rear = rear_deque_block (T, d . blksize)
229
245
new_rear. back = 1
230
246
new_rear. data[1 ] = convert (T, x)
231
247
new_rear. prev = rear
232
- q . rear = rear. next = new_rear
233
- q . nblocks += 1
248
+ d . rear = rear. next = new_rear
249
+ d . nblocks += 1
234
250
end
235
- q . len += 1
236
- return q
251
+ d . len += 1
252
+ return d
237
253
end
238
254
239
255
"""
240
- pushfirst!(q ::Deque{T}, x)
256
+ pushfirst!(d ::Deque{T}, x) where T
241
257
242
- Add an element to the front
258
+ Add an element to the front of deque `d`.
243
259
"""
244
- function Base. pushfirst! (q :: Deque{T} , x) where T
245
- head = q . head
260
+ function Base. pushfirst! (d :: Deque{T} , x) where T
261
+ head = d . head
246
262
247
263
if isempty (head)
248
264
n = head. capa
@@ -253,65 +269,65 @@ function Base.pushfirst!(q::Deque{T}, x) where T
253
269
if head. front > 1
254
270
@inbounds head. data[head. front -= 1 ] = convert (T, x)
255
271
else
256
- n:: Int = q . blksize
272
+ n:: Int = d . blksize
257
273
new_head = head_deque_block (T, n)
258
274
new_head. front = n
259
275
new_head. data[n] = convert (T, x)
260
276
new_head. next = head
261
- q . head = head. prev = new_head
262
- q . nblocks += 1
277
+ d . head = head. prev = new_head
278
+ d . nblocks += 1
263
279
end
264
- q . len += 1
265
- return q
280
+ d . len += 1
281
+ return d
266
282
end
267
283
268
284
"""
269
- pop!(q ::Deque{T})
285
+ pop!(d ::Deque{T}) where T
270
286
271
- Remove the element at the back
287
+ Remove the element at the back of deque `d`.
272
288
"""
273
- function Base. pop! (q :: Deque{T} ) where T
274
- isempty (q ) && throw (ArgumentError (" Deque must be non-empty" ))
275
- rear = q . rear
289
+ function Base. pop! (d :: Deque{T} ) where T
290
+ isempty (d ) && throw (ArgumentError (" Deque must be non-empty" ))
291
+ rear = d . rear
276
292
@assert rear. back >= rear. front
277
293
278
294
@inbounds x = rear. data[rear. back]
279
295
rear. back -= 1
280
296
if rear. back < rear. front
281
- if q . nblocks > 1
297
+ if d . nblocks > 1
282
298
# release and detach the rear block
283
299
empty! (rear. data)
284
- q . rear = rear. prev:: DequeBlock{T}
285
- q . rear. next = q . rear
286
- q . nblocks -= 1
300
+ d . rear = rear. prev:: DequeBlock{T}
301
+ d . rear. next = d . rear
302
+ d . nblocks -= 1
287
303
end
288
304
end
289
- q . len -= 1
305
+ d . len -= 1
290
306
return x
291
307
end
292
308
293
309
"""
294
- popfirst!(q ::Deque{T})
310
+ popfirst!(d ::Deque{T}) where T
295
311
296
- Remove the element at the front
312
+ Remove the element at the front of deque `d`.
297
313
"""
298
- function Base. popfirst! (q :: Deque{T} ) where T
299
- isempty (q ) && throw (ArgumentError (" Deque must be non-empty" ))
300
- head = q . head
314
+ function Base. popfirst! (d :: Deque{T} ) where T
315
+ isempty (d ) && throw (ArgumentError (" Deque must be non-empty" ))
316
+ head = d . head
301
317
@assert head. back >= head. front
302
318
303
319
@inbounds x = head. data[head. front]
304
320
head. front += 1
305
321
if head. back < head. front
306
- if q . nblocks > 1
322
+ if d . nblocks > 1
307
323
# release and detach the head block
308
324
empty! (head. data)
309
- q . head = head. next:: DequeBlock{T}
310
- q . head. prev = q . head
311
- q . nblocks -= 1
325
+ d . head = head. next:: DequeBlock{T}
326
+ d . head. prev = d . head
327
+ d . nblocks -= 1
312
328
end
313
329
end
314
- q . len -= 1
330
+ d . len -= 1
315
331
return x
316
332
end
317
333
@@ -324,6 +340,11 @@ function Base.hash(x::Deque, h::UInt)
324
340
return h
325
341
end
326
342
343
+ """
344
+ ==(x::Deque, y::Deque)
345
+
346
+ Verify if the deques `x` and `y` are equal in terms of their contents.
347
+ """
327
348
function Base.:(== )(x:: Deque , y:: Deque )
328
349
length (x) != length (y) && return false
329
350
for (i, j) in zip (x, y)
0 commit comments