rangesetblaze

This commit is contained in:
John Smith 2023-04-24 21:24:40 -04:00
parent 62615ad657
commit 8368ca461a
8 changed files with 257 additions and 94 deletions

21
Cargo.lock generated
View File

@ -2150,6 +2150,12 @@ dependencies = [
"slab",
]
[[package]]
name = "gen_ops"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f41347f4fa32183c2549b86daf6b6b12a26029a77463e25358f7287580b088b"
[[package]]
name = "generic-array"
version = "0.12.4"
@ -4245,6 +4251,20 @@ dependencies = [
"rand_core 0.5.1",
]
[[package]]
name = "range-set-blaze"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e139f0c5edf89edb65753e67eaf8e6031de21ea59f84cb63e0cfb36aaf80e6d0"
dependencies = [
"gen_ops",
"itertools",
"num-integer",
"num-traits",
"rand 0.8.5",
"thiserror",
]
[[package]]
name = "raw-window-handle"
version = "0.5.2"
@ -6064,6 +6084,7 @@ dependencies = [
"paranoid-android",
"parking_lot 0.12.1",
"rand 0.7.3",
"range-set-blaze",
"rkyv",
"rtnetlink",
"rusqlite",

View File

@ -69,6 +69,7 @@ keyvaluedb = { path = "../external/keyvaluedb/keyvaluedb" }
rkyv = { version = "^0", default_features = false, features = ["std", "alloc", "strict", "size_32", "validation"] }
data-encoding = { version = "^2" }
weak-table = "0.3.2"
range-set-blaze = "0.1.4"
# Dependencies for native builds only
# Linux, Windows, Mac, iOS, Android

View File

@ -0,0 +1,37 @@
mod rkyv_enum_set;
mod rkyv_range_set_blaze;
pub mod serialize_arc;
pub mod serialize_range_set_blaze;
mod serialize_json;
use super::*;
use core::fmt::Debug;
pub use rkyv_enum_set::*;
pub use rkyv_range_set_blaze::*;
pub use serialize_json::*;
pub fn to_rkyv<T>(v: &T) -> EyreResult<Vec<u8>>
where
T: RkyvSerialize<rkyv::ser::serializers::AllocSerializer<1024>>,
{
Ok(rkyv::to_bytes::<T, 1024>(v)
.wrap_err("failed to freeze object")?
.to_vec())
}
pub fn from_rkyv<T>(v: Vec<u8>) -> EyreResult<T>
where
T: RkyvArchive,
<T as RkyvArchive>::Archived:
for<'t> CheckBytes<rkyv::validation::validators::DefaultValidator<'t>>,
<T as RkyvArchive>::Archived:
rkyv::Deserialize<T, rkyv::de::deserializers::SharedDeserializeMap>,
{
match rkyv::from_bytes::<T>(&v) {
Ok(v) => Ok(v),
Err(e) => {
bail!("failed to deserialize frozen object: {}", e);
}
}
}

View File

@ -0,0 +1,53 @@
use super::*;
pub struct RkyvEnumSet;
impl<T> rkyv::with::ArchiveWith<EnumSet<T>> for RkyvEnumSet
where
T: EnumSetType + EnumSetTypeWithRepr,
<T as EnumSetTypeWithRepr>::Repr: rkyv::Archive,
{
type Archived = rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>;
type Resolver = rkyv::Resolver<<T as EnumSetTypeWithRepr>::Repr>;
#[inline]
unsafe fn resolve_with(
field: &EnumSet<T>,
pos: usize,
resolver: Self::Resolver,
out: *mut Self::Archived,
) {
let r = field.as_repr();
r.resolve(pos, resolver, out);
}
}
impl<T, S> rkyv::with::SerializeWith<EnumSet<T>, S> for RkyvEnumSet
where
S: rkyv::Fallible + ?Sized,
T: EnumSetType + EnumSetTypeWithRepr,
<T as EnumSetTypeWithRepr>::Repr: rkyv::Serialize<S>,
{
fn serialize_with(field: &EnumSet<T>, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
let r = field.as_repr();
r.serialize(serializer)
}
}
impl<T, D>
rkyv::with::DeserializeWith<rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>, EnumSet<T>, D>
for RkyvEnumSet
where
D: rkyv::Fallible + ?Sized,
T: EnumSetType + EnumSetTypeWithRepr,
<T as EnumSetTypeWithRepr>::Repr: rkyv::Archive,
rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>:
rkyv::Deserialize<<T as EnumSetTypeWithRepr>::Repr, D>,
{
fn deserialize_with(
field: &rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>,
deserializer: &mut D,
) -> Result<EnumSet<T>, D::Error> {
Ok(EnumSet::<T>::from_repr(field.deserialize(deserializer)?))
}
}

View File

@ -0,0 +1,73 @@
use super::*;
use range_set_blaze::*;
pub struct RkyvRangeSetBlaze;
impl<T> rkyv::with::ArchiveWith<RangeSetBlaze<T>> for RkyvRangeSetBlaze
where
T: rkyv::Archive + Integer,
{
type Archived = rkyv::Archived<Vec<T>>;
type Resolver = rkyv::Resolver<Vec<T>>;
#[inline]
unsafe fn resolve_with(
field: &RangeSetBlaze<T>,
pos: usize,
resolver: Self::Resolver,
out: *mut Self::Archived,
) {
let mut r = Vec::<T>::with_capacity(field.ranges_len() * 2);
for range in field.ranges() {
r.push(*range.start());
r.push(*range.end());
}
r.resolve(pos, resolver, out);
}
}
impl<T, S> rkyv::with::SerializeWith<RangeSetBlaze<T>, S> for RkyvRangeSetBlaze
where
S: rkyv::Fallible + ?Sized,
Vec<T>: rkyv::Serialize<S>,
T: rkyv::Archive + Integer,
{
fn serialize_with(
field: &RangeSetBlaze<T>,
serializer: &mut S,
) -> Result<Self::Resolver, S::Error> {
let mut r = Vec::<T>::with_capacity(field.ranges_len() * 2);
for range in field.ranges() {
r.push(*range.start());
r.push(*range.end());
}
r.serialize(serializer)
}
}
impl<T, D> rkyv::with::DeserializeWith<rkyv::Archived<Vec<T>>, RangeSetBlaze<T>, D>
for RkyvRangeSetBlaze
where
D: rkyv::Fallible + ?Sized,
T: rkyv::Archive + Integer,
rkyv::Archived<T>: rkyv::Deserialize<T, D>,
D::Error: From<String>,
{
fn deserialize_with(
field: &rkyv::Archived<Vec<T>>,
deserializer: &mut D,
) -> Result<RangeSetBlaze<T>, D::Error> {
let mut out = RangeSetBlaze::<T>::new();
if field.len() % 2 == 1 {
return Err("invalid range set length".to_owned().into());
}
let f = field.as_slice();
for i in 0..field.len() / 2 {
let l: T = f[i].deserialize(deserializer)?;
let u: T = f[i + 1].deserialize(deserializer)?;
out.ranges_insert(l..=u);
}
Ok(out)
}
}

View File

@ -0,0 +1,12 @@
use alloc::sync::Arc;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
pub fn serialize<T: Serialize, S: Serializer>(v: &Arc<T>, s: S) -> Result<S::Ok, S::Error> {
T::serialize(v.as_ref(), s)
}
pub fn deserialize<'de, T: Deserialize<'de>, D: Deserializer<'de>>(
d: D,
) -> Result<Arc<T>, D::Error> {
Ok(Arc::new(T::deserialize(d)?))
}

