The InspIRCd Project
Home | Developers | Wiki | Forums | Bug Tracker | SVN | Download | Blog
Personal tools

Development/ChannelMembership

From Inspire IRCd (InspIRCd)

Jump to: navigation, search

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).