Skip to content

Commit

Permalink
Small naming fixes. Fixes database identity creation. (#1892)
Browse files Browse the repository at this point in the history
  • Loading branch information
cloutiertyler authored Oct 24, 2024
1 parent c840eda commit fa960b3
Show file tree
Hide file tree
Showing 13 changed files with 60 additions and 63 deletions.
2 changes: 1 addition & 1 deletion crates/client-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ pub trait ControlStateWriteAccess: Send + Sync {
async fn register_tld(&self, identity: &Identity, tld: Tld) -> anyhow::Result<RegisterTldResult>;
async fn create_dns_record(
&self,
identity: &Identity,
owner_identity: &Identity,
domain: &DomainName,
database_identity: &Identity,
) -> anyhow::Result<InsertDomainResult>;
Expand Down
41 changes: 23 additions & 18 deletions crates/client-api/src/routes/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,17 +384,17 @@ pub async fn info<S: ControlStateDelegate>(
State(worker_ctx): State<S>,
Path(InfoParams { name_or_identity }): Path<InfoParams>,
) -> axum::response::Result<impl IntoResponse> {
log::trace!("Trying to resolve address: {:?}", name_or_identity);
let address = name_or_identity.resolve(&worker_ctx).await?.into();
log::trace!("Resolved address to: {address:?}");
let database = worker_ctx_find_database(&worker_ctx, &address)
log::trace!("Trying to resolve database identity: {:?}", name_or_identity);
let database_identity = name_or_identity.resolve(&worker_ctx).await?.into();
log::trace!("Resolved identity to: {database_identity:?}");
let database = worker_ctx_find_database(&worker_ctx, &database_identity)
.await?
.ok_or((StatusCode::NOT_FOUND, "No such database."))?;
log::trace!("Fetched database from the worker db for address: {address:?}");
log::trace!("Fetched database from the worker db for address: {database_identity:?}");

let host_type: &str = database.host_type.as_ref();
let response_json = json!({
"address": database.database_identity,
"database_identity": database.database_identity,
"owner_identity": database.owner_identity,
"host_type": host_type,
"initial_program": database.initial_program,
Expand Down Expand Up @@ -679,32 +679,37 @@ pub async fn publish<S: NodeDelegate + ControlStateDelegate>(
// You should not be able to publish to a database that you do not own
// so, unless you are the owner, this will fail.

let (db_addr, db_name) = match name_or_identity {
let (database_identity, db_name) = match name_or_identity {
Some(noa) => match noa.try_resolve(&ctx).await? {
Ok(resolved) => resolved.into(),
Err(domain) => {
// `name_or_address` was a `NameOrAddress::Name`, but no record
// exists yet. Create it now with a fresh address.
let database_identity = Identity::placeholder();
let database_auth = SpacetimeAuth::alloc(&ctx).await?;
let database_identity = database_auth.identity;
ctx.create_dns_record(&auth.identity, &domain, &database_identity)
.await
.map_err(log_and_500)?;
(database_identity, Some(domain))
}
},
None => {
let database_identity = Identity::placeholder();
let database_auth = SpacetimeAuth::alloc(&ctx).await?;
let database_identity = database_auth.identity;
(database_identity, None)
}
};

log::trace!("Publishing to the address: {}", db_addr.to_hex());
log::trace!("Publishing to the address: {}", database_identity.to_hex());

let op = {
let exists = ctx.get_database_by_identity(&db_addr).map_err(log_and_500)?.is_some();
let exists = ctx
.get_database_by_identity(&database_identity)
.map_err(log_and_500)?
.is_some();

if clear && exists {
ctx.delete_database(&auth.identity, &db_addr)
ctx.delete_database(&auth.identity, &database_identity)
.await
.map_err(log_and_500)?;
}
Expand All @@ -720,7 +725,7 @@ pub async fn publish<S: NodeDelegate + ControlStateDelegate>(
.publish_database(
&auth.identity,
DatabaseDef {
database_identity: db_addr,
database_identity,
program_bytes: body.into(),
num_replicas: 1,
host_type: HostType::Wasm,
Expand All @@ -747,7 +752,7 @@ pub async fn publish<S: NodeDelegate + ControlStateDelegate>(

Ok(axum::Json(PublishResult::Success {
domain: db_name.as_ref().map(ToString::to_string),
database_identity: db_addr,
database_identity,
op,
}))
}
Expand Down Expand Up @@ -783,14 +788,14 @@ pub async fn set_name<S: ControlStateDelegate>(
State(ctx): State<S>,
Query(SetNameQueryParams {
domain,
database_identity: address,
database_identity,
}): Query<SetNameQueryParams>,
Extension(auth): Extension<SpacetimeAuth>,
) -> axum::response::Result<impl IntoResponse> {
let address = Identity::from(address);
let database_identity = Identity::from(database_identity);

let database = ctx
.get_database_by_identity(&address)
.get_database_by_identity(&database_identity)
.map_err(log_and_500)?
.ok_or((StatusCode::NOT_FOUND, "No such database."))?;

Expand All @@ -800,7 +805,7 @@ pub async fn set_name<S: ControlStateDelegate>(

let domain = domain.parse().map_err(|_| DomainParsingRejection)?;
let response = ctx
.create_dns_record(&auth.identity, &domain, &address)
.create_dns_record(&auth.identity, &domain, &database_identity)
.await
// TODO: better error code handling
.map_err(log_and_500)?;
Expand Down
12 changes: 6 additions & 6 deletions crates/client-api/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,16 @@ impl NameOrIdentity {
ctx: &(impl ControlStateReadAccess + ?Sized),
) -> axum::response::Result<Result<ResolvedIdentity, DomainName>> {
Ok(match self {
Self::Identity(addr) => Ok(ResolvedIdentity {
identity: Identity::from(*addr),
Self::Identity(identity) => Ok(ResolvedIdentity {
identity: Identity::from(*identity),
domain: None,
}),
Self::Name(name) => {
let domain = name.parse().map_err(|_| DomainParsingRejection)?;
let address = ctx.lookup_identity(&domain).map_err(log_and_500)?;
match address {
Some(address) => Ok(ResolvedIdentity {
identity: address,
let identity = ctx.lookup_identity(&domain).map_err(log_and_500)?;
match identity {
Some(identity) => Ok(ResolvedIdentity {
identity,
domain: Some(domain),
}),
None => Err(domain),
Expand Down
9 changes: 0 additions & 9 deletions crates/lib/src/identity.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use crate::from_hex_pad;
use blake3;
use core::mem;
use rand;
use rand::Rng;
use spacetimedb_bindings_macro::{Deserialize, Serialize};
use spacetimedb_sats::hex::HexString;
use spacetimedb_sats::{hash, impl_st, u256, AlgebraicType, AlgebraicValue};
Expand Down Expand Up @@ -53,13 +51,6 @@ impl spacetimedb_metrics::typed_prometheus::AsPrometheusLabel for Identity {
impl Identity {
pub const ZERO: Self = Self::from_u256(u256::ZERO);

pub fn placeholder() -> Self {
// Generate a random identity.
let mut rng = rand::thread_rng();
let mut random_bytes = [0u8; 32];
rng.fill(&mut random_bytes);
Identity::from_byte_array(random_bytes)
}
/// Returns an `Identity` defined as the given `bytes` byte array.
pub const fn from_byte_array(bytes: [u8; 32]) -> Self {
// SAFETY: The transmute is an implementation of `u256::from_ne_bytes`,
Expand Down
3 changes: 2 additions & 1 deletion crates/testing/src/modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::time::Instant;

use spacetimedb::messages::control_db::HostType;
use spacetimedb::Identity;
use spacetimedb_client_api::auth::SpacetimeAuth;
use spacetimedb_client_api::routes::subscribe::generate_random_address;
use spacetimedb_lib::ser::serde::SerializeWrapper;
use tokio::runtime::{Builder, Runtime};
Expand Down Expand Up @@ -152,7 +153,7 @@ impl CompiledModule {
let env = spacetimedb_standalone::StandaloneEnv::init(config).await.unwrap();
// TODO: Fix this when we update identity generation.
let identity = Identity::ZERO;
let db_identity = Identity::placeholder();
let db_identity = SpacetimeAuth::alloc(&env).await.unwrap().identity;
let client_address = generate_random_address();

let program_bytes = self
Expand Down
18 changes: 9 additions & 9 deletions smoketests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,20 +159,20 @@ def spacetime(cls, *args, **kwargs):
return spacetime(*args, **kwargs)

def _check_published(self):
if not hasattr(self, "address"):
if not hasattr(self, "database_identity"):
raise Exception("Cannot use this function without publishing a module")

def call(self, reducer, *args, anon=False):
self._check_published()
anon = ["--anonymous"] if anon else []
self.spacetime("call", *anon, "--", self.address, reducer, *map(json.dumps, args))
self.spacetime("call", *anon, "--", self.database_identity, reducer, *map(json.dumps, args))

def logs(self, n):
return [log["message"] for log in self.log_records(n)]

def log_records(self, n):
self._check_published()
logs = self.spacetime("logs", "--format=json", "-n", str(n), "--", self.address)
logs = self.spacetime("logs", "--format=json", "-n", str(n), "--", self.database_identity)
return list(map(json.loads, logs.splitlines()))

def publish_module(self, domain=None, *, clear=True, capture_stderr=True):
Expand All @@ -184,7 +184,7 @@ def publish_module(self, domain=None, *, clear=True, capture_stderr=True):
capture_stderr=capture_stderr,
)
self.resolved_identity = re.search(r"identity: ([0-9a-fA-F]+)", publish_output)[1]
self.address = domain if domain is not None else self.resolved_identity
self.database_identity = domain if domain is not None else self.resolved_identity

@classmethod
def reset_config(cls):
Expand Down Expand Up @@ -215,7 +215,7 @@ def subscribe(self, *queries, n):

env = os.environ.copy()
env["SPACETIME_CONFIG_FILE"] = str(self.config_path)
args = [SPACETIME_BIN, "subscribe", self.address, "-t", "60", "-n", str(n), "--print-initial-update", "--", *queries]
args = [SPACETIME_BIN, "subscribe", self.database_identity, "-t", "60", "-n", str(n), "--print-initial-update", "--", *queries]
fake_args = ["spacetime", *args[1:]]
log_cmd(fake_args)

Expand Down Expand Up @@ -273,19 +273,19 @@ def setUpClass(cls):

def tearDown(self):
# if this single test method published a database, clean it up now
if "address" in self.__dict__:
if "database_identity" in self.__dict__:
try:
# TODO: save the credentials in publish_module()
self.spacetime("delete", self.address)
self.spacetime("delete", self.database_identity)
except Exception:
pass

@classmethod
def tearDownClass(cls):
if hasattr(cls, "address"):
if hasattr(cls, "database_identity"):
try:
# TODO: save the credentials in publish_module()
cls.spacetime("delete", cls.address)
cls.spacetime("delete", cls.database_identity)
except Exception:
pass

Expand Down
6 changes: 3 additions & 3 deletions smoketests/tests/auto_migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class AddTableAutoMigration(Smoketest):

def assertSql(self, sql, expected):
self.maxDiff = None
sql_out = self.spacetime("sql", self.address, sql)
sql_out = self.spacetime("sql", self.database_identity, sql)
sql_out = "\n".join([line.rstrip() for line in sql_out.splitlines()])
expected = "\n".join([line.rstrip() for line in expected.splitlines()])
self.assertMultiLineEqual(sql_out, expected)
Expand Down Expand Up @@ -98,7 +98,7 @@ def test_add_table_auto_migration(self):
)

self.write_module_code(self.MODULE_CODE_UPDATED)
self.publish_module(self.address, clear=False)
self.publish_module(self.database_identity, clear=False)

logging.info("Updated")

Expand Down Expand Up @@ -176,6 +176,6 @@ def test_reject_schema_changes(self):

with self.assertRaises(Exception):
self.write_module_code(self.MODULE_CODE_UPDATED)
self.publish_module(self.address, clear=False)
self.publish_module(self.database_identity, clear=False)

logging.info("Rejected as expected.")
6 changes: 3 additions & 3 deletions smoketests/tests/describe.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ class ModuleDescription(Smoketest):
def test_describe(self):
"""Check describing a module"""

self.spacetime("describe", self.address)
self.spacetime("describe", self.address, "reducer", "say_hello")
self.spacetime("describe", self.address, "table", "person")
self.spacetime("describe", self.database_identity)
self.spacetime("describe", self.database_identity, "reducer", "say_hello")
self.spacetime("describe", self.database_identity, "table", "person")
6 changes: 3 additions & 3 deletions smoketests/tests/domains.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ def test_set_name(self):
rand_name = random_string()

self.spacetime("dns", "register-tld", rand_name)
self.spacetime("dns", "set-name", rand_name, self.address)
self.spacetime("dns", "set-name", rand_name, self.database_identity)
lookup_result = self.spacetime("dns", "lookup", rand_name).strip()
self.assertEqual(lookup_result, self.address)
self.assertEqual(lookup_result, self.database_identity)

names = self.spacetime("dns", "reverse-lookup", self.address).splitlines()
names = self.spacetime("dns", "reverse-lookup", self.database_identity).splitlines()
self.assertIn(rand_name, names)
2 changes: 1 addition & 1 deletion smoketests/tests/new_user_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def test_new_user_flow(self):
self.assertEqual(self.logs(5).count("Hello, World!"), 2)
self.assertEqual(self.logs(5).count("Hello, Tyler!"), 1)

out = self.spacetime("sql", self.address, "SELECT * FROM person")
out = self.spacetime("sql", self.database_identity, "SELECT * FROM person")
# The spaces after the name are important
self.assertMultiLineEqual(out, """\
name
Expand Down
14 changes: 7 additions & 7 deletions smoketests/tests/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def test_delete(self):

self.reset_config()
with self.assertRaises(Exception):
self.spacetime("delete", self.address)
self.spacetime("delete", self.database_identity)

def test_describe(self):
"""Ensure that anyone can describe any database"""
Expand All @@ -42,7 +42,7 @@ def test_describe(self):

self.reset_config()
self.new_identity()
self.spacetime("describe", self.address)
self.spacetime("describe", self.database_identity)

def test_logs(self):
"""Ensure that we are not able to view the logs of a module that we don't have permission to view"""
Expand All @@ -57,7 +57,7 @@ def test_logs(self):
self.reset_config()
identity = self.new_identity(default=True)
with self.assertRaises(Exception):
self.spacetime("logs", self.address, "-n", "10000")
self.spacetime("logs", self.database_identity, "-n", "10000")

def test_publish(self):
"""This test checks to make sure that you cannot publish to an address that you do not own."""
Expand All @@ -68,11 +68,11 @@ def test_publish(self):
self.reset_config()

with self.assertRaises(Exception):
self.spacetime("publish", self.address, "--project-path", self.project_path, "--clear-database", "--yes")
self.spacetime("publish", self.database_identity, "--project-path", self.project_path, "--clear-database", "--yes")

# Check that this holds without `--clear-database`, too.
with self.assertRaises(Exception):
self.spacetime("publish", self.address, "--project-path", self.project_path)
self.spacetime("publish", self.database_identity, "--project-path", self.project_path)


class PrivateTablePermissions(Smoketest):
Expand Down Expand Up @@ -104,7 +104,7 @@ class PrivateTablePermissions(Smoketest):
def test_private_table(self):
"""Ensure that a private table can only be queried by the database owner"""

out = self.spacetime("sql", self.address, "select * from secret")
out = self.spacetime("sql", self.database_identity, "select * from secret")
self.assertMultiLineEqual(out, """\
answer
--------
Expand All @@ -115,7 +115,7 @@ def test_private_table(self):
self.new_identity()

with self.assertRaises(Exception):
self.spacetime("sql", self.address, "select * from secret")
self.spacetime("sql", self.database_identity, "select * from secret")

with self.assertRaises(Exception):
self.subscribe("SELECT * FROM secret", n=0)
Expand Down
2 changes: 1 addition & 1 deletion smoketests/tests/sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class SqlFormat(Smoketest):

def assertSql(self, sql, expected):
self.maxDiff = None
sql_out = self.spacetime("sql", self.address, sql)
sql_out = self.spacetime("sql", self.database_identity, sql)
sql_out = "\n".join([line.rstrip() for line in sql_out.splitlines()])
expected = "\n".join([line.rstrip() for line in expected.splitlines()])
self.assertMultiLineEqual(sql_out, expected)
Expand Down
2 changes: 1 addition & 1 deletion smoketests/tests/zz_docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def test_restart_module(self):

restart_docker()

sql_out = self.spacetime("sql", self.address, "SELECT name FROM person WHERE id = 3")
sql_out = self.spacetime("sql", self.database_identity, "SELECT name FROM person WHERE id = 3")
self.assertMultiLineEqual(sql_out, """ name \n------------\n "Samantha" \n""")

@requires_docker
Expand Down

2 comments on commit fa960b3

@github-actions
Copy link

@github-actions github-actions bot commented on fa960b3 Oct 24, 2024

Choose a reason for hiding this comment

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

Benchmarking failed. Please check the workflow run for details.

@github-actions
Copy link

@github-actions github-actions bot commented on fa960b3 Oct 24, 2024

Choose a reason for hiding this comment

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

Callgrind benchmark results

Callgrind Benchmark Report

These benchmarks were run using callgrind,
an instruction-level profiler. They allow comparisons between sqlite (sqlite), SpacetimeDB running through a module (stdb_module), and the underlying SpacetimeDB data storage engine (stdb_raw). Callgrind emulates a CPU to collect the below estimates.

Measurement changes larger than five percent are in bold.

In-memory benchmarks

callgrind: empty transaction

db total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw 6516 6516 0.00% 6550 6550 0.00%
sqlite 5579 5579 0.00% 6033 6047 -0.23%

callgrind: filter

db schema indices count preload _column data_type total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str no_index 64 128 1 u64 76682 76682 0.00% 77012 77012 0.00%
stdb_raw u32_u64_str no_index 64 128 2 string 119180 119180 0.00% 119708 119688 0.02%
stdb_raw u32_u64_str btree_each_column 64 128 2 string 25232 25231 0.00% 25640 25635 0.02%
stdb_raw u32_u64_str btree_each_column 64 128 1 u64 24199 24199 0.00% 24521 24517 0.02%
sqlite u32_u64_str no_index 64 128 2 string 144695 144713 -0.01% 146157 146203 -0.03%
sqlite u32_u64_str no_index 64 128 1 u64 124044 124044 0.00% 125292 125300 -0.01%
sqlite u32_u64_str btree_each_column 64 128 1 u64 131361 131361 0.00% 132741 132741 0.00%
sqlite u32_u64_str btree_each_column 64 128 2 string 134494 134494 0.00% 136024 136092 -0.05%

callgrind: insert bulk

db schema indices count preload total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str unique_0 64 128 906430 905986 0.05% 961708 964378 -0.28%
stdb_raw u32_u64_str btree_each_column 64 128 1057834 1056884 0.09% 1090966 1121246 -2.70%
sqlite u32_u64_str unique_0 64 128 398320 398320 0.00% 419244 413144 1.48%
sqlite u32_u64_str btree_each_column 64 128 983637 983637 0.00% 1021811 1019011 0.27%

callgrind: iterate

db schema indices count total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str unique_0 1024 153946 153946 0.00% 154012 154012 0.00%
stdb_raw u32_u64_str unique_0 64 16971 16971 0.00% 17025 17025 0.00%
sqlite u32_u64_str unique_0 1024 1067255 1067261 -0.00% 1070519 1070667 -0.01%
sqlite u32_u64_str unique_0 64 76201 76201 0.00% 77211 77223 -0.02%

callgrind: serialize_product_value

count format total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
64 json 47528 47528 0.00% 50214 50214 0.00%
64 bsatn 25509 25509 0.00% 27821 27821 0.00%
16 bsatn 8200 8200 0.00% 9628 9628 0.00%
16 json 12188 12188 0.00% 14126 14126 0.00%

callgrind: update bulk

db schema indices count preload total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str unique_0 1024 1024 21243815 21033835 1.00% 21939547 21745879 0.89%
stdb_raw u32_u64_str unique_0 64 128 1318871 1318442 0.03% 1365317 1364750 0.04%
sqlite u32_u64_str unique_0 1024 1024 1802182 1802128 0.00% 1811732 1811252 0.03%
sqlite u32_u64_str unique_0 64 128 128528 128474 0.04% 131408 131286 0.09%
On-disk benchmarks

callgrind: empty transaction

db total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw 6521 6521 0.00% 6559 6555 0.06%
sqlite 5621 5621 0.00% 6123 6149 -0.42%

callgrind: filter

db schema indices count preload _column data_type total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str no_index 64 128 1 u64 76687 76687 0.00% 77021 77017 0.01%
stdb_raw u32_u64_str no_index 64 128 2 string 119185 120274 -0.91% 119689 120694 -0.83%
stdb_raw u32_u64_str btree_each_column 64 128 2 string 25254 25253 0.00% 25618 25649 -0.12%
stdb_raw u32_u64_str btree_each_column 64 128 1 u64 24204 24204 0.00% 24526 24522 0.02%
sqlite u32_u64_str no_index 64 128 1 u64 125965 125965 0.00% 127485 127569 -0.07%
sqlite u32_u64_str no_index 64 128 2 string 146616 146616 0.00% 148374 148370 0.00%
sqlite u32_u64_str btree_each_column 64 128 2 string 136616 136616 0.00% 138728 138620 0.08%
sqlite u32_u64_str btree_each_column 64 128 1 u64 133457 133457 0.00% 135315 135211 0.08%

callgrind: insert bulk

db schema indices count preload total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str unique_0 64 128 854497 855656 -0.14% 908637 913182 -0.50%
stdb_raw u32_u64_str btree_each_column 64 128 1006975 1007247 -0.03% 1069061 1069975 -0.09%
sqlite u32_u64_str unique_0 64 128 415857 415857 0.00% 436187 430099 1.42%
sqlite u32_u64_str btree_each_column 64 128 1021898 1021898 0.00% 1058838 1055392 0.33%

callgrind: iterate

db schema indices count total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str unique_0 1024 153951 153951 0.00% 154001 154001 0.00%
stdb_raw u32_u64_str unique_0 64 16976 16976 0.00% 17026 17026 0.00%
sqlite u32_u64_str unique_0 1024 1070323 1070341 -0.00% 1074129 1074155 -0.00%
sqlite u32_u64_str unique_0 64 77973 77973 0.00% 79259 79215 0.06%

callgrind: serialize_product_value

count format total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
64 json 47528 47528 0.00% 50214 50214 0.00%
64 bsatn 25509 25509 0.00% 27821 27821 0.00%
16 bsatn 8200 8200 0.00% 9628 9628 0.00%
16 json 12188 12188 0.00% 14126 14126 0.00%

callgrind: update bulk

db schema indices count preload total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str unique_0 1024 1024 19547973 19546511 0.01% 20268207 20268893 -0.00%
stdb_raw u32_u64_str unique_0 64 128 1272389 1272130 0.02% 1348361 1347640 0.05%
sqlite u32_u64_str unique_0 1024 1024 1809743 1809689 0.00% 1818453 1818393 0.00%
sqlite u32_u64_str unique_0 64 128 132654 132600 0.04% 135622 135572 0.04%

Please sign in to comment.