Code Monkey home page Code Monkey logo

rsonpath's Introduction

rsonpath โ€“ SIMD-powered JSONPath ๐Ÿš€

Rust docs.rs Book

OpenSSF Best Practices OpenSSF Scorecard fuzzing

Crates.io GitHub Release Date GitHub last commit

MSRV License

Experimental JSONPath engine for querying massive streamed datasets.

The rsonpath crate provides a JSONPath parser and a query execution engine rq, which utilizes SIMD instructions to provide massive throughput improvements over conventional engines.

Benchmarks of rsonpath against a reference no-SIMD engine on the Pison dataset. NOTE: Scale is logarithmic! Main throughput plot

Usage

To run a JSONPath query on a file execute:

rq '$..a.b' ./file.json

If the file is omitted, the engine reads standard input. JSON can also be passed inline:

$ rq '$..a.b' --json '{"c":{"a":{"b":42}}}'
42

For details, consult rq --help or the rsonbook.

Results

The result of running a query is a sequence of matched values, delimited by newlines. Alternatively, passing --result count returns only the number of matches, which might be much faster. For other result modes consult the --help usage page.

Installation

See Releases for precompiled binaries for all first-class support targets.

cargo

Easiest way to install is via cargo.

$ cargo install rsonpath
...

Native CPU optimizations

If maximum speed is paramount, you should install rsonpath with native CPU instructions support. This will result in a binary that is not portable and might work incorrectly on any other machine, but will squeeze out every last bit of throughput.

To do this, run the following cargo install variant:

$ RUSTFLAGS="-C target-cpu=native" cargo install rsonpath
...

Check out the relevant chapter in the rsonbook.

Query language

The project is actively developed and currently supports only a subset of the JSONPath query language. A query is a sequence of segments, each containing one or more selectors.

Supported segments

Segment Syntax Supported Since Tracking Issue
Child segment (single) [<selector>] โœ”๏ธ v0.1.0
Child segment (multiple) [<selector1>,...,<selectorN>] โŒ
Descendant segment (single) ..[<selector>] โœ”๏ธ v0.1.0
Descendant segment (multiple) ..[<selector1>,...,<selectorN>] โŒ

Supported selectors

Selector Syntax Supported Since Tracking Issue
Root $ โœ”๏ธ v0.1.0
Name .<member>, [<member>] โœ”๏ธ v0.1.0
Wildcard .*, ..*, [*] โœ”๏ธ v0.4.0
Index (array index) [<index>] โœ”๏ธ v0.5.0
Index (array index from end) [-<index>] โŒ
Array slice (forward, positive bounds) [<start>:<end>:<step>] โŒ #152
Array slice (forward, arbitrary bounds) [<start>:<end>:<step>] โŒ
Array slice (backward, arbitrary bounds) [<start>:<end>:-<step>] โŒ
Filters โ€“ existential tests [?<path>] โŒ #154
Filters โ€“ const atom comparisons [?<path> <binop> <atom>] โŒ #156
Filters โ€“ logical expressions &&, ||, ! โŒ
Filters โ€“ nesting [?<expr>[?<expr>]...] โŒ
Filters โ€“ arbitrary comparisons [?<path> <binop> <path>] โŒ
Filters โ€“ function extensions [?func(<path>)] โŒ

Supported platforms

The crate is continuously built for all Tier 1 Rust targets, and tests are continuously ran for targets that can be ran with GitHub action images. SIMD is supported only on x86/x86_64 platforms.

Target triple nosimd build SIMD support Continuous testing Tracking issues
aarch64-unknown-linux-gnu โœ”๏ธ โŒ โŒ #21, #115
i686-unknown-linux-gnu โœ”๏ธ โœ”๏ธ โœ”๏ธ
x86_64-unknown-linux-gnu โœ”๏ธ โœ”๏ธ โœ”๏ธ
x86_64-apple-darwin โœ”๏ธ โœ”๏ธ โœ”๏ธ
i686-pc-windows-gnu โœ”๏ธ โœ”๏ธ โœ”๏ธ
i686-pc-windows-msvc โœ”๏ธ โœ”๏ธ โœ”๏ธ
x86_64-pc-windows-gnu โœ”๏ธ โœ”๏ธ โœ”๏ธ
x86_64-pc-windows-msvc โœ”๏ธ โœ”๏ธ โœ”๏ธ

