Skip to main content

Session

Struct Session 

Source
pub struct Session<'engine> { /* private fields */ }
Expand description

Reusable evaluation handle. Construct via Engine::session.

Owns a bumpalo::Bump; the caller controls reset via Self::reset. Subsequent evaluate* calls append to the bump until the caller resets or the session is dropped — letting the caller amortise reset cost across logical batches and avoid resetting between calls that don’t need it.

§Example

use datalogic_rs::Engine;

let engine = Engine::new();
let compiled = engine.compile(r#"{"+": [{"var": "x"}, 1]}"#).unwrap();
let mut session = engine.session();

for x in 0..3 {
    let payload = format!(r#"{{"x": {}}}"#, x);
    let result = session.eval_str(&compiled, &payload).unwrap();
    assert_eq!(result, (x + 1).to_string());
    // Reset between iterations to keep peak memory bounded by the
    // largest single evaluation rather than the cumulative loop.
    session.reset();
}

Implementations§

Source§

impl<'engine> Session<'engine>

Source

pub fn reset(&mut self)

Reset the session’s arena, returning every allocated chunk to the free list’s start-of-chunk position without freeing OS memory.

Call this between logical batches to bound peak memory. After reset, any borrowed reference previously returned by Self::eval_borrowed is invalidated — the borrow checker enforces this for the common case (the result borrow ends with the previous &mut self borrow).

Bump::reset is constant-time (resets a few pointers); the freed chunks remain allocated and serve subsequent calls without re-asking the OS for memory.

Source

pub fn reset_with_capacity(&mut self, capacity: usize)

Drop the session’s arena and replace it with a fresh one whose initial chunk holds at least capacity bytes.

Use this when you know the steady-state high-water mark of your workload (e.g. captured via Self::allocated_bytes after a warm-up pass) and want subsequent calls to run on a single pre-sized chunk — no chunk-growth events during the timed window.

Unlike Self::reset, which keeps the existing chunks and only rewinds the bump pointer, this drops the chunks entirely and allocates one new chunk of the requested capacity. Any reference previously returned by Self::eval_borrowed is invalidated; the &mut self signature lets the borrow checker enforce this.

Source

pub fn allocated_bytes(&self) -> usize

Total bytes currently occupied by the session’s arena chunks.

Useful for capturing a workload’s steady-state high-water mark after a warm-up pass — feed the returned value into Self::reset_with_capacity to pre-size the arena before a timed loop. Stable across Self::reset calls (chunks aren’t freed); drops to the new chunk size after Self::reset_with_capacity.

Forwards to bumpalo::Bump::allocated_bytes.

Source

pub fn eval<'a, D>( &'a mut self, compiled: &Logic, data: D, ) -> Result<OwnedDataValue>
where D: EvalInput<'a>,

Evaluate compiled against data and deep-clone the result into an OwnedDataValue that survives subsequent calls and resets.

The intermediate arena allocations stay in the session’s bump until the caller invokes Self::reset. For long-running loops, call reset between iterations to keep peak memory bounded.

§Example
use datalogic_rs::Engine;

let engine = Engine::new();
let compiled = engine.compile(r#"{"==": [{"var": "x"}, 1]}"#).unwrap();
let mut session = engine.session();
let result = session.eval(&compiled, r#"{"x": 1}"#).unwrap();
assert_eq!(result.as_bool(), Some(true));
Source

pub fn eval_str<'a, D>( &'a mut self, compiled: &Logic, data: D, ) -> Result<String>
where D: EvalInput<'a>,

JSON-string convenience: evaluate against data and serialise the result back to a JSON String. Reuses the arena across calls; does not reset — see Self::reset.

Source

pub fn eval_into<'a, T, D>(&'a mut self, compiled: &Logic, data: D) -> Result<T>
where T: DeserializeOwned, D: EvalInput<'a>,

Available on crate feature serde_json only.

Typed convenience: evaluate and deserialise the result into T: DeserializeOwned. Use T = serde_json::Value for a JSON Value result; use a typed struct for direct mapping. Internally routes through serde_json.

Source

pub fn eval_borrowed<'a, D>( &'a mut self, compiled: &'a Logic, data: D, ) -> Result<&'a DataValue<'a>>
where D: EvalInput<'a>,

Evaluate and return a borrowed result tied to this session’s arena. Same semantics as Self::eval but skips the deep-clone — the returned reference is invalidated by the next &mut self call (the borrow checker enforces). Use this when the result is consumed before the next session call; for cross-call retention use Self::eval.

Symmetric with Engine::evaluate (caller-managed bump, borrowed result) but with the bump owned by the session. Does not reset the arena — call Self::reset explicitly.

§Example
use datalogic_rs::Engine;

let engine = Engine::new();
let compiled = engine.compile(r#"{"+": [{"var": "x"}, 1]}"#).unwrap();
let mut session = engine.session();
let result = session.eval_borrowed(&compiled, r#"{"x": 5}"#).unwrap();
assert_eq!(result.as_i64(), Some(6));

Trait Implementations§

Source§

impl Debug for Session<'_>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'engine> !Freeze for Session<'engine>

§

impl<'engine> !RefUnwindSafe for Session<'engine>

§

impl<'engine> Send for Session<'engine>

§

impl<'engine> !Sync for Session<'engine>

§

impl<'engine> Unpin for Session<'engine>

§

impl<'engine> UnsafeUnpin for Session<'engine>

§

impl<'engine> !UnwindSafe for Session<'engine>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.