Skip to content

Commit 97035cb

Browse files
committed
Things
1 parent 4d92253 commit 97035cb

File tree

4 files changed

+44
-52
lines changed

4 files changed

+44
-52
lines changed

src/function/fetch.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::{
44
accumulator::accumulated_map::InputAccumulatedValues,
55
runtime::StampedValue,
66
zalsa::{Zalsa, ZalsaDatabase},
7-
AsDynDatabase as _, Id,
7+
Id,
88
};
99

1010
impl<C> IngredientImpl<C>
@@ -16,11 +16,14 @@ where
1616
zalsa.unwind_if_revision_cancelled(db);
1717

1818
let memo = self.refresh_memo(db, id);
19+
// SAFETY: We just refreshed the memo so it is guaranteed to contain a value now.
1920
let StampedValue {
2021
value,
2122
durability,
2223
changed_at,
23-
} = memo.revisions.stamped_value(memo.value.as_ref().unwrap());
24+
} = memo
25+
.revisions
26+
.stamped_value(unsafe { memo.value.as_ref().unwrap_unchecked() });
2427

2528
self.lru.record_use(id);
2629

@@ -83,20 +86,16 @@ where
8386
id: Id,
8487
memo_ingredient_index: MemoIngredientIndex,
8588
) -> Option<&'db Memo<C::Output<'db>>> {
86-
let zalsa_local = db.zalsa_local();
8789
let database_key_index = self.database_key_index(id);
8890

8991
// Try to claim this query: if someone else has claimed it already, go back and start again.
90-
let _claim_guard = zalsa.sync_table_for(id).claim(
91-
db.as_dyn_database(),
92-
zalsa,
93-
zalsa_local,
94-
database_key_index,
95-
memo_ingredient_index,
96-
)?;
92+
let _claim_guard =
93+
zalsa
94+
.sync_table_for(id)
95+
.claim(db, zalsa, database_key_index, memo_ingredient_index)?;
9796

9897
// Push the query on the stack.
99-
let active_query = zalsa_local.push_query(database_key_index);
98+
let active_query = db.zalsa_local().push_query(database_key_index);
10099

101100
// Now that we've claimed the item, check again to see if there's a "hot" value.
102101
let opt_old_memo = self.get_memo_from_table_for(zalsa, id, memo_ingredient_index);

src/function/lru.rs

+8
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,26 @@ impl Lru {
1717
}
1818
}
1919

20+
#[inline(always)]
2021
pub(super) fn record_use(&self, index: Id) {
2122
if self.capacity.is_none() {
2223
// LRU is disabled
2324
return;
2425
}
26+
self.insert(index);
27+
}
2528

29+
#[inline(never)]
30+
fn insert(&self, index: Id) {
2631
let mut set = self.set.lock();
2732
set.insert(index);
2833
}
2934

3035
pub(super) fn set_capacity(&mut self, capacity: usize) {
3136
self.capacity = NonZeroUsize::new(capacity);
37+
if self.capacity.is_none() {
38+
self.set.get_mut().clear();
39+
}
3240
}
3341

