diff --git a/Cargo.lock b/Cargo.lock index 95994f02..ac4ae94a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1009,6 +1009,7 @@ dependencies = [ "env_logger", "flate2", "heapless", + "heapopt", "hex", "htp", "humantime", diff --git a/Cargo.toml b/Cargo.toml index ab56f283..565a202a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,6 +53,7 @@ enumset-ext = { path = "./crate/enumset-ext" } env_logger = "0" flate2 = "1" heapless = "0" +heapopt = { path = "./crate/heapopt" } hex = "0" htp = { git = "https://github.com/pamburus/htp.git" } humantime = "2" diff --git a/src/fmtx.rs b/src/fmtx.rs index c168e0d3..d283f511 100644 --- a/src/fmtx.rs +++ b/src/fmtx.rs @@ -24,65 +24,7 @@ where // --- -#[derive(Default)] -pub struct OptimizedBuf { - pub head: heapless::Vec, - pub tail: Vec, -} - -impl OptimizedBuf -where - T: Clone, -{ - #[inline] - pub fn new() -> Self { - Self { - head: heapless::Vec::new(), - tail: Vec::new(), - } - } - - #[inline] - pub fn len(&self) -> usize { - self.head.len() + self.tail.len() - } - - #[inline] - pub fn clear(&mut self) { - self.head.clear(); - self.tail.clear(); - } - - #[inline] - pub fn truncate(&mut self, len: usize) { - if len <= self.head.len() { - self.head.truncate(len); - self.tail.clear(); - } else { - self.tail.truncate(len - self.head.len()); - } - } - - #[inline] - pub fn push(&mut self, value: T) { - if self.head.len() < N { - self.head.push(value).ok(); - } else { - self.tail.push(value); - } - } - - #[inline] - pub fn extend_from_slice(&mut self, values: &[T]) { - if self.head.len() + values.len() <= N { - self.head.extend_from_slice(values).ok(); - } else { - let n = N - self.head.len(); - self.head.extend_from_slice(&values[..n]).ok(); - self.tail.extend_from_slice(&values[n..]); - } - } -} +pub type OptimizedBuf = heapopt::Vec; impl Push for OptimizedBuf where @@ -495,8 +437,8 @@ mod tests { assert_eq!(buf.len(), 4); buf.push(5); assert_eq!(buf.len(), 5); - assert_eq!(buf.head.as_slice(), &[1, 2, 3, 4]); - assert_eq!(buf.tail.as_slice(), &[5]); + assert_eq!(buf.as_slices().0, &[1, 2, 3, 4]); + assert_eq!(buf.as_slices().1, &[5]); } #[test] @@ -511,8 +453,8 @@ mod tests { assert_eq!(buf.len(), 3); buf.extend_from_slice(&[4, 5, 6]); assert_eq!(buf.len(), 6); - assert_eq!(buf.head.as_slice(), &[1, 2, 3, 4]); - assert_eq!(buf.tail.as_slice(), &[5, 6]); + assert_eq!(buf.as_slices().0, &[1, 2, 3, 4]); + assert_eq!(buf.as_slices().1, &[5, 6]); } #[test] @@ -523,32 +465,32 @@ mod tests { assert_eq!(buf.len(), 7); buf.truncate(8); assert_eq!(buf.len(), 7); - assert_eq!(buf.head.as_slice(), &[1, 2, 3, 4]); - assert_eq!(buf.tail.as_slice(), &[5, 6, 7]); + assert_eq!(buf.as_slices().0, &[1, 2, 3, 4]); + assert_eq!(buf.as_slices().1, &[5, 6, 7]); buf.truncate(7); assert_eq!(buf.len(), 7); - assert_eq!(buf.head.as_slice(), &[1, 2, 3, 4]); - assert_eq!(buf.tail.as_slice(), &[5, 6, 7]); + assert_eq!(buf.as_slices().0, &[1, 2, 3, 4]); + assert_eq!(buf.as_slices().1, &[5, 6, 7]); buf.truncate(6); assert_eq!(buf.len(), 6); - assert_eq!(buf.head.as_slice(), &[1, 2, 3, 4]); - assert_eq!(buf.tail.as_slice(), &[5, 6]); + assert_eq!(buf.as_slices().0, &[1, 2, 3, 4]); + assert_eq!(buf.as_slices().1, &[5, 6]); buf.truncate(4); assert_eq!(buf.len(), 4); - assert_eq!(buf.head.as_slice(), &[1, 2, 3, 4]); - assert_eq!(buf.tail.len(), 0); + assert_eq!(buf.as_slices().0, &[1, 2, 3, 4]); + assert_eq!(buf.as_slices().1.len(), 0); buf.truncate(4); buf.extend_from_slice(&[8, 9]); assert_eq!(buf.len(), 6); - assert_eq!(buf.head.as_slice(), &[1, 2, 3, 4]); - assert_eq!(buf.tail.as_slice(), &[8, 9]); + assert_eq!(buf.as_slices().0, &[1, 2, 3, 4]); + assert_eq!(buf.as_slices().1, &[8, 9]); buf.truncate(3); assert_eq!(buf.len(), 3); - assert_eq!(buf.head.as_slice(), &[1, 2, 3]); - assert_eq!(buf.tail.len(), 0); + assert_eq!(buf.as_slices().0, &[1, 2, 3]); + assert_eq!(buf.as_slices().1.len(), 0); buf.truncate(0); assert_eq!(buf.len(), 0); - assert_eq!(buf.head.len(), 0); - assert_eq!(buf.tail.len(), 0); + assert_eq!(buf.as_slices().0.len(), 0); + assert_eq!(buf.as_slices().1.len(), 0); } } diff --git a/src/formatting.rs b/src/formatting.rs index 8a724e16..e66531cc 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -326,8 +326,8 @@ impl KeyPrefix { #[inline] fn format>(&self, buf: &mut B) { - buf.extend_from_slice(&self.value.head); - buf.extend_from_slice(&self.value.tail); + buf.extend_from_slice(&self.value.as_slices().0); + buf.extend_from_slice(&self.value.as_slices().1); } #[inline] @@ -985,10 +985,7 @@ mod tests { impl<'a> RecordExt<'a> for Record<'a> { fn from_fields(fields: &[(&'a str, RawValue<'a>)]) -> Record<'a> { Record { - fields: RecordFields { - head: heapless::Vec::from_slice(fields).unwrap(), - ..Default::default() - }, + fields: RecordFields::from_slice(fields), ..Default::default() } } @@ -1003,10 +1000,7 @@ mod tests { level: Some(Level::Debug), logger: Some("tl"), caller: Some(Caller::Text("tc")), - fields: RecordFields { - head: heapless::Vec::from_slice(&[("k_a", RawValue::from(RawObject::Json(&ka)))]).unwrap(), - ..Default::default() - }, + fields: RecordFields::from_slice(&[("k_a", RawValue::from(RawObject::Json(&ka)))]), ..Default::default() }; diff --git a/src/model.rs b/src/model.rs index cff8ebf9..e709656a 100644 --- a/src/model.rs +++ b/src/model.rs @@ -322,7 +322,7 @@ pub struct Record<'a> { impl<'a> Record<'a> { #[inline(always)] pub fn fields(&self) -> impl Iterator)> { - self.fields.head.iter().chain(self.fields.tail.iter()) + self.fields.iter() } #[inline(always)] @@ -342,24 +342,13 @@ impl<'a> Record<'a> { level: None, logger: None, caller: None, - fields: RecordFields { - head: heapless::Vec::new(), - tail: if capacity > RECORD_EXTRA_CAPACITY { - Vec::with_capacity(capacity - RECORD_EXTRA_CAPACITY) - } else { - Vec::new() - }, - }, + fields: RecordFields::with_capacity(capacity), predefined: heapless::Vec::new(), } } } -#[derive(Default)] -pub struct RecordFields<'a> { - pub(crate) head: heapless::Vec<(&'a str, RawValue<'a>), RECORD_EXTRA_CAPACITY>, - pub(crate) tail: Vec<(&'a str, RawValue<'a>)>, -} +pub type RecordFields<'a> = heapopt::Vec<(&'a str, RawValue<'a>), RECORD_EXTRA_CAPACITY>; // --- @@ -660,10 +649,7 @@ impl ParserSettingsBlock { return; } } - match to.fields.head.push((key, value)) { - Ok(_) => {} - Err(value) => to.fields.tail.push(value), - } + to.fields.push((key, value)); } #[inline(always)] @@ -899,17 +885,7 @@ impl<'de: 'a, 'a> Deserialize<'de> for RawRecord<'a> { // --- -pub struct RawRecordFields<'a> { - head: heapless::Vec<(&'a str, RawValue<'a>), RAW_RECORD_FIELDS_CAPACITY>, - tail: Vec<(&'a str, RawValue<'a>)>, -} - -impl<'a> RawRecordFields<'a> { - #[inline] - pub fn iter(&self) -> impl Iterator)> { - self.head.iter().chain(self.tail.iter()) - } -} +pub type RawRecordFields<'a> = heapopt::Vec<(&'a str, RawValue<'a>), RAW_RECORD_FIELDS_CAPACITY>; // --- @@ -1108,23 +1084,14 @@ where } fn visit_map>(self, mut access: M) -> std::result::Result { - let mut head = heapless::Vec::new(); - let count = access.size_hint().unwrap_or(0); - let mut tail = match count > RAW_RECORD_FIELDS_CAPACITY { - false => Vec::new(), - true => Vec::with_capacity(count - RAW_RECORD_FIELDS_CAPACITY), - }; + let mut fields = heapopt::Vec::with_capacity(access.size_hint().unwrap_or(0)); + while let Some(key) = access.next_key::<&'a str>()? { let value: &RV = access.next_value()?; - match head.push((key, value.into())) { - Ok(_) => {} - Err(value) => tail.push(value), - } + fields.push((key, value.into())); } - Ok(RawRecord { - fields: RawRecordFields { head, tail }, - }) + Ok(RawRecord { fields }) } } @@ -1766,8 +1733,8 @@ mod tests { let rec = stream.next().unwrap().unwrap(); assert_eq!(rec.prefix, b""); - assert_eq!(rec.record.fields.head.len(), 0); - assert_eq!(rec.record.fields.tail.len(), 0); + assert_eq!(rec.record.fields.as_slices().0.len(), 0); + assert_eq!(rec.record.fields.as_slices().1.len(), 0); } #[test]