aboutsummaryrefslogtreecommitdiffstats
path: root/st.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-02-07 10:37:40 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-02-07 10:37:40 +0000
commit4a43f9203b5a9005108ecc59e01737597072433c (patch)
treefedad17739e5cc76e1e1850885aeb37f77ffe037 /st.c
parentcf1a22fdf914f96126f5a8b671dab9a69db236f8 (diff)
downloadruby-4a43f9203b5a9005108ecc59e01737597072433c.tar.gz
* st.c: refactor packed entries using structs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34461 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'st.c')
-rw-r--r--st.c56
1 files changed, 36 insertions, 20 deletions
diff --git a/st.c b/st.c
index c45338abfd..f40ad33c8c 100644
--- a/st.c
+++ b/st.c
@@ -25,10 +25,25 @@ struct st_table_entry {
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
@@ -85,26 +100,27 @@ static void rehash(st_table *);
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 @@ st_init_table_with_size(const struct st_hash_type *type, st_index_t size)
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 @@ st_clear(st_table *table)
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 @@ st_lookup(st_table *table, register st_data_t key, st_data_t *value)
return 0;
}
else {
- if (value != 0) *value = ptr->record;
+ if (value != 0) *value = ptr->record;
return 1;
}
}
@@ -455,14 +471,14 @@ static void
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 @@ unpack_entries(register st_table *table)
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 @@ st_copy(st_table *old_table)
}
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;
}