Skip to content

Commit 3c13bf0

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 20a347e commit 3c13bf0

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
@@ -173,7 +173,10 @@ impl ActiveQuery {
173173
.is_empty()
174174
.not()
175175
.then(|| Box::new(mem::take(accumulated)));
176-
let tracked_struct_ids = mem::take(tracked_struct_ids);
176+
let tracked_struct_ids = tracked_struct_ids
177+
.is_empty()
178+
.not()
179+
.then(|| Box::new(mem::take(tracked_struct_ids)));
177180
let accumulated_inputs = AtomicInputAccumulatedValues::new(accumulated_inputs);
178181
let cycle_heads = mem::take(cycle_heads);
179182
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
@@ -142,7 +142,7 @@ pub(super) struct Memo<V> {
142142
// Memo's are stored a lot, make sure their size is doesn't randomly increase.
143143
// #[cfg(test)]
144144
const _: [(); std::mem::size_of::<Memo<std::num::NonZeroUsize>>()] =
145-
[(); std::mem::size_of::<[usize; 13]>()];
145+
[(); std::mem::size_of::<[usize; 10]>()];
146146

147147
impl<V> Memo<V> {
148148
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
@@ -310,7 +310,11 @@ pub(crate) struct QueryRevisions {
310310
/// previous revision. To handle this, `diff_outputs` compares
311311
/// the structs from the old/new revision and retains
312312
/// only entries that appeared in the new revision.
313-
pub(super) tracked_struct_ids: IdentityMap,
313+
///
314+
/// Since not all queries produce a tracked struct, wrapping
315+
/// `IdentityMap` in an `Option<Box<T>>` reduces the size of
316+
/// `QueryRevisions` by 3 words (24 bytes on a 64-bit platform).
317+
pub(super) tracked_struct_ids: Option<Box<IdentityMap>>,
314318

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

0 commit comments

Comments
 (0)