Skip to content

Commit a0e7a06

Browse files
authored
refactor entries API (#987)
1 parent a3ffa22 commit a0e7a06

File tree

10 files changed

+133
-46
lines changed

10 files changed

+133
-46
lines changed

components/salsa-macro-rules/src/setup_input_struct.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ macro_rules! setup_input_struct {
216216
zalsa: &$zalsa::Zalsa
217217
) -> impl Iterator<Item = $zalsa::DatabaseKeyIndex> + '_ {
218218
let ingredient_index = zalsa.lookup_jar_by_type::<$zalsa_struct::JarImpl<$Configuration>>();
219-
<$Configuration>::ingredient_(zalsa).entries(zalsa).map(|(key, _)| key)
219+
<$Configuration>::ingredient_(zalsa).entries(zalsa).map(|entry| entry.key())
220220
}
221221

222222
#[inline]

components/salsa-macro-rules/src/setup_interned_struct.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ macro_rules! setup_interned_struct {
244244
zalsa: &$zalsa::Zalsa
245245
) -> impl Iterator<Item = $zalsa::DatabaseKeyIndex> + '_ {
246246
let ingredient_index = zalsa.lookup_jar_by_type::<$zalsa_struct::JarImpl<$Configuration>>();
247-
<$Configuration>::ingredient(zalsa).entries(zalsa).map(|(key, _)| key)
247+
<$Configuration>::ingredient(zalsa).entries(zalsa).map(|entry| entry.key())
248248
}
249249

250250
#[inline]

components/salsa-macro-rules/src/setup_tracked_fn.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ macro_rules! setup_tracked_fn {
129129
zalsa: &$zalsa::Zalsa
130130
) -> impl Iterator<Item = $zalsa::DatabaseKeyIndex> + '_ {
131131
let ingredient_index = zalsa.lookup_jar_by_type::<$fn_name>().successor(0);
132-
<$Configuration>::intern_ingredient(zalsa).entries(zalsa).map(|(key, _)| key)
132+
<$Configuration>::intern_ingredient(zalsa).entries(zalsa).map(|entry| entry.key())
133133
}
134134

135135
#[inline]

components/salsa-macro-rules/src/setup_tracked_struct.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ macro_rules! setup_tracked_struct {
276276
zalsa: &$zalsa::Zalsa
277277
) -> impl Iterator<Item = $zalsa::DatabaseKeyIndex> + '_ {
278278
let ingredient_index = zalsa.lookup_jar_by_type::<$zalsa_struct::JarImpl<$Configuration>>();
279-
<$Configuration>::ingredient_(zalsa).entries(zalsa).map(|(key, _)| key)
279+
<$Configuration>::ingredient_(zalsa).entries(zalsa).map(|entry| entry.key())
280280
}
281281

282282
#[inline]

src/input.rs

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -238,14 +238,14 @@ impl<C: Configuration> IngredientImpl<C> {
238238
}
239239

