From ebd407e19234b0fbb8626cb298b099ce4bcd0c1b Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Tue, 10 Sep 2024 08:20:05 +0100 Subject: [PATCH] try to avoid lots of mem moves --- crates/jiter/src/value.rs | 46 ++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/crates/jiter/src/value.rs b/crates/jiter/src/value.rs index 5254e3c..eaca36f 100644 --- a/crates/jiter/src/value.rs +++ b/crates/jiter/src/value.rs @@ -307,38 +307,40 @@ fn take_value_recursive<'j, 's>( // now try to advance position in the current array or object peek = loop { - current_recursion = match current_recursion { - RecursedValue::Array(mut array) => { - array.push(value); + match &mut current_recursion { + RecursedValue::Array(array) => { if let Some(next_peek) = parser.array_step()? { + array.push(value); // array continuing - current_recursion = RecursedValue::Array(array); break next_peek; - } else if let Some(recursed) = recursion_stack.pop() { - // array finished, recursing - value = JsonValue::Array(Arc::new(array)); - recursed - } else { - // no recursion left and array finished - return Ok(JsonValue::Array(Arc::new(array))); } } - RecursedValue::Object { mut partial, next_key } => { - partial.insert(next_key, value); - if let Some(next_key) = parser.object_step::(tape)?.map(create_cow) { + RecursedValue::Object { partial, next_key } => { + if let Some(yet_another_key) = parser.object_step::(tape)?.map(create_cow) { + partial.insert(std::mem::replace(next_key, yet_another_key), value); // object continuing - current_recursion = RecursedValue::Object { partial, next_key }; break parser.peek()?; - } else if let Some(recursed) = recursion_stack.pop() { - // object finished, recursing - value = JsonValue::Object(Arc::new(LazyIndexMap::new())); - recursed - } else { - // no recursion left and object finished - return Ok(JsonValue::Object(Arc::new(partial))); } } } + + value = match current_recursion { + RecursedValue::Array(mut array) => { + array.push(value); + JsonValue::Array(Arc::new(array)) + } + RecursedValue::Object { mut partial, next_key } => { + partial.insert(next_key, value); + JsonValue::Object(Arc::new(partial)) + } + }; + + if let Some(r) = recursion_stack.pop() { + // value is the current array or object, next turn of the loop will insert it to the parent + current_recursion = r; + } else { + return Ok(value); + } }; } }