degesch: partially implement rehashing
This commit is contained in:
parent
63a65f9f7c
commit
e39bb976cb
77
degesch.c
77
degesch.c
|
@ -1059,6 +1059,8 @@ struct server
|
|||
// TODO: an output queue to prevent excess floods (this will be needed
|
||||
// especially for away status polling)
|
||||
|
||||
bool rehashing; ///< Rehashing IRC identifiers
|
||||
|
||||
struct str_map irc_users; ///< IRC user data
|
||||
struct str_map irc_channels; ///< IRC channel data
|
||||
struct str_map irc_buffer_map; ///< Maps IRC identifiers to buffers
|
||||
|
@ -2791,7 +2793,8 @@ irc_user_on_destroy (void *object, void *user_data)
|
|||
{
|
||||
struct user *user = object;
|
||||
struct server *s = user_data;
|
||||
str_map_set (&s->irc_users, user->nickname, NULL);
|
||||
if (!s->rehashing)
|
||||
str_map_set (&s->irc_users, user->nickname, NULL);
|
||||
}
|
||||
|
||||
static struct user *
|
||||
|
@ -2877,7 +2880,8 @@ irc_channel_on_destroy (void *object, void *user_data)
|
|||
struct server *s = user_data;
|
||||
LIST_FOR_EACH (struct channel_user, iter, channel->users)
|
||||
irc_channel_unlink_user (channel, iter);
|
||||
str_map_set (&s->irc_channels, channel->name, NULL);
|
||||
if (!s->rehashing)
|
||||
str_map_set (&s->irc_channels, channel->name, NULL);
|
||||
}
|
||||
|
||||
static struct channel *
|
||||
|
@ -2924,7 +2928,74 @@ irc_left_channel (struct channel *channel)
|
|||
static void
|
||||
irc_rehash_and_fix_conflicts (struct server *s)
|
||||
{
|
||||
// TODO
|
||||
// Save the old maps and initialize new ones
|
||||
struct str_map old_users = s->irc_users;
|
||||
struct str_map old_channels = s->irc_channels;
|
||||
struct str_map old_buffer_map = s->irc_buffer_map;
|
||||
|
||||
str_map_init (&s->irc_users);
|
||||
str_map_init (&s->irc_channels);
|
||||
str_map_init (&s->irc_buffer_map);
|
||||
|
||||
s->irc_users .free = old_users .free;
|
||||
s->irc_channels .free = old_channels .free;
|
||||
s->irc_buffer_map.free = old_buffer_map.free;
|
||||
|
||||
s->irc_users .key_xfrm = s->irc_strxfrm;
|
||||
s->irc_channels .key_xfrm = s->irc_strxfrm;
|
||||
s->irc_buffer_map.key_xfrm = s->irc_strxfrm;
|
||||
|
||||
// Prevent channels and users from unsetting themselves
|
||||
// from server maps upon removing the last reference to them
|
||||
s->rehashing = true;
|
||||
|
||||
// TODO: "Removed similarly named buffer %s because of casemapping conflict"
|
||||
// XXX: to be perfectly sure, we should also check
|
||||
// whether any users collide with channels and vice versa
|
||||
|
||||
struct str_map_iter iter;
|
||||
str_map_iter_init (&iter, &old_users);
|
||||
struct user *user;
|
||||
while ((user = str_map_iter_next (&iter)))
|
||||
{
|
||||
// FIXME: don't remove ourselves!
|
||||
if (str_map_find (&s->irc_users, user->nickname))
|
||||
{
|
||||
// TODO: move or merge any PM buffer and remove
|
||||
// the user from channels and altogether
|
||||
}
|
||||
else
|
||||
{
|
||||
str_map_set (&s->irc_users, user->nickname, user);
|
||||
str_map_set (&s->irc_buffer_map, user->nickname,
|
||||
str_map_find (&old_buffer_map, user->nickname));
|
||||
}
|
||||
}
|
||||
|
||||
str_map_iter_init (&iter, &old_channels);
|
||||
struct channel *channel;
|
||||
while ((channel = str_map_iter_next (&iter)))
|
||||
{
|
||||
if (str_map_find (&s->irc_channels, channel->name))
|
||||
{
|
||||
// TODO: remove all users from the buffer
|
||||
// and probably issue NAMES if registered and on the channel,
|
||||
// and of course remove the colliding channel
|
||||
}
|
||||
else
|
||||
{
|
||||
str_map_set (&s->irc_channels, channel->name, user);
|
||||
str_map_set (&s->irc_buffer_map, user->nickname,
|
||||
str_map_find (&old_buffer_map, user->nickname));
|
||||
}
|
||||
}
|
||||
|
||||
// Hopefully we've either moved or destroyed all the old content
|
||||
s->rehashing = false;
|
||||
|
||||
str_map_free (&old_users);
|
||||
str_map_free (&old_channels);
|
||||
str_map_free (&old_buffer_map);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
Loading…
Reference in New Issue