SIMD support

SIMD support is enabled on a module-by-module basis. Generally, any CPU released in the past decade supports AVX2, which enables all available optimizations.

Older CPUs with SSE2 or higher get partial support. You can check what exactly is enabled with rq --version โ€“ check the SIMD support field:

$ rq --version
rq 0.8.3

Commit SHA:      be6abb7fc8a3a9342876d01cad2388c10f5751e3
Features:        default,simd
Opt level:       3
Target triple:   x86_64-unknown-linux-gnu
Codegen flags:   link-arg=-fuse-ld=lld
SIMD support:    avx2;fast_quotes;fast_popcnt

The fast_quotes capability depends on the pclmulqdq instruction, and fast_popcnt on the popcnt instruction.

Caveats and limitations

JSONPath

Not all selectors are supported, see the support table above.

Duplicate keys

The engine assumes that every object in the input JSON has no duplicate keys. Behavior on duplicate keys is not guaranteed to be stable, but currently the engine will simply match the first such key.

$ rq '$.key' --json '{"key":"value","key":"other value"}'
"value"

Unicode

The engine does not parse unicode escape sequences in member names. This means that a key "a" is different from a key "\u0041", even though semantically they represent the same string. This is actually as-designed with respect to the current JSONPath spec. Parsing unicode sequences is costly, so the support for this was postponed in favour of high performance. This is tracked as #117.

Contributing

The gist is: fork, implement, make a PR back here. More details are in the CONTRIBUTING doc.

Build & test

The dev workflow utilizes just. Use the included Justfile. It will automatically install Rust for you using the rustup tool if it detects there is no Cargo in your environment.

$ just build
...
$ just test
...

Benchmarks

Benchmarks for rsonpath are located in a separate repository, included as a git submodule in this main repository.

Easiest way to run all the benchmarks is just bench. For details, look at the README in the submodule.

Background

We have a paper on rsonpath to be published at ASPLOS '24! You can read it here.

This project was conceived as my thesis. You can read it for details on the theoretical background on the engine and details of its implementation.

Dependencies

Showing direct dependencies, for full graph see below.

cargo tree --package rsonpath --edges normal --depth 1
rsonpath v0.8.3 (/home/mat/rsonpath/crates/rsonpath)
โ”œโ”€โ”€ clap v4.4.6
โ”œโ”€โ”€ color-eyre v0.6.2
โ”œโ”€โ”€ eyre v0.6.8
โ”œโ”€โ”€ log v0.4.20
โ”œโ”€โ”€ rsonpath-lib v0.8.3 (/home/mat/rsonpath/crates/rsonpath-lib)
โ””โ”€โ”€ simple_logger v4.2.0
[build-dependencies]
โ”œโ”€โ”€ rustflags v0.1.4
โ””โ”€โ”€ vergen v8.2.5
    [build-dependencies]
cargo tree --package rsonpath-lib --edges normal --depth 1
rsonpath-lib v0.8.3 (/home/mat/rsonpath/crates/rsonpath-lib)
โ”œโ”€โ”€ cfg-if v1.0.0
โ”œโ”€โ”€ log v0.4.20
โ”œโ”€โ”€ memmap2 v0.9.0
โ”œโ”€โ”€ nom v7.1.3
โ”œโ”€โ”€ smallvec v1.11.1
โ”œโ”€โ”€ static_assertions v1.1.0
โ”œโ”€โ”€ thiserror v1.0.49
โ””โ”€โ”€ vector-map v1.0.1

Justification

  • clap โ€“ standard crate to provide the CLI.
  • color-eyre, eyre โ€“ more accessible error messages for the parser.
  • log, simple-logger โ€“ diagnostic logs during compilation and execution.
  • cfg-if โ€“ used to support SIMD and no-SIMD versions.
  • memmap2 โ€“ for fast reading of source files via a memory map instead of buffered copies.
  • nom โ€“ for parser implementation.
  • smallvec โ€“ crucial for small-stack performance.
  • static_assertions โ€“ additional reliability by some constant assumptions validated at compile time.
  • thiserror โ€“ idiomatic Error implementations.
  • vector_map โ€“ used in the query compiler for measurably better performance.

