Skip to content

Commit 1aad021

Browse files
authored
Count bytes_written for updates (#2616)
1 parent 6da76ed commit 1aad021

File tree

2 files changed

+75
-11
lines changed

2 files changed

+75
-11
lines changed

crates/core/src/db/relational_db.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,7 @@ impl RelationalDB {
884884
name: &str,
885885
schema: &[(&str, AlgebraicType)],
886886
indexes: &[ColList],
887+
unique_constraints: &[ColList],
887888
access: StAccess,
888889
) -> Result<TableId, DBError> {
889890
let mut module_def_builder = RawModuleDefV9Builder::new();
@@ -895,6 +896,9 @@ impl RelationalDB {
895896
for columns in indexes {
896897
table_builder = table_builder.with_index(btree(columns.clone()), "accessor_name_doesnt_matter");
897898
}
899+
for columns in unique_constraints {
900+
table_builder = table_builder.with_unique_constraint(columns.clone());
901+
}
898902
table_builder.finish();
899903
let module_def: ModuleDef = module_def_builder.finish().try_into()?;
900904

@@ -915,7 +919,7 @@ impl RelationalDB {
915919
access: StAccess,
916920
) -> Result<TableId, DBError> {
917921
let indexes: Vec<ColList> = indexes.iter().map(|col_id| (*col_id).into()).collect();
918-
self.create_table_for_test_with_the_works(name, schema, &indexes[..], access)
922+
self.create_table_for_test_with_the_works(name, schema, &indexes[..], &[], access)
919923
}
920924

921925
pub fn create_table_for_test(
@@ -933,7 +937,7 @@ impl RelationalDB {
933937
schema: &[(&str, AlgebraicType)],
934938
idx_cols: ColList,
935939
) -> Result<TableId, DBError> {
936-
self.create_table_for_test_with_the_works(name, schema, &[idx_cols], StAccess::Public)
940+
self.create_table_for_test_with_the_works(name, schema, &[idx_cols], &[], StAccess::Public)
937941
}
938942

939943
pub fn create_table_for_test_mix_indexes(
@@ -949,7 +953,7 @@ impl RelationalDB {
949953
.chain(std::iter::once(idx_cols_multi))
950954
.collect();
951955

952-
self.create_table_for_test_with_the_works(name, schema, &indexes[..], StAccess::Public)
956+
self.create_table_for_test_with_the_works(name, schema, &indexes[..], &[], StAccess::Public)
953957
}
954958

955959
pub fn drop_table(&self, tx: &mut MutTx, table_id: TableId) -> Result<(), DBError> {

crates/core/src/host/instance_env.rs

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,8 @@ impl InstanceEnv {
295295
if update_flags.is_scheduler_table {
296296
self.schedule_row(stdb, tx, table_id, row_ptr)?;
297297
}
298+
tx.metrics.bytes_written += buffer.len();
299+
tx.metrics.rows_updated += 1;
298300

299301
Ok(row_len)
300302
}
@@ -490,14 +492,6 @@ impl From<GetTxError> for NodesError {
490492
mod test {
491493
use std::{ops::Bound, sync::Arc};
492494

493-
use anyhow::{anyhow, Result};
494-
use parking_lot::RwLock;
495-
use spacetimedb_lib::{bsatn::to_vec, AlgebraicType, AlgebraicValue, Hash, Identity, ProductValue};
496-
use spacetimedb_paths::{server::ModuleLogsDir, FromPathUnchecked};
497-
use spacetimedb_primitives::{IndexId, TableId};
498-
use spacetimedb_sats::product;
499-
use tempfile::TempDir;
500-
501495
use crate::{
502496
database_logger::DatabaseLogger,
503497
db::{
@@ -512,6 +506,14 @@ mod test {
512506
module_subscription_actor::ModuleSubscriptions, module_subscription_manager::SubscriptionManager,
513507
},
514508
};
509+
use anyhow::{anyhow, Result};
510+
use parking_lot::RwLock;
511+
use spacetimedb_lib::db::auth::StAccess;
512+
use spacetimedb_lib::{bsatn::to_vec, AlgebraicType, AlgebraicValue, Hash, Identity, ProductValue};
513+
use spacetimedb_paths::{server::ModuleLogsDir, FromPathUnchecked};
514+
use spacetimedb_primitives::{IndexId, TableId};
515+
use spacetimedb_sats::product;
516+
use tempfile::TempDir;
515517

516518
use super::{ChunkPool, InstanceEnv, TxSlot};
517519

@@ -622,6 +624,37 @@ mod test {
622624
Ok((table_id, index_id))
623625
}
624626

627+
fn create_table_with_unique_index(db: &RelationalDB) -> Result<(TableId, IndexId)> {
628+
let table_id = db.create_table_for_test_with_the_works(
629+
"t",
630+
&[("id", AlgebraicType::U64), ("str", AlgebraicType::String)],
631+
&[0.into()],
632+
&[0.into()],
633+
StAccess::Public,
634+
)?;
635+
let index_id = db.with_read_only(Workload::ForTests, |tx| {
636+
db.schema_for_table(tx, table_id)?
637+
.indexes
638+
.iter()
639+
.find(|schema| {
640+
schema
641+
.index_algorithm
642+
.columns()
643+
.as_singleton()
644+
.is_some_and(|col_id| col_id.idx() == 0)
645+
})
646+
.map(|schema| schema.index_id)
647+
.ok_or_else(|| anyhow!("Index not found for ColId `{}`", 0))
648+
})?;
649+
db.with_auto_commit(Workload::ForTests, |tx| -> Result<_> {
650+
for i in 1..=5 {
651+
db.insert(tx, table_id, &bsatn_row(i)?)?;
652+
}
653+
Ok(())
654+
})?;
655+
Ok((table_id, index_id))
656+
}
657+
625658
#[test]
626659
fn table_scan_metrics() -> Result<()> {
627660
let db = relational_db()?;
@@ -743,6 +776,33 @@ mod test {
743776
Ok(())
744777
}
745778

779+
#[test]
780+
fn update_metrics() -> Result<()> {
781+
let db = relational_db()?;
782+
let env = instance_env(db.clone())?;
783+
784+
let (table_id, index_id) = create_table_with_unique_index(&db)?;
785+
786+
let mut tx_slot = env.tx.clone();
787+
788+
let row_id: u64 = 1;
789+
let row_val: String = "string".to_string();
790+
let mut new_row_bytes = to_vec(&product!(row_id, row_val))?;
791+
let new_row_len = new_row_bytes.len();
792+
// Delete a single row via the index
793+
let f = || -> Result<_> {
794+
env.update(table_id, index_id, new_row_bytes.as_mut_slice())?;
795+
Ok(())
796+
};
797+
let tx = db.begin_mut_tx(IsolationLevel::Serializable, Workload::ForTests);
798+
let (tx, res) = tx_slot.set(tx, f);
799+
800+
res?;
801+
802+
assert_eq!(new_row_len, tx.metrics.bytes_written);
803+
Ok(())
804+
}
805+
746806
#[test]
747807
fn delete_by_index_metrics() -> Result<()> {
748808
let db = relational_db()?;

0 commit comments

Comments
 (0)