Skip to content

Commit d072f46

Browse files
committed
Use Cow
1 parent 8b9dc85 commit d072f46

File tree

1 file changed

+35
-32
lines changed
  • turbopack/crates/turbo-tasks-fs/src

1 file changed

+35
-32
lines changed

turbopack/crates/turbo-tasks-fs/src/rope.rs

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::{
22
borrow::Cow,
33
cmp::{Ordering, min},
44
fmt,
5-
io::{BufRead, Read, Result as IoResult, Write},
5+
io::{BufRead, Cursor, Read, Result as IoResult, Write},
66
mem,
77
ops::{AddAssign, Deref},
88
pin::Pin,
@@ -48,7 +48,7 @@ struct InnerRope(Arc<[RopeElem]>);
4848
#[derive(Clone, Debug)]
4949
enum RopeElem {
5050
/// Local bytes are owned directly by this rope.
51-
Local(Bytes),
51+
Local(Cow<'static, [u8]>),
5252

5353
/// Shared holds the Arc container of another rope.
5454
Shared(InnerRope),
@@ -122,21 +122,24 @@ impl Rope {
122122
impl From<Vec<u8>> for Rope {
123123
fn from(mut bytes: Vec<u8>) -> Self {
124124
bytes.shrink_to_fit();
125-
Rope::from(Bytes::from(bytes))
125+
Rope::from(Cow::Owned(bytes))
126126
}
127127
}
128128

129129
impl From<String> for Rope {
130-
fn from(mut bytes: String) -> Self {
131-
bytes.shrink_to_fit();
132-
Rope::from(Bytes::from(bytes))
130+
fn from(bytes: String) -> Self {
131+
Rope::from(bytes.into_bytes())
133132
}
134133
}
135134

136-
impl<T: Into<Bytes>> From<T> for Rope {
137-
default fn from(bytes: T) -> Self {
138-
let bytes = bytes.into();
139-
// We can't have an InnerRope which contains an empty Local section.
135+
impl From<&'static str> for Rope {
136+
fn from(bytes: &'static str) -> Self {
137+
Rope::from(Cow::Borrowed(bytes.as_bytes()))
138+
}
139+
}
140+
141+
impl From<Cow<'static, [u8]>> for Rope {
142+
fn from(bytes: Cow<'static, [u8]>) -> Self {
140143
if bytes.is_empty() {
141144
Default::default()
142145
} else {
@@ -181,7 +184,7 @@ impl RopeBuilder {
181184
self.finish();
182185

183186
self.length += bytes.len();
184-
self.committed.push(Local(Bytes::from_static(bytes)));
187+
self.committed.push(Local(Cow::Borrowed(bytes)));
185188
}
186189

187190
/// Concatenate another Rope instance into our builder.
@@ -320,10 +323,10 @@ impl Uncommitted {
320323

321324
/// Converts the current uncommitted bytes into a Bytes, resetting our
322325
/// representation to None.
323-
fn finish(&mut self) -> Option<Bytes> {
326+
fn finish(&mut self) -> Option<Cow<'static, [u8]>> {
324327
match mem::take(self) {
325328
Self::None => None,
326-
Self::Static(s) => Some(Bytes::from_static(s)),
329+
Self::Static(s) => Some(Cow::Borrowed(s)),
327330
Self::Owned(mut v) => {
328331
v.shrink_to_fit();
329332
Some(v.into())
@@ -336,10 +339,7 @@ impl fmt::Debug for Uncommitted {
336339
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
337340
match self {
338341
Uncommitted::None => f.write_str("None"),
339-
Uncommitted::Static(s) => f
340-
.debug_tuple("Static")
341-
.field(&Bytes::from_static(s))
342-
.finish(),
342+
Uncommitted::Static(s) => f.debug_tuple("Static").field(&Cow::Borrowed(s)).finish(),
343343
Uncommitted::Owned(v) => f
344344
.debug_tuple("Owned")
345345
.field(&Bytes::from(v.clone()))
@@ -637,7 +637,7 @@ pub struct RopeReader {
637637
/// continue onto the next item in the stack.
638638
#[derive(Debug)]
639639
enum StackElem {
640-
Local(Bytes),
640+
Local(Cursor<Cow<'static, [u8]>>),
641641
Shared(InnerRope, usize),
642642
}
643643

@@ -660,14 +660,14 @@ impl RopeReader {
660660
while remaining > 0 {
661661
let mut bytes = match self.next() {
662662
None => break,
663-
Some(b) => b,
663+
Some(b) => Cursor::new(b),
664664
};
665665

666-
let amount = min(bytes.len(), remaining);
666+
let amount = min(bytes.get_ref().len(), remaining);
667667

668-
buf.put_slice(&bytes[0..amount]);
668+
buf.put_slice(&bytes.get_ref()[0..amount]);
669669

670-
if amount < bytes.len() {
670+
if amount < bytes.get_ref().len() {
671671
bytes.advance(amount);
672672
self.stack.push(StackElem::Local(bytes))
673673
}
@@ -679,7 +679,7 @@ impl RopeReader {
679679
}
680680

681681
impl Iterator for RopeReader {
682-
type Item = Bytes;
682+
type Item = Cow<'static, [u8]>;
683683

684684
fn next(&mut self) -> Option<Self::Item> {
685685
// Iterates the rope's elements recursively until we find the next Local
@@ -688,8 +688,8 @@ impl Iterator for RopeReader {
688688
let (inner, mut index) = match self.stack.pop() {
689689
None => return None,
690690
Some(StackElem::Local(b)) => {
691-
debug_assert!(!b.is_empty(), "must not have empty Bytes section");
692-
return Some(b);
691+
debug_assert!(!b.get_ref().is_empty(), "must not have empty Bytes section");
692+
return Some(b.into_inner());
693693
}
694694
Some(StackElem::Shared(r, i)) => (r, i),
695695
};
@@ -735,17 +735,17 @@ impl BufRead for RopeReader {
735735
// This is just so we can get a reference to the asset that is kept alive by the
736736
// RopeReader itself. We can then auto-convert that reference into the needed u8
737737
// slice reference.
738-
self.stack.push(StackElem::Local(bytes));
738+
self.stack.push(StackElem::Local(Cursor::new(bytes)));
739739
let Some(StackElem::Local(bytes)) = self.stack.last() else {
740740
unreachable!()
741741
};
742742

743-
Ok(bytes)
743+
Ok(bytes.get_ref())
744744
}
745745

746746
fn consume(&mut self, amt: usize) {
747747
if let Some(StackElem::Local(b)) = self.stack.last_mut() {
748-
if amt == b.len() {
748+
if amt == b.get_ref().len() {
749749
self.stack.pop();
750750
} else {
751751
// Consume some amount of bytes from the current Bytes instance, ensuring
@@ -759,7 +759,7 @@ impl BufRead for RopeReader {
759759
impl Stream for RopeReader {
760760
// The Result<Bytes> item type is required for this to be streamable into a
761761
// [Hyper::Body].
762-
type Item = Result<Bytes>;
762+
type Item = Result<Cow<'static, [u8]>>;
763763

764764
// Returns a "result" of reading the next shared bytes reference. This
765765
// differs from [Read::read] by not copying any memory.
@@ -772,7 +772,7 @@ impl Stream for RopeReader {
772772
impl From<RopeElem> for StackElem {
773773
fn from(el: RopeElem) -> Self {
774774
match el {
775-
Local(bytes) => Self::Local(bytes),
775+
Local(bytes) => Self::Local(Cursor::new(bytes)),
776776
Shared(inner) => Self::Shared(inner, 0),
777777
}
778778
}
@@ -794,7 +794,7 @@ mod test {
794794
// in order to fully test cases.
795795
impl From<&str> for RopeElem {
796796
fn from(value: &str) -> Self {
797-
RopeElem::Local(value.to_string().into())
797+
RopeElem::Local(value.to_string().into_bytes().into())
798798
}
799799
}
800800
impl From<Vec<RopeElem>> for RopeElem {
@@ -977,7 +977,10 @@ mod test {
977977
let shared = Rope::from("def");
978978
let rope = Rope::new(vec!["abc".into(), shared.into(), "ghi".into()]);
979979

980-
let chunks = rope.read().collect::<Vec<_>>();
980+
let chunks = rope
981+
.read()
982+
.map(|v| String::from_utf8(v.into_owned()).unwrap())
983+
.collect::<Vec<_>>();
981984

982985
assert_eq!(chunks, vec!["abc", "def", "ghi"]);
983986
}

0 commit comments

Comments
 (0)