Skip to content

Commit 3cec6c0

Browse files
committed
use SmallHashMap to optimize TxData
1 parent 346fef7 commit 3cec6c0

2 files changed

Lines changed: 18 additions & 7 deletions

File tree

crates/core/src/db/durability.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,17 +206,23 @@ impl DurabilityWorkerActor {
206206
return;
207207
}
208208

209-
let inserts: Box<_> = tx_data
209+
let mut inserts: Box<_> = tx_data
210210
.persistent_inserts()
211211
.map(|(table_id, rowdata)| Ops { table_id, rowdata })
212212
.collect();
213+
// What we get from `tx_data` is not necessarily sorted,
214+
// but the durability layer expects by-table_id sorted data.
215+
// Unstable sorts are valid, there will only ever be one entry per table_id.
216+
inserts.sort_unstable_by_key(|ops| ops.table_id);
213217

214-
let deletes: Box<_> = tx_data
218+
let mut deletes: Box<_> = tx_data
215219
.persistent_deletes()
216220
.map(|(table_id, rowdata)| Ops { table_id, rowdata })
217221
.collect();
222+
deletes.sort_unstable_by_key(|ops| ops.table_id);
218223

219-
let truncates: Box<[_]> = tx_data.persistent_truncates().collect();
224+
let mut truncates: Box<[_]> = tx_data.persistent_truncates().collect();
225+
truncates.sort_unstable_by_key(|table_id| *table_id);
220226

221227
let inputs = reducer_context.map(|rcx| rcx.into());
222228

crates/datastore/src/traits.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use core::ops::Deref;
22
use std::borrow::Cow;
3-
use std::collections::BTreeMap;
43
use std::{ops::RangeBounds, sync::Arc};
54

65
use super::locking_tx_datastore::datastore::TxMetrics;
@@ -9,6 +8,7 @@ use super::Result;
98
use crate::execution_context::Workload;
109
use crate::system_tables::ST_TABLE_ID;
1110
use spacetimedb_data_structures::map::IntSet;
11+
use spacetimedb_data_structures::small_map::SmallHashMap;
1212
use spacetimedb_durability::TxOffset;
1313
use spacetimedb_lib::{hash_bytes, Identity};
1414
use spacetimedb_primitives::*;
@@ -171,6 +171,12 @@ pub enum IsolationLevel {
171171

172172
pub type EphemeralTables = IntSet<TableId>;
173173

174+
/// The [`TxData`] entry for one table.
175+
///
176+
/// All information about a table is stored in one place
177+
/// as the access pattern is to write as fast as possible
178+
/// and because it all fits within a single cache line
179+
/// and so that we can use `SmallVec`.
174180
#[derive(Debug, Clone, PartialEq, Eq)]
175181
pub struct TxDataTableEntry {
176182
/// The name of the table for which there were deletions and/or insertions.
@@ -222,7 +228,7 @@ impl TxDataTableEntry {
222228
/// so that the recording of execution metrics can be done without holding the tx lock.
223229
#[derive(Default)]
224230
pub struct TxData {
225-
entries: BTreeMap<TableId, TxDataTableEntry>,
231+
entries: SmallHashMap<TableId, TxDataTableEntry, 1, 8>,
226232

227233
/// Tx offset of the transaction which performed these operations.
228234
///
@@ -250,8 +256,7 @@ impl TxData {
250256
/// or initializes it with `table_name`.
251257
fn init_entry(&mut self, table_id: TableId, table_name: &TableName) -> &mut TxDataTableEntry {
252258
self.entries
253-
.entry(table_id)
254-
.or_insert_with(|| TxDataTableEntry::new(table_name.clone()))
259+
.get_or_insert(table_id, || TxDataTableEntry::new(table_name.clone()))
255260
}
256261

257262
/// Set `rows` as the inserted rows for `(table_id, table_name)`.

0 commit comments

Comments
 (0)