Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove AsVarULE #1126

Merged
merged 3 commits into from
Oct 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions utils/yoke/derive/examples/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct CowExample<'a> {

#[derive(Yokeable, ZeroCopyFrom)]
pub struct ZeroVecExample<'a> {
var: VarZeroVec<'a, String>,
var: VarZeroVec<'a, str>,
vec: ZeroVec<'a, u16>,
}

Expand All @@ -34,7 +34,7 @@ pub struct ZeroVecExample<'a> {
#[derive(Yokeable)]
#[yoke(prove_covariance_manually)]
pub struct ZeroMapExample<'a> {
map: ZeroMap<'a, String, u16>,
map: ZeroMap<'a, str, u16>,
}

fn main() {}
4 changes: 2 additions & 2 deletions utils/zerovec/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ pub struct DataStruct<'data> {
#[serde(borrow)]
nums: ZeroVec<'data, u32>,
#[serde(borrow)]
strs: VarZeroVec<'data, String>,
strs: VarZeroVec<'data, str>,
}

let data = DataStruct {
nums: ZeroVec::from_slice(&[211, 281, 421, 461]),
strs: VarZeroVec::from(&["hello".to_string(), "world".to_string()] as &[_]),
strs: VarZeroVec::from(&["hello", "world"] as &[_]),
};
let bincode_bytes = bincode::serialize(&data)
.expect("Serialization should be successful");
Expand Down
19 changes: 11 additions & 8 deletions utils/zerovec/benches/vzv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ fn overview_bench(c: &mut Criterion) {
// Same as vzv/char_count/vzv but with different inputs
let seed = 42;
let (string_vec, _) = random_alphanums(2..=10, 100, seed);
let bytes: Vec<u8> = VarZeroVec::get_serializable_bytes(string_vec.as_slice()).unwrap();
let vzv = VarZeroVec::<String>::parse_byte_slice(black_box(bytes.as_slice())).unwrap();
let bytes: Vec<u8> =
VarZeroVec::<str>::get_serializable_bytes::<String>(string_vec.as_slice()).unwrap();
let vzv = VarZeroVec::<str>::parse_byte_slice(black_box(bytes.as_slice())).unwrap();

c.bench_function("vzv/overview", |b| {
b.iter(|| {
Expand All @@ -72,8 +73,9 @@ fn overview_bench(c: &mut Criterion) {
fn char_count_benches(c: &mut Criterion) {
let seed = 2021;
let (string_vec, _) = random_alphanums(2..=20, 100, seed);
let bytes: Vec<u8> = VarZeroVec::get_serializable_bytes(string_vec.as_slice()).unwrap();
let vzv = VarZeroVec::<String>::parse_byte_slice(black_box(bytes.as_slice())).unwrap();
let bytes: Vec<u8> =
VarZeroVec::<str>::get_serializable_bytes::<String>(string_vec.as_slice()).unwrap();
let vzv = VarZeroVec::<str>::parse_byte_slice(black_box(bytes.as_slice())).unwrap();

// *** Count chars in vec of 100 strings ***
c.bench_function("vzv/char_count/slice", |b| {
Expand All @@ -99,8 +101,9 @@ fn binary_search_benches(c: &mut Criterion) {
let seed = 2021;
let (string_vec, seed) = random_alphanums(2..=20, 500, seed);
let (needles, _) = random_alphanums(2..=20, 10, seed);
let bytes: Vec<u8> = VarZeroVec::get_serializable_bytes(string_vec.as_slice()).unwrap();
let vzv = VarZeroVec::<String>::parse_byte_slice(black_box(bytes.as_slice())).unwrap();
let bytes: Vec<u8> =
VarZeroVec::<str>::get_serializable_bytes::<String>(string_vec.as_slice()).unwrap();
let vzv = VarZeroVec::<str>::parse_byte_slice(black_box(bytes.as_slice())).unwrap();
let single_needle = "lmnop".to_string();

// *** Binary search vec of 500 strings 10 times ***
Expand Down Expand Up @@ -139,7 +142,7 @@ fn serde_benches(c: &mut Criterion) {
let seed = 2021;
let (string_vec, _) = random_alphanums(2..=20, 100, seed);
let bincode_vec = bincode::serialize(&string_vec).unwrap();
let vzv = VarZeroVec::from(&*string_vec);
let vzv: VarZeroVec<str> = VarZeroVec::from(&*string_vec);
let bincode_vzv = bincode::serialize(&vzv).unwrap();

// *** Deserialize vec of 100 strings ***
Expand All @@ -154,7 +157,7 @@ fn serde_benches(c: &mut Criterion) {

// *** Deserialize vec of 100 strings ***
c.bench_function("vzv/deserialize/string/vzv", |b| {
b.iter(|| bincode::deserialize::<VarZeroVec<String>>(black_box(&bincode_vzv)));
b.iter(|| bincode::deserialize::<VarZeroVec<str>>(black_box(&bincode_vzv)));
});
}

Expand Down
4 changes: 2 additions & 2 deletions utils/zerovec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@
//! #[serde(borrow)]
//! nums: ZeroVec<'data, u32>,
//! #[serde(borrow)]
//! strs: VarZeroVec<'data, String>,
//! strs: VarZeroVec<'data, str>,
//! }
//!
//! let data = DataStruct {
//! nums: ZeroVec::from_slice(&[211, 281, 421, 461]),
//! strs: VarZeroVec::from(&["hello".to_string(), "world".to_string()] as &[_]),
//! strs: VarZeroVec::from(&["hello", "world"] as &[_]),
//! };
//! let bincode_bytes = bincode::serialize(&data)
//! .expect("Serialization should be successful");
Expand Down
71 changes: 58 additions & 13 deletions utils/zerovec/src/map/kv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,41 @@ use super::vecs::ZeroVecLike;
use crate::ule::*;
use crate::VarZeroVec;
use crate::ZeroVec;
use alloc::string::String;
use alloc::vec::Vec;
use alloc::boxed::Box;
use core::cmp::Ordering;

/// Trait marking types which are allowed to be keys or values in [`ZeroMap`](super::ZeroMap).
///
/// Users should not be calling methods of this trait directly, however if you are
/// implementing your own [`AsULE`] or [`AsVarULE`] type you may wish to implement
/// implementing your own [`AsULE`] or [`VarULE`] type you may wish to implement
/// this trait.
// this lifetime should be a GAT on Container once that is possible
#[allow(clippy::upper_case_acronyms)] // KV is not an acronym
pub trait ZeroMapKV<'a>: Sized {
pub trait ZeroMapKV<'a> {
/// The container that can be used with this type: [`ZeroVec`] or [`VarZeroVec`].
type Container: ZeroVecLike<'a, Self, NeedleType = Self::NeedleType, GetType = Self::GetType>
+ Sized;
type Container: ZeroVecLike<
'a,
Self,
NeedleType = Self::NeedleType,
GetType = Self::GetType,
OwnedType = Self::OwnedType,
> + Sized;
/// The type to use with `Container::binary_search()`
///
/// This type will be predetermined by the choice of `Self::Container`
type NeedleType: ?Sized;
/// The type produces by `Container::get()`
/// The type produced by `Container::get()`
///
/// This type will be predetermined by the choice of `Self::Container`
type GetType: ?Sized;
/// The type to use whilst serializing. This may not necessarily be `Self`, however it
/// must serialize to the exact same thing as `Self`
type SerializeType: ?Sized;
/// The type produced by `Container::replace()` and `Container::remove()`,
/// also used during deserialization. If `Self` is human readable serialized,
/// deserializing to `Self::OwnedType` should produce the same value once
/// passed through `Self::owned_as_self()`
type OwnedType;
/// Convert to a needle for searching
fn as_needle(&self) -> &Self::NeedleType;
/// Compare this type with a `Self::GetType`. This must produce the same result as
Expand All @@ -42,6 +51,9 @@ pub trait ZeroMapKV<'a>: Sized {
/// This uses a callback because it's not possible to return owned-or-borrowed
/// types without GATs
fn with_ser<R>(g: &Self::GetType, f: impl FnOnce(&Self::SerializeType) -> R) -> R;

/// Convert an owned value to a borrowed Self
fn owned_as_self(o: &Self::OwnedType) -> &Self;
}

macro_rules! impl_sized_kv {
Expand All @@ -51,16 +63,27 @@ macro_rules! impl_sized_kv {
type NeedleType = $ty;
type GetType = <$ty as AsULE>::ULE;
type SerializeType = $ty;
type OwnedType = $ty;

#[inline]
fn as_needle(&self) -> &Self {
self
}

#[inline]
fn cmp_get(&self, g: &Self::GetType) -> Ordering {
self.cmp(&$ty::from_unaligned(g))
}

#[inline]
fn with_ser<R>(g: &Self::GetType, f: impl FnOnce(&Self) -> R) -> R {
f(&Self::from_unaligned(g))
}

#[inline]
fn owned_as_self(o: &Self::OwnedType) -> &Self {
o
}
}
};
}
Expand All @@ -75,36 +98,58 @@ impl_sized_kv!(i64);
impl_sized_kv!(i128);
impl_sized_kv!(char);

impl<'a> ZeroMapKV<'a> for String {
type Container = VarZeroVec<'a, String>;
impl<'a> ZeroMapKV<'a> for str {
type Container = VarZeroVec<'a, str>;
type NeedleType = str;
type GetType = str;
type SerializeType = str;
type OwnedType = Box<str>;

#[inline]
fn as_needle(&self) -> &str {
self
}

#[inline]
fn cmp_get(&self, g: &str) -> Ordering {
(&**self).cmp(g)
(&*self).cmp(g)
}

#[inline]
fn with_ser<R>(g: &str, f: impl FnOnce(&str) -> R) -> R {
f(g)
}

#[inline]
fn owned_as_self(o: &Self::OwnedType) -> &Self {
o
}
}

impl<'a> ZeroMapKV<'a> for Vec<u8> {
type Container = VarZeroVec<'a, Vec<u8>>;
impl<'a> ZeroMapKV<'a> for [u8] {
type Container = VarZeroVec<'a, [u8]>;
type NeedleType = [u8];
type GetType = [u8];
type SerializeType = [u8];
type OwnedType = Box<[u8]>;

#[inline]
fn as_needle(&self) -> &[u8] {
self
}

#[inline]
fn cmp_get(&self, g: &[u8]) -> Ordering {
(&**self).cmp(g)
(&*self).cmp(g)
}

#[inline]
fn with_ser<R>(g: &[u8], f: impl FnOnce(&[u8]) -> R) -> R {
f(g)
}

#[inline]
fn owned_as_self(o: &Self::OwnedType) -> &Self {
o
}
}
40 changes: 23 additions & 17 deletions utils/zerovec/src/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub use vecs::ZeroVecLike;
/// ];
///
/// // Deserializing to ZeroMap requires no heap allocations.
/// let zero_map: ZeroMap<u32, String> = bincode::deserialize(BINCODE_BYTES)
/// let zero_map: ZeroMap<u32, str> = bincode::deserialize(BINCODE_BYTES)
/// .expect("Should deserialize successfully");
/// assert_eq!(zero_map.get(&1), Some("one"));
/// ```
Expand All @@ -49,6 +49,8 @@ pub struct ZeroMap<'a, K, V>
where
K: ZeroMapKV<'a>,
V: ZeroMapKV<'a>,
K: ?Sized,
V: ?Sized,
{
pub(crate) keys: K::Container,
pub(crate) values: V::Container,
Expand All @@ -58,6 +60,8 @@ impl<'a, K, V> Default for ZeroMap<'a, K, V>
where
K: ZeroMapKV<'a>,
V: ZeroMapKV<'a>,
K: ?Sized,
V: ?Sized,
{
fn default() -> Self {
Self {
Expand All @@ -71,6 +75,8 @@ impl<'a, K, V> ZeroMap<'a, K, V>
where
K: ZeroMapKV<'a>,
V: ZeroMapKV<'a>,
K: ?Sized,
V: ?Sized,
{
/// Construct a new [`ZeroMap`]
pub fn new() -> Self {
Expand Down Expand Up @@ -116,8 +122,8 @@ where
/// use zerovec::ZeroMap;
///
/// let mut map = ZeroMap::new();
/// map.insert(1, "one".to_owned());
/// map.insert(2, "two".to_owned());
/// map.insert(&1, "one");
/// map.insert(&2, "two");
/// assert_eq!(map.get(&1), Some("one"));
/// assert_eq!(map.get(&3), None);
/// ```
Expand All @@ -132,8 +138,8 @@ where
/// use zerovec::ZeroMap;
///
/// let mut map = ZeroMap::new();
/// map.insert(1, "one".to_owned());
/// map.insert(2, "two".to_owned());
/// map.insert(&1, "one");
/// map.insert(&2, "two");
/// assert_eq!(map.contains_key(&1), true);
/// assert_eq!(map.contains_key(&3), false);
/// ```
Expand All @@ -147,12 +153,12 @@ where
/// use zerovec::ZeroMap;
///
/// let mut map = ZeroMap::new();
/// map.insert(1, "one".to_owned());
/// map.insert(2, "two".to_owned());
/// map.insert(&1, "one");
/// map.insert(&2, "two");
/// assert_eq!(map.get(&1), Some("one"));
/// assert_eq!(map.get(&3), None);
/// ```
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
pub fn insert(&mut self, key: &K, value: &V) -> Option<V::OwnedType> {
let key_needle = key.as_needle();
match self.keys.binary_search(key_needle) {
Ok(index) => Some(self.values.replace(index, value)),
Expand All @@ -170,12 +176,12 @@ where
/// use zerovec::ZeroMap;
///
/// let mut map = ZeroMap::new();
/// map.insert(1, "one".to_owned());
/// map.insert(2, "two".to_owned());
/// assert_eq!(map.remove(&1), Some("one".to_owned()));
/// map.insert(&1, "one");
/// map.insert(&2, "two");
/// assert_eq!(map.remove(&1), Some("one".to_owned().into_boxed_str()));
/// assert_eq!(map.get(&1), None);
/// ```
pub fn remove(&mut self, key: &K::NeedleType) -> Option<V> {
pub fn remove(&mut self, key: &K::NeedleType) -> Option<V::OwnedType> {
let idx = self.keys.binary_search(key).ok()?;
self.keys.remove(idx);
Some(self.values.remove(idx))
Expand All @@ -188,13 +194,13 @@ where
/// use zerovec::ZeroMap;
///
/// let mut map = ZeroMap::new();
/// assert!(map.try_append(1, "uno".to_owned()).is_none());
/// assert!(map.try_append(3, "tres".to_owned()).is_none());
/// assert!(map.try_append(&1, "uno").is_none());
/// assert!(map.try_append(&3, "tres").is_none());
///
/// let unsuccessful = map.try_append(3, "tres-updated".to_owned());
/// let unsuccessful = map.try_append(&3, "tres-updated");
/// assert!(unsuccessful.is_some(), "append duplicate of last key");
///
/// let unsuccessful = map.try_append(2, "dos".to_owned());
/// let unsuccessful = map.try_append(&2, "dos");
/// assert!(unsuccessful.is_some(), "append out of order");
///
/// assert_eq!(map.get(&1), Some("uno"));
Expand All @@ -206,7 +212,7 @@ where
/// assert_eq!(map.get(&2), None);
/// ```
#[must_use]
pub fn try_append(&mut self, key: K, value: V) -> Option<(K, V)> {
pub fn try_append<'b>(&mut self, key: &'b K, value: &'b V) -> Option<(&'b K, &'b V)> {
if self.keys.len() != 0 {
if let Some(last) = self.keys.get(self.keys.len() - 1) {
if key.cmp_get(last) != Ordering::Greater {
Expand Down
Loading