Skip to content

Commit 8bdd6fa

Browse files
committed
Add PackedSeqBase::from_raw_parts
1 parent 73b8257 commit 8bdd6fa

1 file changed

Lines changed: 14 additions & 5 deletions

File tree

src/packed_seq.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ pub struct PackedSeqVecBase<const B: usize>
138138
where
139139
Bits<B>: SupportedBits,
140140
{
141-
/// NOTE: We maintain the invariant that this has at least 16 bytes padding
141+
/// NOTE: We maintain the invariant that this has at least 48 bytes of padding
142142
/// at the end after `len` finishes.
143143
/// This ensures that `read_unaligned` in `as_64` works OK.
144144
pub(crate) seq: Vec<u8>,
@@ -369,10 +369,19 @@ pub const fn rev_u128(word: u128, len: usize) -> u128 {
369369

370370
// ======================================================================
371371

372-
impl<const B: usize> PackedSeqBase<'_, B>
372+
impl<'s, const B: usize> PackedSeqBase<'s, B>
373373
where
374374
Bits<B>: SupportedBits,
375375
{
376+
/// Creates a `Seq` from a slice of packed bytes, an offset in bp and a length in bp.
377+
///
378+
/// The slice should have at least 48 bytes of padding after `offset + len`.
379+
/// Otherwise, the function will panic.
380+
pub fn from_raw_parts(seq: &'s [u8], offset: usize, len: usize) -> Self {
381+
assert!(offset + len + PADDING * Self::C8 <= seq.len() * Self::C8);
382+
Self { seq, offset, len }
383+
}
384+
376385
/// Shrink `seq` to only just cover the data.
377386
#[inline(always)]
378387
pub fn normalize(&self) -> Self {
@@ -467,7 +476,7 @@ where
467476
let mask = u64::MAX >> (64 - B * self.len());
468477

469478
// The unaligned read is OK, because we ensure that the underlying `PackedSeqVecBase::seq` always
470-
// has at least 16 bytes (the size of a u128) of padding at the end.
479+
// has at least 48 bytes of padding at the end.
471480
if self.len() <= Self::K64 {
472481
let x = unsafe { (self.seq.as_ptr() as *const u64).read_unaligned() };
473482
(x >> (B * self.offset)) & mask
@@ -500,7 +509,7 @@ where
500509
let mask = u128::MAX >> (128 - B * self.len());
501510

502511
// The unaligned read is OK, because we ensure that the underlying `PackedSeqVecBase::seq` always
503-
// has at least 16 bytes (the size of a u128) of padding at the end.
512+
// has at least 48 bytes of padding at the end.
504513
let x = unsafe { (self.seq.as_ptr() as *const u128).read_unaligned() };
505514
(x >> (B * self.offset)) & mask
506515
}
@@ -1377,7 +1386,7 @@ where
13771386
{
13781387
/// Creates a `SeqVec` from a vector of packed bytes and a length in bp.
13791388
///
1380-
/// The vector should have at least 16 bytes of padding after `len`.
1389+
/// The vector should have at least 48 bytes of padding after `len`.
13811390
/// Otherwise, the vector will be resized to be padded with zeros.
13821391
pub fn from_raw_parts(mut seq: Vec<u8>, len: usize) -> Self {
13831392
assert!(len <= seq.len() * Self::C8);

0 commit comments

Comments
 (0)