diff options
| author | Zeyla Hellyer <[email protected]> | 2017-02-09 13:34:08 -0800 |
|---|---|---|
| committer | Zeyla Hellyer <[email protected]> | 2017-02-09 13:34:08 -0800 |
| commit | 0c9ec377aa7281fb3d4bc390c896b426660a5387 (patch) | |
| tree | a355bda0c0d02d8b67331e0a99090c7b26206cb1 /src/client/dispatch.rs | |
| parent | Release v0.1.5 (diff) | |
| download | serenity-0c9ec377aa7281fb3d4bc390c896b426660a5387.tar.xz serenity-0c9ec377aa7281fb3d4bc390c896b426660a5387.zip | |
Optimize caching
Improve the cache by keeping track of new maps, making other maps have
`Arc<RwLock>` values, optimizing already-existing methods, and take advantage
of new, more efficient retrievals (e.g. simply keying a value from a map rather
than iterating over vecs or maps and then itering over another vec).
Keep track of two new maps in the cache:
- **channels**: a map of all guild channels that exist, so that they can be
efficiently found, and so a message's guild can be efficiently found
- **users**: a map of all users that exist, so that it can be shared across
all members and presences
Other cache fields now have `Arc<RwLock>` values:
- `groups`
- `guilds`
- `private_channels`
`Cache::unavailable_guilds` is now a `HashSet<GuildId>` instead of a
`Vec<GuildId>`. This should slightly optimize removals/insertions for large
bots.
`ext::cache::ChannelRef` has been removed as it became equivilant in
functionality to `model::Channel`. Also, `model::Channel` now has all variant
data encased in `Arc<RwLock>`s. E.g., `Channel::Group(Group)` is now
`Channel::Group(Arc<RwLock<Group>>)`.
Some model struct fields are now wrapped in an `Arc<RwLock>`. These are:
- `Group::recipients`: `HashMap<UserId, User>` -> `HashMap<UserId, Arc<RwLock<User>>>`
- `Guild::channels`: `HashMap<ChannelId, GuildChannel>` -> `HashMap<ChannelId, Arc<RwLock<GuildChannel>>>`
- `Member::user`: `User` -> `Arc<RwLock<User>>`
- `PrivateChannel::recipient`: `User` -> `Arc<RwLock<User>>`
Some (cache-enabled) event handler signatures have changed to use
`Arc<RwLock>`s:
- `Client::on_call_delete`
- `Client::on_call_update`
- `Client::on_guild_delete`
- `Client::on_guild_update`
Many function signatures have changed:
- `Cache::get_call` now returns a `Option<Arc<RwLock<Call>>>` instead of a
`Option<&Call>`
- `Cache::get_channel` now returns a `Option<Channel>` instead of a
`Option<ChannelRef>`. This now also retrieves directly from the
`Guild::channels` instead of iterating over guilds' for a guild channel
- `Cache::get_guild` now returns a `Option<Arc<RwLock<Guild>>>` instead of a
`Option<&Guild>`
- `Cache::get_guild_channel` now returns a `Option<Arc<RwLock<GuildChannel>>>`
instead of a `Option<&GuildChannel>`
- `Cache::get_group` now returns a `Option<Arc<RwLock<Group>>>` instead of a
`Option<&Group>`
- `Cache::get_member` now returns a `Option<Member>` instead of a
`Option<&Member>`, due to guilds being behind a lock themselves
- `Cache::get_role` now returns a `Option<Role>` instead of a `Option<&Role>`
for the above reason
- `Cache::get_user` now returns a `Option<Arc<RwLock<User>>>` instead of a
`Option<&User>`
- `GuildId::find` now returns a `Option<Arc<RwLock<Guild>>>` instead of a
`Option<Guild>`
- `UserId::find` now returns a `Option<Arc<RwLock<User>>>` instead of a
`Option<User>`
- `Member::display_name` now returns a `Cow<String>` instead of a `&str`
A new cache method has been added, `Cache::get_private_channel`, to retrieve a
`PrivateChannel`.
The `Display` formatter for `Channel` has been optimized to not clone.
Diffstat (limited to 'src/client/dispatch.rs')
| -rw-r--r-- | src/client/dispatch.rs | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/src/client/dispatch.rs b/src/client/dispatch.rs index e70f280..33267ff 100644 --- a/src/client/dispatch.rs +++ b/src/client/dispatch.rs @@ -25,6 +25,22 @@ macro_rules! handler { } macro_rules! update { + ($method:ident, @$event:expr) => { + { + #[cfg(feature="cache")] + { + CACHE.write().unwrap().$method(&mut $event) + } + } + }; + ($method:ident, @$event:expr, $old:expr) => { + { + #[cfg(feature="cache")] + { + CACHE.write().unwrap().$method(&mut $event, $old) + } + } + }; ($method:ident, $event:expr) => { { #[cfg(feature="cache")] @@ -107,7 +123,7 @@ fn dispatch_message(context: Context, } } -#[allow(cyclomatic_complexity)] +#[allow(cyclomatic_complexity, unused_mut)] fn handle_event(event: Event, conn: &Arc<Mutex<Shard>>, data: &Arc<Mutex<ShareMap>>, @@ -207,8 +223,8 @@ fn handle_event(event: Event, thread::spawn(move || (handler)(context, event)); } }, - Event::ChannelRecipientAdd(event) => { - update!(update_with_channel_recipient_add, event); + Event::ChannelRecipientAdd(mut event) => { + update!(update_with_channel_recipient_add, @event); if let Some(handler) = handler!(on_channel_recipient_addition, event_store) { let context = context(Some(event.channel_id), @@ -241,8 +257,7 @@ fn handle_event(event: Event, feature_cache! {{ let before = CACHE.read() .unwrap() - .get_channel(event.channel.id()) - .map(|x| x.clone_inner()); + .get_channel(event.channel.id()); update!(update_with_channel_update, event); thread::spawn(move || (handler)(context, before, event.channel)); @@ -324,8 +339,8 @@ fn handle_event(event: Event, thread::spawn(move || (handler)(context, event.guild_id)); } }, - Event::GuildMemberAdd(event) => { - update!(update_with_guild_member_add, event); + Event::GuildMemberAdd(mut event) => { + update!(update_with_guild_member_add, @event); if let Some(handler) = handler!(on_guild_member_addition, event_store) { let context = context(None, conn, data, login_type); @@ -516,8 +531,8 @@ fn handle_event(event: Event, thread::spawn(move || (handler)(context, event.presences)); } }, - Event::PresenceUpdate(event) => { - update!(update_with_presence_update, event); + Event::PresenceUpdate(mut event) => { + update!(update_with_presence_update, @event); if let Some(handler) = handler!(on_presence_update, event_store) { let context = context(None, conn, data, login_type); |