[前][次][番号順一覧][スレッド一覧]

ruby-changes:13338

From: nobu <ko1@a...>
Date: Sat, 26 Sep 2009 17:53:32 +0900 (JST)
Subject: [ruby-changes:13338] Ruby:r25102 (trunk): * st.c (COLLISION): improved collision log feature.

nobu	2009-09-26 17:53:15 +0900 (Sat, 26 Sep 2009)

  New Revision: 25102

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=25102

  Log:
    * st.c (COLLISION): improved collision log feature.

  Modified files:
    trunk/ChangeLog
    trunk/st.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 25101)
+++ ChangeLog	(revision 25102)
@@ -1,5 +1,7 @@
-Sat Sep 26 16:48:32 2009  Nobuyoshi Nakada  <nobu@r...>
+Sat Sep 26 17:53:13 2009  Nobuyoshi Nakada  <nobu@r...>
 
+	* st.c (COLLISION): improved collision log feature.
+
 	* string.c (hash): updated to MurmurHash 2.0 2009-09-19.
 
 	* string.c (rb_hash_start): fixed shift width on 128bit platform.
Index: st.c
===================================================================
--- st.c	(revision 25101)
+++ st.c	(revision 25102)
@@ -71,6 +71,7 @@
 
 #define EQUAL(table,x,y) ((x)==(y) || (*table->type->compare)((x),(y)) == 0)
 
+/* remove cast to unsigned int in the future */
 #define do_hash(key,table) (unsigned int)(st_index_t)(*(table)->type->hash)((key))
 #define do_hash_bin(key,table) (do_hash(key, table)%(table)->num_bins)
 
@@ -140,19 +141,27 @@
 }
 
 #ifdef HASH_LOG
-static int collision = 0;
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+static struct {
+    int all, total, num, str, strcase;
+}  collision;
 static int init_st = 0;
 
 static void
 stat_col(void)
 {
-    FILE *f = fopen("/tmp/col", "w");
-    fprintf(f, "collision: %d\n", collision);
+    char fname[10+sizeof(long)*3];
+    FILE *f = fopen((snprintf(fname, sizeof(fname), "/tmp/col%ld", (long)getpid()), fname), "w");
+    fprintf(f, "collision: %d / %d (%6.2f)\n", collision.all, collision.total,
+	    ((double)collision.all / (collision.total)) * 100);
+    fprintf(f, "num: %d, str: %d, strcase: %d\n", collision.num, collision.str, collision.strcase);
     fclose(f);
 }
 #endif
 
-#define MAX_PACKED_NUMHASH ((st_index_t)5)
+#define MAX_PACKED_NUMHASH (ST_DEFAULT_INIT_TABLE_SIZE/2)
 
 st_table*
 st_init_table_with_size(const struct st_hash_type *type, st_index_t size)
@@ -160,6 +169,12 @@
     st_table *tbl;
 
 #ifdef HASH_LOG
+# if HASH_LOG+0 < 0
+    {
+	const char *e = getenv("ST_HASH_LOG");
+	if (!e || !*e) init_st = 1;
+    }
+# endif
     if (init_st == 0) {
 	init_st = 1;
 	atexit(stat_col);
@@ -270,14 +285,31 @@
 ((ptr) != 0 && (ptr->hash != (hash_val) || !EQUAL((table), (key), (ptr)->key)))
 
 #ifdef HASH_LOG
-#define COLLISION collision++
+static void
+count_collision(const struct st_hash_type *type)
+{
+    collision.all++;
+    if (type == &type_numhash) {
+	collision.num++;
+    }
+    else if (type == &type_strhash) {
+	collision.strcase++;
+    }
+    else if (type == &type_strcasehash) {
+	collision.str++;
+    }
+}
+#define COLLISION (collision_check ? count_collision(table->type) : (void)0)
+#define FOUND_ENTRY (collision_check ? collision.total++ : (void)0)
 #else
 #define COLLISION
+#define FOUND_ENTRY
 #endif
 
 #define FIND_ENTRY(table, ptr, hash_val, bin_pos) do {\
     bin_pos = hash_val%(table)->num_bins;\
     ptr = (table)->bins[bin_pos];\
+    FOUND_ENTRY;\
     if (PTR_NOT_EQUAL(table, ptr, hash_val, key)) {\
 	COLLISION;\
 	while (PTR_NOT_EQUAL(table, ptr->next, hash_val, key)) {\
@@ -287,6 +319,8 @@
     }\
 } while (0)
 
+#define collision_check 0
+
 int
 st_lookup(st_table *table, register st_data_t key, st_data_t *value)
 {
@@ -345,10 +379,17 @@
     }
 }
 
+#undef collision_check
+#define collision_check 1
+
+#define MORE_PACKABLE_P(table) \
+    ((st_index_t)((table)->num_entries+1) * 2 <= (table)->num_bins && \
+     (table)->num_entries+1 <= MAX_PACKED_NUMHASH)
+
 #define ADD_DIRECT(table, key, value, hash_val, bin_pos)\
 do {\
     st_table_entry *entry;\
-    if (table->num_entries/(table->num_bins) > ST_DEFAULT_MAX_DENSITY) {\
+    if (table->num_entries > ST_DEFAULT_MAX_DENSITY * table->num_bins) {\
 	rehash(table);\
         bin_pos = hash_val % table->num_bins;\
     }\
@@ -402,7 +443,7 @@
                 return 1;
             }
         }
-        if ((table->num_entries+1) * 2 <= table->num_bins && table->num_entries+1 <= MAX_PACKED_NUMHASH) {
+        if (MORE_PACKABLE_P(table)) {
             i = table->num_entries++;
             table->bins[i*2] = (struct st_table_entry*)key;
             table->bins[i*2+1] = (struct st_table_entry*)value;
@@ -441,7 +482,7 @@
                 return 1;
             }
         }
-        if ((table->num_entries+1) * 2 <= table->num_bins && table->num_entries+1 <= MAX_PACKED_NUMHASH) {
+        if (MORE_PACKABLE_P(table)) {
             i = table->num_entries++;
             table->bins[i*2] = (struct st_table_entry*)key;
             table->bins[i*2+1] = (struct st_table_entry*)value;
@@ -473,7 +514,7 @@
 
     if (table->entries_packed) {
         int i;
-        if ((table->num_entries+1) * 2 <= table->num_bins && table->num_entries+1 <= MAX_PACKED_NUMHASH) {
+        if (MORE_PACKABLE_P(table)) {
             i = table->num_entries++;
             table->bins[i*2] = (struct st_table_entry*)key;
             table->bins[i*2+1] = (struct st_table_entry*)value;

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]