View File

@ -1,7 +1,5 @@
use super::*;
use core::fmt::Debug;
// Don't trace these functions as they are used in the transfer of API logs, which will recurse!
// #[instrument(level = "trace", ret, err)]
@ -114,95 +112,3 @@ pub mod opt_json_as_string {
}
}
}
pub mod arc_serialize {
use alloc::sync::Arc;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
pub fn serialize<T: Serialize, S: Serializer>(v: &Arc<T>, s: S) -> Result<S::Ok, S::Error> {
T::serialize(v.as_ref(), s)
}
pub fn deserialize<'de, T: Deserialize<'de>, D: Deserializer<'de>>(
d: D,
) -> Result<Arc<T>, D::Error> {
Ok(Arc::new(T::deserialize(d)?))
}
}
pub fn to_rkyv<T>(v: &T) -> EyreResult<Vec<u8>>
where
T: RkyvSerialize<rkyv::ser::serializers::AllocSerializer<1024>>,
{
Ok(rkyv::to_bytes::<T, 1024>(v)
.wrap_err("failed to freeze object")?
.to_vec())
}
pub fn from_rkyv<T>(v: Vec<u8>) -> EyreResult<T>
where
T: RkyvArchive,
<T as RkyvArchive>::Archived:
for<'t> CheckBytes<rkyv::validation::validators::DefaultValidator<'t>>,
<T as RkyvArchive>::Archived:
rkyv::Deserialize<T, rkyv::de::deserializers::SharedDeserializeMap>,
{
match rkyv::from_bytes::<T>(&v) {
Ok(v) => Ok(v),
Err(e) => {
bail!("failed to deserialize frozen object: {}", e);
}
}
}
pub struct RkyvEnumSet;
impl<T> rkyv::with::ArchiveWith<EnumSet<T>> for RkyvEnumSet
where
T: EnumSetType + EnumSetTypeWithRepr,
<T as EnumSetTypeWithRepr>::Repr: rkyv::Archive,
{
type Archived = rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>;
type Resolver = rkyv::Resolver<<T as EnumSetTypeWithRepr>::Repr>;
#[inline]
unsafe fn resolve_with(
field: &EnumSet<T>,
pos: usize,
resolver: Self::Resolver,
out: *mut Self::Archived,
) {
let r = field.as_repr();
r.resolve(pos, resolver, out);
}
}
impl<T, S> rkyv::with::SerializeWith<EnumSet<T>, S> for RkyvEnumSet
where
S: rkyv::Fallible + ?Sized,
T: EnumSetType + EnumSetTypeWithRepr,
<T as EnumSetTypeWithRepr>::Repr: rkyv::Serialize<S>,
{
fn serialize_with(field: &EnumSet<T>, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
let r = field.as_repr();
r.serialize(serializer)
}
}
impl<T, D>
rkyv::with::DeserializeWith<rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>, EnumSet<T>, D>
for RkyvEnumSet
where
D: rkyv::Fallible + ?Sized,
T: EnumSetType + EnumSetTypeWithRepr,
<T as EnumSetTypeWithRepr>::Repr: rkyv::Archive,
rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>:
rkyv::Deserialize<<T as EnumSetTypeWithRepr>::Repr, D>,
{
fn deserialize_with(
field: &rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>,
deserializer: &mut D,
) -> Result<EnumSet<T>, D::Error> {
Ok(EnumSet::<T>::from_repr(field.deserialize(deserializer)?))
}
}

