mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Hash to preserve order as Ruby1.9 does
This commit is contained in:
+25
-16
@@ -90,8 +90,13 @@ mrb_hash_ht_hash_equal(mrb_state *mrb, mrb_value a, mrb_value b)
|
||||
}
|
||||
}
|
||||
|
||||
KHASH_DECLARE(ht, mrb_value, mrb_value, 1)
|
||||
KHASH_DEFINE (ht, mrb_value, mrb_value, 1, mrb_hash_ht_hash_func, mrb_hash_ht_hash_equal)
|
||||
typedef struct {
|
||||
mrb_value v;
|
||||
mrb_int n;
|
||||
} mrb_hash_value;
|
||||
|
||||
KHASH_DECLARE(ht, mrb_value, mrb_hash_value, 1)
|
||||
KHASH_DEFINE (ht, mrb_value, mrb_hash_value, 1, mrb_hash_ht_hash_func, mrb_hash_ht_hash_equal)
|
||||
|
||||
static void mrb_hash_modify(mrb_state *mrb, mrb_value hash);
|
||||
|
||||
@@ -116,7 +121,7 @@ mrb_gc_mark_hash(mrb_state *mrb, struct RHash *hash)
|
||||
for (k = kh_begin(h); k != kh_end(h); k++) {
|
||||
if (kh_exist(h, k)) {
|
||||
mrb_value key = kh_key(h, k);
|
||||
mrb_value val = kh_value(h, k);
|
||||
mrb_value val = kh_value(h, k).v;
|
||||
|
||||
mrb_gc_mark_value(mrb, key);
|
||||
mrb_gc_mark_value(mrb, val);
|
||||
@@ -167,7 +172,7 @@ mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key)
|
||||
if (h) {
|
||||
k = kh_get(ht, mrb, h, key);
|
||||
if (k != kh_end(h))
|
||||
return kh_value(h, k);
|
||||
return kh_value(h, k).v;
|
||||
}
|
||||
|
||||
/* not found */
|
||||
@@ -186,7 +191,7 @@ mrb_hash_fetch(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value def)
|
||||
if (h) {
|
||||
k = kh_get(ht, mrb, h, key);
|
||||
if (k != kh_end(h))
|
||||
return kh_value(h, k);
|
||||
return kh_value(h, k).v;
|
||||
}
|
||||
|
||||
/* not found */
|
||||
@@ -209,9 +214,10 @@ mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val)
|
||||
int ai = mrb_gc_arena_save(mrb);
|
||||
k = kh_put(ht, mrb, h, KEY(key));
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
kh_value(h, k).n = kh_size(h)-1;
|
||||
}
|
||||
|
||||
kh_value(h, k) = val;
|
||||
kh_value(h, k).v = val;
|
||||
mrb_write_barrier(mrb, (struct RBasic*)RHASH(hash));
|
||||
return;
|
||||
}
|
||||
@@ -495,7 +501,7 @@ mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key)
|
||||
if (h) {
|
||||
k = kh_get(ht, mrb, h, key);
|
||||
if (k != kh_end(h)) {
|
||||
delVal = kh_value(h, k);
|
||||
delVal = kh_value(h, k).v;
|
||||
kh_del(ht, mrb, h, k);
|
||||
return delVal;
|
||||
}
|
||||
@@ -657,7 +663,7 @@ mrb_hash_replace(mrb_state *mrb, mrb_value hash)
|
||||
if (h2) {
|
||||
for (k = kh_begin(h2); k != kh_end(h2); k++) {
|
||||
if (kh_exist(h2, k))
|
||||
mrb_hash_set(mrb, hash, kh_key(h2, k), kh_value(h2, k));
|
||||
mrb_hash_set(mrb, hash, kh_key(h2, k), kh_value(h2, k).v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -738,7 +744,7 @@ inspect_hash(mrb_state *mrb, mrb_value hash, int recur)
|
||||
str2 = mrb_inspect(mrb, kh_key(h,k));
|
||||
mrb_str_append(mrb, str, str2);
|
||||
mrb_str_cat_lit(mrb, str, "=>");
|
||||
str2 = mrb_inspect(mrb, kh_value(h,k));
|
||||
str2 = mrb_inspect(mrb, kh_value(h,k).v);
|
||||
mrb_str_append(mrb, str, str2);
|
||||
|
||||
mrb_gc_arena_restore(mrb, ai);
|
||||
@@ -809,8 +815,10 @@ mrb_hash_keys(mrb_state *mrb, mrb_value hash)
|
||||
ary = mrb_ary_new_capa(mrb, kh_size(h));
|
||||
for (k = kh_begin(h); k != kh_end(h); k++) {
|
||||
if (kh_exist(h, k)) {
|
||||
mrb_value v = kh_key(h,k);
|
||||
mrb_ary_push(mrb, ary, v);
|
||||
mrb_value kv = kh_key(h,k);
|
||||
mrb_hash_value hv = kh_value(h,k);
|
||||
|
||||
mrb_ary_set(mrb, ary, hv.n, kv);
|
||||
}
|
||||
}
|
||||
return ary;
|
||||
@@ -840,8 +848,9 @@ mrb_hash_values(mrb_state *mrb, mrb_value hash)
|
||||
ary = mrb_ary_new_capa(mrb, kh_size(h));
|
||||
for (k = kh_begin(h); k != kh_end(h); k++) {
|
||||
if (kh_exist(h, k)){
|
||||
mrb_value v = kh_value(h,k);
|
||||
mrb_ary_push(mrb, ary, v);
|
||||
mrb_hash_value hv = kh_value(h,k);
|
||||
|
||||
mrb_ary_set(mrb, ary, hv.n, hv.v);
|
||||
}
|
||||
}
|
||||
return ary;
|
||||
@@ -898,7 +907,7 @@ mrb_hash_has_valueWithvalue(mrb_state *mrb, mrb_value hash, mrb_value value)
|
||||
for (k = kh_begin(h); k != kh_end(h); k++) {
|
||||
if (!kh_exist(h, k)) continue;
|
||||
|
||||
if (mrb_equal(mrb, kh_value(h,k), value)) {
|
||||
if (mrb_equal(mrb, kh_value(h,k).v, value)) {
|
||||
return mrb_true_value();
|
||||
}
|
||||
}
|
||||
@@ -969,9 +978,9 @@ hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, mrb_bool eql)
|
||||
k2 = kh_get(ht, mrb, h2, key);
|
||||
if (k2 != kh_end(h2)) {
|
||||
if (eql)
|
||||
eq = mrb_eql(mrb, kh_value(h1,k1), kh_value(h2,k2));
|
||||
eq = mrb_eql(mrb, kh_value(h1,k1).v, kh_value(h2,k2).v);
|
||||
else
|
||||
eq = mrb_equal(mrb, kh_value(h1,k1), kh_value(h2,k2));
|
||||
eq = mrb_equal(mrb, kh_value(h1,k1).v, kh_value(h2,k2).v);
|
||||
if (eq) {
|
||||
continue; /* next key */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user