Skip to content

Commit eff510e

Browse files
committed
perf/sorter: sort pointers instead of records, use arena allocation
1. Use bump arena for in-memory records - Allows contiguous allocation and bulk deallocate - Allows sorting pointers instead of sorting large SortableImmutableRecord structs which pay a large memmove penalty 2. Use boxed records for on-disk chunk heap: avoids the same memmove problem
1 parent 9582043 commit eff510e

File tree

4 files changed

+212
-73
lines changed

4 files changed

+212
-73
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ rustc-hash = "2.0"
8888
either = { workspace = true }
8989
tracing-subscriber.workspace = true
9090
rapidhash = "4.1.1"
91+
bumpalo = { version = "3", features = ["collections"] }
9192

9293
# Use pure-rust for Android to avoid C cross-compilation issues
9394
[target.'cfg(target_os = "android")'.dependencies]

core/types.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,7 +1311,12 @@ impl RecordCursor {
13111311
record: &ImmutableRecord,
13121312
target_idx: usize,
13131313
) -> Result<()> {
1314-
let payload = record.get_payload();
1314+
self.ensure_parsed_upto_payload(record.get_payload(), target_idx)
1315+
}
1316+
1317+
/// Like `ensure_parsed_upto` but works directly with raw payload bytes.
1318+
#[inline(always)]
1319+
pub fn ensure_parsed_upto_payload(&mut self, payload: &[u8], target_idx: usize) -> Result<()> {
13151320
if payload.is_empty() {
13161321
return Ok(());
13171322
}
@@ -1365,6 +1370,15 @@ impl RecordCursor {
13651370
&self,
13661371
record: &'a ImmutableRecord,
13671372
idx: usize,
1373+
) -> Result<ValueRef<'a>> {
1374+
self.deserialize_column_payload(record.get_payload(), idx)
1375+
}
1376+
1377+
/// Like `deserialize_column` but works directly with raw payload bytes.
1378+
pub fn deserialize_column_payload<'a>(
1379+
&self,
1380+
payload: &'a [u8],
1381+
idx: usize,
13681382
) -> Result<ValueRef<'a>> {
13691383
if idx >= self.serial_types.len() {
13701384
return Ok(ValueRef::Null);
@@ -1386,7 +1400,6 @@ impl RecordCursor {
13861400

13871401
let start = self.offsets[idx];
13881402
let end = self.offsets[idx + 1];
1389-
let payload = record.get_payload();
13901403

13911404
let slice = &payload[start..end];
13921405
let (value, _) = crate::storage::sqlite3_ondisk::read_value(slice, serial_type_obj)?;

0 commit comments

Comments
 (0)