mirror of
https://github.com/fluencelabs/jsonpath
synced 2025-04-25 09:22:19 +00:00
remove alloc, dealloc in wasm
This commit is contained in:
parent
d2a5d9092e
commit
3f89b9b183
59
README.md
59
README.md
@ -32,7 +32,6 @@ It is JsonPath [JsonPath](https://goessner.net/articles/JsonPath/) engine writte
|
|||||||
- [Javascript - jsonpath.select(json: string|object, jsonpath: string)](#javascript---jsonpathselectjson-stringobject-jsonpath-string)
|
- [Javascript - jsonpath.select(json: string|object, jsonpath: string)](#javascript---jsonpathselectjson-stringobject-jsonpath-string)
|
||||||
- [Javascript - jsonpath.compile(jsonpath: string)](#javascript---jsonpathcompilejsonpath-string)
|
- [Javascript - jsonpath.compile(jsonpath: string)](#javascript---jsonpathcompilejsonpath-string)
|
||||||
- [Javascript - jsonpath.selector(json: string|object)](#javascript---jsonpathselectorjson-stringobject)
|
- [Javascript - jsonpath.selector(json: string|object)](#javascript---jsonpathselectorjson-stringobject)
|
||||||
- [Javascript - allocJson, deallocJson (Webassembly Only)](#javascript---allocjson-deallocjson-webassembly-only)
|
|
||||||
- [Javascript - Other Examples](https://github.com/freestrings/jsonpath/wiki/Javascript-examples)
|
- [Javascript - Other Examples](https://github.com/freestrings/jsonpath/wiki/Javascript-examples)
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -532,60 +531,4 @@ console.log(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// => true, true
|
// => true, true
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Javascript - allocJson, deallocJson (Webassembly Only)
|
|
||||||
wasm-bindgen은 Javascript와 Webassembly간 값을 주고받을 때 JSON 객체는 String으로 변환되기 때문에, 반복해서 사용되는 JSON 객체는 Webassembly 영역에 생성해 두면 성능에 도움이 된다.
|
|
||||||
|
|
||||||
Since wasm-bindgen converts JSON objects to String when exchanging values between Javascript and Webassembly, creating frequently used JSON objects in the WebAssembly area helps performance.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const jsonpath = require('jsonpath-wasm');
|
|
||||||
|
|
||||||
let jsonObj = {
|
|
||||||
"school": {
|
|
||||||
"friends": [
|
|
||||||
{"name": "친구1", "age": 20},
|
|
||||||
{"name": "친구2", "age": 20}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"friends": [
|
|
||||||
{"name": "친구3", "age": 30},
|
|
||||||
{"name": "친구4"}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
// allocate jsonObj in webassembly
|
|
||||||
let ptr = jsonpath.allocJson(jsonObj);
|
|
||||||
|
|
||||||
// `0` is invalid pointer
|
|
||||||
if(ptr == 0) {
|
|
||||||
console.error('invalid ptr');
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = '$..friends[0]';
|
|
||||||
let template = jsonpath.compile(path);
|
|
||||||
let selector = jsonpath.selector(jsonObj);
|
|
||||||
// create selector as pointer
|
|
||||||
let ptrSelector = jsonpath.selector(ptr);
|
|
||||||
|
|
||||||
let ret1 = selector(path)
|
|
||||||
let ret2 = ptrSelector(path)
|
|
||||||
let ret3 = template(jsonObj);
|
|
||||||
// select as pointer
|
|
||||||
let ret4 = template(ptr);
|
|
||||||
let ret5 = jsonpath.select(jsonObj, path);
|
|
||||||
// select as pointer
|
|
||||||
let ret6 = jsonpath.select(ptr, path);
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
JSON.stringify(ret1) == JSON.stringify(ret2),
|
|
||||||
JSON.stringify(ret1) == JSON.stringify(ret3),
|
|
||||||
JSON.stringify(ret1) == JSON.stringify(ret4),
|
|
||||||
JSON.stringify(ret1) == JSON.stringify(ret5),
|
|
||||||
JSON.stringify(ret1) == JSON.stringify(ret6));
|
|
||||||
|
|
||||||
// => true true true true true
|
|
||||||
|
|
||||||
jsonpath.deallocJson(ptr);
|
|
||||||
```
|
|
@ -160,4 +160,14 @@ fn refval_copy(b: &mut Bencher) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn value_clone(b: &mut Bencher) {
|
||||||
|
let json = get_json();
|
||||||
|
b.iter(move || {
|
||||||
|
for _ in 1..100 {
|
||||||
|
let _ = json.clone();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
@ -12,6 +12,7 @@ use std::io::Read;
|
|||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use self::test::Bencher;
|
use self::test::Bencher;
|
||||||
|
use jsonpath::ref_value::model::RefValueWrapper;
|
||||||
|
|
||||||
fn read_json(path: &str) -> String {
|
fn read_json(path: &str) -> String {
|
||||||
let mut f = std::fs::File::open(path).unwrap();
|
let mut f = std::fs::File::open(path).unwrap();
|
||||||
@ -50,32 +51,70 @@ fn get_path(i: usize) -> &'static str {
|
|||||||
paths[i]
|
paths[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! example {
|
fn _as_value(b: &mut Bencher, index: usize) {
|
||||||
|
let json = get_json();
|
||||||
|
b.iter(move || {
|
||||||
|
for _ in 1..100 {
|
||||||
|
let _ = jsonpath::select(&json, get_path(index));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _as_ref_value(b: &mut Bencher, index: usize) {
|
||||||
|
let ref json = get_json();
|
||||||
|
let rv: RefValueWrapper = json.into();
|
||||||
|
b.iter(move || {
|
||||||
|
for _ in 1..100 {
|
||||||
|
let mut selector = jsonpath::Selector::new();
|
||||||
|
let _ = selector.path(get_path(index));
|
||||||
|
let _ = selector.value_from_ref_value(rv.clone());
|
||||||
|
let _ = selector.select_as_value();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! example_val {
|
||||||
($name:ident, $i:expr) => {
|
($name:ident, $i:expr) => {
|
||||||
#[bench]
|
#[bench]
|
||||||
fn $name(b: &mut Bencher) {
|
fn $name(b: &mut Bencher) { _as_value(b, $i); }
|
||||||
let json = get_json();
|
|
||||||
b.iter(move || {
|
|
||||||
for _ in 1..100 {
|
|
||||||
let _ = jsonpath::select(&json, get_path($i));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
example!(example0, 0);
|
macro_rules! example_val_ref {
|
||||||
example!(example1, 1);
|
($name:ident, $i:expr) => {
|
||||||
example!(example2, 2);
|
#[bench]
|
||||||
example!(example3, 3);
|
fn $name(b: &mut Bencher) { _as_ref_value(b, $i); }
|
||||||
example!(example4, 4);
|
};
|
||||||
example!(example5, 5);
|
}
|
||||||
example!(example6, 6);
|
|
||||||
example!(example7, 7);
|
example_val!(example_val_0, 0);
|
||||||
example!(example8, 8);
|
example_val!(example_val_1, 1);
|
||||||
example!(example9, 9);
|
example_val!(example_val_2, 2);
|
||||||
example!(example10, 10);
|
example_val!(example_val_3, 3);
|
||||||
example!(example11, 11);
|
example_val!(example_val_4, 4);
|
||||||
example!(example12, 12);
|
example_val!(example_val_5, 5);
|
||||||
example!(example13, 13);
|
example_val!(example_val_6, 6);
|
||||||
example!(example14, 14);
|
example_val!(example_val_7, 7);
|
||||||
|
example_val!(example_val_8, 8);
|
||||||
|
example_val!(example_val_9, 9);
|
||||||
|
example_val!(example_val_10, 10);
|
||||||
|
example_val!(example_val_11, 11);
|
||||||
|
example_val!(example_val_12, 12);
|
||||||
|
example_val!(example_val_13, 13);
|
||||||
|
example_val!(example_val_14, 14);
|
||||||
|
|
||||||
|
example_val_ref!(example_val_ref_0, 0);
|
||||||
|
example_val_ref!(example_val_ref_1, 1);
|
||||||
|
example_val_ref!(example_val_ref_2, 2);
|
||||||
|
example_val_ref!(example_val_ref_3, 3);
|
||||||
|
example_val_ref!(example_val_ref_4, 4);
|
||||||
|
example_val_ref!(example_val_ref_5, 5);
|
||||||
|
example_val_ref!(example_val_ref_6, 6);
|
||||||
|
example_val_ref!(example_val_ref_7, 7);
|
||||||
|
example_val_ref!(example_val_ref_8, 8);
|
||||||
|
example_val_ref!(example_val_ref_9, 9);
|
||||||
|
example_val_ref!(example_val_ref_10, 10);
|
||||||
|
example_val_ref!(example_val_ref_11, 11);
|
||||||
|
example_val_ref!(example_val_ref_12, 12);
|
||||||
|
example_val_ref!(example_val_ref_13, 13);
|
||||||
|
example_val_ref!(example_val_ref_14, 14);
|
@ -92,45 +92,12 @@ function wasmCompile() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function wasmCompileAlloc() {
|
|
||||||
let ptr = jpw.allocJson(getJson());
|
|
||||||
if (ptr == 0) {
|
|
||||||
console.error('Invalid pointer');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
let template = jpw.compile(path);
|
|
||||||
for (var i = 0; i < iter; i++) {
|
|
||||||
let _ = template(ptr);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
jpw.deallocJson(ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function wasmSelect() {
|
function wasmSelect() {
|
||||||
for (var i = 0; i < iter; i++) {
|
for (var i = 0; i < iter; i++) {
|
||||||
let _ = jpw.select(getJson(), path);
|
let _ = jpw.select(getJson(), path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function wasmSelectAlloc() {
|
|
||||||
let ptr = jpw.allocJson(getJson());
|
|
||||||
if (ptr == 0) {
|
|
||||||
console.error('Invalid pointer');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (var i = 0; i < iter; i++) {
|
|
||||||
let _ = jpw.select(ptr, path);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
jpw.deallocJson(ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function wasmSelectorClass() {
|
function wasmSelectorClass() {
|
||||||
let selector = new jpw.Selector();
|
let selector = new jpw.Selector();
|
||||||
for (var i = 0; i < iter; i++) {
|
for (var i = 0; i < iter; i++) {
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
use super::cmp::*;
|
use super::cmp::*;
|
||||||
use super::value_filter::ValueFilterKey;
|
use super::value_filter::ValueFilterKey;
|
||||||
use super::value_manager::*;
|
use super::value_manager::*;
|
||||||
use std::cell::RefCell;
|
|
||||||
use select::path_map::PathMap;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum TermContext {
|
pub enum TermContext {
|
||||||
@ -55,7 +52,7 @@ impl TermContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cmp_cond(&self, other: &TermContext, cmp_cond_type: CmpCondType, path_map: Arc<RefCell<PathMap>>) -> TermContext {
|
fn cmp_cond(&self, other: &TermContext, cmp_cond_type: CmpCondType) -> TermContext {
|
||||||
match self {
|
match self {
|
||||||
TermContext::Constants(et) => {
|
TermContext::Constants(et) => {
|
||||||
match other {
|
match other {
|
||||||
@ -70,7 +67,7 @@ impl TermContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TermContext::Json(_, v) => {
|
TermContext::Json(_, v) => {
|
||||||
TermContext::Json(None, ValueManager::new(v.get_val().clone(), false, path_map))
|
TermContext::Json(None, ValueManager::new(v.get_val().clone(), false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,7 +80,7 @@ impl TermContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
TermContext::Json(None, ValueManager::new(v.get_val().clone(), false, path_map))
|
TermContext::Json(None, ValueManager::new(v.get_val().clone(), false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,12 +117,12 @@ impl TermContext {
|
|||||||
self.cmp(other, CmpLe, false)
|
self.cmp(other, CmpLe, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn and(&mut self, other: &mut TermContext, path_map: Arc<RefCell<PathMap>>) -> TermContext {
|
pub fn and(&mut self, other: &mut TermContext) -> TermContext {
|
||||||
self.cmp_cond(other, CmpCondType::And, path_map)
|
self.cmp_cond(other, CmpCondType::And)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn or(&mut self, other: &mut TermContext, path_map: Arc<RefCell<PathMap>>) -> TermContext {
|
pub fn or(&mut self, other: &mut TermContext) -> TermContext {
|
||||||
self.cmp_cond(other, CmpCondType::Or, path_map)
|
self.cmp_cond(other, CmpCondType::Or)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
use std::cell::RefCell;
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
@ -8,7 +6,6 @@ use filter::term::*;
|
|||||||
use filter::value_manager::*;
|
use filter::value_manager::*;
|
||||||
use parser::parser::{FilterToken, NodeVisitor, ParseToken};
|
use parser::parser::{FilterToken, NodeVisitor, ParseToken};
|
||||||
use ref_value::model::*;
|
use ref_value::model::*;
|
||||||
use select::path_map::PathMap;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ValueFilterKey {
|
pub enum ValueFilterKey {
|
||||||
@ -52,16 +49,14 @@ pub struct ValueFilter {
|
|||||||
value_mgr: ValueManager,
|
value_mgr: ValueManager,
|
||||||
last_key: Option<ValueFilterKey>,
|
last_key: Option<ValueFilterKey>,
|
||||||
is_relative: bool,
|
is_relative: bool,
|
||||||
path_map: Arc<RefCell<PathMap>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ValueFilter {
|
impl ValueFilter {
|
||||||
pub fn new(v: RefValueWrapper, is_leaves: bool, is_relative: bool, path_map: Arc<RefCell<PathMap>>) -> Self {
|
pub fn new(v: RefValueWrapper, is_leaves: bool, is_relative: bool) -> Self {
|
||||||
ValueFilter {
|
ValueFilter {
|
||||||
value_mgr: ValueManager::new(v, is_leaves, path_map.clone()),
|
value_mgr: ValueManager::new(v, is_leaves),
|
||||||
last_key: None,
|
last_key: None,
|
||||||
is_relative,
|
is_relative,
|
||||||
path_map,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +64,7 @@ impl ValueFilter {
|
|||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
collect_all(key, &self.value_mgr.get_val(), &mut buf);
|
collect_all(key, &self.value_mgr.get_val(), &mut buf);
|
||||||
trace!("step_leaves - {:?}", buf);
|
trace!("step_leaves - {:?}", buf);
|
||||||
self.value_mgr = ValueManager::new(RefValue::Array(buf).into(), true, self.path_map.clone());
|
self.value_mgr = ValueManager::new(RefValue::Array(buf).into(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn step_leaves_all(&mut self) -> &ValueManager {
|
pub fn step_leaves_all(&mut self) -> &ValueManager {
|
||||||
@ -136,17 +131,15 @@ impl ValueFilter {
|
|||||||
|
|
||||||
pub struct JsonValueFilter {
|
pub struct JsonValueFilter {
|
||||||
json: RefValueWrapper,
|
json: RefValueWrapper,
|
||||||
path_map: Arc<RefCell<PathMap>>,
|
|
||||||
filter_stack: Vec<ValueFilter>,
|
filter_stack: Vec<ValueFilter>,
|
||||||
token_stack: Vec<ParseToken>,
|
token_stack: Vec<ParseToken>,
|
||||||
term_stack: Vec<TermContext>,
|
term_stack: Vec<TermContext>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JsonValueFilter {
|
impl JsonValueFilter {
|
||||||
pub fn new(json: RefValueWrapper, path_map: Arc<RefCell<PathMap>>) -> Self {
|
pub fn new(json: RefValueWrapper) -> Self {
|
||||||
JsonValueFilter {
|
JsonValueFilter {
|
||||||
json,
|
json,
|
||||||
path_map,
|
|
||||||
filter_stack: Vec::new(),
|
filter_stack: Vec::new(),
|
||||||
token_stack: Vec::new(),
|
token_stack: Vec::new(),
|
||||||
term_stack: Vec::new(),
|
term_stack: Vec::new(),
|
||||||
@ -164,7 +157,6 @@ impl JsonValueFilter {
|
|||||||
ValueFilter::new(vf.value_mgr.get_val().clone(),
|
ValueFilter::new(vf.value_mgr.get_val().clone(),
|
||||||
vf.value_mgr.is_leaves(),
|
vf.value_mgr.is_leaves(),
|
||||||
is_relative,
|
is_relative,
|
||||||
self.path_map.clone(),
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.and_then(|vf| {
|
.and_then(|vf| {
|
||||||
@ -175,7 +167,6 @@ impl JsonValueFilter {
|
|||||||
self.json.clone(),
|
self.json.clone(),
|
||||||
false,
|
false,
|
||||||
is_relative,
|
is_relative,
|
||||||
self.path_map.clone(),
|
|
||||||
);
|
);
|
||||||
self.filter_stack.push(vf);
|
self.filter_stack.push(vf);
|
||||||
}
|
}
|
||||||
@ -187,7 +178,6 @@ impl JsonValueFilter {
|
|||||||
v,
|
v,
|
||||||
is_leaves,
|
is_leaves,
|
||||||
false,
|
false,
|
||||||
self.path_map.clone(),
|
|
||||||
));
|
));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -348,8 +338,8 @@ impl JsonValueFilter {
|
|||||||
FilterToken::GreaterOrEqual => left.ge(&mut right),
|
FilterToken::GreaterOrEqual => left.ge(&mut right),
|
||||||
FilterToken::Little => left.lt(&mut right),
|
FilterToken::Little => left.lt(&mut right),
|
||||||
FilterToken::LittleOrEqual => left.le(&mut right),
|
FilterToken::LittleOrEqual => left.le(&mut right),
|
||||||
FilterToken::And => left.and(&mut right, self.path_map.clone()),
|
FilterToken::And => left.and(&mut right),
|
||||||
FilterToken::Or => left.or(&mut right, self.path_map.clone()),
|
FilterToken::Or => left.or(&mut right),
|
||||||
};
|
};
|
||||||
self.term_stack.push(tc);
|
self.term_stack.push(tc);
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
use std::cell::RefCell;
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use indexmap::{IndexMap, IndexSet};
|
use indexmap::{IndexMap, IndexSet};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use ref_value::model::*;
|
use ref_value::model::*;
|
||||||
use select::path_map::PathMap;
|
|
||||||
|
|
||||||
use super::cmp::*;
|
use super::cmp::*;
|
||||||
use super::term::*;
|
use super::term::*;
|
||||||
@ -176,13 +173,12 @@ pub type ValueWrapper = ValueManager;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ValueManager {
|
pub struct ValueManager {
|
||||||
val: RefValueWrapper,
|
val: RefValueWrapper,
|
||||||
path_map: Arc<RefCell<PathMap>>,
|
|
||||||
is_leaves: bool,
|
is_leaves: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ValueManager {
|
impl ValueManager {
|
||||||
pub fn new(val: RefValueWrapper, is_leaves: bool, path_map: Arc<RefCell<PathMap>>) -> Self {
|
pub fn new(val: RefValueWrapper, is_leaves: bool) -> Self {
|
||||||
ValueManager { val, is_leaves, path_map }
|
ValueManager { val, is_leaves }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_leaves(&self) -> bool {
|
pub fn is_leaves(&self) -> bool {
|
||||||
@ -226,16 +222,13 @@ impl ValueManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let ret = set.into_iter().collect();
|
let ret = set.into_iter().collect();
|
||||||
Self::new(
|
Self::new(RefValue::Array(ret).into(), false)
|
||||||
RefValue::Array(ret).into(),
|
|
||||||
false,
|
|
||||||
self.path_map.clone())
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if cmp_with_term(&self.val, et, &cmp, false, reverse) {
|
if cmp_with_term(&self.val, et, &cmp, false, reverse) {
|
||||||
Self::new(self.val.clone(), false, self.path_map.clone())
|
Self::new(self.val.clone(), false)
|
||||||
} else {
|
} else {
|
||||||
Self::new(RefValue::Null.into(), false, self.path_map.clone())
|
Self::new(RefValue::Null.into(), false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -427,7 +420,7 @@ impl ValueManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let vec = ret.into_iter().map(|v| v.clone()).collect();
|
let vec = ret.into_iter().map(|v| v.clone()).collect();
|
||||||
ValueManager::new(RefValue::Array(vec).into(), false, self.path_map.clone())
|
ValueManager::new(RefValue::Array(vec).into(), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn intersect(&self, other: &Self) -> Self {
|
pub fn intersect(&self, other: &Self) -> Self {
|
||||||
@ -450,7 +443,7 @@ impl ValueManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let vec = ret.into_iter().map(|v| v.clone()).collect();
|
let vec = ret.into_iter().map(|v| v.clone()).collect();
|
||||||
ValueManager::new(RefValue::Array(vec).into(), false, self.path_map.clone())
|
ValueManager::new(RefValue::Array(vec).into(), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn union(&self, other: &Self) -> Self {
|
pub fn union(&self, other: &Self) -> Self {
|
||||||
@ -478,7 +471,7 @@ impl ValueManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let vec = ret.into_iter().map(|v| v.clone()).collect();
|
let vec = ret.into_iter().map(|v| v.clone()).collect();
|
||||||
ValueManager::new(RefValue::Array(vec).into(), false, self.path_map.clone())
|
ValueManager::new(RefValue::Array(vec).into(), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_term(&self, key: &Option<ValueFilterKey>) -> TermContext {
|
pub fn into_term(&self, key: &Option<ValueFilterKey>) -> TermContext {
|
||||||
@ -489,7 +482,7 @@ impl ValueManager {
|
|||||||
_ => TermContext::Json(match key {
|
_ => TermContext::Json(match key {
|
||||||
Some(vk) => Some(vk.clone()),
|
Some(vk) => Some(vk.clone()),
|
||||||
_ => None
|
_ => None
|
||||||
}, ValueManager::new(self.val.clone(), false, self.path_map.clone()))
|
}, ValueManager::new(self.val.clone(), false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -519,6 +512,6 @@ impl ValueManager {
|
|||||||
_ => self.val.clone()
|
_ => self.val.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
ValueManager::new(v, false, self.path_map.clone())
|
ValueManager::new(v, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
pub mod selector;
|
pub mod selector;
|
||||||
pub mod modifiable;
|
pub mod modifiable;
|
||||||
pub mod path_map;
|
|
@ -1,53 +0,0 @@
|
|||||||
//use std::collections::HashMap;
|
|
||||||
use std::ops::Deref;
|
|
||||||
|
|
||||||
use ref_value::model::{RefValue, RefValueWrapper};
|
|
||||||
use indexmap::IndexMap;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct PathMap {
|
|
||||||
map: IndexMap<RefValueWrapper, String>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PathMap {
|
|
||||||
pub(in select) fn new() -> Self {
|
|
||||||
PathMap { map: IndexMap::new() }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_path(&self, v: &RefValueWrapper) -> Option<&String> {
|
|
||||||
self.map.get(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(in select) fn replace(&mut self, v: &RefValueWrapper) {
|
|
||||||
self.map.clear();
|
|
||||||
self.walk("".to_string(), v);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn walk(&mut self, parent_path: String, v: &RefValueWrapper) {
|
|
||||||
if &parent_path == "" {
|
|
||||||
self.map.insert(v.clone(), "/".to_string());
|
|
||||||
} else {
|
|
||||||
self.map.insert(v.clone(), parent_path.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
match v.deref() {
|
|
||||||
RefValue::Object(map) => {
|
|
||||||
for (key, value) in map {
|
|
||||||
self.walk(format!("{}/{}", &parent_path, key), value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RefValue::Array(vec) => {
|
|
||||||
for (index, value) in vec.iter().enumerate() {
|
|
||||||
self.walk(format!("{}/{}", &parent_path, index), value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn print(&self) {
|
|
||||||
for (k, v) in &self.map {
|
|
||||||
println!("{:?} : {}", k, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,9 +7,6 @@ use filter::value_filter::*;
|
|||||||
use parser::parser::*;
|
use parser::parser::*;
|
||||||
use ref_value;
|
use ref_value;
|
||||||
use ref_value::model::*;
|
use ref_value::model::*;
|
||||||
use select::path_map::PathMap;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::cell::RefCell;
|
|
||||||
|
|
||||||
/// Utility. Functions like jsonpath::selector or jsonpath::compile are also implemented using this structure.
|
/// Utility. Functions like jsonpath::selector or jsonpath::compile are also implemented using this structure.
|
||||||
///
|
///
|
||||||
@ -110,12 +107,11 @@ use std::cell::RefCell;
|
|||||||
pub struct Selector {
|
pub struct Selector {
|
||||||
pub(crate) node: Option<Node>,
|
pub(crate) node: Option<Node>,
|
||||||
pub(crate) value: Option<RefValueWrapper>,
|
pub(crate) value: Option<RefValueWrapper>,
|
||||||
path_builder: Arc<RefCell<PathMap>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Selector {
|
impl Selector {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Selector { node: None, value: None, path_builder: Arc::new(RefCell::new(PathMap::new())) }
|
Selector { node: None, value: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_value(&mut self, value: RefValueWrapper) {
|
fn set_value(&mut self, value: RefValueWrapper) {
|
||||||
@ -157,8 +153,7 @@ impl Selector {
|
|||||||
|
|
||||||
fn jf(&self) -> result::Result<JsonValueFilter, String> {
|
fn jf(&self) -> result::Result<JsonValueFilter, String> {
|
||||||
match &self.value {
|
match &self.value {
|
||||||
Some(v) => Ok(JsonValueFilter::new(v.clone(),
|
Some(v) => Ok(JsonValueFilter::new(v.clone())),
|
||||||
self.path_builder.clone())),
|
|
||||||
_ => return Err(SelectorErrorMessage::EmptyValue.to_string())
|
_ => return Err(SelectorErrorMessage::EmptyValue.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,10 +189,6 @@ impl Selector {
|
|||||||
serde_json::to_string(self.select()?.deref()).map_err(|e| e.to_string())
|
serde_json::to_string(self.select()?.deref()).map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_as_value2(&self) {
|
|
||||||
let _ = &self.select();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn select_as_value(&self) -> result::Result<Value, String> {
|
pub fn select_as_value(&self) -> result::Result<Value, String> {
|
||||||
Ok((&self.select()?).into())
|
Ok((&self.select()?).into())
|
||||||
}
|
}
|
||||||
@ -212,7 +203,7 @@ impl Selector {
|
|||||||
match func((&self.select()?).into()).map(|ref v| v.into()) {
|
match func((&self.select()?).into()).map(|ref v| v.into()) {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
self.set_value(value)
|
self.set_value(value)
|
||||||
},
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
Ok(self)
|
Ok(self)
|
||||||
|
107
tests/filter.rs
107
tests/filter.rs
@ -8,19 +8,18 @@ use std::io::Read;
|
|||||||
|
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use jsonpath::filter::value_filter::{JsonValueFilter, ValueFilter};
|
|
||||||
use jsonpath::parser::parser::Parser;
|
|
||||||
use jsonpath::Selector;
|
use jsonpath::Selector;
|
||||||
|
use jsonpath::filter::value_filter::ValueFilter;
|
||||||
|
|
||||||
fn setup() {
|
fn setup() {
|
||||||
let _ = env_logger::try_init();
|
let _ = env_logger::try_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
//fn new_value_filter(file: &str) -> ValueFilter {
|
fn new_value_filter(file: &str) -> ValueFilter {
|
||||||
// let string = read_json(file);
|
let string = read_json(file);
|
||||||
// let json: Value = serde_json::from_str(string.as_str()).unwrap();
|
let json: Value = serde_json::from_str(string.as_str()).unwrap();
|
||||||
// ValueFilter::new((&json).into(), false, false)
|
ValueFilter::new((&json).into(), false, false)
|
||||||
//}
|
}
|
||||||
|
|
||||||
fn selector(path: &str, file: &str) -> Selector {
|
fn selector(path: &str, file: &str) -> Selector {
|
||||||
let string = read_json(file);
|
let string = read_json(file);
|
||||||
@ -37,53 +36,53 @@ fn read_json(path: &str) -> String {
|
|||||||
contents
|
contents
|
||||||
}
|
}
|
||||||
|
|
||||||
//#[test]
|
#[test]
|
||||||
//fn step_in() {
|
fn step_in() {
|
||||||
// setup();
|
setup();
|
||||||
//
|
|
||||||
// let mut jf = new_value_filter("./benches/data_obj.json");
|
let mut jf = new_value_filter("./benches/data_obj.json");
|
||||||
// {
|
{
|
||||||
// let current = jf.step_in_str("friends");
|
let current = jf.step_in_str("friends");
|
||||||
// assert_eq!(current.is_array(), true);
|
assert_eq!(current.is_array(), true);
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// let mut jf = new_value_filter("./benches/data_array.json");
|
let mut jf = new_value_filter("./benches/data_array.json");
|
||||||
// {
|
{
|
||||||
// let current = jf.step_in_num(&1.0);
|
let current = jf.step_in_num(&1.0);
|
||||||
// assert_eq!(current.get_val().is_object(), true);
|
assert_eq!(current.get_val().is_object(), true);
|
||||||
// }
|
}
|
||||||
// {
|
{
|
||||||
// let current = jf.step_in_str("friends");
|
let current = jf.step_in_str("friends");
|
||||||
// assert_eq!(current.is_array(), true);
|
assert_eq!(current.is_array(), true);
|
||||||
// }
|
}
|
||||||
// let mut jf = new_value_filter("./benches/data_obj.json");
|
let mut jf = new_value_filter("./benches/data_obj.json");
|
||||||
// {
|
{
|
||||||
// jf.step_in_str("school");
|
jf.step_in_str("school");
|
||||||
// jf.step_in_str("friends");
|
jf.step_in_str("friends");
|
||||||
// jf.step_in_all();
|
jf.step_in_all();
|
||||||
// let current = jf.step_in_str("name");
|
let current = jf.step_in_str("name");
|
||||||
// let friends = json!([
|
let friends = json!([
|
||||||
// "Millicent Norman",
|
"Millicent Norman",
|
||||||
// "Vincent Cannon",
|
"Vincent Cannon",
|
||||||
// "Gray Berry"
|
"Gray Berry"
|
||||||
// ]);
|
]);
|
||||||
//
|
|
||||||
// assert_eq!(friends, current.into_value());
|
assert_eq!(friends, current.into_value());
|
||||||
// }
|
}
|
||||||
// let mut jf = new_value_filter("./benches/data_obj.json");
|
let mut jf = new_value_filter("./benches/data_obj.json");
|
||||||
// {
|
{
|
||||||
// let current = jf.step_leaves_str("name");
|
let current = jf.step_leaves_str("name");
|
||||||
// let names = json!([
|
let names = json!([
|
||||||
// "Leonor Herman",
|
"Leonor Herman",
|
||||||
// "Millicent Norman",
|
"Millicent Norman",
|
||||||
// "Vincent Cannon",
|
"Vincent Cannon",
|
||||||
// "Gray Berry",
|
"Gray Berry",
|
||||||
// "Vincent Cannon",
|
"Vincent Cannon",
|
||||||
// "Gray Berry"
|
"Gray Berry"
|
||||||
// ]);
|
]);
|
||||||
// assert_eq!(names, current.into_value());
|
assert_eq!(names, current.into_value());
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn array() {
|
fn array() {
|
||||||
|
118
wasm/src/lib.rs
118
wasm/src/lib.rs
@ -1,18 +1,14 @@
|
|||||||
extern crate cfg_if;
|
extern crate cfg_if;
|
||||||
extern crate js_sys;
|
extern crate js_sys;
|
||||||
extern crate jsonpath_lib as jsonpath;
|
extern crate jsonpath_lib as jsonpath;
|
||||||
#[macro_use]
|
|
||||||
extern crate lazy_static;
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
extern crate wasm_bindgen;
|
extern crate wasm_bindgen;
|
||||||
extern crate web_sys;
|
extern crate web_sys;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::result;
|
use std::result;
|
||||||
use std::result::Result;
|
use std::result::Result;
|
||||||
use std::sync::{Mutex, Arc};
|
|
||||||
|
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
use jsonpath::filter::value_filter::JsonValueFilter;
|
use jsonpath::filter::value_filter::JsonValueFilter;
|
||||||
@ -23,8 +19,6 @@ use serde_json::Value;
|
|||||||
use wasm_bindgen::*;
|
use wasm_bindgen::*;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use web_sys::console;
|
use web_sys::console;
|
||||||
use std::cell::RefCell;
|
|
||||||
use jsonpath::select::path_map::PathMap;
|
|
||||||
|
|
||||||
cfg_if! {
|
cfg_if! {
|
||||||
if #[cfg(feature = "wee_alloc")] {
|
if #[cfg(feature = "wee_alloc")] {
|
||||||
@ -45,14 +39,13 @@ cfg_if! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn filter_ref_value(json: RefValueWrapper, node: Node) -> JsValue {
|
fn filter_ref_value(json: RefValueWrapper, node: Node) -> JsValue {
|
||||||
// let mut jf = JsonValueFilter::new(json, Arc::new(RefCell::new(PathMap::new())));
|
let mut jf = JsonValueFilter::new(json);
|
||||||
// jf.visit(node);
|
jf.visit(node);
|
||||||
// let taken = &jf.clone_value();
|
let taken = &jf.clone_value();
|
||||||
// match JsValue::from_serde(taken.deref()) {
|
match JsValue::from_serde(taken.deref()) {
|
||||||
// Ok(js_value) => js_value,
|
Ok(js_value) => js_value,
|
||||||
// Err(e) => JsValue::from_str(&format!("Json deserialize error: {:?}", e))
|
Err(e) => JsValue::from_str(&format!("Json deserialize error: {:?}", e))
|
||||||
// }
|
}
|
||||||
JsValue::from_str("")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_serde_json<D>(js_value: &JsValue) -> Result<D, String>
|
fn into_serde_json<D>(js_value: &JsValue) -> Result<D, String>
|
||||||
@ -80,51 +73,7 @@ fn into_ref_value(js_value: &JsValue, node: Node) -> JsValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_ref_value(js_value: JsValue, node: Node) -> JsValue {
|
fn get_ref_value(js_value: JsValue, node: Node) -> JsValue {
|
||||||
// match js_value.as_f64() {
|
into_ref_value(&js_value, node)
|
||||||
// Some(val) => {
|
|
||||||
// match CACHE_JSON.lock().unwrap().get(&(val as usize)) {
|
|
||||||
// Some(json) => filter_ref_value(json.clone(), node),
|
|
||||||
// _ => JsValue::from_str("Invalid pointer")
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// _ => into_ref_value(&js_value, node)
|
|
||||||
// }
|
|
||||||
JsValue::from_str("")
|
|
||||||
}
|
|
||||||
|
|
||||||
//lazy_static! {
|
|
||||||
// static ref CACHE_JSON: Mutex<HashMap<usize, RefValueWrapper>> = Mutex::new(HashMap::new());
|
|
||||||
// static ref CACHE_JSON_IDX: Mutex<usize> = Mutex::new(0);
|
|
||||||
//}
|
|
||||||
|
|
||||||
#[wasm_bindgen(js_name = allocJson)]
|
|
||||||
pub extern fn alloc_json(js_value: JsValue) -> usize {
|
|
||||||
// let result: result::Result<RefValue, String> = into_serde_json(&js_value);
|
|
||||||
// match result {
|
|
||||||
// Ok(json) => {
|
|
||||||
// let mut map = CACHE_JSON.lock().unwrap();
|
|
||||||
// if map.len() >= std::u8::MAX as usize {
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// let mut idx = CACHE_JSON_IDX.lock().unwrap();
|
|
||||||
// *idx += 1;
|
|
||||||
// map.insert(*idx, json.into());
|
|
||||||
// *idx
|
|
||||||
// }
|
|
||||||
// Err(e) => {
|
|
||||||
// console::error_1(&e.into());
|
|
||||||
// 0
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen(js_name = deallocJson)]
|
|
||||||
pub extern fn dealloc_json(ptr: usize) -> bool {
|
|
||||||
// let mut map = CACHE_JSON.lock().unwrap();
|
|
||||||
// map.remove(&ptr).is_some()
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
@ -145,35 +94,22 @@ pub fn compile(path: &str) -> JsValue {
|
|||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn selector(js_value: JsValue) -> JsValue {
|
pub fn selector(js_value: JsValue) -> JsValue {
|
||||||
// let json = match js_value.as_f64() {
|
let json: RefValueWrapper = match into_serde_json::<RefValue>(&js_value) {
|
||||||
// Some(val) => {
|
Ok(json) => json.into(),
|
||||||
// match CACHE_JSON.lock().unwrap().get(&(val as usize)) {
|
Err(e) => return JsValue::from_str(e.as_str())
|
||||||
// Some(json) => json.clone(),
|
};
|
||||||
// _ => return JsValue::from_str("Invalid pointer")
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// _ => {
|
|
||||||
// match into_serde_json::<RefValue>(&js_value) {
|
|
||||||
// Ok(json) => json.into(),
|
|
||||||
// Err(e) => return JsValue::from_str(e.as_str())
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// };
|
let cb = Closure::wrap(Box::new(move |path: String| {
|
||||||
|
let mut parser = Parser::new(path.as_str());
|
||||||
|
match parser.compile() {
|
||||||
|
Ok(node) => filter_ref_value(json.clone(), node),
|
||||||
|
Err(e) => return JsValue::from_str(e.as_str())
|
||||||
|
}
|
||||||
|
}) as Box<Fn(String) -> JsValue>);
|
||||||
|
|
||||||
// let cb = Closure::wrap(Box::new(move |path: String| {
|
let ret = cb.as_ref().clone();
|
||||||
// let mut parser = Parser::new(path.as_str());
|
cb.forget();
|
||||||
// match parser.compile() {
|
ret
|
||||||
// Ok(node) => filter_ref_value(json.clone(), node),
|
|
||||||
// Err(e) => return JsValue::from_str(e.as_str())
|
|
||||||
// }
|
|
||||||
// }) as Box<Fn(String) -> JsValue>);
|
|
||||||
//
|
|
||||||
// let ret = cb.as_ref().clone();
|
|
||||||
// cb.forget();
|
|
||||||
// ret
|
|
||||||
|
|
||||||
JsValue::from_str("")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
@ -279,14 +215,4 @@ impl Selector {
|
|||||||
let v = self.selector.get().map_err(|e| JsValue::from_str(&e.to_string()))?;
|
let v = self.selector.get().map_err(|e| JsValue::from_str(&e.to_string()))?;
|
||||||
JsValue::from_serde(&v).map_err(|e| JsValue::from_str(&e.to_string()))
|
JsValue::from_serde(&v).map_err(|e| JsValue::from_str(&e.to_string()))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen(catch)]
|
|
||||||
pub fn testa(js_value: JsValue, path: &str, iter: usize) -> result::Result<(), JsValue> {
|
|
||||||
for _ in 0..iter {
|
|
||||||
let mut parser = Parser::new(path);
|
|
||||||
let node = parser.compile().unwrap();
|
|
||||||
into_ref_value(&js_value, node);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
@ -95,20 +95,6 @@ fn selector() {
|
|||||||
assert_eq!(json, target_json());
|
assert_eq!(json, target_json());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen_test]
|
|
||||||
fn alloc_dealloc_json() {
|
|
||||||
let ptr = jsonpath::alloc_json(JsValue::from_str(json_str()));
|
|
||||||
assert_eq!(ptr > 0, true);
|
|
||||||
|
|
||||||
let json: Value = jsonpath::select(JsValue::from_f64(ptr as f64), "$..book[2]").into_serde().unwrap();
|
|
||||||
assert_eq!(json, target_json());
|
|
||||||
|
|
||||||
assert_eq!(jsonpath::dealloc_json(ptr), true);
|
|
||||||
|
|
||||||
let err = jsonpath::select(JsValue::from_f64(ptr as f64), "$..book[2]").as_string().unwrap();
|
|
||||||
assert_eq!(err, "Invalid pointer".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen_test]
|
#[wasm_bindgen_test]
|
||||||
fn selector_struct() {
|
fn selector_struct() {
|
||||||
let mut selector = jsonpath::Selector::new();
|
let mut selector = jsonpath::Selector::new();
|
||||||
|
@ -61,9 +61,6 @@ let path = '$..book[?(@.price<30 && @.category=="fiction")]';
|
|||||||
let template = jpw.compile(path);
|
let template = jpw.compile(path);
|
||||||
let selector = jpw.selector(json);
|
let selector = jpw.selector(json);
|
||||||
|
|
||||||
let ptr = jpw.allocJson(json);
|
|
||||||
if(ptr == 0) console.error('invalid ptr');
|
|
||||||
|
|
||||||
let iterCount = 2000;
|
let iterCount = 2000;
|
||||||
|
|
||||||
run('jsonpath', iterCount, function() { jp.query(json, path) })
|
run('jsonpath', iterCount, function() { jp.query(json, path) })
|
||||||
@ -73,15 +70,9 @@ run('jsonpath', iterCount, function() { jp.query(json, path) })
|
|||||||
.then(function() {
|
.then(function() {
|
||||||
return run('jsonpath-wasm- compile', iterCount, function() { template(json) });
|
return run('jsonpath-wasm- compile', iterCount, function() { template(json) });
|
||||||
})
|
})
|
||||||
.then(function() {
|
|
||||||
return run('jsonpath-wasm- compile-alloc', iterCount, function() { template(ptr) });
|
|
||||||
})
|
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return run('jsonpath-wasm- select', iterCount, function() { jpw.select(json, path) });
|
return run('jsonpath-wasm- select', iterCount, function() { jpw.select(json, path) });
|
||||||
})
|
})
|
||||||
.then(function() {
|
|
||||||
return run('jsonpath-wasm- select-alloc', iterCount, function() { jpw.select(ptr, path) });
|
|
||||||
})
|
|
||||||
.finally(function() {
|
.finally(function() {
|
||||||
if(!jpw.deallocJson(ptr)) {
|
if(!jpw.deallocJson(ptr)) {
|
||||||
console.error('fail to dealloc');
|
console.error('fail to dealloc');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user