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:
parent
cf1a22fdf9
commit
4a43f9203b
2 changed files with 40 additions and 20 deletions
|
@ -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
56
st.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue