degesch: partially implement rehashing
This commit is contained in:
parent
63a65f9f7c
commit
e39bb976cb
73
degesch.c
73
degesch.c
|
@ -1059,6 +1059,8 @@ struct server
|
||||||
// TODO: an output queue to prevent excess floods (this will be needed
|
// TODO: an output queue to prevent excess floods (this will be needed
|
||||||
// especially for away status polling)
|
// especially for away status polling)
|
||||||
|
|
||||||
|
bool rehashing; ///< Rehashing IRC identifiers
|
||||||
|
|
||||||
struct str_map irc_users; ///< IRC user data
|
struct str_map irc_users; ///< IRC user data
|
||||||
struct str_map irc_channels; ///< IRC channel data
|
struct str_map irc_channels; ///< IRC channel data
|
||||||
struct str_map irc_buffer_map; ///< Maps IRC identifiers to buffers
|
struct str_map irc_buffer_map; ///< Maps IRC identifiers to buffers
|
||||||
|
@ -2791,6 +2793,7 @@ irc_user_on_destroy (void *object, void *user_data)
|
||||||
{
|
{
|
||||||
struct user *user = object;
|
struct user *user = object;
|
||||||
struct server *s = user_data;
|
struct server *s = user_data;
|
||||||
|
if (!s->rehashing)
|
||||||
str_map_set (&s->irc_users, user->nickname, NULL);
|
str_map_set (&s->irc_users, user->nickname, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2877,6 +2880,7 @@ irc_channel_on_destroy (void *object, void *user_data)
|
||||||
struct server *s = user_data;
|
struct server *s = user_data;
|
||||||
LIST_FOR_EACH (struct channel_user, iter, channel->users)
|
LIST_FOR_EACH (struct channel_user, iter, channel->users)
|
||||||
irc_channel_unlink_user (channel, iter);
|
irc_channel_unlink_user (channel, iter);
|
||||||
|
if (!s->rehashing)
|
||||||
str_map_set (&s->irc_channels, channel->name, NULL);
|
str_map_set (&s->irc_channels, channel->name, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2924,7 +2928,74 @@ irc_left_channel (struct channel *channel)
|
||||||
static void
|
static void
|
||||||
irc_rehash_and_fix_conflicts (struct server *s)
|
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
|
static void
|
||||||
|
|
Loading…
Reference in New Issue