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
Old Model
Channel membership was represented in two fairly separate 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>.
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).
New Model
The new model is based around a Membership object.
class Membership : public Extensible
{
User *u; // user this pertains to
Channel *c; // channel this pertains to
std::string prefixes; // prefixes of the user in the channel
};
Channels contain a single std::map<User*, Membership*> for all members; filtering for prefix sending is done by iterating the list; as /msg @#channel is used less commonly than mode changes, this saves time and memory compared to maintaining a separate list for each prefix, and makes messages to &#channel work in the same way as those to @#channel.
Users currently contain only an std::set<Channel*>, because using a channel-side lookup is possible in almost every case where the Membership object is needed. If a sufficiently important use case is found for it, this can be converted to std::map<Channel*, Membership*> making the structures symmetric.
Future optimizations
Module hooks that take a (User*, Channel*) pair representing a user-channel relationship can be replaced by a Membership* parameter, to avoid each module needing to do a map lookup to find the object.

















