Skip to content

Commit fcedd45

Browse files
committed
Also reduce capacity on dequeue
1 parent 16e4285 commit fcedd45

File tree

2 files changed

+18
-13
lines changed

2 files changed

+18
-13
lines changed

Deque/Deque-Optimized.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@ public struct Deque<T> {
4545
head += 1
4646

4747
if capacity > 10 && head >= capacity*2 {
48-
array.removeFirst(capacity)
49-
head -= capacity
48+
let amountToRemove = capacity + capacity/2
49+
array.removeFirst(amountToRemove)
50+
head -= amountToRemove
51+
capacity /= 2
5052
}
5153
return element
5254
}

Deque/README.markdown

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -254,11 +254,11 @@ If `head` equals 0, there is no room left at the front. When that happens, we ad
254254
255255
We have to do something similar for `dequeue()`. If you mostly enqueue a lot of elements at the back and mostly dequeue from the front, then you may end up with an array that looks like this:
256256

257-
[ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, 1, 2, 3 ]
257+
[ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, 1, 2, 3 ]
258258
|
259259
head
260260

261-
Those empty spots at the front only get used when you use `enqueueFront()`. But if enqueuing objects at the front happens only rarely, this leaves a lot of wasted space. So let's add some code to `dequeue()` to clean this up:
261+
Those empty spots at the front only get used when you call `enqueueFront()`. But if enqueuing objects at the front happens only rarely, this leaves a lot of wasted space. So let's add some code to `dequeue()` to clean this up:
262262

263263
```swift
264264
public mutating func dequeue() -> T? {
@@ -268,26 +268,29 @@ Those empty spots at the front only get used when you use `enqueueFront()`. But
268268
head += 1
269269

270270
if capacity > 10 && head >= capacity*2 {
271-
array.removeFirst(capacity)
272-
head -= capacity
271+
let amountToRemove = capacity + capacity/2
272+
array.removeFirst(amountToRemove)
273+
head -= amountToRemove
274+
capacity /= 2
273275
}
274276
return element
275277
}
276278
```
277279

278-
Recall that `capacity` is the original number of empty places at the front of the queue. If the `head` has advanced more to the right than twice the capacity, then it's time to trim off half of these empty spots.
280+
Recall that `capacity` is the original number of empty places at the front of the queue. If the `head` has advanced more to the right than twice the capacity, then it's time to trim off a bunch of these empty spots. We reduce it to about 25%.
279281

280282
For example, this:
281283

282-
[ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, 1, 2, 3 ]
283-
| |
284-
capacity head
284+
[ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, 1, 2, 3 ]
285+
| |
286+
capacity head
285287

286288
becomes this after trimming:
287289

288-
[ x, x, x, x, x, x, x, x, x, 1, 2, 3 ]
289-
|
290-
head
290+
[ x, x, x, x, x, 1, 2, 3 ]
291+
|
292+
head
293+
capacity
291294

292295
This way we can strike a balance between fast enqueuing and dequeuing at the front and keeping the memory requirements reasonable.
293296

0 commit comments

Comments
 (0)