]>
jfr.im git - irc/quakenet/newserv.git/blob - channel/chanuserhash.c
4 #include "../server/server.h"
5 #include "../nick/nick.h"
6 #include "../lib/irc_string.h"
7 #include "../irc/irc_config.h"
8 #include "../parser/parser.h"
9 #include "../irc/irc.h"
10 #include "../lib/base64.h"
14 * Make the channel hash a notch larger, to accomodate more users
17 void rehashchannel(channel
*cp
) {
19 chanuserhash
*newhash
;
22 /* Pick a new hash size. If we're not making good use of the current hash,
23 * just increase size slightly, otherwise multiply size by 1.5 */
25 if (cp
->users
->totalusers
*1.6 < cp
->users
->hashsize
) {
26 newhashsize
=cp
->users
->hashsize
+1;
28 newhashsize
= ((int)cp
->users
->hashsize
*1.5);
30 if (newhashsize
<=cp
->users
->hashsize
) {
36 newhash
=newchanuserhash(newhashsize
);
37 for (i
=0;i
<cp
->users
->hashsize
;i
++) {
38 if (cp
->users
->content
[i
]!=nouser
) {
39 if (addnumerictochanuserhash(newhash
,cp
->users
->content
[i
])) {
40 /* It didn't fit. It's clearly not our day :(
41 * Increase the newhashsize by one and hope for a better fit
42 * If you whine about the goto I'll just point out that the
43 * other alternative was exit(1) :) */
45 freechanuserhash(newhash
);
51 /* If we got to here it means we crammed all the old stuff into the new hash */
52 freechanuserhash(cp
->users
);
57 * addnumerictochanuserhash:
58 * Try to fit the given numeric into the channel user hash
60 * Returns 0 if the numeric went in, 1 if not.
63 int addnumerictochanuserhash(chanuserhash
*cuh
, long numeric
) {
66 /* Double hashing scheme; use the next higher bits of the numeric
67 * for the second hash (increment)
69 * TODO: discover if there is a better alternative
70 * to the fixed max search depth value */
72 hash
=(numeric
&CU_NUMERICMASK
);
73 hash2
=(hash
/(cuh
->hashsize
))%(cuh
->hashsize
);
74 hash
=hash
%(cuh
->hashsize
);
80 for(i
=0,j
=hash
;i
<CUHASH_DEPTH
&& (j
!=hash
|| i
==0);i
++,j
=(j
+hash2
)%(cuh
->hashsize
)) {
81 if (cuh
->content
[j
]==nouser
) {
82 cuh
->content
[j
]=numeric
;
88 /* Eeep, we didn't find a space */
92 unsigned long *getnumerichandlefromchanhash(chanuserhash
*cuh
, long numeric
) {
93 int i
, j
, hash
, hash2
;
95 hash
=(numeric
&CU_NUMERICMASK
);
96 hash2
=(hash
/(cuh
->hashsize
))%(cuh
->hashsize
);
97 hash
=hash
%(cuh
->hashsize
);
103 for (i
=0,j
=hash
;i
<CUHASH_DEPTH
&& (j
!=hash
|| i
==0);i
++,j
=(j
+hash2
)%(cuh
->hashsize
)) {
104 if ((cuh
->content
[j
]&CU_NUMERICMASK
)==(numeric
&CU_NUMERICMASK
)) {
105 return &(cuh
->content
[j
]);