Skip to content

Commit 6b8c3f0

Browse files
committed
try using simplified jiter value
1 parent 8758528 commit 6b8c3f0

File tree

4 files changed

+32
-23
lines changed

4 files changed

+32
-23
lines changed

Cargo.lock

Lines changed: 7 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ idna = "1.0.3"
4545
base64 = "0.22.1"
4646
num-bigint = "0.4.6"
4747
uuid = "1.11.0"
48-
jiter = { version = "0.8.2", features = ["python"] }
48+
jiter = { git = "https://github.com/pydantic/jiter", branch = "dh/simpler-value", features = ["python"] }
4949
hex = "0.4.3"
5050

5151
[lib]

src/input/input_json.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use std::borrow::Cow;
22

3-
use jiter::{JsonArray, JsonObject, JsonValue, LazyIndexMap};
3+
use jiter::{JsonArray, JsonObject, JsonValue};
44
use pyo3::prelude::*;
55
use pyo3::types::{PyDict, PyList, PyString};
6-
use smallvec::SmallVec;
76
use speedate::MicrosecondsPrecisionOverflowBehavior;
87
use strum::EnumMessage;
98

@@ -62,7 +61,9 @@ impl<'py, 'data> Input<'py> for JsonValue<'data> {
6261
match self {
6362
JsonValue::Object(object) => {
6463
let dict = PyDict::new(py);
65-
for (k, v) in LazyIndexMap::iter(object) {
64+
for (k, v) in object.as_slice() {
65+
// TODO: jiter doesn't deduplicate keys, so we should probably do that here to
66+
// avoid potential wasted work creating Python objects.
6667
dict.set_item(k, v).unwrap();
6768
}
6869
Some(dict)
@@ -253,7 +254,14 @@ impl<'py, 'data> Input<'py> for JsonValue<'data> {
253254
JsonValue::Str(s) => Ok(string_to_vec(s).into()),
254255
JsonValue::Object(object) => {
255256
// return keys iterator to match python's behavior
256-
let keys: JsonArray = JsonArray::new(object.keys().map(|k| JsonValue::Str(k.clone())).collect());
257+
// FIXME jiter doesn't deduplicate keys, should probably do that here before iteration.
258+
let keys: JsonArray = JsonArray::new(
259+
object
260+
.as_slice()
261+
.iter()
262+
.map(|(k, _)| JsonValue::Str(k.clone()))
263+
.collect(),
264+
);
257265
Ok(GenericIterator::from(keys).into_static())
258266
}
259267
_ => Err(ValError::new(ErrorTypeDefaults::IterableType, self)),
@@ -543,19 +551,19 @@ impl<'data> ValidatedDict<'_> for &'_ JsonObject<'data> {
543551
&'a self,
544552
consumer: impl ConsumeIterator<ValResult<(Self::Key<'a>, Self::Item<'a>)>, Output = R>,
545553
) -> ValResult<R> {
546-
Ok(consumer.consume_iterator(LazyIndexMap::iter(self).map(|(k, v)| Ok((k.as_ref(), v)))))
554+
Ok(consumer.consume_iterator(self.as_slice().iter().map(|(k, v)| Ok((k.as_ref(), v)))))
547555
}
548556

549557
fn last_key(&self) -> Option<Self::Key<'_>> {
550-
self.keys().last().map(AsRef::as_ref)
558+
self.last().map(|(k, _)| k.as_ref())
551559
}
552560
}
553561

554562
impl<'a, 'py, 'data> ValidatedList<'py> for &'a JsonArray<'data> {
555563
type Item = &'a JsonValue<'data>;
556564

557565
fn len(&self) -> Option<usize> {
558-
Some(SmallVec::len(self))
566+
Some(Vec::len(self))
559567
}
560568
fn iterate<R>(self, consumer: impl ConsumeIterator<PyResult<Self::Item>, Output = R>) -> ValResult<R> {
561569
Ok(consumer.consume_iterator(self.iter().map(Ok)))
@@ -569,7 +577,7 @@ impl<'a, 'data> ValidatedTuple<'_> for &'a JsonArray<'data> {
569577
type Item = &'a JsonValue<'data>;
570578

571579
fn len(&self) -> Option<usize> {
572-
Some(SmallVec::len(self))
580+
Some(Vec::len(self))
573581
}
574582
fn iterate<R>(self, consumer: impl ConsumeIterator<PyResult<Self::Item>, Output = R>) -> ValResult<R> {
575583
Ok(consumer.consume_iterator(self.iter().map(Ok)))
@@ -637,12 +645,12 @@ impl<'data> KeywordArgs<'_> for JsonObject<'data> {
637645
Self: 'a;
638646

639647
fn len(&self) -> usize {
640-
LazyIndexMap::len(self)
648+
Vec::len(self)
641649
}
642650
fn get_item<'k>(&self, key: &'k LookupKey) -> ValResult<Option<(&'k LookupPath, Self::Item<'_>)>> {
643651
key.json_get(self)
644652
}
645653
fn iter(&self) -> impl Iterator<Item = ValResult<(Self::Key<'_>, Self::Item<'_>)>> {
646-
LazyIndexMap::iter(self).map(|(k, v)| Ok((k.as_ref(), v)))
654+
self.as_slice().iter().map(|(k, v)| Ok((k.as_ref(), v)))
647655
}
648656
}

src/lookup_key.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,9 @@ impl LookupKey {
264264
&'s self,
265265
dict: &'a JsonObject<'data>,
266266
) -> ValResult<Option<(&'s LookupPath, &'a JsonValue<'data>)>> {
267+
// FIXME: use of find_map in here probably leads to quadratic complexity
267268
match self {
268-
Self::Simple { key, path, .. } => match dict.get(key.as_str()) {
269+
Self::Simple { key, path, .. } => match dict.iter().rev().find_map(|(k, v)| (k == key).then_some(v)) {
269270
Some(value) => Ok(Some((path, value))),
270271
None => Ok(None),
271272
},
@@ -275,9 +276,9 @@ impl LookupKey {
275276
key2,
276277
path2,
277278
..
278-
} => match dict.get(key1.as_str()) {
279+
} => match dict.iter().rev().find_map(|(k, v)| (k == key1).then_some(v)) {
279280
Some(value) => Ok(Some((path1, value))),
280-
None => match dict.get(key2.as_str()) {
281+
None => match dict.iter().rev().find_map(|(k, v)| (k == key2).then_some(v)) {
281282
Some(value) => Ok(Some((path2, value))),
282283
None => Ok(None),
283284
},
@@ -499,7 +500,8 @@ impl PathItem {
499500

500501
pub fn json_obj_get<'a, 'data>(&self, json_obj: &'a JsonObject<'data>) -> Option<&'a JsonValue<'data>> {
501502
match self {
502-
Self::S(key, _) => json_obj.get(key.as_str()),
503+
// FIXME: use of find_map in here probably leads to quadratic complexity
504+
Self::S(key, _) => json_obj.iter().rev().find_map(|(k, v)| (k == key).then_some(v)),
503505
_ => None,
504506
}
505507
}

0 commit comments

Comments
 (0)