Skip to content

Commit

Permalink
Move connection events to reducers (#309)
Browse files Browse the repository at this point in the history
* Move connection events to reducers

* More rebase fixups

* Avoid double-reference

* Filter out special reducers in generate cli

This updates filtering of `__init__` to exclude all special reducers, as well as moves the filtering to centralised place before calling language-specific generate command.

* Incrememted ABI version number

---------

Co-authored-by: Tyler Cloutier <cloutiertyler@aol.com>
  • Loading branch information
RReverser and cloutiertyler authored Oct 3, 2023
1 parent de43e96 commit ba535f2
Show file tree
Hide file tree
Showing 21 changed files with 146 additions and 406 deletions.
2 changes: 1 addition & 1 deletion crates/bindings-csharp/Codegen/Codegen.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<AssemblyName>SpacetimeDB.Codegen</AssemblyName>
<AssemblyVersion>0.7.0</AssemblyVersion>
<AssemblyVersion>0.7.1</AssemblyVersion>
</PropertyGroup>

<PropertyGroup>
Expand Down
2 changes: 2 additions & 0 deletions crates/bindings-csharp/Runtime/Module.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ public static class ReducerKind
{
public const string Init = "__init__";
public const string Update = "__update__";
public const string Connect = "__identity_connected__";
public const string Disconnect = "__identity_disconnected__";
}

public interface IReducer
Expand Down
31 changes: 0 additions & 31 deletions crates/bindings-csharp/Runtime/Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -276,37 +276,6 @@ public DbEventArgs(byte[] senderIdentity, byte[] senderAddress, ulong timestamp_
}
}

public static event Action<DbEventArgs>? OnConnect;
public static event Action<DbEventArgs>? OnDisconnect;

// Note: this is accessed by C bindings.
private static string? IdentityConnected(byte[] sender_identity, byte[] sender_address, ulong timestamp)
{
try
{
OnConnect?.Invoke(new(sender_identity, sender_address, timestamp));
return null;
}
catch (Exception e)
{
return e.ToString();
}
}

// Note: this is accessed by C bindings.
private static string? IdentityDisconnected(byte[] sender_identity, byte[] sender_address, ulong timestamp)
{
try
{
OnDisconnect?.Invoke(new(sender_identity, sender_address, timestamp));
return null;
}
catch (Exception e)
{
return e.ToString();
}
}

[MethodImpl(MethodImplOptions.InternalCall)]
private extern static void ScheduleReducer(
string name,
Expand Down
2 changes: 1 addition & 1 deletion crates/bindings-csharp/Runtime/Runtime.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<AssemblyName>SpacetimeDB.Runtime</AssemblyName>
<AssemblyVersion>0.7.0</AssemblyVersion>
<AssemblyVersion>0.7.1</AssemblyVersion>
</PropertyGroup>

<PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion crates/bindings-csharp/Runtime/bindings.c
Original file line number Diff line number Diff line change
Expand Up @@ -779,5 +779,5 @@ __preinit__10_init_csharp() {

// __attribute__((export_name("SPACETIME_ABI_VERSION"))) -
// doesn't work on non-functions, must specify on command line
const uint32_t SPACETIME_ABI_VERSION = /* 4.0 */ (4 << 16) | 0;
const uint32_t SPACETIME_ABI_VERSION = /* 5.0 */ (5 << 16) | 0;
const uint8_t SPACETIME_ABI_VERSION_IS_ADDR = 1;
178 changes: 59 additions & 119 deletions crates/bindings-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,11 @@ fn route_input(input: MacroInput, item: TokenStream) -> syn::Result<TokenStream>
MacroInput::Table => spacetimedb_table(item),
MacroInput::Init => spacetimedb_init(item),
MacroInput::Reducer { repeat } => spacetimedb_reducer(repeat, item),
MacroInput::Connect => spacetimedb_connect_disconnect(item, true),
MacroInput::Disconnect => spacetimedb_connect_disconnect(item, false),
MacroInput::Migrate => spacetimedb_migrate(item),
MacroInput::Connect => spacetimedb_special_reducer("__identity_connected__", item),
MacroInput::Disconnect => spacetimedb_special_reducer("__identity_disconnected__", item),
MacroInput::Migrate => spacetimedb_special_reducer("__migrate__", item),
MacroInput::Index { ty, name, field_names } => spacetimedb_index(ty, name, field_names, item),
MacroInput::Update => spacetimedb_update(item),
MacroInput::Update => spacetimedb_special_reducer("__update__", item),
}
}

