1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* st.c: refactor packed entries using structs.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34461 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2012-02-07 10:37:40 +00:00
parent cf1a22fdf9
commit 4a43f9203b
2 changed files with 40 additions and 20 deletions

View file

@ -1,3 +1,7 @@
Tue Feb 7 19:37:35 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* st.c: refactor packed entries using structs.
Tue Feb 7 14:52:10 2012 Nobuyoshi Nakada <nobu@ruby-lang.org> Tue Feb 7 14:52:10 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* st.c (st_update): table can be unpacked in the callback. * st.c (st_update): table can be unpacked in the callback.

56
st.c
View file

@ -25,10 +25,25 @@ struct st_table_entry {
st_table_entry *fore, *back; 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_MAX_DENSITY 5
#define ST_DEFAULT_INIT_TABLE_SIZE 11 #define ST_DEFAULT_INIT_TABLE_SIZE 11
#define ST_DEFAULT_SECOND_TABLE_SIZE 19 #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 * 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** static inline st_table_entry**
st_realloc_bins(st_table_entry **bins, st_index_t newsize, st_index_t oldsize) 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 *)); bins = (st_table_entry **)realloc(bins, newsize * sizeof(st_table_entry *));
memset(bins, 0, newsize * sizeof(st_table_entry *)); MEMZERO(bins, st_table_entry*, newsize);
return bins; return bins;
} }
/* preparation for possible packing improvements */ /* preparation for possible packing improvements */
#define PKEY_POS(i, num_bins) ((i)*2) #define PACKED_BINS(table) (*(st_packed_bins *)(table)->bins)
#define PVAL_POS(i, num_bins) ((i)*2+1) #define PACKED_ENT(table, i) PACKED_BINS(table).kv[i]
#define PKEY(table, i) (st_data_t)(table)->bins[PKEY_POS(i, (table)->num_bins)] #define PKEY(table, i) PACKED_ENT((table), (i)).key
#define PVAL(table, i) (st_data_t)(table)->bins[PVAL_POS(i, (table)->num_bins)] #define PVAL(table, i) PACKED_ENT((table), (i)).val
#define PKEY_SET(table, i, v) do{ (table)->bins[PKEY_POS(i, (table)->num_bins)] = (st_table_entry *)(v); } while(0) #define PHASH(table, i) PKEY((table), (i))
#define PVAL_SET(table, i, v) do{ (table)->bins[PVAL_POS(i, (table)->num_bins)] = (st_table_entry *)(v); } while(0) #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 */ /* this function depends much on packed layout, so that it placed here */
static inline void static inline void
remove_packed_entry(st_table *table, st_index_t i) remove_packed_entry(st_table *table, st_index_t i)
{ {
table->num_entries--; table->num_entries--;
if (i < table->num_entries) { if (i < table->num_entries) {
memmove(table->bins + 2*i, table->bins + 2*(i+1), MEMMOVE(&PACKED_ENT(table, i), &PACKED_ENT(table, i+1),
sizeof(st_table_entry *) * 2 * (table->num_entries - i)); 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 = st_alloc_table();
tbl->type = type; tbl->type = type;
tbl->num_entries = 0; 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->num_bins = size;
tbl->bins = st_alloc_bins(size); tbl->bins = st_alloc_bins(size);
tbl->head = 0; tbl->head = 0;
@ -279,7 +295,7 @@ st_clear(st_table *table)
return; return;
} }
for(i = 0; i < table->num_bins; i++) { for (i = 0; i < table->num_bins; i++) {
ptr = table->bins[i]; ptr = table->bins[i];
table->bins[i] = 0; table->bins[i] = 0;
while (ptr != 0) { while (ptr != 0) {
@ -387,7 +403,7 @@ st_lookup(st_table *table, register st_data_t key, st_data_t *value)
return 0; return 0;
} }
else { else {
if (value != 0) *value = ptr->record; if (value != 0) *value = ptr->record;
return 1; return 1;
} }
} }
@ -455,14 +471,14 @@ static void
unpack_entries(register st_table *table) unpack_entries(register st_table *table)
{ {
st_index_t i; 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; st_table tmp_table = *table;
memcpy(packed_bins, table->bins, sizeof(st_table_entry *) * ST_DEFAULT_INIT_TABLE_SIZE); packed_bins = PACKED_BINS(table);
table->bins = packed_bins; table->bins = (st_table_entry **)&packed_bins;
tmp_table.entries_packed = 0; tmp_table.entries_packed = 0;
tmp_table.num_entries = 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++) { for (i = 0; i < table->num_entries; i++) {
/* packed table should be numhash */ /* packed table should be numhash */
st_index_t key = PKEY(table, i), value = PVAL(table, i); st_index_t key = PKEY(table, i), value = PVAL(table, i);
@ -474,7 +490,7 @@ unpack_entries(register st_table *table)
static void static void
add_packed_direct(st_table *table, st_data_t key, st_data_t value) 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++; st_index_t i = table->num_entries++;
PKEY_SET(table, i, key); PKEY_SET(table, i, key);
PVAL_SET(table, i, value); PVAL_SET(table, i, value);
@ -606,7 +622,7 @@ st_copy(st_table *old_table)
} }
if (old_table->entries_packed) { 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; return new_table;
} }