Skip to content

Commit 7182416

Browse files
committed
Prefer Box<[u8]> where possible
1 parent b0e92b4 commit 7182416

7 files changed

Lines changed: 52 additions & 52 deletions

File tree

src/de.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl<'a> DeserializeBorrowed<'a> for Vec<RecordIndex> {
107107
}
108108
}
109109

110-
impl<'a> DeserializeBorrowed<'a> for Vec<u8> {
110+
impl<'a> DeserializeBorrowed<'a> for Box<[u8]> {
111111
fn deserialize_borrowed(data: &'a [u8], pos: &mut usize) -> std::io::Result<Self> {
112112
let len = read_vlq_u64(data, pos)? as usize;
113113
if *pos + len > data.len() {
@@ -116,7 +116,7 @@ impl<'a> DeserializeBorrowed<'a> for Vec<u8> {
116116
"unexpected end of data reading bytes",
117117
));
118118
}
119-
let bytes = data[*pos..*pos + len].to_vec();
119+
let bytes = data[*pos..*pos + len].to_vec().into_boxed_slice();
120120
*pos += len;
121121
Ok(bytes)
122122
}
@@ -126,10 +126,10 @@ impl<'a> DeserializeBorrowed<'a> for AttrMap {
126126
fn deserialize_borrowed(data: &'a [u8], pos: &mut usize) -> std::io::Result<Self> {
127127
let _byte_count = read_u64_le_slice(data, pos)?;
128128
let len = read_vlq_u64(data, pos)? as usize;
129-
let mut map: HashMap<usize, Vec<u8>> = HashMap::with_capacity(len);
129+
let mut map: HashMap<usize, Box<[u8]>> = HashMap::with_capacity(len);
130130
for _ in 0..len {
131131
let key = read_vlq_u64(data, pos)? as usize;
132-
let value = <Vec<u8>>::deserialize_borrowed(data, pos)?;
132+
let value = <Box<[u8]>>::deserialize_borrowed(data, pos)?;
133133
map.insert(key, value);
134134
}
135135
Ok(map)
@@ -415,11 +415,11 @@ impl DeserializeOwned for AttrMap {
415415
let start = reader.stream_position().await?;
416416
let _byte_count = read_u64_le(reader).await?;
417417
let len = reader.read_vu64().await?;
418-
let mut buf: HashMap<usize, Vec<u8>> = HashMap::with_capacity(len as usize);
418+
let mut buf: HashMap<usize, Box<[u8]>> = HashMap::with_capacity(len as usize);
419419
for _ in 0..len {
420420
let key = reader.read_vu64().await?;
421421
let value = <Vec<u8>>::deserialize_owned(reader).await?;
422-
buf.insert(key as usize, value);
422+
buf.insert(key as usize, value.into_boxed_slice());
423423
}
424424
let end = reader.stream_position().await?;
425425
tracing::debug!(
@@ -443,7 +443,7 @@ impl DeserializeOwned for FileRecord<'static> {
443443
let decompressed_length = read_u64_le(reader).await?;
444444
let data = read_u64_le(reader).await?;
445445
let name = String::deserialize_owned(reader).await?;
446-
let attrs = <HashMap<usize, Vec<u8>>>::deserialize_owned(reader).await?;
446+
let attrs = <HashMap<usize, Box<[u8]>>>::deserialize_owned(reader).await?;
447447

448448
let end = reader.stream_position().await?;
449449
tracing::debug!(start = format_args!("{:#x}", start), end = format_args!("{:#x}", end), bytes = end - start, %name, "deserialized FileRecord");
@@ -496,7 +496,7 @@ pub(crate) async fn deserialize_directory_owned<R: AsyncRead + AsyncSeek + Unpin
496496
Vec::new()
497497
};
498498

499-
let attrs = <HashMap<usize, Vec<u8>>>::deserialize_owned(reader).await?;
499+
let attrs = <HashMap<usize, Box<[u8]>>>::deserialize_owned(reader).await?;
500500

501501
let end = reader.stream_position().await?;
502502
tracing::debug!(start = format_args!("{:#x}", start), end = format_args!("{:#x}", end), bytes = end - start, %name, "deserialized DirectoryRecord");
@@ -545,7 +545,7 @@ impl DeserializeOwned for LinkRecord<'static> {
545545
let start = reader.stream_position().await?;
546546
let name = String::deserialize_owned(reader).await?;
547547
let target = RecordIndex::deserialize_owned(reader).await?;
548-
let attrs = <HashMap<usize, Vec<u8>>>::deserialize_owned(reader).await?;
548+
let attrs = <HashMap<usize, Box<[u8]>>>::deserialize_owned(reader).await?;
549549

550550
let end = reader.stream_position().await?;
551551
tracing::debug!(start = format_args!("{:#x}", start), end = format_args!("{:#x}", end), bytes = end - start, %name, "deserialized LinkRecord");
@@ -565,7 +565,7 @@ impl DeserializeOwned for ExternalLinkRecord<'static> {
565565
let start = reader.stream_position().await?;
566566
let name = String::deserialize_owned(reader).await?;
567567
let target = String::deserialize_owned(reader).await?;
568-
let attrs = <HashMap<usize, Vec<u8>>>::deserialize_owned(reader).await?;
568+
let attrs = <HashMap<usize, Box<[u8]>>>::deserialize_owned(reader).await?;
569569

570570
let end = reader.stream_position().await?;
571571
tracing::debug!(start = format_args!("{:#x}", start), end = format_args!("{:#x}", end), bytes = end - start, %name, "deserialized ExternalLinkRecord");
@@ -642,7 +642,7 @@ pub(crate) async fn deserialize_metadata_owned<R: AsyncRead + AsyncSeek + Unpin
642642
}
643643

644644
let attr_keys = deserialize_attr_keys_owned(reader, version).await?;
645-
let attrs = <HashMap<usize, Vec<u8>>>::deserialize_owned(reader).await?;
645+
let attrs = <HashMap<usize, Box<[u8]>>>::deserialize_owned(reader).await?;
646646

647647
// Skip 0-padding to 8-byte boundary
648648
loop {

src/file/meta.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -498,10 +498,10 @@ impl<'a> BoxMetadata<'a> {
498498
}
499499

500500
#[inline(always)]
501-
pub fn file_attr<S: AsRef<str>>(&self, key: S) -> Option<&Vec<u8>> {
501+
pub fn file_attr<S: AsRef<str>>(&self, key: S) -> Option<&[u8]> {
502502
let key = self.attr_key(key.as_ref())?;
503503

504-
self.attrs.get(&key)
504+
self.attrs.get(&key).map(|v| &**v)
505505
}
506506

507507
/// Get all attribute keys used in this archive (both file-level and record-level).

src/file/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub mod writer;
2929

3030
pub use self::meta::BoxMetadata;
3131

32-
pub type AttrMap = HashMap<usize, Vec<u8>>;
32+
pub type AttrMap = HashMap<usize, Box<[u8]>>;
3333

3434
#[cfg(test)]
3535
mod tests {

src/file/reader.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ impl BoxFileReader {
359359
return Some(value);
360360
}
361361
// Fall back to archive-level attr
362-
self.meta.file_attr(key).map(|v| v.as_slice())
362+
self.meta.file_attr(key)
363363
}
364364

365365
/// Get the unix mode for a record, with fallback to defaults.

src/file/writer.rs

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -364,51 +364,51 @@ impl BoxFileWriter {
364364
fn convert_attrs(
365365
&mut self,
366366
attrs: HashMap<String, Vec<u8>>,
367-
) -> std::io::Result<HashMap<usize, Vec<u8>>> {
367+
) -> std::io::Result<HashMap<usize, Box<[u8]>>> {
368368
// Set archive-level uid/gid defaults from first file if not already set
369369
if let Some(uid) = attrs.get("unix.uid") {
370370
let uid_key = self.meta.attr_key_or_create("unix.uid", AttrType::Vu32)?;
371371
self.meta
372372
.attrs
373373
.entry(uid_key)
374-
.or_insert_with(|| uid.clone());
374+
.or_insert_with(|| uid.clone().into_boxed_slice());
375375
}
376376
if let Some(gid) = attrs.get("unix.gid") {
377377
let gid_key = self.meta.attr_key_or_create("unix.gid", AttrType::Vu32)?;
378378
self.meta
379379
.attrs
380380
.entry(gid_key)
381-
.or_insert_with(|| gid.clone());
381+
.or_insert_with(|| gid.clone().into_boxed_slice());
382382
}
383383

384-
// Get archive defaults for filtering
385-
let default_uid = self
386-
.meta
387-
.attr_key("unix.uid")
388-
.and_then(|k| self.meta.attrs.get(&k).cloned());
389-
let default_gid = self
390-
.meta
391-
.attr_key("unix.gid")
392-
.and_then(|k| self.meta.attrs.get(&k).cloned());
393-
394-
// Filter out uid/gid that match archive defaults, then convert keys
384+
// Filter out uid/gid that match archive defaults (scoped to release borrows)
385+
let attrs: Vec<_> = {
386+
let default_uid = self
387+
.meta
388+
.attr_key("unix.uid")
389+
.and_then(|k| self.meta.attrs.get(&k).map(|v| &**v));
390+
let default_gid = self
391+
.meta
392+
.attr_key("unix.gid")
393+
.and_then(|k| self.meta.attrs.get(&k).map(|v| &**v));
394+
395+
attrs
396+
.into_iter()
397+
.filter(|(k, v)| {
398+
if k == "unix.uid" && default_uid.is_some_and(|d| v.as_slice() == d) {
399+
return false;
400+
}
401+
if k == "unix.gid" && default_gid.is_some_and(|d| v.as_slice() == d) {
402+
return false;
403+
}
404+
true
405+
})
406+
.collect()
407+
};
408+
409+
// Convert keys (now safe to mutate self.meta)
395410
let mut result = HashMap::new();
396411
for (k, v) in attrs {
397-
// Skip uid if matches archive default
398-
if k == "unix.uid"
399-
&& let Some(ref default) = default_uid
400-
&& &v == default
401-
{
402-
continue;
403-
}
404-
// Skip gid if matches archive default
405-
if k == "unix.gid"
406-
&& let Some(ref default) = default_gid
407-
&& &v == default
408-
{
409-
continue;
410-
}
411-
// Determine type based on well-known attribute names
412412
let attr_type = match k.as_str() {
413413
"unix.mode" | "unix.uid" | "unix.gid" => AttrType::Vu32,
414414
"created" | "modified" | "accessed" => AttrType::DateTime,
@@ -420,7 +420,7 @@ impl BoxFileWriter {
420420
_ => AttrType::Bytes,
421421
};
422422
let key = self.meta.attr_key_or_create(&k, attr_type)?;
423-
result.insert(key, v);
423+
result.insert(key, v.into_boxed_slice());
424424
}
425425
Ok(result)
426426
}
@@ -647,7 +647,7 @@ impl BoxFileWriter {
647647
.record_mut(index)
648648
.unwrap()
649649
.attrs_mut()
650-
.insert(key, hash_bytes);
650+
.insert(key, hash_bytes.into_boxed_slice());
651651
}
652652

653653
Ok(self.meta.record(index).unwrap().as_file().unwrap())
@@ -766,12 +766,12 @@ impl BoxFileWriter {
766766

767767
// Set checksum attribute if present
768768
if let Some((attr_name, hash)) = file.checksum {
769-
let key = self.meta.attr_key_or_create(&attr_name, AttrType::U256)?;
769+
let key = self.meta.attr_key_or_create(attr_name, AttrType::U256)?;
770770
self.meta
771771
.record_mut(index)
772772
.unwrap()
773773
.attrs_mut()
774-
.insert(key, hash);
774+
.insert(key, hash.into_boxed_slice());
775775
}
776776

777777
Ok(self.meta.record(index).unwrap().as_file().unwrap())
@@ -795,7 +795,7 @@ impl BoxFileWriter {
795795

796796
let attr_type = value.attr_type();
797797
let key_idx = self.meta.attr_key_or_create(key.as_ref(), attr_type)?;
798-
let bytes = value.as_raw_bytes().into_owned();
798+
let bytes = value.as_raw_bytes().into_owned().into_boxed_slice();
799799
let record = self.meta.record_mut(index).unwrap();
800800
record.attrs_mut().insert(key_idx, bytes);
801801

@@ -809,7 +809,7 @@ impl BoxFileWriter {
809809
) -> std::io::Result<()> {
810810
let attr_type = value.attr_type();
811811
let key_idx = self.meta.attr_key_or_create(key.as_ref(), attr_type)?;
812-
let bytes = value.as_raw_bytes().into_owned();
812+
let bytes = value.as_raw_bytes().into_owned().into_boxed_slice();
813813

814814
self.meta.attrs.insert(key_idx, bytes);
815815

src/record.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ impl<'a> Record<'a> {
135135
self.attrs().iter().filter_map(move |(key_idx, value)| {
136136
metadata
137137
.attr_key_name(*key_idx)
138-
.map(|name| (name, value.as_slice()))
138+
.map(|name| (name, &**value))
139139
})
140140
}
141141

src/ser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl<'a> Serialize for std::borrow::Cow<'a, str> {
6767
}
6868
}
6969

70-
impl Serialize for Vec<u8> {
70+
impl Serialize for Box<[u8]> {
7171
async fn write<W: AsyncWrite + AsyncSeek + Unpin + Send>(
7272
&self,
7373
writer: &mut W,

0 commit comments

Comments
 (0)