diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ca9bac..b65c0ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ # Changelog ## Unreleased +- Allowed `WaveletMatrix` builders to construct empty sequences, skipping layer + permutations for zero-length inputs and covering the case with a regression + test. +- Simplified `WaveletMatrixBuilder::freeze` to drain builders in the common + path, removing redundant early returns while preserving empty-layer support. - Added metadata validation in `BitVectorData::from_bytes` to reject lengths exceeding the stored capacity and covered the case with a regression test. - Guarded `CompactVector::from_bytes` against metadata bit-length overflow. diff --git a/src/char_sequences/wavelet_matrix.rs b/src/char_sequences/wavelet_matrix.rs index 2b76e80..eb65fe4 100644 --- a/src/char_sequences/wavelet_matrix.rs +++ b/src/char_sequences/wavelet_matrix.rs @@ -118,9 +118,6 @@ impl<'a> WaveletMatrixBuilder<'a> { len: usize, writer: &mut SectionWriter<'a>, ) -> Result { - if len == 0 { - return Err(Error::invalid_argument("seq must not be empty.")); - } let alph_width = utils::needed_bits(alph_size); let mut handles = writer.reserve::>(alph_width)?; let mut layers = Vec::with_capacity(alph_width); @@ -199,14 +196,14 @@ impl<'a> WaveletMatrixBuilder<'a> { let mut remaining = self.layers; remaining.reverse(); let mut layers = Vec::with_capacity(self.alph_width); + let handles = self.handles; + let mut scratch = ByteArea::new()?; let mut scratch_sections = scratch.sections(); let mut visited = BitVectorBuilder::with_capacity(self.len, &mut scratch_sections)?; - let handles = self.handles; - for _ in 0..self.alph_width { + while let Some(builder) = remaining.pop() { // Freeze the next layer and obtain its index for rank/select queries. - let builder = remaining.pop().expect("layer available"); let layer = builder.freeze::(); let zeros = layer.num_zeros(); @@ -887,11 +884,10 @@ mod test { fn test_empty_seq() { let mut area = ByteArea::new().unwrap(); let mut sections = area.sections(); - let e = WaveletMatrix::::from_iter(1, iter::empty(), &mut sections); - assert_eq!( - e.err().map(|x| x.to_string()), - Some("seq must not be empty.".to_string()) - ); + let wm = WaveletMatrix::::from_iter(1, iter::empty(), &mut sections) + .expect("empty iterator should build successfully"); + assert_eq!(wm.len(), 0); + assert!(wm.is_empty()); } #[test]