aboutsummaryrefslogtreecommitdiff
path: root/src/model/utils.rs
diff options
context:
space:
mode:
authorZeyla Hellyer <[email protected]>2017-02-09 13:34:08 -0800
committerZeyla Hellyer <[email protected]>2017-02-09 13:34:08 -0800
commit0c9ec377aa7281fb3d4bc390c896b426660a5387 (patch)
treea355bda0c0d02d8b67331e0a99090c7b26206cb1 /src/model/utils.rs
parentRelease v0.1.5 (diff)
downloadserenity-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/model/utils.rs')
-rw-r--r--src/model/utils.rs21
1 files changed, 11 insertions, 10 deletions
diff --git a/src/model/utils.rs b/src/model/utils.rs
index 58701bb..8de7dd2 100644
--- a/src/model/utils.rs
+++ b/src/model/utils.rs
@@ -1,4 +1,5 @@
use std::collections::{BTreeMap, HashMap};
+use std::sync::{Arc, RwLock};
use super::{
Channel,
ChannelId,
@@ -22,8 +23,6 @@ use ::utils::{decode_array, into_array};
use super::permissions::{self, Permissions};
#[cfg(feature="cache")]
use ::client::CACHE;
-#[cfg(feature="cache")]
-use ::ext::cache::ChannelRef;
#[macro_escape]
macro_rules! req {
@@ -93,7 +92,9 @@ pub fn decode_members(value: Value) -> Result<HashMap<UserId, Member>> {
let mut members = HashMap::new();
for member in decode_array(value, Member::decode)? {
- members.insert(member.user.id, member);
+ let user_id = member.user.read().unwrap().id;
+
+ members.insert(user_id, member);
}
Ok(members)
@@ -134,8 +135,8 @@ pub fn decode_private_channels(value: Value)
for private_channel in decode_array(value, Channel::decode)? {
let id = match private_channel {
- Channel::Group(ref group) => group.channel_id,
- Channel::Private(ref channel) => channel.id,
+ Channel::Group(ref group) => group.read().unwrap().channel_id,
+ Channel::Private(ref channel) => channel.read().unwrap().id,
Channel::Guild(_) => unreachable!("Guild private channel decode"),
};
@@ -217,11 +218,11 @@ pub fn decode_shards(value: Value) -> Result<[u64; 2]> {
])
}
-pub fn decode_users(value: Value) -> Result<HashMap<UserId, User>> {
+pub fn decode_users(value: Value) -> Result<HashMap<UserId, Arc<RwLock<User>>>> {
let mut users = HashMap::new();
for user in decode_array(value, User::decode)? {
- users.insert(user.id, user);
+ users.insert(user.id, Arc::new(RwLock::new(user)));
}
Ok(users)
@@ -306,10 +307,10 @@ pub fn user_has_perms(channel_id: ChannelId,
};
let guild_id = match channel {
- ChannelRef::Group(_) | ChannelRef::Private(_) => {
+ Channel::Group(_) | Channel::Private(_) => {
return Ok(permissions == permissions::MANAGE_MESSAGES);
},
- ChannelRef::Guild(channel) => channel.guild_id,
+ Channel::Guild(channel) => channel.read().unwrap().guild_id,
};
let guild = match cache.get_guild(guild_id) {
@@ -317,7 +318,7 @@ pub fn user_has_perms(channel_id: ChannelId,
None => return Err(Error::Client(ClientError::ItemMissing)),
};
- let perms = guild.permissions_for(channel_id, current_user.id);
+ let perms = guild.read().unwrap().permissions_for(channel_id, current_user.id);
permissions.remove(perms);