Full dependency tree

cargo tree --package rsonpath --edges normal
rsonpath v0.8.3 (/home/mat/rsonpath/crates/rsonpath)
โ”œโ”€โ”€ clap v4.4.6
โ”‚   โ”œโ”€โ”€ clap_builder v4.4.6
โ”‚   โ”‚   โ”œโ”€โ”€ anstream v0.6.4
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ anstyle v1.0.4
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ anstyle-parse v0.2.2
โ”‚   โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ utf8parse v0.2.1
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ anstyle-query v1.0.0
โ”‚   โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ windows-sys v0.48.0
โ”‚   โ”‚   โ”‚   โ”‚       โ””โ”€โ”€ windows-targets v0.48.1
โ”‚   โ”‚   โ”‚   โ”‚           โ”œโ”€โ”€ windows_aarch64_gnullvm v0.48.0
โ”‚   โ”‚   โ”‚   โ”‚           โ”œโ”€โ”€ windows_aarch64_msvc v0.48.0
โ”‚   โ”‚   โ”‚   โ”‚           โ”œโ”€โ”€ windows_i686_gnu v0.48.0
โ”‚   โ”‚   โ”‚   โ”‚           โ”œโ”€โ”€ windows_i686_msvc v0.48.0
โ”‚   โ”‚   โ”‚   โ”‚           โ”œโ”€โ”€ windows_x86_64_gnu v0.48.0
โ”‚   โ”‚   โ”‚   โ”‚           โ”œโ”€โ”€ windows_x86_64_gnullvm v0.48.0
โ”‚   โ”‚   โ”‚   โ”‚           โ””โ”€โ”€ windows_x86_64_msvc v0.48.0
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ anstyle-wincon v3.0.1
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ anstyle v1.0.4
โ”‚   โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ windows-sys v0.48.0 (*)
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ colorchoice v1.0.0
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ utf8parse v0.2.1
โ”‚   โ”‚   โ”œโ”€โ”€ anstyle v1.0.4
โ”‚   โ”‚   โ”œโ”€โ”€ clap_lex v0.5.1
โ”‚   โ”‚   โ”œโ”€โ”€ strsim v0.10.0
โ”‚   โ”‚   โ””โ”€โ”€ terminal_size v0.3.0
โ”‚   โ”‚       โ”œโ”€โ”€ rustix v0.38.15
โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ bitflags v2.4.0
โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ errno v0.3.4
โ”‚   โ”‚       โ”‚   โ”‚   โ”œโ”€โ”€ errno-dragonfly v0.1.2
โ”‚   โ”‚       โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ libc v0.2.148
โ”‚   โ”‚       โ”‚   โ”‚   โ”‚   [build-dependencies]
โ”‚   โ”‚       โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ cc v1.0.83
โ”‚   โ”‚       โ”‚   โ”‚   โ”‚       โ””โ”€โ”€ libc v0.2.148
โ”‚   โ”‚       โ”‚   โ”‚   โ”œโ”€โ”€ libc v0.2.148
โ”‚   โ”‚       โ”‚   โ”‚   โ””โ”€โ”€ windows-sys v0.48.0 (*)
โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ libc v0.2.148
โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ linux-raw-sys v0.4.8
โ”‚   โ”‚       โ”‚   โ””โ”€โ”€ windows-sys v0.48.0 (*)
โ”‚   โ”‚       โ””โ”€โ”€ windows-sys v0.48.0 (*)
โ”‚   โ””โ”€โ”€ clap_derive v4.4.2 (proc-macro)
โ”‚       โ”œโ”€โ”€ heck v0.4.1
โ”‚       โ”œโ”€โ”€ proc-macro2 v1.0.67
โ”‚       โ”‚   โ””โ”€โ”€ unicode-ident v1.0.12
โ”‚       โ”œโ”€โ”€ quote v1.0.33
โ”‚       โ”‚   โ””โ”€โ”€ proc-macro2 v1.0.67 (*)
โ”‚       โ””โ”€โ”€ syn v2.0.37
โ”‚           โ”œโ”€โ”€ proc-macro2 v1.0.67 (*)
โ”‚           โ”œโ”€โ”€ quote v1.0.33 (*)
โ”‚           โ””โ”€โ”€ unicode-ident v1.0.12
โ”œโ”€โ”€ color-eyre v0.6.2
โ”‚   โ”œโ”€โ”€ backtrace v0.3.69
โ”‚   โ”‚   โ”œโ”€โ”€ addr2line v0.21.0
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ gimli v0.28.0
โ”‚   โ”‚   โ”œโ”€โ”€ cfg-if v1.0.0
โ”‚   โ”‚   โ”œโ”€โ”€ libc v0.2.148
โ”‚   โ”‚   โ”œโ”€โ”€ miniz_oxide v0.7.1
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ adler v1.0.2
โ”‚   โ”‚   โ”œโ”€โ”€ object v0.32.1
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ memchr v2.6.4
โ”‚   โ”‚   โ””โ”€โ”€ rustc-demangle v0.1.23
โ”‚   โ”‚   [build-dependencies]
โ”‚   โ”‚   โ””โ”€โ”€ cc v1.0.83 (*)
โ”‚   โ”œโ”€โ”€ eyre v0.6.8
โ”‚   โ”‚   โ”œโ”€โ”€ indenter v0.3.3
โ”‚   โ”‚   โ””โ”€โ”€ once_cell v1.18.0
โ”‚   โ”œโ”€โ”€ indenter v0.3.3
โ”‚   โ”œโ”€โ”€ once_cell v1.18.0
โ”‚   โ””โ”€โ”€ owo-colors v3.5.0
โ”œโ”€โ”€ eyre v0.6.8 (*)
โ”œโ”€โ”€ log v0.4.20
โ”œโ”€โ”€ rsonpath-lib v0.8.3 (/home/mat/rsonpath/crates/rsonpath-lib)
โ”‚   โ”œโ”€โ”€ cfg-if v1.0.0
โ”‚   โ”œโ”€โ”€ log v0.4.20
โ”‚   โ”œโ”€โ”€ memmap2 v0.9.0
โ”‚   โ”‚   โ””โ”€โ”€ libc v0.2.148
โ”‚   โ”œโ”€โ”€ nom v7.1.3
โ”‚   โ”‚   โ”œโ”€โ”€ memchr v2.6.4
โ”‚   โ”‚   โ””โ”€โ”€ minimal-lexical v0.2.1
โ”‚   โ”œโ”€โ”€ smallvec v1.11.1
โ”‚   โ”œโ”€โ”€ static_assertions v1.1.0
โ”‚   โ”œโ”€โ”€ thiserror v1.0.49
โ”‚   โ”‚   โ””โ”€โ”€ thiserror-impl v1.0.49 (proc-macro)
โ”‚   โ”‚       โ”œโ”€โ”€ proc-macro2 v1.0.67 (*)
โ”‚   โ”‚       โ”œโ”€โ”€ quote v1.0.33 (*)
โ”‚   โ”‚       โ””โ”€โ”€ syn v2.0.37 (*)
โ”‚   โ””โ”€โ”€ vector-map v1.0.1
โ”‚       โ”œโ”€โ”€ contracts v0.4.0 (proc-macro)
โ”‚       โ”‚   โ”œโ”€โ”€ proc-macro2 v1.0.67 (*)
โ”‚       โ”‚   โ”œโ”€โ”€ quote v1.0.33 (*)
โ”‚       โ”‚   โ””โ”€โ”€ syn v1.0.109
โ”‚       โ”‚       โ”œโ”€โ”€ proc-macro2 v1.0.67 (*)
โ”‚       โ”‚       โ”œโ”€โ”€ quote v1.0.33 (*)
โ”‚       โ”‚       โ””โ”€โ”€ unicode-ident v1.0.12
โ”‚       โ””โ”€โ”€ rand v0.7.3
โ”‚           โ”œโ”€โ”€ getrandom v0.1.16
โ”‚           โ”‚   โ”œโ”€โ”€ cfg-if v1.0.0
โ”‚           โ”‚   โ”œโ”€โ”€ libc v0.2.148
โ”‚           โ”‚   โ””โ”€โ”€ wasi v0.9.0+wasi-snapshot-preview1
โ”‚           โ”œโ”€โ”€ libc v0.2.148
โ”‚           โ”œโ”€โ”€ rand_chacha v0.2.2
โ”‚           โ”‚   โ”œโ”€โ”€ ppv-lite86 v0.2.17
โ”‚           โ”‚   โ””โ”€โ”€ rand_core v0.5.1
โ”‚           โ”‚       โ””โ”€โ”€ getrandom v0.1.16 (*)
โ”‚           โ”œโ”€โ”€ rand_core v0.5.1 (*)
โ”‚           โ””โ”€โ”€ rand_hc v0.2.0
โ”‚               โ””โ”€โ”€ rand_core v0.5.1 (*)
โ””โ”€โ”€ simple_logger v4.2.0
    โ”œโ”€โ”€ colored v2.0.4
    โ”‚   โ”œโ”€โ”€ is-terminal v0.4.9
    โ”‚   โ”‚   โ”œโ”€โ”€ hermit-abi v0.3.3
    โ”‚   โ”‚   โ”œโ”€โ”€ rustix v0.38.15 (*)
    โ”‚   โ”‚   โ””โ”€โ”€ windows-sys v0.48.0 (*)
    โ”‚   โ”œโ”€โ”€ lazy_static v1.4.0
    โ”‚   โ””โ”€โ”€ windows-sys v0.48.0 (*)
    โ”œโ”€โ”€ log v0.4.20
    โ”œโ”€โ”€ time v0.3.29
    โ”‚   โ”œโ”€โ”€ deranged v0.3.8
    โ”‚   โ”œโ”€โ”€ itoa v1.0.9
    โ”‚   โ”œโ”€โ”€ libc v0.2.148
    โ”‚   โ”œโ”€โ”€ num_threads v0.1.6
    โ”‚   โ”‚   โ””โ”€โ”€ libc v0.2.148
    โ”‚   โ”œโ”€โ”€ time-core v0.1.2
    โ”‚   โ””โ”€โ”€ time-macros v0.2.15 (proc-macro)
    โ”‚       โ””โ”€โ”€ time-core v0.1.2
    โ””โ”€โ”€ windows-sys v0.42.0
        โ”œโ”€โ”€ windows_aarch64_gnullvm v0.42.2
        โ”œโ”€โ”€ windows_aarch64_msvc v0.42.2
        โ”œโ”€โ”€ windows_i686_gnu v0.42.2
        โ”œโ”€โ”€ windows_i686_msvc v0.42.2
        โ”œโ”€โ”€ windows_x86_64_gnu v0.42.2
        โ”œโ”€โ”€ windows_x86_64_gnullvm v0.42.2
        โ””โ”€โ”€ windows_x86_64_msvc v0.42.2
[build-dependencies]
โ”œโ”€โ”€ rustflags v0.1.4
โ””โ”€โ”€ vergen v8.2.5
    โ”œโ”€โ”€ anyhow v1.0.75
    โ”œโ”€โ”€ rustc_version v0.4.0
    โ”‚   โ””โ”€โ”€ semver v1.0.19
    โ””โ”€โ”€ time v0.3.29
        โ”œโ”€โ”€ deranged v0.3.8
        โ”œโ”€โ”€ itoa v1.0.9
        โ”œโ”€โ”€ libc v0.2.148
        โ”œโ”€โ”€ num_threads v0.1.6 (*)
        โ””โ”€โ”€ time-core v0.1.2
    [build-dependencies]
    โ””โ”€โ”€ rustversion v1.0.14 (proc-macro)

rsonpath's People

Contributors

v0ldek avatar dependabot[bot] avatar zwerdlds avatar step-security-bot avatar zwerddpu avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.