240240
/// Returns all data corresponding to the input struct.
241-
pub fn entries<'db>(
242-
&'db self,
243-
zalsa: &'db Zalsa,
244-
) -> impl Iterator<Item = (DatabaseKeyIndex, &'db Value<C>)> + 'db {
241+
pub fn entries<'db>(&'db self, zalsa: &'db Zalsa) -> impl Iterator<Item = StructEntry<'db, C>> {
245242
zalsa
246243
.table()
247244
.slots_of::<Value<C>>()
248-
.map(|(id, value)| (self.database_key_index(id), value))
245+
.map(|(id, value)| StructEntry {
246+
value,
247+
key: self.database_key_index(id),
248+
})
249249
}
250250

251251
/// Peek at the field values without recording any read dependency.
@@ -257,6 +257,35 @@ impl<C: Configuration> IngredientImpl<C> {
257257
}
258258
}
259259

260+
/// An input struct entry.
261+
pub struct StructEntry<'db, C>
262+
where
263+
C: Configuration,
264+
{
265+
value: &'db Value<C>,
266+
key: DatabaseKeyIndex,
267+
}
268+
269+
impl<'db, C> StructEntry<'db, C>
270+
where
271+
C: Configuration,
272+
{
273+
/// Returns the `DatabaseKeyIndex` for this entry.
274+
pub fn key(&self) -> DatabaseKeyIndex {
275+
self.key
276+
}
277+
278+
/// Returns the input struct.
279+
pub fn as_struct(&self) -> C::Struct {
280+
FromId::from_id(self.key.key_index())
281+
}
282+
283+
#[cfg(feature = "salsa_unstable")]
284+
pub fn value(&self) -> &'db Value<C> {
285+
self.value
286+
}
287+
}
288+
260289
impl<C: Configuration> Ingredient for IngredientImpl<C> {
261290
fn location(&self) -> &'static crate::ingredient::Location {
262291
&C::LOCATION
@@ -312,7 +341,7 @@ impl<C: Configuration> Ingredient for IngredientImpl<C> {
312341
.entries(db.zalsa())
313342
// SAFETY: The memo table belongs to a value that we allocated, so it
314343
// has the correct type.
315-
.map(|(_, value)| unsafe { value.memory_usage(&self.memo_table_types) })
344+
.map(|entry| unsafe { entry.value.memory_usage(&self.memo_table_types) })
316345
.collect();
317346

318347
Some(memory_usage)

src/interned.rs

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -809,10 +809,7 @@ where
809809
}
810810

811811
/// Returns all data corresponding to the interned struct.
812-
pub fn entries<'db>(
813-
&'db self,
814-
zalsa: &'db Zalsa,
815-
) -> impl Iterator<Item = (DatabaseKeyIndex, &'db Value<C>)> + 'db {
812+
pub fn entries<'db>(&'db self, zalsa: &'db Zalsa) -> impl Iterator<Item = StructEntry<'db, C>> {
816813
// SAFETY: `should_lock` is `true`
817814
unsafe { self.entries_inner(true, zalsa) }
818815
}
@@ -827,7 +824,7 @@ where
827824
&'db self,
828825
should_lock: bool,
829826
zalsa: &'db Zalsa,
830-
) -> impl Iterator<Item = (DatabaseKeyIndex, &'db Value<C>)> + 'db {
827+
) -> impl Iterator<Item = StructEntry<'db, C>> {
831828
// TODO: Grab all locks eagerly.
832829
zalsa.table().slots_of::<Value<C>>().map(move |(_, value)| {
833830
if should_lock {
@@ -840,11 +837,43 @@ where
840837
// Note that this ID includes the generation, unlike the ID provided by the table.
841838
let id = unsafe { (*value.shared.get()).id };
842839

843-
(self.database_key_index(id), value)
840+
StructEntry {
841+
value,
842+
key: self.database_key_index(id),
843+
}
844844
})
845845
}
846846
}
847847

848+
/// An interned struct entry.
849+
pub struct StructEntry<'db, C>
850+
where
851+
C: Configuration,
852+
{
853+
value: &'db Value<C>,
854+
key: DatabaseKeyIndex,
855+
}
856+
857+
impl<'db, C> StructEntry<'db, C>
858+
where
859+
C: Configuration,
860+
{
861+
/// Returns the `DatabaseKeyIndex` for this entry.
862+
pub fn key(&self) -> DatabaseKeyIndex {
863+
self.key
864+
}
865+
866+
/// Returns the interned struct.
867+
pub fn as_struct(&self) -> C::Struct<'_> {
868+
FromId::from_id(self.key.key_index())
869+
}
870+
871+
#[cfg(feature = "salsa_unstable")]
872+
pub fn value(&self) -> &'db Value<C> {
873+
self.value
874+
}
875+
}
876+
848877
impl<C> Ingredient for IngredientImpl<C>
849878
where
850879
C: Configuration,
@@ -949,7 +978,7 @@ where
949978
let memory_usage = entries
950979
// SAFETY: The memo table belongs to a value that we allocated, so it
951980
// has the correct type. Additionally, we are holding the locks for all shards.
952-
.map(|(_, value)| unsafe { value.memory_usage(&self.memo_table_types) })
981+
.map(|entry| unsafe { entry.value.memory_usage(&self.memo_table_types) })
953982
.collect();
954983

955984
for shard in self.shards.iter() {

src/tracked_struct.rs

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -901,14 +901,43 @@ where
901901
}
902902

903903
/// Returns all data corresponding to the tracked struct.
904-
pub fn entries<'db>(
905-
&'db self,
906-
zalsa: &'db Zalsa,
907-
) -> impl Iterator<Item = (DatabaseKeyIndex, &'db Value<C>)> + 'db {
904+
pub fn entries<'db>(&'db self, zalsa: &'db Zalsa) -> impl Iterator<Item = StructEntry<'db, C>> {
908905
zalsa
909906
.table()
910907
.slots_of::<Value<C>>()
911-
.map(|(id, value)| (self.database_key_index(id), value))
908+
.map(|(id, value)| StructEntry {
909+
value,
910+
key: self.database_key_index(id),
911+
})
912+
}
913+
}
914+
915+
/// A tracked struct entry.
916+
pub struct StructEntry<'db, C>
917+
where
918+
C: Configuration,
919+
{
920+
value: &'db Value<C>,
921+
key: DatabaseKeyIndex,
922+
}
923+
924+
impl<'db, C> StructEntry<'db, C>
925+
where
926+
C: Configuration,
927+
{
928+
/// Returns the `DatabaseKeyIndex` for this entry.
929+
pub fn key(&self) -> DatabaseKeyIndex {
930+
self.key
931+
}
932+
933+
/// Returns the tracked struct.
934+
pub fn as_struct(&self) -> C::Struct<'_> {
935+
FromId::from_id(self.key.key_index())
936+
}
937+
938+
#[cfg(feature = "salsa_unstable")]
939+
pub fn value(&self) -> &'db Value<C> {
940+
self.value
912941
}
913942
}
914943

@@ -990,7 +1019,7 @@ where
9901019
.entries(db.zalsa())
9911020
// SAFETY: The memo table belongs to a value that we allocated, so it
9921021
// has the correct type.
993-
.map(|(_, value)| unsafe { value.memory_usage(&self.memo_table_types) })
1022+
.map(|entry| unsafe { entry.value.memory_usage(&self.memo_table_types) })
9941023
.collect();
9951024

