Expand description
An EntityMap<E, V> is a map from EntityId<E> to values of type V with a hash-map-like API
optimized for densely populated maps.
An EntityMap is “dense” in the sense that it uses a vector Vec<Option<V>> internally for
storage, using the EntityId<E> to index into the vector. Use an EntityMap in any of the
following cases:
- The number of entities is small
- Most entities are expected to be used as a key
- Access or creation speed is important
- You want access to the
EntityId<E>key a value was stored with
If you know beforehand how many entities you expect to store, use the EntityMap::with_capacity
constructor or EntityMap::reserve to preallocate the map, as that is more efficient than letting
it lazily reallocate as needed.
Because every value added to an EntityMap is accompanied by a valid EntityId<E>, EntityMap is
guaranteed to only “store” valid entity IDs. You can therefore use it as a replacement for
EntityVec<E, V> (or just Vec<V>) for cases where you need to recover the original entity ID that
a value was stored with, for example, by iterating over the (entity ID, value) pairs returned by
EntityMap::iter. The only cost you pay for this is the extra memory needed to store Option<V>
values instead of V values, which in some cases is nothing. The EntityId<E> itself is not
stored.
An EntityMap<E, V> can be cheaply converted to an EntityVec<E, Option<V>> using the
EntityMap::into_entity_vec method.
§Example
Imagine you have Person and Setting entities, and you want an efficient way to store for each
SettingId a Vec<PersonId> representing all the people that can be found in the setting. It is
possible to use a HashMap<SettingId, Vec<PersonId>> to store this information, but an
EntityMap<SettingId, Vec<PersonId>> is more efficient.
use ixa::data_structures::entity_map::EntityMap;
let mut setting_membership = EntityMap::<SettingId, Vec<PersonId>>::new();
// During population initialization you might initialize the map with data in, say, a `PersonRecord`
// struct that has a `home_id` field of type `SettingId`.
let person_id = context.add_entity(with!(Person, person_record.age));
let setting_members = setting_membership.get_or_insert(person_record.home_id, Vec::new);
setting_members.push(person_id);
// Look-ups are extremely efficient.
if let Some(setting_members) = setting_membership.get(setting_id){
// Do something with the setting members.
}
// You can also iterate over the (entity ID, value) pairs.
for (setting_id, setting_members) in setting_membership.iter() {
// Do something with the setting and its members.
}