Skip to content

Commit

Permalink
Improve codec to be generic over its inner region
Browse files Browse the repository at this point in the history
Signed-off-by: Moritz Hoffmann <[email protected]>
  • Loading branch information
antiguru committed Feb 12, 2024
1 parent aa736dc commit 1b46bdc
Showing 1 changed file with 18 additions and 13 deletions.
31 changes: 18 additions & 13 deletions src/codec.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! TODO
//! A region that encodes its contents.
use crate::{CopyOnto, CopyRegion, Region};

Expand Down Expand Up @@ -72,18 +72,22 @@ pub fn consolidate_slice<T: Ord>(slice: &mut [(T, usize)]) -> usize {

/// A region that encodes its data in a codec `C`.
#[derive(Default, Debug)]
pub struct CodecRegion<C: Codec> {
inner: CopyRegion<u8>,
pub struct CodecRegion<C: Codec, R = CopyRegion<u8>> {
inner: R,
codec: C,
staging: Vec<u8>,
}

impl<C: Codec> Region for CodecRegion<C> {
impl<C: Codec, R> Region for CodecRegion<C, R>
where
for<'a> R: Region<ReadItem<'a> = &'a [u8]> + 'a,
for<'a> &'a [u8]: CopyOnto<R>,
{
type ReadItem<'a> = &'a [u8]
where
Self: 'a;

type Index = (usize, usize);
type Index = R::Index;

/// Construct a region that can absorb the contents of `regions` in the future.
fn merge_regions<'a>(regions: impl Iterator<Item = &'a Self> + Clone) -> Self
Expand All @@ -92,7 +96,7 @@ impl<C: Codec> Region for CodecRegion<C> {
{
let codec = C::new_from(regions.clone().map(|r| &r.codec));
Self {
inner: CopyRegion::merge_regions(regions.map(|r| &r.inner)),
inner: R::merge_regions(regions.map(|r| &r.inner)),
codec,
staging: vec![],
}
Expand All @@ -116,15 +120,19 @@ impl<C: Codec> Region for CodecRegion<C> {
}
}

impl<C: Codec> CopyOnto<CodecRegion<C>> for &[u8] {
fn copy_onto(self, target: &mut CodecRegion<C>) -> <CodecRegion<C> as Region>::Index {
impl<C: Codec, R> CopyOnto<CodecRegion<C, R>> for &[u8]
where
for<'a> R: Region<ReadItem<'a> = &'a [u8]> + 'a,
for<'a> &'a [u8]: CopyOnto<R>,
{
fn copy_onto(self, target: &mut CodecRegion<C, R>) -> <CodecRegion<C, R> as Region>::Index {
target.staging.clear();
target.codec.encode(self, &mut target.staging);
target.staging.as_slice().copy_onto(&mut target.inner)
}
}

/// TODO
/// Encode and decode byte strings.
pub trait Codec: Default + 'static {
/// Decodes an input byte slice into a sequence of byte slices.
fn decode<'a>(&'a self, bytes: &'a [u8]) -> &'a [u8];
Expand Down Expand Up @@ -189,10 +197,7 @@ mod dictionary {
fn new_from<'a, I: Iterator<Item = &'a Self> + Clone>(stats: I) -> Self {
// Collect most popular bytes from combined containers.
let mut mg = MisraGries::default();
for (thing, count) in stats
.clone()
.flat_map(|stats| stats.stats.0.clone().done())
{
for (thing, count) in stats.clone().flat_map(|stats| stats.stats.0.clone().done()) {
mg.update(thing, count);
}
let mut mg = mg.done().into_iter();
Expand Down

0 comments on commit 1b46bdc

Please sign in to comment.