Expand Down Expand Up @@ -264,16 +264,12 @@ mod kw {

/// Generates a reducer in place of `item`.
fn spacetimedb_reducer(repeat: Option<Duration>, item: TokenStream) -> syn::Result<TokenStream> {
// TODO(kim): Find a better place for these. `core/host/wasm_common.rs` has similar
// definitions, but we can't depend on `core` here.
const RESERVED_REDUCER_NAMES: &[&str] = &["__init__", "__migrate__", "__update__"];

let repeat_dur = repeat.map_or(ReducerExtra::None, ReducerExtra::Repeat);
let repeat_dur = repeat.map_or(ReducerExtra::Schedule, ReducerExtra::Repeat);
let original_function = syn::parse2::<ItemFn>(item)?;

// Extract reducer name, making sure it's not `__init__`.
// Extract reducer name, making sure it's not `__XXX__` as that's the form we reserve for special reducers.
let reducer_name = original_function.sig.ident.to_string();
if RESERVED_REDUCER_NAMES.iter().any(|name| name == &reducer_name) {
if reducer_name.starts_with("__") && reducer_name.ends_with("__") {
return Err(syn::Error::new_spanned(
&original_function.sig.ident,
"reserved reducer name",
Expand All @@ -287,13 +283,13 @@ fn spacetimedb_reducer(repeat: Option<Duration>, item: TokenStream) -> syn::Resu
fn spacetimedb_init(item: TokenStream) -> syn::Result<TokenStream> {
let original_function = syn::parse2::<ItemFn>(item)?;

gen_reducer(original_function, "__init__", ReducerExtra::Init)
gen_reducer(original_function, "__init__", ReducerExtra::None)
}

enum ReducerExtra {
None,
Schedule,
Repeat(Duration),
Init,
}

fn gen_reducer(original_function: ItemFn, reducer_name: &str, extra: ReducerExtra) -> syn::Result<TokenStream> {
Expand Down Expand Up @@ -321,14 +317,18 @@ fn gen_reducer(original_function: ItemFn, reducer_name: &str, extra: ReducerExtr
// }

// Extract all function parameters, except for `self` ones that aren't allowed.
let args = original_function.sig.inputs.iter().map(|x| match x {
// TODO: improve error message!
FnArg::Receiver(_) => panic!(),
FnArg::Typed(x) => x,
});
let typed_args = original_function
.sig
.inputs
.iter()
.map(|arg| match arg {
FnArg::Typed(arg) => Ok(arg),
_ => Err(syn::Error::new_spanned(arg, "expected typed argument")),
})
.collect::<syn::Result<Vec<_>>>()?;

// Extract all function parameter names.
let arg_names = args.clone().map(|arg| {
let opt_arg_names = typed_args.iter().map(|arg| {
if let syn::Pat::Ident(i) = &*arg.pat {
let name = i.ident.to_string();
quote!(Some(#name))
Expand All @@ -337,8 +337,7 @@ fn gen_reducer(original_function: ItemFn, reducer_name: &str, extra: ReducerExtr
}
});

// Extract all function parameter types.
let arg_tys = args.map(|arg| &arg.ty);
let arg_tys = typed_args.iter().map(|arg| arg.ty.as_ref()).collect::<Vec<_>>();

// Extract the return type.
let ret_ty = match &original_function.sig.output {
Expand All @@ -349,34 +348,49 @@ fn gen_reducer(original_function: ItemFn, reducer_name: &str, extra: ReducerExtr

let register_describer_symbol = format!("__preinit__20_register_describer_{reducer_name}");

let (epilogue, repeater_impl) = match &extra {
ReducerExtra::None | ReducerExtra::Init => (quote!(), quote!()),
ReducerExtra::Repeat(repeat_dur) => {
let repeat_dur = duration_totokens(*repeat_dur);
let epilogue = quote! {
if _res.is_ok() {
spacetimedb::rt::schedule_repeater::<_, _, #func_name>(#func_name)
}
};
let repeater_impl = quote! {
impl spacetimedb::rt::RepeaterInfo for #func_name {
const REPEAT_INTERVAL: ::core::time::Duration = #repeat_dur;
}
};
(epilogue, repeater_impl)
}
};
let mut epilogue = TokenStream::new();
let mut extra_impls = TokenStream::new();

if !matches!(extra, ReducerExtra::None) {
let arg_names = typed_args
.iter()
.enumerate()
.map(|(i, arg)| match &*arg.pat {
syn::Pat::Ident(pat) => pat.ident.clone(),
_ => format_ident!("__arg{}", i),
})
.collect::<Vec<_>>();

extra_impls.extend(quote!(impl #func_name {
pub fn schedule(__time: spacetimedb::Timestamp #(, #arg_names: #arg_tys)*) -> spacetimedb::ScheduleToken<#func_name> {
spacetimedb::rt::schedule(__time, (#(#arg_names,)*))
}
}));
}

if let ReducerExtra::Repeat(repeat_dur) = &extra {
let repeat_dur = duration_totokens(*repeat_dur);
epilogue.extend(quote! {
if _res.is_ok() {
spacetimedb::rt::schedule_repeater::<_, _, #func_name>(#func_name)
}
});
extra_impls.extend(quote! {
impl spacetimedb::rt::RepeaterInfo for #func_name {
const REPEAT_INTERVAL: ::core::time::Duration = #repeat_dur;
}
});
}

let generated_function = quote! {
// NOTE: double-underscoring names here is unnecessary, as Rust macros are hygienic.
fn __reducer(
__sender: spacetimedb::sys::Buffer,
__caller_address: spacetimedb::sys::Buffer,
__timestamp: u64,
__args: &[u8]
) -> spacetimedb::sys::Buffer {
#(spacetimedb::rt::assert_reducerarg::<#arg_tys>();)*
#(spacetimedb::rt::assert_reducerret::<#ret_ty>();)*
#(spacetimedb::rt::assert_reducer_arg::<#arg_tys>();)*
#(spacetimedb::rt::assert_reducer_ret::<#ret_ty>();)*
spacetimedb::rt::invoke_reducer(
#func_name,
__sender,
Expand All @@ -395,56 +409,21 @@ fn gen_reducer(original_function: ItemFn, reducer_name: &str, extra: ReducerExtr
}
};

let mut schedule_func_sig = original_function.sig.clone();
let schedule_func_body = {
schedule_func_sig.ident = format_ident!("schedule");
schedule_func_sig.output = syn::ReturnType::Type(
Token![->](Span::call_site()),
Box::new(syn::parse_quote!(spacetimedb::ScheduleToken<#func_name>)),
);
let arg_names = schedule_func_sig.inputs.iter_mut().enumerate().map(|(i, arg)| {
let syn::FnArg::Typed(arg) = arg else { panic!() };
match &mut *arg.pat {
syn::Pat::Ident(id) => {
id.by_ref = None;
id.mutability = None;
id.ident.clone()
}
_ => {
let ident = format_ident!("__arg{}", i);
arg.pat = Box::new(syn::parse_quote!(#ident));
ident
}
}
});
let schedule_args = quote!((#(#arg_names,)*));
let time_arg = format_ident!("__time");
schedule_func_sig
.inputs
.insert(0, syn::parse_quote!(#time_arg: spacetimedb::Timestamp));
quote! {
spacetimedb::rt::schedule(#time_arg, #schedule_args)
}
};

Ok(quote! {
const _: () = {
#generated_describe_function
};
#[allow(non_camel_case_types)]
#vis struct #func_name { _never: ::core::convert::Infallible }
impl #func_name {
#vis #schedule_func_sig { #schedule_func_body }
}
impl spacetimedb::rt::ReducerInfo for #func_name {
const NAME: &'static str = #reducer_name;
const ARG_NAMES: &'static [Option<&'static str>] = &[#(#arg_names),*];
const ARG_NAMES: &'static [Option<&'static str>] = &[#(#opt_arg_names),*];
const INVOKE: spacetimedb::rt::ReducerFn = {
#generated_function
__reducer
};
}
#repeater_impl
#extra_impls
#original_function
})
}
Expand Down Expand Up @@ -880,48 +859,9 @@ fn spacetimedb_index(
Ok(output)
}

fn spacetimedb_migrate(item: TokenStream) -> syn::Result<TokenStream> {
let original_function = syn::parse2::<ItemFn>(item)?;
gen_reducer(original_function, "__migrate__", ReducerExtra::None)
}

fn spacetimedb_update(item: TokenStream) -> syn::Result<TokenStream> {
fn spacetimedb_special_reducer(name: &str, item: TokenStream) -> syn::Result<TokenStream> {
let original_function = syn::parse2::<ItemFn>(item)?;
gen_reducer(original_function, "__update__", ReducerExtra::None)
}

fn spacetimedb_connect_disconnect(item: TokenStream, connect: bool) -> syn::Result<TokenStream> {
let original_function = syn::parse2::<ItemFn>(item)?;
let func_name = &original_function.sig.ident;
let connect_disconnect_symbol = if connect {
"__identity_connected__"
} else {
"__identity_disconnected__"
};

let emission = quote! {
const _: () = {
#[export_name = #connect_disconnect_symbol]
extern "C" fn __connect_disconnect(
__sender: spacetimedb::sys::Buffer,
__caller_address: spacetimedb::sys::Buffer,
__timestamp: u64,
) -> spacetimedb::sys::Buffer {
spacetimedb::rt::invoke_connection_func(#func_name, __sender, __caller_address, __timestamp)
}
};

#original_function
};

if std::env::var("PROC_MACRO_DEBUG").is_ok() {
{
#![allow(clippy::disallowed_macros)]
println!("{}", emission);
}
}

Ok(emission)
gen_reducer(original_function, name, ReducerExtra::None)
}

#[proc_macro]
Expand Down
6 changes: 1 addition & 5 deletions crates/bindings-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use alloc::boxed::Box;
/// can run a module declaring `X.Y` if and only if `X == A && Y <= B`.
/// So, the minor version is intended for backwards-compatible changes, e.g. adding a new function,
/// and the major version is for fully breaking changes.
pub const ABI_VERSION: u32 = 0x0004_0000;
pub const ABI_VERSION: u32 = 0x0005_0000;

/// Provides a raw set of sys calls which abstractions can be built atop of.
pub mod raw {
Expand Down Expand Up @@ -395,10 +395,6 @@ pub mod raw {
/// Required. id is an index into the `ModuleDef.reducers` returned from `__describe_module__`.
/// args is a bsatn-encoded product value defined by the schema at `reducers[id]`.
fn __call_reducer__(id: usize, sender: Identity, timestamp: Timestamp, args: Buffer) -> Result;
/// Optional. Called when a client connects to the database.
fn __identity_connected__(sender: Identity, timestamp: Timestamp) -> Result;
/// Optional. Called when a client disconnects to the database.
fn __identity_disconnected__(sender: Identity, timestamp: Timestamp) -> Result;
/// Currently unused?
fn __migrate_database__XXXX(sender: Identity, timestamp: Timestamp, something: Buffer) -> Result;
}
Expand Down
18 changes: 2 additions & 16 deletions crates/bindings/src/rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,6 @@ pub fn create_index(index_name: &str, table_id: u32, index_type: sys::raw::Index
cvt_result(result.map_err(cvt_errno))
}

/// Runs the on-connect function `f` provided with a new reducer context
/// created from `sender` and `timestamp`.
pub fn invoke_connection_func<R: ReducerResult>(
f: impl Fn(ReducerContext) -> R,
sender: Buffer,
client_address: Buffer,
timestamp: u64,
) -> Buffer {
let ctx = assemble_context(sender, timestamp, client_address);

let res = with_timestamp_set(ctx.timestamp, || f(ctx).into_result());
cvt_result(res)
}

/// Creates a reducer context from the given `sender`, `timestamp` and `client_address`.
///
/// `sender` must contain 32 bytes, from which we will read an `Identity`.
Expand Down Expand Up @@ -205,9 +191,9 @@ pub trait ReducerArg<'de> {}
impl<'de, T: Deserialize<'de>> ReducerArg<'de> for T {}
impl ReducerArg<'_> for ReducerContext {}
/// Assert that `T: ReducerArg`.
pub fn assert_reducerarg<'de, T: ReducerArg<'de>>() {}
pub fn assert_reducer_arg<'de, T: ReducerArg<'de>>() {}
/// Assert that `T: ReducerResult`.
pub fn assert_reducerret<T: ReducerResult>() {}
pub fn assert_reducer_ret<T: ReducerResult>() {}
/// Assert that `T: TableType`.
pub const fn assert_table<T: TableType>() {}

Expand Down
Loading

1 comment on commit ba535f2

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark for ba535f2

Click to view benchmark
Test Base PR %
serialize/location/bsatn/count=100 2.7±0.05µs 35.7 MElem/sec N/A N/A
serialize/location/json/count=100 3.9±0.06µs 24.3 MElem/sec N/A N/A
serialize/location/product_value/count=100 2.7±0.03µs 35.2 MElem/sec N/A N/A
serialize/person/bsatn/count=100 3.2±0.04µs 29.4 MElem/sec N/A N/A
serialize/person/json/count=100 5.9±0.09µs 16.3 MElem/sec N/A N/A
serialize/person/product_value/count=100 1893.6±28.62ns 50.4 MElem/sec N/A N/A
sqlite/disk/empty 466.8±5.27ns 465.9±5.84ns -0.19%
sqlite/disk/filter/string/indexed/load=1000/count=10 6.1±0.16µs 161.2 KElem/sec N/A N/A
sqlite/disk/filter/string/non_indexed/load=1000/count=10 57.7±0.65µs 16.9 KElem/sec N/A N/A
sqlite/disk/filter/u64/indexed/load=1000/count=10 5.9±0.12µs 165.6 KElem/sec N/A N/A
sqlite/disk/filter/u64/non_indexed/load=1000/count=10 43.9±0.72µs 22.3 KElem/sec N/A N/A
sqlite/disk/find_unique/u32/load=1000 2.4±0.05µs 408.2 KElem/sec N/A N/A
sqlite/disk/insert_1/location/multi_index/load=0 16.7±0.40µs 58.6 KElem/sec N/A N/A
sqlite/disk/insert_1/location/multi_index/load=1000 21.6±0.86µs 45.2 KElem/sec N/A N/A
sqlite/disk/insert_1/location/non_unique/load=0 8.1±0.19µs 121.2 KElem/sec N/A N/A
sqlite/disk/insert_1/location/non_unique/load=1000 8.5±0.32µs 115.3 KElem/sec N/A N/A
sqlite/disk/insert_1/location/unique/load=0 8.1±0.20µs 121.1 KElem/sec N/A N/A
sqlite/disk/insert_1/location/unique/load=1000 8.6±0.31µs 114.0 KElem/sec N/A N/A
sqlite/disk/insert_1/person/multi_index/load=0 16.4±0.40µs 59.4 KElem/sec N/A N/A
sqlite/disk/insert_1/person/multi_index/load=1000 22.2±1.23µs 44.0 KElem/sec N/A N/A
sqlite/disk/insert_1/person/non_unique/load=0 8.2±0.17µs 119.6 KElem/sec N/A N/A
sqlite/disk/insert_1/person/non_unique/load=1000 8.9±0.33µs 110.2 KElem/sec N/A N/A
sqlite/disk/insert_1/person/unique/load=0 8.1±0.14µs 120.8 KElem/sec N/A N/A
sqlite/disk/insert_1/person/unique/load=1000 8.9±0.32µs 110.1 KElem/sec N/A N/A
sqlite/disk/insert_bulk/location/multi_index/load=0/count=100 139.6±2.46µs 142.8±20.68µs +2.29%
sqlite/disk/insert_bulk/location/multi_index/load=1000/count=100 235.2±4.03µs 238.3±13.61µs +1.32%
sqlite/disk/insert_bulk/location/non_unique/load=0/count=100 49.1±1.06µs 19.9 KElem/sec N/A N/A
sqlite/disk/insert_bulk/location/non_unique/load=1000/count=100 53.7±0.88µs 18.2 KElem/sec N/A N/A
sqlite/disk/insert_bulk/location/unique/load=0/count=100 48.3±0.55µs 20.2 KElem/sec N/A N/A
sqlite/disk/insert_bulk/location/unique/load=1000/count=100 55.2±0.98µs 17.7 KElem/sec N/A N/A
sqlite/disk/insert_bulk/person/multi_index/load=0/count=100 129.3±1.88µs 129.1±2.19µs -0.15%
sqlite/disk/insert_bulk/person/multi_index/load=1000/count=100 279.9±4.75µs 277.7±6.29µs -0.79%
sqlite/disk/insert_bulk/person/non_unique/load=0/count=100 46.7±0.94µs 20.9 KElem/sec N/A N/A
sqlite/disk/insert_bulk/person/non_unique/load=1000/count=100 65.6±1.67µs 14.9 KElem/sec N/A N/A
sqlite/disk/insert_bulk/person/unique/load=0/count=100 48.8±0.64µs 20.0 KElem/sec N/A N/A
sqlite/disk/insert_bulk/person/unique/load=1000/count=100 57.0±2.74µs 17.1 KElem/sec N/A N/A
sqlite/disk/iterate/location/unique/count=100 8.8±0.11µs 110.7 KElem/sec N/A N/A
sqlite/disk/iterate/person/unique/count=100 9.2±0.14µs 106.0 KElem/sec N/A N/A
sqlite/mem/empty 469.7±5.15ns 456.7±9.64ns -2.77%
sqlite/mem/filter/string/indexed/load=1000/count=10 4.5±0.09µs 217.8 KElem/sec N/A N/A
sqlite/mem/filter/string/non_indexed/load=1000/count=10 57.5±0.74µs 17.0 KElem/sec N/A N/A
sqlite/mem/filter/u64/indexed/load=1000/count=10 4.3±0.07µs 226.7 KElem/sec N/A N/A
sqlite/mem/filter/u64/non_indexed/load=1000/count=10 42.8±0.75µs 22.8 KElem/sec N/A N/A
sqlite/mem/find_unique/u32/load=1000 1118.0±14.61ns 873.5 KElem/sec N/A N/A
sqlite/mem/insert_1/location/multi_index/load=0 4.7±0.09µs 207.7 KElem/sec N/A N/A
sqlite/mem/insert_1/location/multi_index/load=1000 6.2±0.35µs 156.7 KElem/sec N/A N/A
sqlite/mem/insert_1/location/non_unique/load=0 1907.4±42.94ns 512.0 KElem/sec N/A N/A
sqlite/mem/insert_1/location/non_unique/load=1000 2.1±0.14µs 464.2 KElem/sec N/A N/A
sqlite/mem/insert_1/location/unique/load=0 1902.7±40.38ns 513.2 KElem/sec N/A N/A
sqlite/mem/insert_1/location/unique/load=1000 2.1±0.12µs 469.4 KElem/sec N/A N/A
sqlite/mem/insert_1/person/multi_index/load=0 4.5±0.06µs 216.0 KElem/sec N/A N/A
sqlite/mem/insert_1/person/multi_index/load=1000 7.2±0.42µs 136.1 KElem/sec N/A N/A
sqlite/mem/insert_1/person/non_unique/load=0 1947.0±27.98ns 501.6 KElem/sec N/A N/A
sqlite/mem/insert_1/person/non_unique/load=1000 2.2±0.17µs 440.1 KElem/sec N/A N/A
sqlite/mem/insert_1/person/unique/load=0 1951.6±45.64ns 500.4 KElem/sec N/A N/A
sqlite/mem/insert_1/person/unique/load=1000 2.2±0.17µs 446.3 KElem/sec N/A N/A
sqlite/mem/insert_bulk/location/multi_index/load=0/count=100 122.2±1.40µs 121.1±2.71µs -0.90%
sqlite/mem/insert_bulk/location/multi_index/load=1000/count=100 183.4±2.78µs 185.1±2.85µs +0.93%
sqlite/mem/insert_bulk/location/non_unique/load=0/count=100 38.7±0.51µs 25.2 KElem/sec N/A N/A
sqlite/mem/insert_bulk/location/non_unique/load=1000/count=100 42.2±1.28µs 23.1 KElem/sec N/A N/A
sqlite/mem/insert_bulk/location/unique/load=0/count=100 41.1±0.50µs 23.7 KElem/sec N/A N/A
sqlite/mem/insert_bulk/location/unique/load=1000/count=100 46.7±0.99µs 20.9 KElem/sec N/A N/A
sqlite/mem/insert_bulk/person/multi_index/load=0/count=100 113.8±1.52µs 114.9±3.97µs +0.97%
sqlite/mem/insert_bulk/person/multi_index/load=1000/count=100 215.0±3.96µs 210.7±3.43µs -2.00%
sqlite/mem/insert_bulk/person/non_unique/load=0/count=100 39.7±0.68µs 24.6 KElem/sec N/A N/A
sqlite/mem/insert_bulk/person/non_unique/load=1000/count=100 47.2±0.94µs 20.7 KElem/sec N/A N/A
sqlite/mem/insert_bulk/person/unique/load=0/count=100 41.9±1.13µs 23.3 KElem/sec N/A N/A
sqlite/mem/insert_bulk/person/unique/load=1000/count=100 47.1±1.13µs 20.7 KElem/sec N/A N/A
sqlite/mem/iterate/location/unique/count=100 7.7±0.14µs 126.0 KElem/sec N/A N/A
sqlite/mem/iterate/person/unique/count=100 8.1±0.39µs 120.8 KElem/sec N/A N/A
stdb_module/disk/empty 28.3±1.96µs 27.9±1.54µs -1.41%
stdb_module/disk/filter/string/indexed/load=1000/count=10 66.7±8.36µs 14.6 KElem/sec N/A N/A
stdb_module/disk/filter/string/non_indexed/load=1000/count=10 198.1±6.74µs 188.6±3.12µs -4.80%
stdb_module/disk/filter/u64/indexed/load=1000/count=10 55.3±3.82µs 17.7 KElem/sec N/A N/A
stdb_module/disk/filter/u64/non_indexed/load=1000/count=10 155.9±2.87µs 161.0±4.40µs +3.27%
stdb_module/disk/find_unique/u32/load=1000 37.7±2.60µs 25.9 KElem/sec N/A N/A
stdb_module/disk/insert_1/location/multi_index/load=0 58.0±6.01µs 16.8 KElem/sec N/A N/A
stdb_module/disk/insert_1/location/multi_index/load=1000 436.2±36.13µs 415.3±94.12µs -4.79%
stdb_module/disk/insert_1/location/non_unique/load=0 53.4±6.15µs 18.3 KElem/sec N/A N/A
stdb_module/disk/insert_1/location/non_unique/load=1000 325.5±28.62µs 348.2±22.92µs +6.97%
stdb_module/disk/insert_1/location/unique/load=0 54.6±4.39µs 17.9 KElem/sec N/A N/A
stdb_module/disk/insert_1/location/unique/load=1000 363.1±26.00µs 389.0±20.76µs +7.13%
stdb_module/disk/insert_1/person/multi_index/load=0 66.2±3.91µs 14.7 KElem/sec N/A N/A
stdb_module/disk/insert_1/person/multi_index/load=1000 601.8±59.24µs 522.9±62.67µs -13.11%
stdb_module/disk/insert_1/person/non_unique/load=0 55.9±6.00µs 17.5 KElem/sec N/A N/A
stdb_module/disk/insert_1/person/non_unique/load=1000 373.2±39.65µs 373.3±51.87µs +0.03%
stdb_module/disk/insert_1/person/unique/load=0 66.7±6.90µs 14.6 KElem/sec N/A N/A
stdb_module/disk/insert_1/person/unique/load=1000 465.6±43.90µs 437.4±38.96µs -6.06%
stdb_module/disk/insert_bulk/location/multi_index/load=0/count=100 974.8±17.45µs 967.9±16.67µs -0.71%
stdb_module/disk/insert_bulk/location/multi_index/load=1000/count=100 1358.8±53.54µs 1301.0±53.68µs -4.25%
stdb_module/disk/insert_bulk/location/non_unique/load=0/count=100 682.7±11.40µs 678.1±15.17µs -0.67%
stdb_module/disk/insert_bulk/location/non_unique/load=1000/count=100 910.3±37.27µs 912.7±29.77µs +0.26%
stdb_module/disk/insert_bulk/location/unique/load=0/count=100 844.7±22.92µs 844.1±37.99µs -0.07%
stdb_module/disk/insert_bulk/location/unique/load=1000/count=100 1124.4±43.31µs 1108.3±38.71µs -1.43%
stdb_module/disk/insert_bulk/person/multi_index/load=0/count=100 1575.1±38.43µs 1568.9±33.39µs -0.39%
stdb_module/disk/insert_bulk/person/multi_index/load=1000/count=100 2.1±0.08ms 1966.6±72.05µs -6.35%
stdb_module/disk/insert_bulk/person/non_unique/load=0/count=100 891.3±49.85µs 892.0±22.85µs +0.08%
stdb_module/disk/insert_bulk/person/non_unique/load=1000/count=100 1161.1±45.04µs 1159.2±56.98µs -0.16%
stdb_module/disk/insert_bulk/person/unique/load=0/count=100 1132.4±15.87µs 1147.2±16.30µs +1.31%
stdb_module/disk/insert_bulk/person/unique/load=1000/count=100 1519.3±92.20µs 1523.3±58.66µs +0.26%
stdb_module/disk/iterate/location/unique/count=100 154.3±3.01µs 155.9±7.46µs +1.04%
stdb_module/disk/iterate/person/unique/count=100 246.7±8.74µs 245.9±5.69µs -0.32%
stdb_module/large_arguments/64KiB 117.3±3.71µs 115.8±3.68µs -1.28%
stdb_module/mem/empty 29.3±1.08µs 28.8±1.08µs -1.71%
stdb_module/mem/filter/string/indexed/load=1000/count=10 61.7±5.76µs 15.8 KElem/sec N/A N/A
stdb_module/mem/filter/string/non_indexed/load=1000/count=10 194.7±8.52µs 196.9±4.57µs +1.13%
stdb_module/mem/filter/u64/indexed/load=1000/count=10 54.9±5.17µs 17.8 KElem/sec N/A N/A
stdb_module/mem/filter/u64/non_indexed/load=1000/count=10 154.9±2.40µs 153.2±6.09µs -1.10%
stdb_module/mem/find_unique/u32/load=1000 39.0±2.53µs 25.0 KElem/sec N/A N/A
stdb_module/mem/insert_1/location/multi_index/load=0 50.7±4.13µs 19.3 KElem/sec N/A N/A
stdb_module/mem/insert_1/location/multi_index/load=1000 373.1±43.43µs 376.4±32.16µs +0.88%
stdb_module/mem/insert_1/location/non_unique/load=0 45.0±3.19µs 21.7 KElem/sec N/A N/A
stdb_module/mem/insert_1/location/non_unique/load=1000 265.2±27.05µs 255.3±29.57µs -3.73%
stdb_module/mem/insert_1/location/unique/load=0 48.0±3.61µs 20.3 KElem/sec N/A N/A
stdb_module/mem/insert_1/location/unique/load=1000 330.0±30.76µs 308.3±29.45µs -6.58%
stdb_module/mem/insert_1/person/multi_index/load=0 56.2±4.63µs 17.4 KElem/sec N/A N/A
stdb_module/mem/insert_1/person/multi_index/load=1000 491.1±59.19µs 474.4±49.09µs -3.40%
stdb_module/mem/insert_1/person/non_unique/load=0 47.5±5.84µs 20.6 KElem/sec N/A N/A
stdb_module/mem/insert_1/person/non_unique/load=1000 323.0±38.85µs 333.2±34.97µs +3.16%
stdb_module/mem/insert_1/person/unique/load=0 55.1±5.06µs 17.7 KElem/sec N/A N/A
stdb_module/mem/insert_1/person/unique/load=1000 432.7±41.22µs 391.3±39.54µs -9.57%
stdb_module/mem/insert_bulk/location/multi_index/load=0/count=100 859.1±33.39µs 846.1±14.81µs -1.51%
stdb_module/mem/insert_bulk/location/multi_index/load=1000/count=100 1170.8±39.22µs 1147.3±53.85µs -2.01%
stdb_module/mem/insert_bulk/location/non_unique/load=0/count=100 559.4±18.07µs 570.2±9.22µs +1.93%
stdb_module/mem/insert_bulk/location/non_unique/load=1000/count=100 751.5±29.37µs 737.1±31.33µs -1.92%
stdb_module/mem/insert_bulk/location/unique/load=0/count=100 720.4±18.28µs 727.2±10.94µs +0.94%
stdb_module/mem/insert_bulk/location/unique/load=1000/count=100 985.8±40.82µs 939.6±36.87µs -4.69%
stdb_module/mem/insert_bulk/person/multi_index/load=0/count=100 1490.2±28.70µs 1514.8±27.23µs +1.65%
stdb_module/mem/insert_bulk/person/multi_index/load=1000/count=100 1920.0±90.79µs 1863.4±80.59µs -2.95%
stdb_module/mem/insert_bulk/person/non_unique/load=0/count=100 788.5±15.41µs 809.0±31.66µs +2.60%
stdb_module/mem/insert_bulk/person/non_unique/load=1000/count=100 1037.5±66.06µs 1049.0±41.81µs +1.11%
stdb_module/mem/insert_bulk/person/unique/load=0/count=100 1049.6±20.71µs 1057.7±18.65µs +0.77%
stdb_module/mem/insert_bulk/person/unique/load=1000/count=100 1435.0±47.91µs 1378.7±69.41µs -3.92%
stdb_module/mem/iterate/location/unique/count=100 165.6±31.76µs 154.9±3.06µs -6.46%
stdb_module/mem/iterate/person/unique/count=100 235.2±5.39µs 256.0±10.62µs +8.84%
stdb_module/print_bulk/lines=1 40.2±2.68µs 38.7±2.77µs -3.73%
stdb_module/print_bulk/lines=100 361.0±4.93µs 347.9±7.25µs -3.63%
stdb_module/print_bulk/lines=1000 3.3±0.04ms 3.2±0.05ms -3.03%
stdb_raw/disk/empty 112.4±1.98ns 112.5±1.29ns +0.09%
stdb_raw/disk/filter/string/indexed/load=1000/count=10 2.9±0.06µs 337.9 KElem/sec N/A N/A
stdb_raw/disk/filter/string/non_indexed/load=1000/count=10 133.0±2.40µs 132.7±1.77µs -0.23%
stdb_raw/disk/filter/u64/indexed/load=1000/count=10 2.7±0.04µs 366.2 KElem/sec N/A N/A
stdb_raw/disk/filter/u64/non_indexed/load=1000/count=10 112.7±1.99µs 112.4±2.98µs -0.27%
stdb_raw/disk/find_unique/u32/load=1000 619.6±10.13ns 1576.1 KElem/sec N/A N/A
stdb_raw/disk/insert_1/location/multi_index/load=0 6.9±0.14µs 142.1 KElem/sec N/A N/A
stdb_raw/disk/insert_1/location/multi_index/load=1000 38.6±2.25µs 25.3 KElem/sec N/A N/A
stdb_raw/disk/insert_1/location/non_unique/load=0 4.2±0.07µs 230.7 KElem/sec N/A N/A
stdb_raw/disk/insert_1/location/non_unique/load=1000 23.6±1.25µs 41.5 KElem/sec N/A N/A
stdb_raw/disk/insert_1/location/unique/load=0 5.6±0.15µs 175.1 KElem/sec N/A N/A
stdb_raw/disk/insert_1/location/unique/load=1000 31.4±5.85µs 31.1 KElem/sec N/A N/A
stdb_raw/disk/insert_1/person/multi_index/load=0 11.3±0.17µs 86.3 KElem/sec N/A N/A
stdb_raw/disk/insert_1/person/multi_index/load=1000 38.4±2.73µs 25.4 KElem/sec N/A N/A
stdb_raw/disk/insert_1/person/non_unique/load=0 5.0±0.07µs 194.9 KElem/sec N/A N/A
stdb_raw/disk/insert_1/person/non_unique/load=1000 18.5±1.09µs 52.7 KElem/sec N/A N/A
stdb_raw/disk/insert_1/person/unique/load=0 7.5±0.10µs 129.4 KElem/sec N/A N/A
stdb_raw/disk/insert_1/person/unique/load=1000 31.1±6.28µs 31.4 KElem/sec N/A N/A
stdb_raw/disk/insert_bulk/location/multi_index/load=0/count=100 407.6±8.71µs 408.1±9.77µs +0.12%
stdb_raw/disk/insert_bulk/location/multi_index/load=1000/count=100 481.4±11.35µs 489.1±18.09µs +1.60%
stdb_raw/disk/insert_bulk/location/non_unique/load=0/count=100 184.2±13.12µs 186.4±3.30µs +1.19%
stdb_raw/disk/insert_bulk/location/non_unique/load=1000/count=100 209.2±5.50µs 215.5±8.08µs +3.01%
stdb_raw/disk/insert_bulk/location/unique/load=0/count=100 292.0±3.32µs 287.2±3.60µs -1.64%
stdb_raw/disk/insert_bulk/location/unique/load=1000/count=100 361.7±22.71µs 356.7±10.84µs -1.38%
stdb_raw/disk/insert_bulk/person/multi_index/load=0/count=100 821.2±16.12µs 817.4±16.80µs -0.46%
stdb_raw/disk/insert_bulk/person/multi_index/load=1000/count=100 903.7±22.78µs 901.6±25.66µs -0.23%
stdb_raw/disk/insert_bulk/person/non_unique/load=0/count=100 254.9±3.47µs 258.5±5.43µs +1.41%
stdb_raw/disk/insert_bulk/person/non_unique/load=1000/count=100 282.5±6.67µs 286.1±6.03µs +1.27%
stdb_raw/disk/insert_bulk/person/unique/load=0/count=100 474.0±7.61µs 472.6±12.43µs -0.30%
stdb_raw/disk/insert_bulk/person/unique/load=1000/count=100 530.6±15.30µs 536.6±23.85µs +1.13%
stdb_raw/disk/iterate/location/unique/count=100 10.6±0.18µs 92.2 KElem/sec N/A N/A
stdb_raw/disk/iterate/person/unique/count=100 12.2±0.13µs 80.3 KElem/sec N/A N/A
stdb_raw/mem/empty 113.3±3.02ns 113.0±1.28ns -0.26%
stdb_raw/mem/filter/string/indexed/load=1000/count=10 2.9±0.08µs 339.6 KElem/sec N/A N/A
stdb_raw/mem/filter/string/non_indexed/load=1000/count=10 134.2±2.53µs 132.9±2.31µs -0.97%
stdb_raw/mem/filter/u64/indexed/load=1000/count=10 2.7±0.04µs 363.2 KElem/sec N/A N/A
stdb_raw/mem/filter/u64/non_indexed/load=1000/count=10 114.1±1.54µs 112.2±1.60µs -1.67%
stdb_raw/mem/find_unique/u32/load=1000 618.2±13.25ns 1579.7 KElem/sec N/A N/A
stdb_raw/mem/insert_1/location/multi_index/load=0 5.4±0.06µs 181.3 KElem/sec N/A N/A
stdb_raw/mem/insert_1/location/multi_index/load=1000 32.2±2.13µs 30.4 KElem/sec N/A N/A
stdb_raw/mem/insert_1/location/non_unique/load=0 2.9±0.07µs 334.8 KElem/sec N/A N/A
stdb_raw/mem/insert_1/location/non_unique/load=1000 20.8±1.00µs 46.9 KElem/sec N/A N/A
stdb_raw/mem/insert_1/location/unique/load=0 4.0±0.08µs 246.0 KElem/sec N/A N/A
stdb_raw/mem/insert_1/location/unique/load=1000 27.1±1.59µs 36.1 KElem/sec N/A N/A
stdb_raw/mem/insert_1/person/multi_index/load=0 9.6±0.14µs 101.6 KElem/sec N/A N/A
stdb_raw/mem/insert_1/person/multi_index/load=1000 32.8±2.93µs 29.8 KElem/sec N/A N/A
stdb_raw/mem/insert_1/person/non_unique/load=0 3.5±0.05µs 276.7 KElem/sec N/A N/A
stdb_raw/mem/insert_1/person/non_unique/load=1000 16.4±1.20µs 59.6 KElem/sec N/A N/A
stdb_raw/mem/insert_1/person/unique/load=0 5.8±0.08µs 167.0 KElem/sec N/A N/A
stdb_raw/mem/insert_1/person/unique/load=1000 24.1±1.81µs 40.6 KElem/sec N/A N/A
stdb_raw/mem/insert_bulk/location/multi_index/load=0/count=100 424.2±6.32µs 416.1±6.49µs -1.91%
stdb_raw/mem/insert_bulk/location/multi_index/load=1000/count=100 470.8±10.64µs 466.2±8.68µs -0.98%
stdb_raw/mem/insert_bulk/location/non_unique/load=0/count=100 179.6±3.27µs 181.4±4.36µs +1.00%
stdb_raw/mem/insert_bulk/location/non_unique/load=1000/count=100 202.1±4.29µs 203.8±5.38µs +0.84%
stdb_raw/mem/insert_bulk/location/unique/load=0/count=100 290.1±3.47µs 287.4±6.49µs -0.93%
stdb_raw/mem/insert_bulk/location/unique/load=1000/count=100 346.5±6.03µs 344.7±7.99µs -0.52%
stdb_raw/mem/insert_bulk/person/multi_index/load=0/count=100 814.0±20.25µs 801.1±12.06µs -1.58%
stdb_raw/mem/insert_bulk/person/multi_index/load=1000/count=100 928.3±32.49µs 893.2±22.36µs -3.78%
stdb_raw/mem/insert_bulk/person/non_unique/load=0/count=100 252.4±4.65µs 250.6±3.08µs -0.71%
stdb_raw/mem/insert_bulk/person/non_unique/load=1000/count=100 280.4±6.40µs 278.0±5.01µs -0.86%
stdb_raw/mem/insert_bulk/person/unique/load=0/count=100 469.6±5.70µs 462.8±6.32µs -1.45%
stdb_raw/mem/insert_bulk/person/unique/load=1000/count=100 529.1±18.08µs 521.8±12.66µs -1.38%
stdb_raw/mem/iterate/location/unique/count=100 10.6±0.18µs 91.9 KElem/sec N/A N/A
stdb_raw/mem/iterate/person/unique/count=100 12.2±0.18µs 80.0 KElem/sec N/A N/A

Please sign in to comment.