summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--hash.c5
-rw-r--r--include/ruby/st.h1
-rw-r--r--st.c40
4 files changed, 51 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 4a0a9dff2c..eb831b1fb9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,14 @@ Wed May 27 23:00:38 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
* parse.y (struct parser_params): lex_gets_ptr should be long.
+Wed May 27 14:08:39 2009 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * 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.
+
Wed May 27 02:31:38 2009 NARUSE, Yui <naruse@ruby-lang.org>
* ext/readline/readline.c (readline_getc): the function for
diff --git a/hash.c b/hash.c
index 5405410fd1..e80051e737 100644
--- a/hash.c
+++ b/hash.c
@@ -1015,12 +1015,11 @@ VALUE
rb_hash_aset(VALUE hash, VALUE key, VALUE val)
{
rb_hash_modify(hash);
- if (RHASH(hash)->ntbl->type == &identhash ||
- rb_obj_class(key) != rb_cString || st_lookup(RHASH(hash)->ntbl, key, 0)) {
+ if (RHASH(hash)->ntbl->type == &identhash || rb_obj_class(key) != rb_cString) {
st_insert(RHASH(hash)->ntbl, key, val);
}
else {
- st_add_direct(RHASH(hash)->ntbl, rb_str_new4(key), val);
+ st_insert2(RHASH(hash)->ntbl, key, val, rb_str_new4);
}
return val;
}
diff --git a/include/ruby/st.h b/include/ruby/st.h
index 73216ba45c..0c80d3a225 100644
--- a/include/ruby/st.h
+++ b/include/ruby/st.h
@@ -93,6 +93,7 @@ st_table *st_init_strcasetable_with_size(int);
int st_delete(st_table *, st_data_t *, st_data_t *); /* returns 0:notfound 1:deleted */
int st_delete_safe(st_table *, st_data_t *, st_data_t *, st_data_t);
int st_insert(st_table *, st_data_t, st_data_t);
+int st_insert2(st_table *, st_data_t, st_data_t, st_data_t (*)(st_data_t));
int st_lookup(st_table *, st_data_t, st_data_t *);
int st_get_key(st_table *, st_data_t, st_data_t *);
int st_foreach(st_table *, int (*)(ANYARGS), st_data_t);
diff --git a/st.c b/st.c
index 1401ba0180..5fa7e24f53 100644
--- a/st.c
+++ b/st.c
@@ -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)
{