Skip to content

Commit 67a9dfd

Browse files
committed
PyByteInner::replace_in_place
1 parent 20bdcac commit 67a9dfd

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

vm/src/obj/objbyteinner.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,38 @@ impl PyByteInner {
11681168
result
11691169
}
11701170

1171+
pub fn replace_in_place(
1172+
&self,
1173+
from: PyByteInner,
1174+
to: PyByteInner,
1175+
maxcount: Option<usize>,
1176+
) -> Vec<u8> {
1177+
let len = from.len();
1178+
let mut iter = self.elements.find_iter(&from.elements);
1179+
1180+
let mut new = if let Some(offset) = iter.next() {
1181+
let mut new = self.elements.clone();
1182+
new[offset..offset + len].clone_from_slice(to.elements.as_slice());
1183+
if maxcount == Some(1) {
1184+
return new;
1185+
} else {
1186+
new
1187+
}
1188+
} else {
1189+
return self.elements.clone();
1190+
};
1191+
1192+
let mut count = maxcount.unwrap_or(std::usize::MAX) - 1;
1193+
for offset in iter {
1194+
new[offset..offset + len].clone_from_slice(to.elements.as_slice());
1195+
count -= 1;
1196+
if count == 0 {
1197+
break;
1198+
}
1199+
}
1200+
new
1201+
}
1202+
11711203
fn replace_general(
11721204
&self,
11731205
from: PyByteInner,
@@ -1248,6 +1280,9 @@ impl PyByteInner {
12481280
if to.elements.is_empty() {
12491281
// delete all occurrences of 'from' bytes
12501282
Ok(self.replace_delete(from, maxcount))
1283+
} else if from.len() == to.len() {
1284+
// Handle special case where both bytes have the same length
1285+
Ok(self.replace_in_place(from, to, maxcount))
12511286
} else {
12521287
// Otherwise use the more generic algorithms
12531288
self.replace_general(from, to, maxcount, vm)

0 commit comments

Comments
 (0)