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

ruby-changes:22412

From: nobu <ko1@a...>
Date: Tue, 7 Feb 2012 19:37:53 +0900 (JST)
Subject: [ruby-changes:22412] nobu:r34461 (trunk): * st.c: refactor packed entries using structs.

nobu	2012-02-07 19:37:40 +0900 (Tue, 07 Feb 2012)

  New Revision: 34461

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

  Log:
    * st.c: refactor packed entries using structs.

  Modified files:
    trunk/ChangeLog
    trunk/st.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 34460)
+++ ChangeLog	(revision 34461)
@@ -1,3 +1,7 @@
+Tue Feb  7 19:37:35 2012  Nobuyoshi Nakada  <nobu@r...>
+
+	* st.c: refactor packed entries using structs.
+
 Tue Feb  7 14:52:10 2012  Nobuyoshi Nakada  <nobu@r...>
 
 	* st.c (st_update): table can be unpacked in the callback.
Index: st.c
===================================================================
--- st.c	(revision 34460)
+++ st.c	(revision 34461)
@@ -25,11 +25,26 @@
     st_table_entry *fore, *back;
 };
 
+typedef struct st_packed_entry {
+    st_data_t key, val;
+} st_packed_entry;
+
+#define STATIC_ASSERT(name, expr) typedef int static_assert_##name##_check[(expr) ? 1 : -1];
+
 #define ST_DEFAULT_MAX_DENSITY 5
 #define ST_DEFAULT_INIT_TABLE_SIZE 11
 #define ST_DEFAULT_SECOND_TABLE_SIZE 19
-#define MAX_PACKED_NUMHASH (ST_DEFAULT_INIT_TABLE_SIZE/2)
+#define ST_DEFAULT_PACKED_TABLE_SIZE ST_DEFAULT_INIT_TABLE_SIZE
+#define PACKED_UNIT (int)(sizeof(st_packed_entry) / sizeof(st_table_entry*))
+#define MAX_PACKED_HASH (int)(ST_DEFAULT_PACKED_TABLE_SIZE * sizeof(st_table_entry*) / sizeof(st_packed_entry))
 
+typedef struct {
+    st_packed_entry kv[MAX_PACKED_HASH];
+} st_packed_bins;
+
+STATIC_ASSERT(st_packed_entry, sizeof(st_packed_entry) == sizeof(st_table_entry*[PACKED_UNIT]))
+STATIC_ASSERT(st_packed_bins, sizeof(st_packed_bins) <= sizeof(st_table_entry*[ST_DEFAULT_PACKED_TABLE_SIZE]))
+
     /*
      * DEFAULT_MAX_DENSITY is the default for the largest we allow the
      * average number of items per bin before increasing the number of
@@ -85,26 +100,27 @@
 static inline st_table_entry**
 st_realloc_bins(st_table_entry **bins, st_index_t newsize, st_index_t oldsize)
 {
-    bins = (st_table_entry **) realloc(bins, newsize * sizeof(st_table_entry *));
-    memset(bins, 0, newsize * sizeof(st_table_entry *));
+    bins = (st_table_entry **)realloc(bins, newsize * sizeof(st_table_entry *));
+    MEMZERO(bins, st_table_entry*, newsize);
     return bins;
 }
 
 /* preparation for possible packing improvements */
