Skip to content

Commit 20f8e85

Browse files
committed
refactor: Shrink QueryRevisions by 3 usize by boxing IdentityMap
Not all queries actually create tracked structs and so this may be empty in those cases
1 parent 6cfe2aa commit 20f8e85

File tree

5 files changed

+32
-13
lines changed

5 files changed

+32
-13
lines changed

src/active_query.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,10 @@ impl ActiveQuery {
172172
.is_empty()
173173
.not()
174174
.then(|| Box::new(mem::take(accumulated)));
175-
let tracked_struct_ids = mem::take(tracked_struct_ids);
175+
let tracked_struct_ids = tracked_struct_ids
176+
.is_empty()
177+
.not()
178+
.then(|| Box::new(mem::take(tracked_struct_ids)));
176179
let accumulated_inputs = AtomicInputAccumulatedValues::new(accumulated_inputs);
177180
let cycle_heads = mem::take(cycle_heads);
178181
QueryRevisions {

src/function/diff_outputs.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,23 @@ where
2727
) {
2828
// Iterate over the outputs of the `old_memo` and put them into a hashset
2929
let mut old_outputs: FxHashSet<_> = old_memo.revisions.origin.outputs().collect();
30-
3130
// Iterate over the outputs of the current query
3231
// and remove elements from `old_outputs` when we find them
3332
for new_output in revisions.origin.outputs() {
3433
old_outputs.remove(&new_output);
3534
}
3635

37-
if !old_outputs.is_empty() {
38-
// Remove the outputs that are no longer present in the current revision
39-
// to prevent that the next revision is seeded with a id mapping that no longer exists.
40-
revisions.tracked_struct_ids.retain(|&k, &mut value| {
41-
!old_outputs.contains(&DatabaseKeyIndex::new(k.ingredient_index(), value))
42-
});
36+
if let Some(tracked_struct_ids) = &mut revisions.tracked_struct_ids {
37+
if !old_outputs.is_empty() {
38+
// Remove the outputs that are no longer present in the current revision
39+
// to prevent that the next revision is seeded with a id mapping that no longer exists.
40+
tracked_struct_ids.retain(|&k, &mut value| {
41+
!old_outputs.contains(&DatabaseKeyIndex::new(k.ingredient_index(), value))
42+
});
43+
}
44+
if tracked_struct_ids.is_empty() {
45+
revisions.tracked_struct_ids = None;
46+
}
4347
}
4448

4549
for old_output in old_outputs {

src/function/execute.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{
22
cycle::{CycleRecoveryStrategy, MAX_ITERATIONS},
33
zalsa::ZalsaDatabase,
4-
zalsa_local::ActiveQueryGuard,
4+
zalsa_local::{ActiveQueryGuard, QueryRevisions},
55
Database, Event, EventKind,
66
};
77

@@ -52,8 +52,16 @@ where
5252
loop {
5353
// If we already executed this query once, then use the tracked-struct ids from the
5454
// previous execution as the starting point for the new one.
55-
if let Some(old_memo) = opt_old_memo {
56-
active_query.seed_tracked_struct_ids(&old_memo.revisions.tracked_struct_ids);
55+
if let Some(Memo {
56+
revisions:
57+
QueryRevisions {
58+
tracked_struct_ids: Some(tracked_struct_ids),
59+
..
60+
},
61+
..
62+
}) = opt_old_memo
63+
{
64+
active_query.seed_tracked_struct_ids(tracked_struct_ids);
5765
}
5866

5967
// Query was not previously executed, or value is potentially

src/function/memo.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ pub(super) struct Memo<V> {
143143
// Memo's are stored a lot, make sure their size is doesn't randomly increase.
144144
// #[cfg(test)]
145145
const _: [(); std::mem::size_of::<Memo<std::num::NonZeroUsize>>()] =
146-
[(); std::mem::size_of::<[usize; 14]>()];
146+
[(); std::mem::size_of::<[usize; 11]>()];
147147

148148
impl<V> Memo<V> {
149149
pub(super) fn new(value: Option<V>, revision_now: Revision, revisions: QueryRevisions) -> Self {

src/zalsa_local.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,11 @@ pub(crate) struct QueryRevisions {
309309
/// previous revision. To handle this, `diff_outputs` compares
310310
/// the structs from the old/new revision and retains
311311
/// only entries that appeared in the new revision.
312-
pub(super) tracked_struct_ids: IdentityMap,
312+
///
313+
/// Since not all queries produce a tracked struct, wrapping
314+
/// `IdentityMap` in an `Option<Box<T>>` reduces the size of
315+
/// `QueryRevisions` by 3 words (24 bytes on a 64-bit platform).
316+
pub(super) tracked_struct_ids: Option<Box<IdentityMap>>,
313317

314318
pub(super) accumulated: Option<Box<AccumulatedMap>>,
315319

0 commit comments

Comments
 (0)