Skip to content

Commit

Permalink
feat: fewer reallocations (#4)
Browse files Browse the repository at this point in the history
* feat: stitch parts for correct buffer processing, added ord, remove interpreter for now

* feat: reduce memory reallocations
  • Loading branch information
varovainen authored Jun 24, 2023
1 parent d281dc3 commit 3cefd5b
Show file tree
Hide file tree
Showing 5 changed files with 306 additions and 41 deletions.
18 changes: 9 additions & 9 deletions src/frame.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bitvec::prelude::{BitVec, Lsb0};
use bitvec::prelude::{BitSlice, BitVec, Lsb0};
use crc::{Crc, CRC_16_ISO_IEC_14443_3_A};
#[cfg(feature = "std")]
use std::{borrow::ToOwned, cmp::Ordering, vec::Vec};
Expand All @@ -20,12 +20,12 @@ pub enum Frame {
}

#[derive(Debug, Eq, PartialEq)]
pub struct CompleteCollector {
pub(crate) data: BitVec<u8, Lsb0>,
pub struct CompleteCollector<'a> {
pub(crate) data: &'a BitSlice<u8, Lsb0>,
}

impl CompleteCollector {
pub fn to_frame(&self) -> Result<Frame, FrameError> {
impl <'a> CompleteCollector <'a> {
pub fn to_frame(self) -> Result<Frame, FrameError> {
let data_len = self.data.len();
if data_len == 0 {return Err(FrameError::EmptyFrame)}
match data_len.cmp(&8) {
Expand Down Expand Up @@ -94,7 +94,7 @@ mod tests {
#[test]
fn wrap_collector_1() {
let complete_collector = CompleteCollector {
data: bitvec![u8, Lsb0; 0, 1, 1, 0, 0, 1, 0],
data: &bitvec![u8, Lsb0; 0, 1, 1, 0, 0, 1, 0],
};
let frame = complete_collector.to_frame().unwrap();
assert_eq!(frame, Frame::Short(0x26));
Expand All @@ -103,7 +103,7 @@ mod tests {
#[test]
fn wrap_collector_2() {
let complete_collector = CompleteCollector {
data: bitvec![u8, Lsb0; 0, 1, 0, 0, 1, 0, 1],
data: &bitvec![u8, Lsb0; 0, 1, 0, 0, 1, 0, 1],
};
let frame = complete_collector.to_frame().unwrap();
assert_eq!(frame, Frame::Short(0x52));
Expand All @@ -112,7 +112,7 @@ mod tests {
#[test]
fn wrap_collector_3() {
let complete_collector = CompleteCollector {
data: bitvec![u8, Lsb0; 0, 0, 0, 0, 1, 0, 1, 0, 1],
data: &bitvec![u8, Lsb0; 0, 0, 0, 0, 1, 0, 1, 0, 1],
};
let frame = complete_collector.to_frame().unwrap();
assert_eq!(frame, Frame::SddCleanCut(vec![0x50]));
Expand All @@ -121,7 +121,7 @@ mod tests {
#[test]
fn wrap_collector_4() {
let complete_collector = CompleteCollector {
data: bitvec![u8, Lsb0; 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0],
data: &bitvec![u8, Lsb0; 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0],
};
let frame = complete_collector.to_frame().unwrap();
assert_eq!(frame, Frame::Standard(vec![0x50, 0x00]));
Expand Down
5 changes: 3 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ extern crate alloc;

pub mod error;
pub mod frame;
pub mod manchester;
//pub mod manchester;
pub mod miller;
pub mod time_record_both_ways;
pub mod miller_reworked;
//pub mod time_record_both_ways;
2 changes: 0 additions & 2 deletions src/manchester.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,9 @@ impl ManchesterCollector {
ManchesterCollector::InProgress(set) => match element {
ManchesterElement::D => {
set.push(true);
*self = ManchesterCollector::InProgress(set.to_bitvec())
}
ManchesterElement::E => {
set.push(false);
*self = ManchesterCollector::InProgress(set.to_bitvec())
}
ManchesterElement::F => {
*self = ManchesterCollector::Complete(CompleteCollector {
Expand Down
48 changes: 20 additions & 28 deletions src/miller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use bitvec::prelude::{BitVec, Lsb0};

use crate::error::MillerError;
use crate::frame::{CompleteCollector, Frame};
use crate::time_record_both_ways::{EntryTimesBoth, SetTimesBoth};
//use crate::time_record_both_ways::{EntryTimesBoth, SetTimesBoth};

#[derive(Debug, Eq, PartialEq)]
pub enum MillerElement {
Expand All @@ -20,11 +20,11 @@ pub enum MillerElement {
pub enum MillerCollector {
Empty,
InProgress(BitVec<u8, Lsb0>),
Complete(CompleteCollector),
Complete(Frame),
}

impl MillerCollector {
pub fn add_element(&mut self, element: &MillerElement) -> Result<(), MillerError> {
pub fn add_element(&mut self, element: MillerElement) -> Result<(), MillerError> {
match self {
MillerCollector::Empty => {
if let MillerElement::Z = element {
Expand All @@ -34,36 +34,27 @@ impl MillerCollector {
}
}
MillerCollector::InProgress(set) => {
let last_bit = {
if set.is_empty() {
None
} else {
Some(set[set.len() - 1])
}
};
let last_bit = set.last().map(|bitref| *bitref);
match element {
MillerElement::X => {
set.push(true);
*self = MillerCollector::InProgress(set.to_bitvec())
}
MillerElement::Y => match last_bit {
None => return Err(MillerError::WrongMillerSequence),
Some(false) => {
*self = MillerCollector::Complete(CompleteCollector {
data: set[..set.len() - 1].to_bitvec(),
})
let collector = CompleteCollector{data: &set[..set.len() - 1]};
let frame = collector.to_frame().map_err(MillerError::Frame)?;
*self = MillerCollector::Complete(frame)
}
Some(true) => {
set.push(false);
*self = MillerCollector::InProgress(set.to_bitvec())
}
},
MillerElement::Z => {
if let Some(true) = last_bit {
return Err(MillerError::WrongMillerSequence);
} else {
set.push(false);
*self = MillerCollector::InProgress(set.to_bitvec())
}
}
}
Expand All @@ -89,16 +80,16 @@ impl<const TICK_LEN: u16> MillerTimesDown<TICK_LEN> {
.collect()
}

pub fn convert(&self) -> Result<MillerElementSet, MillerError> {
pub fn convert(self) -> Result<MillerElementSet, MillerError> {
// each bit length is 8 ticks; expected error is 1 tick;
// time intervals in off mode are identical throughout the code;
// no signal corresponds to 2 or more completely "on" bits, i.e. 16 ticks.
// since only times down are recorded, the selected slices are separated by 16+4 = 20 ticks.
// minimal 19 ticks are taken as the error is expected to be 1 tick;
// XYY (20 ticks) or ZYY (24 ticks)
let mut miller_element_set = MillerElementSet::new();
for time_interval in self.time_down_set.iter() {
miller_element_set.add_time_down_interval::<TICK_LEN>(*time_interval)?;
for time_interval in self.time_down_set.into_iter() {
miller_element_set.add_time_down_interval::<TICK_LEN>(time_interval)?;
}
match miller_element_set.element_set.last() {
None => {},
Expand All @@ -111,7 +102,7 @@ impl<const TICK_LEN: u16> MillerTimesDown<TICK_LEN> {
}
Ok(miller_element_set)
}

pub fn stitch_with_tail(&self, tail: &Self) -> Self {
Self {
time_down_set: [tail.time_down_set.to_vec(), self.time_down_set.to_vec()].concat()
Expand Down Expand Up @@ -183,7 +174,7 @@ impl MillerElementSet {
Some(MillerElement::Z) => self.process_previous_z::<TICK_LEN>(interval),
}
}

/*
pub(crate) fn add_time_both_interval<const TICK_LEN: u16>(
&mut self,
time_both: EntryTimesBoth,
Expand Down Expand Up @@ -232,26 +223,26 @@ impl MillerElementSet {
},
}
}

*/
pub fn from_times_down<const TICK_LEN: u16>(
times_down: MillerTimesDown<TICK_LEN>,
) -> Result<Self, MillerError> {
times_down.convert()
}

/*
pub fn from_times_both<const TICK_LEN: u16>(
times_both: SetTimesBoth<TICK_LEN>,
) -> Result<Self, MillerError> {
times_both.convert_to_miller()
}

pub fn collect_frame(&self) -> Result<Frame, MillerError> {
*/
pub fn collect_frame(self) -> Result<Frame, MillerError> {
let mut collector = MillerCollector::Empty;
for element in self.element_set.iter() {
for element in self.element_set.into_iter() {
collector.add_element(element)?;
}
if let MillerCollector::Complete(complete_collector) = collector {
complete_collector.to_frame().map_err(MillerError::Frame)
Ok(complete_collector)
} else {
Err(MillerError::IncompleteFrame)
}
Expand All @@ -263,7 +254,7 @@ impl Default for MillerElementSet {
Self::new()
}
}

/*
#[cfg(feature = "std")]
#[cfg(test)]
mod tests {
Expand Down Expand Up @@ -441,3 +432,4 @@ mod tests {
assert_eq!(frame, Frame::Standard(vec![0xB2]));
}
}
*/
Loading

0 comments on commit 3cefd5b

Please sign in to comment.