Skip to content

Commit

Permalink
Draft of lazy Value
Browse files Browse the repository at this point in the history
Signed-off-by: Heinz N. Gies <[email protected]>
  • Loading branch information
Licenser committed Aug 3, 2024
1 parent ab9663d commit 2bc889a
Show file tree
Hide file tree
Showing 16 changed files with 1,920 additions and 136 deletions.
2 changes: 1 addition & 1 deletion src/impls/neon/stage1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ impl Stage1Parse for SimdInput {
let cnt: usize = bits.count_ones() as usize;
let mut l = base.len();
let idx_minus_64 = idx.wrapping_sub(64);
let idx_64_v = mem::transmute::<_, int32x4_t>([
let idx_64_v = mem::transmute::<[i32; 4], int32x4_t>([
static_cast_i32!(idx_minus_64),
static_cast_i32!(idx_minus_64),
static_cast_i32!(idx_minus_64),
Expand Down
6 changes: 3 additions & 3 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1262,7 +1262,7 @@ macro_rules! static_cast_i8 {
#[macro_export]
macro_rules! static_cast_i32 {
($v:expr) => {
std::mem::transmute::<_, i32>($v)
std::mem::transmute::<u32, i32>($v)
};
}

Expand All @@ -1278,7 +1278,7 @@ macro_rules! static_cast_u32 {
#[macro_export]
macro_rules! static_cast_i64 {
($v:expr) => {
::std::mem::transmute::<_, i64>($v)
::std::mem::transmute::<u64, i64>($v)
};
}

Expand All @@ -1294,7 +1294,7 @@ macro_rules! static_cast_i128 {
#[macro_export]
macro_rules! static_cast_u64 {
($v:expr) => {
::std::mem::transmute::<_, u64>($v)
::std::mem::transmute::<i64, u64>($v)
};
}

Expand Down
4 changes: 2 additions & 2 deletions src/numberparse/approx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ impl<'de> Deserializer<'de> {
}

if negative && i > 9_223_372_036_854_775_808 {
//i64::min_value() * -1
//i64::MIN * -1
return Err(Self::error_c(
idx + digitcount,
d as char,
Expand Down Expand Up @@ -320,7 +320,7 @@ impl<'de> Deserializer<'de> {
}

if negative && i > 170_141_183_460_469_231_731_687_303_715_884_105_728_u128 {
//i64::min_value() * -1
//i64::MIN * -1
return Err(Self::error_c(
idx + digitcount,
d as char,
Expand Down
4 changes: 4 additions & 0 deletions src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ pub mod borrowed;
pub mod owned;
/// Tape implementation
pub mod tape;

/// A value that starts out as a tape and upgraes to a borrowed value when mutation is needed
pub mod lazy;

pub use self::borrowed::{
to_value as to_borrowed_value, to_value_with_buffers as to_borrowed_value_with_buffers,
Value as BorrowedValue,
Expand Down
112 changes: 87 additions & 25 deletions src/value/borrowed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ mod from;
mod serialize;

use super::ObjectHasher;
use crate::cow::Cow;
use crate::{cow::Cow, safer_unchecked::GetSaferUnchecked as _};
use crate::{prelude::*, Buffers};
use crate::{Deserializer, Node, Result};
use halfbrown::HashMap;
Expand All @@ -34,6 +34,8 @@ use std::ops::{Index, IndexMut};

/// Representation of a JSON object
pub type Object<'value> = HashMap<Cow<'value, str>, Value<'value>, ObjectHasher>;
/// Representation of a JSON array
pub type Array<'value> = Vec<Value<'value>>;

/// Parses a slice of bytes into a Value dom. This function will
/// rewrite the slice to de-escape strings.
Expand Down Expand Up @@ -176,7 +178,7 @@ impl<'value> ValueBuilder<'value> for Value<'value> {
}

impl<'value> ValueAsMutContainer for Value<'value> {
type Array = Vec<Self>;
type Array = Array<'value>;
type Object = Object<'value>;
#[cfg_attr(not(feature = "no-inline"), inline)]
#[must_use]
Expand Down Expand Up @@ -286,7 +288,7 @@ impl<'value> ValueAsScalar for Value<'value> {
}
}
impl<'value> ValueAsContainer for Value<'value> {
type Array = Vec<Self>;
type Array = Array<'value>;
type Object = Object<'value>;

#[cfg_attr(not(feature = "no-inline"), inline)]
Expand Down Expand Up @@ -320,7 +322,7 @@ impl<'value> ValueIntoString for Value<'value> {
}

impl<'value> ValueIntoContainer for Value<'value> {
type Array = Vec<Self>;
type Array = Array<'value>;
type Object = Object<'value>;

fn into_array(self) -> Option<<Self as ValueIntoContainer>::Array> {
Expand Down Expand Up @@ -392,7 +394,7 @@ impl<'value> Default for Value<'value> {
}
}

struct BorrowDeserializer<'de>(Deserializer<'de>);
pub(super) struct BorrowDeserializer<'de>(Deserializer<'de>);

impl<'de> BorrowDeserializer<'de> {
pub fn from_deserializer(de: Deserializer<'de>) -> Self {
Expand Down Expand Up @@ -444,6 +446,66 @@ impl<'de> BorrowDeserializer<'de> {
Value::from(res)
}
}
pub(super) struct BorrowSliceDeserializer<'tape, 'de> {
tape: &'tape [Node<'de>],
idx: usize,
}
impl<'tape, 'de> BorrowSliceDeserializer<'tape, 'de> {
pub fn from_tape(de: &'tape [Node<'de>]) -> Self {
Self { tape: de, idx: 0 }
}
#[cfg_attr(not(feature = "no-inline"), inline)]
pub unsafe fn next_(&mut self) -> Node<'de> {
let r = *self.tape.get_kinda_unchecked(self.idx);
self.idx += 1;
r
}

#[cfg_attr(not(feature = "no-inline"), inline)]
pub fn parse(&mut self) -> Value<'de> {
match unsafe { self.next_() } {
Node::Static(s) => Value::Static(s),
Node::String(s) => Value::from(s),
Node::Array { len, count: _ } => self.parse_array(len),
Node::Object { len, count: _ } => self.parse_map(len),
}
}

#[cfg_attr(not(feature = "no-inline"), inline)]
fn parse_array(&mut self, len: usize) -> Value<'de> {
// Rust doesn't optimize the normal loop away here
// so we write our own avoiding the length
// checks during push
let mut res: Vec<Value<'de>> = Vec::with_capacity(len);
let res_ptr = res.as_mut_ptr();
unsafe {
for i in 0..len {
res_ptr.add(i).write(self.parse());
}
res.set_len(len);
}
Value::Array(res)
}

#[cfg_attr(not(feature = "no-inline"), inline)]
fn parse_map(&mut self, len: usize) -> Value<'de> {
let mut res = Object::with_capacity_and_hasher(len, ObjectHasher::default());

// Since we checked if it's empty we know that we at least have one
// element so we eat this
for _ in 0..len {
if let Node::String(key) = unsafe { self.next_() } {
#[cfg(not(feature = "value-no-dup-keys"))]
res.insert_nocheck(key.into(), self.parse());
#[cfg(feature = "value-no-dup-keys")]
res.insert(key.into(), self.parse());
} else {
unreachable!();
}
}
Value::from(res)
}
}

#[cfg(test)]
mod test {
Expand Down Expand Up @@ -483,7 +545,7 @@ mod test {
#[cfg(feature = "128bit")]
#[test]
fn conversions_i128() {
let v = Value::from(i128::max_value());
let v = Value::from(i128::MAX);
assert!(v.is_i128());
assert!(v.is_u128());
assert!(!v.is_i64());
Expand All @@ -497,7 +559,7 @@ mod test {
assert!(!v.is_f64());
assert!(!v.is_f32());
assert!(v.is_f64_castable());
let v = Value::from(i128::min_value());
let v = Value::from(i128::MIN);
assert!(v.is_i128());
assert!(!v.is_u128());
assert!(!v.is_i64());
Expand All @@ -515,7 +577,7 @@ mod test {

#[test]
fn conversions_i64() {
let v = Value::from(i64::max_value());
let v = Value::from(i64::MAX);
assert!(v.is_i128());
assert!(v.is_u128());
assert!(v.is_i64());
Expand All @@ -529,7 +591,7 @@ mod test {
assert!(!v.is_f64());
assert!(!v.is_f32());
assert!(v.is_f64_castable());
let v = Value::from(i64::min_value());
let v = Value::from(i64::MIN);
assert!(v.is_i128());
assert!(!v.is_u128());
assert!(v.is_i64());
Expand All @@ -547,7 +609,7 @@ mod test {

#[test]
fn conversions_i32() {
let v = Value::from(i32::max_value());
let v = Value::from(i32::MAX);
assert!(v.is_i128());
assert!(v.is_u128());
assert!(v.is_i64());
Expand All @@ -561,7 +623,7 @@ mod test {
assert!(!v.is_f64());
assert!(!v.is_f32());
assert!(v.is_f64_castable());
let v = Value::from(i32::min_value());
let v = Value::from(i32::MIN);
assert!(v.is_i128());
assert!(!v.is_u128());
assert!(v.is_i64());
Expand All @@ -579,7 +641,7 @@ mod test {

#[test]
fn conversions_i16() {
let v = Value::from(i16::max_value());
let v = Value::from(i16::MAX);
assert!(v.is_i128());
assert!(v.is_u128());
assert!(v.is_i64());
Expand All @@ -593,7 +655,7 @@ mod test {
assert!(!v.is_f64());
assert!(!v.is_f32());
assert!(v.is_f64_castable());
let v = Value::from(i16::min_value());
let v = Value::from(i16::MIN);
assert!(v.is_i128());
assert!(!v.is_u128());
assert!(v.is_i64());
Expand All @@ -612,7 +674,7 @@ mod test {

#[test]
fn conversions_i8() {
let v = Value::from(i8::max_value());
let v = Value::from(i8::MAX);
assert!(v.is_i128());
assert!(v.is_u128());
assert!(v.is_i64());
Expand All @@ -626,7 +688,7 @@ mod test {
assert!(!v.is_f64());
assert!(!v.is_f32());
assert!(v.is_f64_castable());
let v = Value::from(i8::min_value());
let v = Value::from(i8::MIN);
assert!(v.is_i128());
assert!(!v.is_u128());
assert!(v.is_i64());
Expand All @@ -644,7 +706,7 @@ mod test {

#[test]
fn conversions_usize() {
let v = Value::from(usize::min_value() as u64);
let v = Value::from(usize::MIN as u64);
assert!(v.is_i128());
assert!(v.is_u128());
assert!(v.is_i64());
Expand All @@ -666,7 +728,7 @@ mod test {
#[cfg(feature = "128bit")]
#[test]
fn conversions_u128() {
let v = Value::from(u128::min_value());
let v = Value::from(u128::MIN);
assert!(v.is_i128());
assert!(v.is_u128());
assert!(v.is_i64());
Expand All @@ -684,7 +746,7 @@ mod test {

#[test]
fn conversions_u64() {
let v = Value::from(u64::min_value());
let v = Value::from(u64::MIN);
assert!(v.is_i128());
assert!(v.is_u128());
assert!(v.is_i64());
Expand All @@ -702,7 +764,7 @@ mod test {

#[test]
fn conversions_u32() {
let v = Value::from(u32::max_value());
let v = Value::from(u32::MAX);
assert!(v.is_i128());
assert!(v.is_u128());
assert!(v.is_i64());
Expand All @@ -720,7 +782,7 @@ mod test {

#[test]
fn conversions_u16() {
let v = Value::from(u16::max_value());
let v = Value::from(u16::MAX);
assert!(v.is_i128());
assert!(v.is_u128());
assert!(v.is_i64());
Expand All @@ -738,7 +800,7 @@ mod test {

#[test]
fn conversions_u8() {
let v = Value::from(u8::max_value());
let v = Value::from(u8::MAX);
assert!(v.is_i128());
assert!(v.is_u128());
assert!(v.is_i64());
Expand All @@ -756,13 +818,13 @@ mod test {

#[test]
fn conversions_f64() {
let v = Value::from(std::f64::MAX);
let v = Value::from(f64::MAX);
assert!(!v.is_i64());
assert!(!v.is_u64());
assert!(v.is_f64());
assert!(!v.is_f32());
assert!(v.is_f64_castable());
let v = Value::from(std::f64::MIN);
let v = Value::from(f64::MIN);
assert!(!v.is_i64());
assert!(!v.is_u64());
assert!(v.is_f64());
Expand All @@ -774,13 +836,13 @@ mod test {

#[test]
fn conversions_f32() {
let v = Value::from(std::f32::MAX);
let v = Value::from(f32::MAX);
assert!(!v.is_i64());
assert!(!v.is_u64());
assert!(v.is_f64());
assert!(v.is_f32());
assert!(v.is_f64_castable());
let v = Value::from(std::f32::MIN);
let v = Value::from(f32::MIN);
assert!(!v.is_i64());
assert!(!v.is_u64());
assert!(v.is_f64());
Expand Down
Loading

0 comments on commit 2bc889a

Please sign in to comment.