-#define PKEY_POS(i, num_bins) ((i)*2)
-#define PVAL_POS(i, num_bins) ((i)*2+1)
-#define PKEY(table, i) (st_data_t)(table)->bins[PKEY_POS(i, (table)->num_bins)]
-#define PVAL(table, i) (st_data_t)(table)->bins[PVAL_POS(i, (table)->num_bins)]
-#define PKEY_SET(table, i, v) do{ (table)->bins[PKEY_POS(i, (table)->num_bins)] = (st_table_entry *)(v); } while(0)
-#define PVAL_SET(table, i, v) do{ (table)->bins[PVAL_POS(i, (table)->num_bins)] = (st_table_entry *)(v); } while(0)
+#define PACKED_BINS(table) (*(st_packed_bins *)(table)->bins)
+#define PACKED_ENT(table, i) PACKED_BINS(table).kv[i]
+#define PKEY(table, i) PACKED_ENT((table), (i)).key
+#define PVAL(table, i) PACKED_ENT((table), (i)).val
+#define PHASH(table, i) PKEY((table), (i))
+#define PKEY_SET(table, i, v) (PKEY((table), (i)) = (v))
+#define PVAL_SET(table, i, v) (PVAL((table), (i)) = (v))
 /* this function depends much on packed layout, so that it placed here */
 static inline void
 remove_packed_entry(st_table *table, st_index_t i)
 {
     table->num_entries--;
     if (i < table->num_entries) {
-	memmove(table->bins + 2*i, table->bins + 2*(i+1),
-		sizeof(st_table_entry *) * 2 * (table->num_entries - i));
+	MEMMOVE(&PACKED_ENT(table, i), &PACKED_ENT(table, i+1),
+		st_packed_entry, table->num_entries - i);
     }
 }
 
@@ -217,7 +233,7 @@
     tbl = st_alloc_table();
     tbl->type = type;
     tbl->num_entries = 0;
-    tbl->entries_packed = type == &type_numhash && size/2 <= MAX_PACKED_NUMHASH;
+    tbl->entries_packed = type == &type_numhash && size/PACKED_UNIT <= MAX_PACKED_HASH;
     tbl->num_bins = size;
     tbl->bins = st_alloc_bins(size);
     tbl->head = 0;
@@ -279,7 +295,7 @@
         return;
     }
 
-    for(i = 0; i < table->num_bins; i++) {
+    for (i = 0; i < table->num_bins; i++) {
 	ptr = table->bins[i];
 	table->bins[i] = 0;
 	while (ptr != 0) {
@@ -387,7 +403,7 @@
 	return 0;
     }
     else {
-	if (value != 0)  *value = ptr->record;
+	if (value != 0) *value = ptr->record;
 	return 1;
     }
 }
@@ -455,14 +471,14 @@
 unpack_entries(register st_table *table)
 {
     st_index_t i;
-    struct st_table_entry *packed_bins[ST_DEFAULT_INIT_TABLE_SIZE];
+    st_packed_bins packed_bins;
     st_table tmp_table = *table;
 
-    memcpy(packed_bins, table->bins, sizeof(st_table_entry *) * ST_DEFAULT_INIT_TABLE_SIZE);
-    table->bins = packed_bins;
+    packed_bins = PACKED_BINS(table);
+    table->bins = (st_table_entry **)&packed_bins;
     tmp_table.entries_packed = 0;
     tmp_table.num_entries = 0;
-    memset(tmp_table.bins, 0, sizeof(struct st_table_entry *) * tmp_table.num_bins);
+    MEMZERO(tmp_table.bins, st_table_entry*, tmp_table.num_bins);
     for (i = 0; i < table->num_entries; i++) {
 	/* packed table should be numhash */
 	st_index_t key = PKEY(table, i), value = PVAL(table, i);
@@ -474,7 +490,7 @@
 static void
 add_packed_direct(st_table *table, st_data_t key, st_data_t value)
 {
-    if (table->num_entries < MAX_PACKED_NUMHASH) {
+    if (table->num_entries < MAX_PACKED_HASH) {
 	st_index_t i = table->num_entries++;
 	PKEY_SET(table, i, key);
 	PVAL_SET(table, i, value);
@@ -606,7 +622,7 @@
     }
 
     if (old_table->entries_packed) {
-        memcpy(new_table->bins, old_table->bins, sizeof(struct st_table_entry *) * old_table->num_bins);
+        MEMCPY(new_table->bins, old_table->bins, st_table_entry*, old_table->num_bins);
         return new_table;
     }
 

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

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