Skip to content

Commit a1c4d10

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

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

src/packed_seq.rs

Lines changed: 18 additions & 4 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,6 +369,20 @@ pub const fn rev_u128(word: u128, len: usize) -> u128 {
369369

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

372+
impl<'s, const B: usize> PackedSeqBase<'s, B>
373+
where
374+
Bits<B>: SupportedBits,
375+
{
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+
}
385+
372386
impl<const B: usize> PackedSeqBase<'_, B>
373387
where
374388
Bits<B>: SupportedBits,
@@ -467,7 +481,7 @@ where
467481
let mask = u64::MAX >> (64 - B * self.len());
468482

469483
// 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.
484+
// has at least 48 bytes of padding at the end.
471485
if self.len() <= Self::K64 {
472486
let x = unsafe { (self.seq.as_ptr() as *const u64).read_unaligned() };
473487
(x >> (B * self.offset)) & mask
@@ -500,7 +514,7 @@ where
500514
let mask = u128::MAX >> (128 - B * self.len());
501515

502516
// 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.
517+
// has at least 48 bytes of padding at the end.
504518
let x = unsafe { (self.seq.as_ptr() as *const u128).read_unaligned() };
505519
(x >> (B * self.offset)) & mask
506520
}
@@ -1377,7 +1391,7 @@ where
13771391
{
13781392
/// Creates a `SeqVec` from a vector of packed bytes and a length in bp.
13791393
///
1380-
/// The vector should have at least 16 bytes of padding after `len`.
1394+
/// The vector should have at least 48 bytes of padding after `len`.
13811395
/// Otherwise, the vector will be resized to be padded with zeros.
13821396
pub fn from_raw_parts(mut seq: Vec<u8>, len: usize) -> Self {
13831397
assert!(len <= seq.len() * Self::C8);

0 commit comments

Comments
 (0)