3442
pub(super) fn for_each_evicted(&mut self, mut cb: impl FnMut(Id)) {

src/function/maybe_changed_after.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ where
3030

3131
// Check if we have a verified version: this is the hot path.
3232
let memo_guard = self.get_memo_from_table_for(zalsa, id, memo_ingredient_index);
33-
if let Some(memo) = &memo_guard {
33+
if let Some(memo) = memo_guard {
3434
if self.shallow_verify_memo(db, zalsa, database_key_index, memo) {
3535
return if memo.revisions.changed_at > revision {
3636
MaybeChangedAfter::Yes
@@ -62,15 +62,13 @@ where
6262
) -> Option<MaybeChangedAfter> {
6363
let database_key_index = self.database_key_index(key_index);
6464

65-
let zalsa_local = db.zalsa_local();
6665
let _claim_guard = zalsa.sync_table_for(key_index).claim(
67-
db.as_dyn_database(),
66+
db,
6867
zalsa,
69-
zalsa_local,
7068
database_key_index,
7169
memo_ingredient_index,
7270
)?;
73-
let active_query = zalsa_local.push_query(database_key_index);
71+
let active_query = db.zalsa_local().push_query(database_key_index);
7472

7573
// Load the current memo, if any.
7674
let Some(old_memo) = self.get_memo_from_table_for(zalsa, key_index, memo_ingredient_index)

src/table/sync.rs

+23-36
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
use std::{
2-
sync::atomic::{AtomicBool, Ordering},
3-
thread::ThreadId,
4-
};
1+
use std::thread::ThreadId;
52

6-
use parking_lot::RwLock;
3+
use parking_lot::Mutex;
74

85
use crate::{
96
key::DatabaseKeyIndex,
107
runtime::WaitResult,
118
zalsa::{MemoIngredientIndex, Zalsa},
12-
zalsa_local::ZalsaLocal,
139
Database,
1410
};
1511

@@ -19,36 +15,35 @@ use super::util;
1915
/// worker threads.
2016
#[derive(Default)]
2117
pub(crate) struct SyncTable {
22-
syncs: RwLock<Vec<Option<SyncState>>>,
18+
syncs: Mutex<Vec<Option<SyncState>>>,
2319
}
2420

2521
struct SyncState {
2622
id: ThreadId,
2723

2824
/// Set to true if any other queries are blocked,
2925
/// waiting for this query to complete.
30-
anyone_waiting: AtomicBool,
26+
anyone_waiting: bool,
3127
}
3228

3329
impl SyncTable {
3430
pub(crate) fn claim<'me>(
3531
&'me self,
36-
db: &'me dyn Database,
32+
db: &'me (impl ?Sized + Database),
3733
zalsa: &'me Zalsa,
38-
zalsa_local: &ZalsaLocal,
3934
database_key_index: DatabaseKeyIndex,
4035
memo_ingredient_index: MemoIngredientIndex,
4136
) -> Option<ClaimGuard<'me>> {
42-
let mut syncs = self.syncs.write();
37+
let mut syncs = self.syncs.lock();
4338
let thread_id = std::thread::current().id();
4439

4540
util::ensure_vec_len(&mut syncs, memo_ingredient_index.as_usize() + 1);
4641

47-
match &syncs[memo_ingredient_index.as_usize()] {
42+
match &mut syncs[memo_ingredient_index.as_usize()] {
4843
None => {
4944
syncs[memo_ingredient_index.as_usize()] = Some(SyncState {
5045
id: thread_id,
51-
anyone_waiting: AtomicBool::new(false),
46+
anyone_waiting: false,
5247
});
5348
Some(ClaimGuard {
5449
database_key_index,
@@ -61,16 +56,10 @@ impl SyncTable {
6156
id: other_id,
6257
anyone_waiting,
6358
}) => {
64-
// NB: `Ordering::Relaxed` is sufficient here,
65-
// as there are no loads that are "gated" on this
66-
// value. Everything that is written is also protected
67-
// by a lock that must be acquired. The role of this
68-
// boolean is to decide *whether* to acquire the lock,
69-
// not to gate future atomic reads.
70-
anyone_waiting.store(true, Ordering::Relaxed);
59+
*anyone_waiting = true;
7160
zalsa.runtime().block_on_or_unwind(
72-
db,
73-
zalsa_local,
61+
db.as_dyn_database(),
62+
db.zalsa_local(),
7463
database_key_index,
7564
*other_id,
7665
syncs,
@@ -92,30 +81,28 @@ pub(crate) struct ClaimGuard<'me> {
9281
}
9382

9483
impl ClaimGuard<'_> {
95-
fn remove_from_map_and_unblock_queries(&self, wait_result: WaitResult) {
96-
let mut syncs = self.sync_table.syncs.write();
84+
fn remove_from_map_and_unblock_queries(&self) {
85+
let mut syncs = self.sync_table.syncs.lock();
9786

9887
let SyncState { anyone_waiting, .. } =
9988
syncs[self.memo_ingredient_index.as_usize()].take().unwrap();
10089

101-
// NB: `Ordering::Relaxed` is sufficient here,
102-
// see `store` above for explanation.
103-
if anyone_waiting.load(Ordering::Relaxed) {
104-
self.zalsa
105-
.runtime()
106-
.unblock_queries_blocked_on(self.database_key_index, wait_result)
90+
if anyone_waiting {
91+
self.zalsa.runtime().unblock_queries_blocked_on(
92+
self.database_key_index,
93+
if std::thread::panicking() {
94+
WaitResult::Panicked
95+
} else {
96+
WaitResult::Completed
97+
},
98+
)
10799
}
108100
}
109101
}
110102

111103
impl Drop for ClaimGuard<'_> {
112104
fn drop(&mut self) {
113-
let wait_result = if std::thread::panicking() {
114-
WaitResult::Panicked
115-
} else {
116-
WaitResult::Completed
117-
};
118-
self.remove_from_map_and_unblock_queries(wait_result)
105+
self.remove_from_map_and_unblock_queries()
119106
}
120107
}
121108

0 commit comments

Comments
 (0)