9961025
Some(memory_usage)

tests/debug_db_contents.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,38 +25,40 @@ fn execute() {
2525
use salsa::plumbing::ZalsaDatabase;
2626
let db = salsa::DatabaseImpl::new();
2727

28-
let _ = InternedStruct::new(&db, "Salsa".to_string());
29-
let _ = InternedStruct::new(&db, "Salsa2".to_string());
28+
let interned1 = InternedStruct::new(&db, "Salsa".to_string());
29+
let interned2 = InternedStruct::new(&db, "Salsa2".to_string());
3030

3131
// test interned structs
3232
let interned = InternedStruct::ingredient(db.zalsa())
3333
.entries(db.zalsa())
34-
.map(|(_, value)| value)
3534
.collect::<Vec<_>>();
3635

3736
assert_eq!(interned.len(), 2);
38-
assert_eq!(interned[0].fields().0, "Salsa");
39-
assert_eq!(interned[1].fields().0, "Salsa2");
37+
assert_eq!(interned[0].as_struct(), interned1);
38+
assert_eq!(interned[1].as_struct(), interned2);
39+
assert_eq!(interned[0].value().fields().0, "Salsa");
40+
assert_eq!(interned[1].value().fields().0, "Salsa2");
4041

4142
// test input structs
42-
let input = InputStruct::new(&db, 22);
43+
let input1 = InputStruct::new(&db, 22);
4344

4445
let inputs = InputStruct::ingredient(&db)
4546
.entries(db.zalsa())
46-
.map(|(_, value)| value)
4747
.collect::<Vec<_>>();
4848

4949
assert_eq!(inputs.len(), 1);
50-
assert_eq!(inputs[0].fields().0, 22);
50+
assert_eq!(inputs[0].as_struct(), input1);
51+
assert_eq!(inputs[0].value().fields().0, 22);
5152

5253
// test tracked structs
53-
let computed = tracked_fn(&db, input).field(&db);
54-
assert_eq!(computed, 44);
54+
let tracked1 = tracked_fn(&db, input1);
55+
assert_eq!(tracked1.field(&db), 44);
56+
5557
let tracked = TrackedStruct::ingredient(&db)
5658
.entries(db.zalsa())
57-
.map(|(_, value)| value)
5859
.collect::<Vec<_>>();
5960

6061
assert_eq!(tracked.len(), 1);
61-
assert_eq!(tracked[0].fields().0, computed);
62+
assert_eq!(tracked[0].as_struct(), tracked1);
63+
assert_eq!(tracked[0].value().fields().0, tracked1.field(&db));
6264
}

tests/interned-structs_self_ref.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ const _: () = {
152152
zalsa.lookup_jar_by_type::<zalsa_struct_::JarImpl<Configuration_>>();
153153
<Configuration_>::ingredient(zalsa)
154154
.entries(zalsa)
155-
.map(|(key, _)| key)
155+
.map(|entry| entry.key())
156156
}
157157

158158
#[inline]

tests/persistence.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ fn everything() {
314314

315315
#[test]
316316
fn partial_query() {
317-
use salsa::plumbing::{FromId, ZalsaDatabase};
317+
use salsa::plumbing::ZalsaDatabase;
318318

319319
#[salsa::tracked(persist)]
320320
fn query<'db>(db: &'db dyn salsa::Database, input: MyInput) -> usize {
@@ -390,12 +390,11 @@ fn partial_query() {
390390
)
391391
.unwrap();
392392

393-
// TODO: Expose a better way of recreating inputs after deserialization.
394-
let (id, _) = MyInput::ingredient(&db)
393+
let input = MyInput::ingredient(&db)
395394
.entries(db.zalsa())
396395
.next()
397-
.expect("`MyInput` was persisted");
398-
let input = MyInput::from_id(id.key_index());
396+
.unwrap()
397+
.as_struct();
399398

400399
let result = query(&db, input);
401400
assert_eq!(result, 1);
@@ -425,7 +424,7 @@ fn partial_query() {
425424

426425
#[test]
427426
fn partial_query_interned() {
428-
use salsa::plumbing::{AsId, FromId, ZalsaDatabase};
427+
use salsa::plumbing::{AsId, ZalsaDatabase};
429428

430429
#[salsa::tracked(persist)]
431430
fn intern<'db>(db: &'db dyn salsa::Database, input: MyInput, value: usize) -> MyInterned<'db> {
@@ -529,12 +528,11 @@ fn partial_query_interned() {
529528
)
530529
.unwrap();
531530

532-
// TODO: Expose a better way of recreating inputs after deserialization.
533-
let (id, _) = MyInput::ingredient(&db)
531+
let input = MyInput::ingredient(&db)
534532
.entries(db.zalsa())
535533
.next()
536-
.expect("`MyInput` was persisted");
537-
let input = MyInput::from_id(id.key_index());
534+
.unwrap()
535+
.as_struct();
538536

539537
// Re-intern `i0`.
540538
let i0 = intern(&db, input, 0);

0 commit comments

Comments
 (0)