Skip to content

Commit f6a9f5c

Browse files
committed
perf(bam): Remove unnecessary heap allocation in Record::aux
Remove the unnecessary heap allocation in `Record::aux` and `Record::remove_aux` by removing the call to `CString::new` and using the byte slice directly. The BAM tag does not need to be null terminated. Return `Error::BamAuxStringError` if the length of the tag is not equal to 2.
1 parent 229d5a2 commit f6a9f5c

File tree

2 files changed

+11
-5
lines changed

2 files changed

+11
-5
lines changed

src/bam/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1695,6 +1695,7 @@ CCCCCCCCCCCCCCCCCCC"[..],
16951695
// fix qual offset
16961696
let qual: Vec<u8> = quals[i].iter().map(|&q| q - 33).collect();
16971697
assert_eq!(rec.qual(), &qual[..]);
1698+
assert_eq!(rec.aux(b"X"), Err(Error::BamAuxStringError));
16981699
assert_eq!(rec.aux(b"NotAvailableAux"), Err(Error::BamAuxTagNotFound));
16991700
}
17001701

@@ -2009,7 +2010,8 @@ CCCCCCCCCCCCCCCCCCC"[..],
20092010
rec.remove_aux(b"YT").unwrap();
20102011
}
20112012

2012-
assert!(rec.remove_aux(b"ab").is_err());
2013+
assert_eq!(rec.remove_aux(b"X"), Err(Error::BamAuxStringError));
2014+
assert_eq!(rec.remove_aux(b"ab"), Err(Error::BamAuxTagNotFound));
20132015

20142016
assert_eq!(rec.aux(b"XS"), Err(Error::BamAuxTagNotFound));
20152017
assert_eq!(rec.aux(b"YT"), Err(Error::BamAuxTagNotFound));

src/bam/record.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -644,11 +644,13 @@ impl Record {
644644
/// Only the first two bytes of a given tag are used for the look-up of a field.
645645
/// See [`Aux`] for more details.
646646
pub fn aux(&self, tag: &[u8]) -> Result<Aux<'_>> {
647-
let c_str = ffi::CString::new(tag).map_err(|_| Error::BamAuxStringError)?;
647+
if tag.len() < 2 {
648+
return Err(Error::BamAuxStringError);
649+
}
648650
let aux = unsafe {
649651
htslib::bam_aux_get(
650652
&self.inner as *const htslib::bam1_t,
651-
c_str.as_ptr() as *mut c_char,
653+
tag.as_ptr() as *const c_char,
652654
)
653655
};
654656
unsafe { Self::read_aux_field(aux).map(|(aux_field, _length)| aux_field) }
@@ -1224,11 +1226,13 @@ impl Record {
12241226

12251227
// Delete auxiliary tag.
12261228
pub fn remove_aux(&mut self, tag: &[u8]) -> Result<()> {
1227-
let c_str = ffi::CString::new(tag).map_err(|_| Error::BamAuxStringError)?;
1229+
if tag.len() < 2 {
1230+
return Err(Error::BamAuxStringError);
1231+
}
12281232
let aux = unsafe {
12291233
htslib::bam_aux_get(
12301234
&self.inner as *const htslib::bam1_t,
1231-
c_str.as_ptr() as *mut c_char,
1235+
tag.as_ptr() as *const c_char,
12321236
)
12331237
};
12341238
unsafe {

0 commit comments

Comments
 (0)