diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-05-27 15:56:14 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-05-27 15:56:14 +0000 |
commit | 844a6890c6fb00a311af6c27bcac482c2086cc3a (patch) | |
tree | 9a350ac63f9d16c4e11c7e4cf1d4bdb2d190939d /st.c | |
parent | 51bf0388aa1b9cf86af556104917a6a544152cf8 (diff) | |
download | ruby-844a6890c6fb00a311af6c27bcac482c2086cc3a.tar.gz |
* st.c (st_insert2): new function with processing new key,
e.g. copy.
* hash.c (rb_hash_aset): use st_insert2() to reduce redundant
st_lookup calls.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23594 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'st.c')
-rw-r--r-- | st.c | 40 |
1 files changed, 40 insertions, 0 deletions
@@ -416,6 +416,46 @@ st_insert(register st_table *table, register st_data_t key, st_data_t value) } } +int +st_insert2(register st_table *table, register st_data_t key, st_data_t value, + st_data_t (*func)(st_data_t)) +{ + unsigned int hash_val, bin_pos; + register st_table_entry *ptr; + + if (table->entries_packed) { + st_index_t i; + for (i = 0; i < table->num_entries; i++) { + if ((st_data_t)table->bins[i*2] == key) { + table->bins[i*2+1] = (struct st_table_entry*)value; + return 1; + } + } + if ((table->num_entries+1) * 2 <= table->num_bins && table->num_entries+1 <= MAX_PACKED_NUMHASH) { + i = table->num_entries++; + table->bins[i*2] = (struct st_table_entry*)key; + table->bins[i*2+1] = (struct st_table_entry*)value; + return 0; + } + else { + unpack_entries(table); + } + } + + hash_val = do_hash(key, table); + FIND_ENTRY(table, ptr, hash_val, bin_pos); + + if (ptr == 0) { + key = (*func)(key); + ADD_DIRECT(table, key, value, hash_val, bin_pos); + return 0; + } + else { + ptr->record = value; + return 1; + } +} + void st_add_direct(st_table *table, st_data_t key, st_data_t value) { |