When dealing with Optimizing weird stuff? we noticed we need a BTreeSet that can use a custom key function, ideally through monomorphization. We have these:
/// A source of data of some specified kind.
pub trait DataSource<T: Kind>: DataSourceBase {
/// Returns the values associated with this kind.
fn get_values(&self) -> T::Values;
/// Returns the value associated with this kind.
///
/// This is the same as [`get_values`] but allows using the singular name,
/// for kinds with up to only one value.
fn get_value(&self) -> Option<T> where T: Kind<Values=Option<T>> {
self.get_values()
}
}
/// A kind of value that can be retrieved from a data source.
pub trait Kind {
/// Values of this kind.
type Values: IntoIterator<Item=Self>;
}
/// A kind of value that can be retrieved from a data source, which can
/// override values of the same kind.
pub trait OverridableKind: Kind {
/// The key, as in a map key, that gets overridden.
type Key: Hash + Eq + Ord;
/// Returns the key for use in a key-value map such as a `BTreeMap` or
/// a set such as `BTreeSet`.
fn as_key(&self) -> &Self::Key;
}
and, well, for an EffectiveDataSource
we can just do:
/// Forwards to the inner [`DataSource`] as there's no filtering we
/// can/need to do here.
impl trait<K> EffectiveDataSourceHelper<K, BTreeSet<K>>
where
K: Kind<Values=BTreeSet<K>> + OverridableKind,
T: DataSource<K>
{
fn get_values_impl(&self) -> BTreeSet<K> {
self.0.get_values()
}
}
but this doesn't work for a CombinedDataSource
that takes multiple other DataSource
s like in a Vec
.
fn get_values(&self) -> BTreeSet<K> {
self.vec_of_data_sources...
let result: BTreeSet<K> = ...
// a BTreeSet, deduplicated by K.as_key, such that only the first
// occurrence of such an as_key (in the order specified by vec_of_data_sources) is included in the set.
}
Currently the only thing we can think of is to collect everything into a Vec
, sort it by as_key
, dedup it by as_key
, and then convert it into a BTreeSet
again. And maybe add a debug check in EffectiveDataSource
that warns if the BTreeSet
contains duplicated keys.