Skip to content

Commit b443c6c

Browse files
committed
hash_load_check bug
1 parent 4d82ff5 commit b443c6c

File tree

2 files changed

+62
-47
lines changed

2 files changed

+62
-47
lines changed

hash.c

Lines changed: 61 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ static void funcp_del(struct hash *hash, struct session *session, void *arg) {
100100

101101
struct Arg {time_t now; int idle_time;};
102102

103+
static void funcp_check_count(struct hash *hash, struct session *session, void *i) {
104+
int *i2 = (int*)i;
105+
(*i2)++;
106+
}
107+
103108
/* hash record will delete if idle time longer than 300s */
104109
static void funcp_delete_idle(struct hash *hash, struct session *session, void *arg) {
105110

@@ -118,6 +123,11 @@ static void funcp_delete_idle(struct hash *hash, struct session *session, void *
118123
}
119124
}
120125

126+
void hash_clean(struct hash* hash) {
127+
hash_loop(hash, funcp_del, NULL);
128+
hash_del(hash);
129+
}
130+
121131
void hash_delete_idle(struct hash* hash, time_t now, int idle_time) {
122132
struct Arg a ;
123133
a.now = now;
@@ -133,6 +143,12 @@ void hash_stat(struct hash* hash) {
133143
dump(L_OK, "hash stat %u-%u", hash->sz, hash->count);
134144
}
135145

146+
void hash_check_count(struct hash* hash) {
147+
int i = 0;
148+
hash_loop(hash, funcp_check_count, (void*)&i);
149+
ASSERT(hash->count == i);
150+
}
151+
136152
/* general hash iterator */
137153
static int hash_loop(struct hash *hash, funcp func, void *arg) {
138154
unsigned long i;
@@ -141,7 +157,6 @@ static int hash_loop(struct hash *hash, funcp func, void *arg) {
141157

142158
for (session = hash->sessions + i; session && session->next;session = session->next) {
143159
if (session->next) func(hash, session, arg);
144-
145160
}
146161
}
147162
return 0;
@@ -297,7 +312,7 @@ hash_get_rem(struct hash *hash,
297312
free(session->next);
298313
session->next = next;
299314

300-
hash->count --;
315+
hash->count--;
301316

302317
return 1;
303318
}
@@ -315,46 +330,14 @@ hash_set(struct hash *hash,
315330
if (hash_set_internal(hash->sessions, hash->sz,
316331
laddr, raddr, lport, rport, value, sql, cmd, user, db, sqlSaveLen, status))
317332
{
318-
hash->count ++;
333+
hash->count++;
319334
return 1;
320335
}
321336

322337
return 0;
323338

324339
}
325340

326-
int
327-
hash_clean(struct hash *hash, unsigned long min) {
328-
unsigned long i;
329-
330-
for (i = 0; i < hash->sz; i ++) {
331-
struct session *session;
332-
333-
for (session = hash->sessions + i; session->next; session = session->next)
334-
if (session->next->tv.tv_sec * 1000000 + session->next->tv.tv_usec <
335-
min)
336-
{
337-
struct session *next;
338-
339-
next = session->next->next;
340-
free(session->next);
341-
session->next = next;
342-
343-
hash->count --;
344-
345-
// This break is to prevent a segmentation fault when
346-
// session->next is NULL (session will be null next)
347-
if (!session->next)
348-
break;
349-
350-
}
351-
352-
}
353-
354-
return 0;
355-
356-
}
357-
358341
/* save stmt_id, param_count */
359342
int
360343
hash_get_param_count(struct hash *hash,
@@ -565,6 +548,8 @@ hash_set_internal(struct session *sessions, unsigned long sz,
565548

566549
port = hash_fun(laddr, raddr, lport, rport) % sz;
567550

551+
dump(L_OK, "%lu-%lu-%u-%u", laddr, raddr, lport, rport);
552+
568553
for (session = sessions + port; session->next; session = session->next) {
569554
if (
570555
session->next->raddr == raddr &&
@@ -704,7 +689,8 @@ static int
704689
hash_load_check(struct hash *hash) {
705690
if ((hash->count * 100) / hash->sz > MAX_LOAD_PERCENT) {
706691
struct session *new_sessions, *old_sessions;
707-
unsigned long nsz, i;
692+
unsigned long nsz, i, count;
693+
count = hash->count;
708694

709695
// New container
710696
nsz = hash_newsz(hash->sz);
@@ -719,23 +705,26 @@ hash_load_check(struct hash *hash) {
719705
for (i = 0; i < hash->sz; i ++) {
720706
struct session *session;
721707

722-
for (session = hash->sessions + i; session->next;
708+
for (session = hash->sessions + i; session && session->next;
723709
session = session->next)
724710
{
725-
726-
hash_set_internal(new_sessions, nsz, session->laddr,
727-
session->raddr, session->lport, session->rport,
728-
session->tv, session->sql, session->cmd, session->user, session->db,
729-
session->sqlSaveLen ,session->status);
730-
711+
if(session->next) {
712+
/* TODO not only this field */
713+
hash_set_internal(new_sessions, nsz, session->next->laddr,
714+
session->next->raddr, session->next->lport, session->next->rport,
715+
session->next->tv, session->next->sql, session->next->cmd,
716+
session->next->user, session->next->db,
717+
session->next->sqlSaveLen ,session->next->status);
718+
}
731719
}
732720
}
733-
721+
//clear, here will clear count, so need save before
722+
hash_loop(hash, funcp_del, NULL);
723+
hash->count = count;
734724
// Switch
735725
hash->sz = nsz;
736-
old_sessions = hash->sessions;
726+
free(hash->sessions);
737727
hash->sessions = new_sessions;
738-
free(old_sessions);
739728

740729
return 1;
741730

@@ -759,3 +748,29 @@ hash_newsz(unsigned long sz) {
759748
return sz * 2 + 1;
760749
}
761750

751+
752+
#ifdef _HASH_TEST_
753+
754+
int main() {
755+
756+
log_init("/tmp/hash", NULL, ".log", L_OK);
757+
struct hash *h = hash_new();
758+
int i;
759+
struct timeval t;
760+
761+
for(i = 0 ;i < 20000; i++) {
762+
hash_set(h, 1, 1,
763+
i, i, t, NULL, 0, NULL, NULL, 0, 0);
764+
hash_check_count(h);
765+
766+
if (i % 100 == 0)
767+
hash_get_rem(h, 1, 1, i, i);
768+
}
769+
770+
hash_check_count(h);
771+
printf("ok - %lu %lu\n", h->count, h->sz);
772+
hash_clean(h);
773+
return 0;
774+
}
775+
776+
#endif

hash.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ int hash_set_sql_len(struct hash *hash,
6161
uint32_t laddr, uint32_t raddr, uint16_t lport, uint16_t rport,
6262
uint32_t sqlSaveLen, int status);
6363

64-
int hash_clean(struct hash *hash, unsigned long min);
64+
void hash_clean(struct hash *hash);
6565

6666
void hash_delete_idle(struct hash* hash, time_t now, int idle_time);
6767

0 commit comments

Comments
 (0)