View File

@ -0,0 +1,60 @@
use core::fmt;
use core::marker::PhantomData;
use range_set_blaze::*;
use serde::{
de::SeqAccess, de::Visitor, ser::SerializeSeq, Deserialize, Deserializer, Serialize, Serializer,
};
pub fn serialize<T: Integer + Serialize, S: Serializer>(
v: &RangeSetBlaze<T>,
s: S,
) -> Result<S::Ok, S::Error> {
let cnt = v.ranges_len() * 2;
let mut seq = s.serialize_seq(Some(cnt))?;
for range in v.ranges() {
seq.serialize_element(range.start())?;
seq.serialize_element(range.end())?;
}
seq.end()
}
pub fn deserialize<'de, T: Integer + Deserialize<'de>, D: Deserializer<'de>>(
d: D,
) -> Result<RangeSetBlaze<T>, D::Error> {
struct RangeSetBlazeVisitor<T> {
marker: PhantomData<T>,
}
impl<'de, T> Visitor<'de> for RangeSetBlazeVisitor<T>
where
T: Deserialize<'de> + Integer,
{
type Value = RangeSetBlaze<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a RangeSetBlaze")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut values = RangeSetBlaze::<T>::new();
while let Some(start) = seq.next_element()? {
let Some(end) = seq.next_element()? else {
break;
};
values.ranges_insert(start..=end);
}
Ok(values)
}
}
let visitor = RangeSetBlazeVisitor {
marker: PhantomData,
};
d.deserialize_seq(visitor)
}