Open nikomatsakis opened 1 month ago
Here are some of the steps required
reset_at
field and reset
method. These were used to record when the intern table was completed emptied. I don't think it's useful and nobody uses it, so let's just remove that capability.
reset_at
was also used in maybe_changed_after
; for now, we can just make this method return false, since interned data never changes. We'll revisit this later on.intern
records a dependency index on the entire intern ingredient
DatabaseKeyIndex
(a dependency on a specific id) and DependencyIndex
(might depend on the ingredient as a whole).DependencyIndex
DatabaseKeyIndex
Ingredient
that take a Option<Id>
can be changed to take an Id
and various unwrap
calls removed from the impls
maybe_changed_after
Value
struct to record the revision when data was interned:
Value
struct is the data that we store in the table
for each interned value.first_interned_at: Revision
, the revision in which the value was first interned (which never changes)last_interned_at: AtomicRevision
, the revision in which it was most recently interned (which is updated each time we intern)first_interned_at
field later on to detect whether an intern id has been re-used.last_interned_at
field later on to detect whether its safe to discard an interned value -- we can NEVER discard values that have already been interned in the current revision, only values that were interned in previous revisions.last_interned_at
to the current revision and then return the id
.
Value
struct from the table by a call to db.zalsa().table().get::<Value<C>>(id)
, like we do here.maybe_changed_after
, we have to do the following:
input
is Some
(if you didn't do the previous refactoring)Value
from the table with code like this
first_interned_at
is greater than the revision:
last_interned_at
to the currrent revision, accessible from db.zalsa().current_revision()
.
id
and expect the same results.last_interned_at
. If this assertion fails, it represents a logic error.reset
, that should be valid to do, if invoked with an &mut self
and triggering a new revision. That could be useful for testing.last_interned_at
equals the new revision; but if you take an &mut self
you can make it trigger a new revision.last_interned_at
field has not been properly updated).@ibraheemdev are you working on this or parts of it?
This seems interesting. I'd like to work on this unless other people is working on this
BTW, I've read some recent papers about cache eviction algorithms saying that they are more efficient than LRU
Though GC might not happen so many times in salsa's real world use cases and the efficient varies by using pattern, I think that it might be worthwhile to implement multiple eviction policies and open them as runtime options because they implementations are quite simple
I have been working on the first part of this described in the hackmd.
I'm wondering how necessary is it. If we don't need to throw away any interned values, we can simply store them in a static pool. Not even needing a salsa db.
I'm thinking that immortal interned values are inherently independent from salsa's incremental computation capabilities.
Maybe a separate crate for these things. There are definitely scenarios where we don't care about the memory consumed by a certain class of interned values. And salsa's gc interned value might deserve a different name.
Separating these things shall make salsa design much easier, I think.
With that being said, it probably has to do with my own implementation of things. For my own programming language, I split types into ethereal types and fluffy types. Fluffy types are those that changes rapidly, for instance, those with some local lifetimes. But ethereal types are those like 'Vec
As described in this hackmd, we would like to support LRU-style collection for interned values so that we can cap maximum memory consumption.