@@ -100,6 +100,11 @@ static void funcp_del(struct hash *hash, struct session *session, void *arg) {
100
100
101
101
struct Arg {time_t now ; int idle_time ;};
102
102
103
+ static void funcp_check_count (struct hash * hash , struct session * session , void * i ) {
104
+ int * i2 = (int * )i ;
105
+ (* i2 )++ ;
106
+ }
107
+
103
108
/* hash record will delete if idle time longer than 300s */
104
109
static void funcp_delete_idle (struct hash * hash , struct session * session , void * arg ) {
105
110
@@ -118,6 +123,11 @@ static void funcp_delete_idle(struct hash *hash, struct session *session, void *
118
123
}
119
124
}
120
125
126
+ void hash_clean (struct hash * hash ) {
127
+ hash_loop (hash , funcp_del , NULL );
128
+ hash_del (hash );
129
+ }
130
+
121
131
void hash_delete_idle (struct hash * hash , time_t now , int idle_time ) {
122
132
struct Arg a ;
123
133
a .now = now ;
@@ -133,6 +143,12 @@ void hash_stat(struct hash* hash) {
133
143
dump (L_OK , "hash stat %u-%u" , hash -> sz , hash -> count );
134
144
}
135
145
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
+
136
152
/* general hash iterator */
137
153
static int hash_loop (struct hash * hash , funcp func , void * arg ) {
138
154
unsigned long i ;
@@ -141,7 +157,6 @@ static int hash_loop(struct hash *hash, funcp func, void *arg) {
141
157
142
158
for (session = hash -> sessions + i ; session && session -> next ;session = session -> next ) {
143
159
if (session -> next ) func (hash , session , arg );
144
-
145
160
}
146
161
}
147
162
return 0 ;
@@ -297,7 +312,7 @@ hash_get_rem(struct hash *hash,
297
312
free (session -> next );
298
313
session -> next = next ;
299
314
300
- hash -> count -- ;
315
+ hash -> count -- ;
301
316
302
317
return 1 ;
303
318
}
@@ -315,46 +330,14 @@ hash_set(struct hash *hash,
315
330
if (hash_set_internal (hash -> sessions , hash -> sz ,
316
331
laddr , raddr , lport , rport , value , sql , cmd , user , db , sqlSaveLen , status ))
317
332
{
318
- hash -> count ++ ;
333
+ hash -> count ++ ;
319
334
return 1 ;
320
335
}
321
336
322
337
return 0 ;
323
338
324
339
}
325
340
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
-
358
341
/* save stmt_id, param_count */
359
342
int
360
343
hash_get_param_count (struct hash * hash ,
@@ -565,6 +548,8 @@ hash_set_internal(struct session *sessions, unsigned long sz,
565
548
566
549
port = hash_fun (laddr , raddr , lport , rport ) % sz ;
567
550
551
+ dump (L_OK , "%lu-%lu-%u-%u" , laddr , raddr , lport , rport );
552
+
568
553
for (session = sessions + port ; session -> next ; session = session -> next ) {
569
554
if (
570
555
session -> next -> raddr == raddr &&
@@ -704,7 +689,8 @@ static int
704
689
hash_load_check (struct hash * hash ) {
705
690
if ((hash -> count * 100 ) / hash -> sz > MAX_LOAD_PERCENT ) {
706
691
struct session * new_sessions , * old_sessions ;
707
- unsigned long nsz , i ;
692
+ unsigned long nsz , i , count ;
693
+ count = hash -> count ;
708
694
709
695
// New container
710
696
nsz = hash_newsz (hash -> sz );
@@ -719,23 +705,26 @@ hash_load_check(struct hash *hash) {
719
705
for (i = 0 ; i < hash -> sz ; i ++ ) {
720
706
struct session * session ;
721
707
722
- for (session = hash -> sessions + i ; session -> next ;
708
+ for (session = hash -> sessions + i ; session && session -> next ;
723
709
session = session -> next )
724
710
{
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
+ }
731
719
}
732
720
}
733
-
721
+ //clear, here will clear count, so need save before
722
+ hash_loop (hash , funcp_del , NULL );
723
+ hash -> count = count ;
734
724
// Switch
735
725
hash -> sz = nsz ;
736
- old_sessions = hash -> sessions ;
726
+ free ( hash -> sessions ) ;
737
727
hash -> sessions = new_sessions ;
738
- free (old_sessions );
739
728
740
729
return 1 ;
741
730
@@ -759,3 +748,29 @@ hash_newsz(unsigned long sz) {
759
748
return sz * 2 + 1 ;
760
749
}
761
750
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
0 commit comments