Skip to content

Commit 1fd1fd3

Browse files
committed
fix: #3153 Deque::retain / Deque::retain_map do not clear when full and wrapped
1 parent 64759af commit 1fd1fd3

File tree

2 files changed

+34
-14
lines changed

2 files changed

+34
-14
lines changed

deque/deque.mbt

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,17 +1346,18 @@ pub fn[A] Deque::retain_map(self : Deque[A], f : (A) -> A?) -> Unit {
13461346
guard !self.is_empty() else { return }
13471347
let { head, buf, .. } = self
13481348
let cap = buf.length()
1349-
let head_len = cap - head
13501349
let mut idx = head
1350+
let mut kept_len = 0
13511351
let (front, back) = self.as_views()
13521352
for cur in front {
13531353
if f(cur) is Some(v) {
13541354
buf[idx] = v
13551355
idx += 1
1356+
kept_len += 1
13561357
}
13571358
}
13581359
if back.length() == 0 {
1359-
self.truncate(idx - head)
1360+
self.truncate(kept_len)
13601361
return
13611362
}
13621363
for cur in back {
@@ -1366,13 +1367,10 @@ pub fn[A] Deque::retain_map(self : Deque[A], f : (A) -> A?) -> Unit {
13661367
if f(cur) is Some(v) {
13671368
buf[idx] = v
13681369
idx += 1
1370+
kept_len += 1
13691371
}
13701372
}
1371-
if idx <= self.len - head_len {
1372-
self.truncate(idx + head_len)
1373-
} else {
1374-
self.truncate(idx - head)
1375-
}
1373+
self.truncate(kept_len)
13761374
}
13771375
13781376
///|
@@ -1405,17 +1403,18 @@ pub fn[A] Deque::retain(self : Deque[A], f : (A) -> Bool) -> Unit {
14051403
guard !self.is_empty() else { return }
14061404
let { head, buf, .. } = self
14071405
let cap = buf.length()
1408-
let head_len = cap - head
14091406
let mut idx = head
1407+
let mut kept_len = 0
14101408
let (front, back) = self.as_views()
14111409
for cur in front {
14121410
if f(cur) {
14131411
buf[idx] = cur
14141412
idx += 1
1413+
kept_len += 1
14151414
}
14161415
}
14171416
if back.length() == 0 {
1418-
self.truncate(idx - head)
1417+
self.truncate(kept_len)
14191418
return
14201419
}
14211420
for cur in back {
@@ -1425,13 +1424,10 @@ pub fn[A] Deque::retain(self : Deque[A], f : (A) -> Bool) -> Unit {
14251424
if f(cur) {
14261425
buf[idx] = cur
14271426
idx += 1
1427+
kept_len += 1
14281428
}
14291429
}
1430-
if idx <= self.len - head_len {
1431-
self.truncate(idx + head_len)
1432-
} else {
1433-
self.truncate(idx - head)
1434-
}
1430+
self.truncate(kept_len)
14351431
}
14361432
14371433
///|

deque/deque_test.mbt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,18 @@ test "deque retain" {
934934
])
935935
}
936936

937+
///|
938+
test "deque retain clears full wrapped deque" {
939+
let dq = @deque.new(capacity=4)
940+
dq..push_back(1)..push_back(2)..push_back(3)..push_back(4)
941+
ignore(dq.pop_front())
942+
dq.push_back(5)
943+
inspect(dq.as_views(), content="([2, 3, 4], [5])")
944+
dq.retain(_ => false)
945+
inspect(dq.as_views(), content="([], [])")
946+
assert_true(dq.is_empty())
947+
}
948+
937949
///|
938950
test "deque retain_map" {
939951
let inc_if = pred => x => if pred(x) { Some(x + 1) } else { None }
@@ -983,6 +995,18 @@ test "deque retain_map" {
983995
])
984996
}
985997

998+
///|
999+
test "deque retain_map clears full wrapped deque" {
1000+
let dq = @deque.new(capacity=4)
1001+
dq..push_back(1)..push_back(2)..push_back(3)..push_back(4)
1002+
ignore(dq.pop_front())
1003+
dq.push_back(5)
1004+
inspect(dq.as_views(), content="([2, 3, 4], [5])")
1005+
dq.retain_map(_ => None)
1006+
inspect(dq.as_views(), content="([], [])")
1007+
assert_true(dq.is_empty())
1008+
}
1009+
9861010
///|
9871011
test "@deque.to_array/empty" {
9881012
let dq : @deque.Deque[Int] = @deque.new()

0 commit comments

Comments
 (0)