Created
July 19, 2020 21:24
-
-
Save Kixiron/3deb7c73f89cf27ce5dc83c97bd317d3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub trait StringInterner: | |
salsa::Database + salsa::plumbing::HasQueryGroup<InternerDatabase> + Database | |
{ | |
fn intern_string(&self, key0: S) -> IStr; | |
fn lookup_intern_string(&self, key0: IStr) -> (S); | |
} | |
/// Representative struct for the query group. | |
pub struct InternerDatabase {} | |
impl salsa::plumbing::QueryGroup for InternerDatabase { | |
type DynDb = dyn StringInterner; | |
type GroupStorage = StringInternerGroupStorage__; | |
} | |
impl<DB> StringInterner for DB | |
where | |
DB: Database, | |
DB: salsa::Database, | |
DB: salsa::plumbing::HasQueryGroup<InternerDatabase>, | |
{ | |
fn intern_string(&self, key0: S) -> IStr { | |
fn __shim(db: &dyn StringInterner, key0: S) -> IStr { | |
salsa::plumbing::get_query_table::<InternStringQuery>(db).get((key0)) | |
} | |
__shim(self, key0) | |
} | |
fn lookup_intern_string(&self, key0: IStr) -> (S) { | |
fn __shim(db: &dyn StringInterner, key0: IStr) -> (S) { | |
salsa::plumbing::get_query_table::<InternStringLookupQuery>(db).get((key0)) | |
} | |
__shim(self, key0) | |
} | |
} | |
pub struct InternStringQuery; | |
#[automatically_derived] | |
#[allow(unused_qualifications)] | |
impl ::core::default::Default for InternStringQuery { | |
#[inline] | |
fn default() -> InternStringQuery { | |
InternStringQuery {} | |
} | |
} | |
#[automatically_derived] | |
#[allow(unused_qualifications)] | |
impl ::core::fmt::Debug for InternStringQuery { | |
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { | |
match *self { | |
InternStringQuery => { | |
let mut debug_trait_builder = f.debug_tuple("InternStringQuery"); | |
debug_trait_builder.finish() | |
} | |
} | |
} | |
} | |
impl InternStringQuery { | |
/// Get access to extra methods pertaining to this query. For | |
/// example, you can use this to run the GC (`sweep`) across a | |
/// single input. You can also use it to invoke this query, though | |
/// it's more common to use the trait method on the database | |
/// itself. | |
pub fn in_db(self, db: &dyn StringInterner) -> salsa::QueryTable<'_, Self> { | |
salsa::plumbing::get_query_table::<InternStringQuery>(db) | |
} | |
} | |
impl InternStringQuery { | |
/// Like `in_db`, but gives access to methods for setting the | |
/// value of an input. Not applicable to derived queries. | |
/// | |
/// # Threads, cancellation, and blocking | |
/// | |
/// Mutating the value of a query cannot be done while there are | |
/// still other queries executing. If you are using your database | |
/// within a single thread, this is not a problem: you only have | |
/// `&self` access to the database, but this method requires `&mut | |
/// self`. | |
/// | |
/// However, if you have used `snapshot` to create other threads, | |
/// then attempts to `set` will **block the current thread** until | |
/// those snapshots are dropped (usually when those threads | |
/// complete). This also implies that if you create a snapshot but | |
/// do not send it to another thread, then invoking `set` will | |
/// deadlock. | |
/// | |
/// Before blocking, the thread that is attempting to `set` will | |
/// also set a cancellation flag. In the threads operating on | |
/// snapshots, you can use the [`is_current_revision_canceled`] | |
/// method to check for this flag and bring those operations to a | |
/// close, thus allowing the `set` to succeed. Ignoring this flag | |
/// may lead to "starvation", meaning that the thread attempting | |
/// to `set` has to wait a long, long time. =) | |
/// | |
/// [`is_current_revision_canceled`]: struct.Runtime.html#method.is_current_revision_canceled | |
pub fn in_db_mut(self, db: &mut dyn StringInterner) -> salsa::QueryTableMut<'_, Self> { | |
salsa::plumbing::get_query_table_mut::<InternStringQuery>(db) | |
} | |
} | |
impl salsa::Query for InternStringQuery { | |
type Key = (S); | |
type Value = IStr; | |
type Storage = salsa::plumbing::InternedStorage<Self>; | |
type Group = InternerDatabase; | |
type GroupStorage = StringInternerGroupStorage__; | |
type DynDb = dyn StringInterner; | |
const QUERY_INDEX: u16 = 0u16; | |
const QUERY_NAME: &'static str = "intern_string"; | |
fn query_storage(group_storage: &Self::GroupStorage) -> &std::sync::Arc<Self::Storage> { | |
&group_storage.intern_string | |
} | |
} | |
pub struct InternStringLookupQuery; | |
#[automatically_derived] | |
#[allow(unused_qualifications)] | |
impl ::core::default::Default for InternStringLookupQuery { | |
#[inline] | |
fn default() -> InternStringLookupQuery { | |
InternStringLookupQuery {} | |
} | |
} | |
#[automatically_derived] | |
#[allow(unused_qualifications)] | |
impl ::core::fmt::Debug for InternStringLookupQuery { | |
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { | |
match *self { | |
InternStringLookupQuery => { | |
let mut debug_trait_builder = f.debug_tuple("InternStringLookupQuery"); | |
debug_trait_builder.finish() | |
} | |
} | |
} | |
} | |
impl InternStringLookupQuery { | |
/// Get access to extra methods pertaining to this query. For | |
/// example, you can use this to run the GC (`sweep`) across a | |
/// single input. You can also use it to invoke this query, though | |
/// it's more common to use the trait method on the database | |
/// itself. | |
pub fn in_db(self, db: &dyn StringInterner) -> salsa::QueryTable<'_, Self> { | |
salsa::plumbing::get_query_table::<InternStringLookupQuery>(db) | |
} | |
} | |
impl InternStringLookupQuery { | |
/// Like `in_db`, but gives access to methods for setting the | |
/// value of an input. Not applicable to derived queries. | |
/// | |
/// # Threads, cancellation, and blocking | |
/// | |
/// Mutating the value of a query cannot be done while there are | |
/// still other queries executing. If you are using your database | |
/// within a single thread, this is not a problem: you only have | |
/// `&self` access to the database, but this method requires `&mut | |
/// self`. | |
/// | |
/// However, if you have used `snapshot` to create other threads, | |
/// then attempts to `set` will **block the current thread** until | |
/// those snapshots are dropped (usually when those threads | |
/// complete). This also implies that if you create a snapshot but | |
/// do not send it to another thread, then invoking `set` will | |
/// deadlock. | |
/// | |
/// Before blocking, the thread that is attempting to `set` will | |
/// also set a cancellation flag. In the threads operating on | |
/// snapshots, you can use the [`is_current_revision_canceled`] | |
/// method to check for this flag and bring those operations to a | |
/// close, thus allowing the `set` to succeed. Ignoring this flag | |
/// may lead to "starvation", meaning that the thread attempting | |
/// to `set` has to wait a long, long time. =) | |
/// | |
/// [`is_current_revision_canceled`]: struct.Runtime.html#method.is_current_revision_canceled | |
pub fn in_db_mut(self, db: &mut dyn StringInterner) -> salsa::QueryTableMut<'_, Self> { | |
salsa::plumbing::get_query_table_mut::<InternStringLookupQuery>(db) | |
} | |
} | |
impl salsa::Query for InternStringLookupQuery { | |
type Key = (IStr); | |
type Value = (S); | |
type Storage = salsa::plumbing::LookupInternedStorage<Self, InternStringQuery>; | |
type Group = InternerDatabase; | |
type GroupStorage = StringInternerGroupStorage__; | |
type DynDb = dyn StringInterner; | |
const QUERY_INDEX: u16 = 1u16; | |
const QUERY_NAME: &'static str = "lookup_intern_string"; | |
fn query_storage(group_storage: &Self::GroupStorage) -> &std::sync::Arc<Self::Storage> { | |
&group_storage.lookup_intern_string | |
} | |
} | |
pub struct StringInternerGroupStorage__ { | |
pub intern_string: std::sync::Arc<<InternStringQuery as salsa::Query>::Storage>, | |
pub lookup_intern_string: | |
std::sync::Arc<<InternStringLookupQuery as salsa::Query>::Storage>, | |
} | |
impl StringInternerGroupStorage__ { | |
pub fn new(group_index: u16) -> Self { | |
StringInternerGroupStorage__ { | |
intern_string: std::sync::Arc::new(salsa::plumbing::QueryStorageOps::new( | |
group_index, | |
)), | |
lookup_intern_string: std::sync::Arc::new(salsa::plumbing::QueryStorageOps::new( | |
group_index, | |
)), | |
} | |
} | |
} | |
impl StringInternerGroupStorage__ { | |
pub fn fmt_index( | |
&self, | |
db: &dyn StringInterner, | |
input: salsa::DatabaseKeyIndex, | |
fmt: &mut std::fmt::Formatter<'_>, | |
) -> std::fmt::Result { | |
match input.query_index() { | |
0u16 => salsa::plumbing::QueryStorageOps::fmt_index( | |
&*self.intern_string, | |
db, | |
input, | |
fmt, | |
), | |
1u16 => salsa::plumbing::QueryStorageOps::fmt_index( | |
&*self.lookup_intern_string, | |
db, | |
input, | |
fmt, | |
), | |
i => ::std::rt::begin_panic_fmt(&::core::fmt::Arguments::new_v1( | |
&["salsa: impossible query index "], | |
&match (&i,) { | |
(arg0,) => [::core::fmt::ArgumentV1::new( | |
arg0, | |
::core::fmt::Display::fmt, | |
)], | |
}, | |
)), | |
} | |
} | |
pub fn maybe_changed_since( | |
&self, | |
db: &dyn StringInterner, | |
input: salsa::DatabaseKeyIndex, | |
revision: salsa::Revision, | |
) -> bool { | |
match input.query_index() { | |
0u16 => salsa::plumbing::QueryStorageOps::maybe_changed_since( | |
&*self.intern_string, | |
db, | |
input, | |
revision, | |
), | |
1u16 => salsa::plumbing::QueryStorageOps::maybe_changed_since( | |
&*self.lookup_intern_string, | |
db, | |
input, | |
revision, | |
), | |
i => ::std::rt::begin_panic_fmt(&::core::fmt::Arguments::new_v1( | |
&["salsa: impossible query index "], | |
&match (&i,) { | |
(arg0,) => [::core::fmt::ArgumentV1::new( | |
arg0, | |
::core::fmt::Display::fmt, | |
)], | |
}, | |
)), | |
} | |
} | |
pub fn for_each_query( | |
&self, | |
_runtime: &salsa::Runtime, | |
mut op: &mut dyn FnMut(&dyn salsa::plumbing::QueryStorageMassOps), | |
) { | |
op(&*self.intern_string); | |
op(&*self.lookup_intern_string); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment