Development/ChannelMembership
From the makers of InspIRCd.
| Development Material - Information posted here is for developer reference only. This material is subject to possible change and will be technical in nature. |
Contents |
Channel Membership in InspIRCd
What Is This
This document discusses potential improvements that can be made to how we (InspIRCd) store channel membership. Channel membership being the link between channels and users (and vice versa), and any metadata associated with this link.
Do note that this document is discussion only (nothing is concrete), and development may not happen in this form, soon, or at all.
Current Model
Currently, channel membership is represented in two fairly seperate portions. That of channel membership of users, and of user membership of channels.
Channels
Channels store information in a number of ways:
- A list of prefixes (std::map<User *, std::vector<std::pair<char, unsigned int>>,
- Four seperate lists of membership of type CUList (std::map<User *, std::string>).
* Internal userlist (all users) * Opped users (+o) * Halfopped (+h) * Voiced (+h)
These are accessed by a variety of functions (AddUser(), AddOppedUser() ...).
Users
Users store a map of channel membership, of type std::map<Channel *, char>.
Discussion of Current Model
The current model works, and is quite stable after numerous development. However, I do believe it could be simplified both in code and in terms of use, probably to the advantage of slightly lower RAM usage and more comprehensible code surrounding this subsystem.
Access Patterns
Of course, before an adequate redesign of the system can be fully thought through, we first need to discuss the different approaches we need to take to accessing this data - there are several different ways.
- NAMES - listing of all users and their access
- WHOIS - listing of all channels of a user and their access
- JOIN/PART/KICK/etc all need to refer to channel membership (is user X on channel, if so, with what access level etc).
Suggested Model
The primary change I would like to propose is in how data is stored relating to the metadata of someone's access, and in how this is stored in channels. In terms of data model only...
class ChannelMembership
{
User *u; // user this pertains to
Channel *c; // channel this pertains to
std::string display; // like CUList, we should generate a string that is displayed to users on NAMES etc. Unlike CUList, we should probably cache this
// as it will change infrequently (on MODE change (namesx), host change (uhnames), etc)
std::vector<std::pair<prefix, prefix_value>> prefixes; // Which prefixes are set on this user.
char prefixes[256] // lookup table for prefixes (e.g. @) for fast lookup of user status, used similar to modes (or something..)
};
In terms of how this would be associated, channels would be storing std::map<User *, ChannelMembership *> (for fast per-user lookup), as well as std::map<char prefix, std::vector<ChannelMembership *>> for fast lookup of lists of users used for things like /notice @#chan and auditorium, etc.
This retains the seperate lists we have, which are useful for quick lookups, in a more extensible form (easier to manipulate new features using this), as well as making specific code for manipulating channel access quite simple (indeed, it could all go into ChannelMembership instead of being spread throughout User and Channel code).

















