Skip to content

Commit d58f563

Browse files
authored
Reintroduce user lookup cache
Found by: mortmann Patch by: thommey Fixes: eggheads#1599
1 parent 844439a commit d58f563

File tree

4 files changed

+31
-10
lines changed

4 files changed

+31
-10
lines changed

src/chan.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ typedef struct memstruct {
5050
time_t split; /* in case they were just netsplit */
5151
time_t last; /* for measuring idle time */
5252
time_t delay; /* for delayed autoop */
53-
int tried_getuser; // TODO: use it to invalidate user cache
53+
struct userrec *user; /* cached user lookup */
54+
int tried_getuser; /* negative user lookup cache */
5455
struct memstruct *next;
5556
} memberlist;
5657

src/chanprog.c

+11-5
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,11 @@ struct chanset_t *findchan_by_dname(const char *name)
118118

119119
/* Clear the user pointers in the chanlists.
120120
*
121-
* Necessary when a hostmask is added/removed, a user is added or a new
122-
* userfile is loaded.
121+
* Necessary when:
122+
* - a hostmask is added/removed
123+
* - an account is added/removed
124+
* - a user is added
125+
* - new userfile is loaded
123126
*/
124127
void clear_chanlist(void)
125128
{
@@ -128,14 +131,16 @@ void clear_chanlist(void)
128131

129132
for (chan = chanset; chan; chan = chan->next)
130133
for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
134+
m->user = NULL;
131135
m->tried_getuser = 0;
132136
}
133137
}
134138

135139
/* Clear the user pointer of a specific nick in the chanlists.
136-
137-
* Necessary when a hostmask is added/removed, a nick changes, etc.
138-
* Does not completely invalidate the channel cache like clear_chanlist().
140+
*
141+
* Necessary when:
142+
* - their hostmask changed (chghost)
143+
* - their account changed
139144
*/
140145
void clear_chanlist_member(const char *nick)
141146
{
@@ -145,6 +150,7 @@ void clear_chanlist_member(const char *nick)
145150
for (chan = chanset; chan; chan = chan->next)
146151
for (m = chan->channel.member; m && m->nick[0]; m = m->next)
147152
if (!rfc_casecmp(m->nick, nick)) {
153+
m->user = NULL;
148154
m->tried_getuser = 0;
149155
break;
150156
}

src/mod/irc.mod/chan.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ static void setaccount(char *nick, char *account)
116116
}
117117
}
118118
}
119+
/* Username for nick could be different after account change, invalidate cache */
120+
clear_chanlist_member(nick);
119121
}
120122

121123
/* Returns the current channel mode.
@@ -1220,7 +1222,7 @@ static int got354(char *from, char *msg)
12201222
* :[email protected] CHGHOST tehgeo foo.io
12211223
* changes user hostmask to [email protected]
12221224
*/
1223-
static int gotchghost(char *from, char *msg){
1225+
static int gotchghost(char *from, char *msg) {
12241226
struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };
12251227
struct userrec *u;
12261228
struct chanset_t *chan;
@@ -1247,6 +1249,8 @@ static int gotchghost(char *from, char *msg){
12471249
check_this_member(chan, m->nick, &fr);
12481250
}
12491251
}
1252+
/* Username for nick could be different after host change, invalidate cache */
1253+
clear_chanlist_member(nick);
12501254
return 0;
12511255
}
12521256

src/userrec.c

+13-3
Original file line numberDiff line numberDiff line change
@@ -224,24 +224,34 @@ struct userrec *get_user_by_handle(struct userrec *bu, char *handle)
224224

225225
struct userrec *get_user_from_member(memberlist *m)
226226
{
227-
struct userrec *ret;
227+
struct userrec *ret = NULL;
228+
229+
/* Check positive/negative cache first */
230+
if (m->user || m->tried_getuser) {
231+
return m->user;
232+
}
228233

229234
/* Check if there is a user with a matching account if one is provided */
230235
if (m->account[0] != '*') {
231236
ret = get_user_by_account(m->account);
232237
if (ret) {
233-
return ret;
238+
goto getuser_done;
234239
}
235240
}
241+
236242
/* Check if there is a user with a matching hostmask if one is provided */
237243
if ((m->userhost[0] != '\0') && (m->nick[0] != '\0')) {
238244
char s[NICKMAX+UHOSTLEN+1];
239245
sprintf(s, "%s!%s", m->nick, m->userhost);
240246
ret = get_user_by_host(s);
241247
if (ret) {
242-
return ret;
248+
goto getuser_done;
243249
}
244250
}
251+
252+
getuser_done:
253+
m->user = ret;
254+
m->tried_getuser = 1;
245255
return NULL;
246256
}
247257

0 commit comments

Comments
 (0)