Skip to content

Cleanup some st.c and hash.c code #107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from
Closed
Prev Previous commit
Next Next commit
* st.c : Save deleted mark as a bit, so that st_delete_safe could be …
…deleted

Embed logic of safe mode and delete mark inside of st_table, so that Hash
could be simplified and st_delete_safe removed at all.
  • Loading branch information
funny-falcon committed Mar 24, 2012
commit b62632427fad022e8818bb0d7627a06c4e76e6b4
9 changes: 6 additions & 3 deletions ext/-test-/st/numhash/numhash.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,11 @@ static VALUE
numhash_each(VALUE self)
{
st_table *table = DATA_PTR(self);
st_data_t data = (st_data_t)self;
return st_foreach_check(table, numhash_i, data, data) ? Qtrue : Qfalse;
int res;
table->safe_mode = ST_SAFEMODE;
res = st_foreach_check(table, numhash_i, (st_data_t)self);
table->safe_mode = ST_REGULAR;
return res ? Qtrue : Qfalse;
}

static int
Expand Down Expand Up @@ -98,7 +101,7 @@ static VALUE
numhash_delete_safe(VALUE self, VALUE key)
{
st_data_t val, k = (st_data_t)key;
if (st_delete_safe((st_table *)DATA_PTR(self), &k, &val, (st_data_t)self)) {
if (st_delete((st_table *)DATA_PTR(self), &k, &val)) {
return val;
}
return Qnil;
Expand Down
6 changes: 3 additions & 3 deletions ext/tk/tkutil/tkutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ tk_symbolkey2str(self, keys)

if NIL_P(keys) return new_keys;
keys = rb_convert_type(keys, T_HASH, "Hash", "to_hash");
st_foreach_check(RHASH_TBL(keys), to_strkey, new_keys, Qundef);
st_foreach_check(RHASH_TBL(keys), to_strkey, new_keys);
return new_keys;
}

Expand Down Expand Up @@ -674,7 +674,7 @@ hash2kv(hash, ary, self)
volatile VALUE dst = rb_ary_new2(2 * RHASH_SIZE(hash));
volatile VALUE args = rb_ary_new3(2, dst, self);

st_foreach_check(RHASH_TBL(hash), push_kv, args, Qundef);
st_foreach_check(RHASH_TBL(hash), push_kv, args);

if (NIL_P(ary)) {
return dst;
Expand Down Expand Up @@ -718,7 +718,7 @@ hash2kv_enc(hash, ary, self)
volatile VALUE dst = rb_ary_new2(2 * RHASH_SIZE(hash));
volatile VALUE args = rb_ary_new3(2, dst, self);

st_foreach_check(RHASH_TBL(hash), push_kv_enc, args, Qundef);
st_foreach_check(RHASH_TBL(hash), push_kv_enc, args);

if (NIL_P(ary)) {
return dst;
Expand Down
46 changes: 12 additions & 34 deletions hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

static VALUE rb_hash_s_try_convert(VALUE, VALUE);

#define HASH_DELETED FL_USER1
#define HASH_PROC_DEFAULT FL_USER2

VALUE
Expand Down Expand Up @@ -131,7 +130,7 @@ st_foreach_safe(st_table *table, int (*func)(ANYARGS), st_data_t a)
arg.tbl = table;
arg.func = (st_foreach_func *)func;
arg.arg = a;
if (st_foreach_check(table, foreach_safe_i, (st_data_t)&arg, Qundef)) {
if (st_foreach_check(table, foreach_safe_i, (st_data_t)&arg)) {
rb_raise(rb_eRuntimeError, "hash modified during iteration");
}
}
Expand All @@ -156,16 +155,7 @@ hash_foreach_iter(st_data_t key, st_data_t value, st_data_t argp)
if (RHASH(arg->hash)->ntbl != tbl) {
rb_raise(rb_eRuntimeError, "rehash occurred during iteration");
}
switch (status) {
case ST_DELETE:
st_delete_safe(tbl, &key, 0, Qundef);
FL_SET(arg->hash, HASH_DELETED);
case ST_CONTINUE:
break;
case ST_STOP:
return ST_STOP;
}
return ST_CHECK;
return status == ST_CONTINUE ? ST_CHECK : status;
}

static VALUE
Expand All @@ -174,9 +164,11 @@ hash_foreach_ensure(VALUE hash)
RHASH(hash)->iter_lev--;

if (RHASH(hash)->iter_lev == 0) {
if (FL_TEST(hash, HASH_DELETED)) {
st_cleanup_safe(RHASH(hash)->ntbl, Qundef);
FL_UNSET(hash, HASH_DELETED);
if (RHASH(hash)->ntbl->safe_mode == ST_HAS_DELETED) {
st_cleanup_safe(RHASH(hash)->ntbl);
}
else {
RHASH(hash)->ntbl->safe_mode = ST_REGULAR;
}
}
return 0;
Expand All @@ -185,7 +177,7 @@ hash_foreach_ensure(VALUE hash)
static VALUE
hash_foreach_call(struct hash_foreach_arg *arg)
{
if (st_foreach_check(RHASH(arg->hash)->ntbl, hash_foreach_iter, (st_data_t)arg, Qundef)) {
if (st_foreach_check(RHASH(arg->hash)->ntbl, hash_foreach_iter, (st_data_t)arg)) {
rb_raise(rb_eRuntimeError, "hash modified during iteration");
}
return Qnil;
Expand All @@ -199,6 +191,7 @@ rb_hash_foreach(VALUE hash, int (*func)(ANYARGS), VALUE farg)
if (!RHASH(hash)->ntbl)
return;
RHASH(hash)->iter_lev++;
RHASH(hash)->ntbl->safe_mode = ST_SAFEMODE;
arg.hash = hash;
arg.func = (rb_foreach_func *)func;
arg.arg = farg;
Expand Down Expand Up @@ -764,13 +757,7 @@ rb_hash_delete_key(VALUE hash, VALUE key)

if (!RHASH(hash)->ntbl)
return Qundef;
if (RHASH(hash)->iter_lev > 0) {
if (st_delete_safe(RHASH(hash)->ntbl, &ktmp, &val, Qundef)) {
FL_SET(hash, HASH_DELETED);
return (VALUE)val;
}
}
else if (st_delete(RHASH(hash)->ntbl, &ktmp, &val))
if (st_delete(RHASH(hash)->ntbl, &ktmp, &val))
return (VALUE)val;
return Qundef;
}
Expand Down Expand Up @@ -861,7 +848,7 @@ static int
delete_if_i(VALUE key, VALUE value, VALUE hash)
{
if (RTEST(rb_yield_values(2, key, value))) {
rb_hash_delete_key(hash, key);
return ST_DELETE;
}
return ST_CONTINUE;
}
Expand Down Expand Up @@ -1043,12 +1030,6 @@ rb_hash_keep_if(VALUE hash)
return hash;
}

static int
clear_i(VALUE key, VALUE value, VALUE dummy)
{
return ST_DELETE;
}

/*
* call-seq:
* hsh.clear -> hsh
Expand All @@ -1067,10 +1048,7 @@ rb_hash_clear(VALUE hash)
if (!RHASH(hash)->ntbl)
return hash;
if (RHASH(hash)->ntbl->num_entries > 0) {
if (RHASH(hash)->iter_lev > 0)
rb_hash_foreach(hash, clear_i, 0);
else
st_clear(RHASH(hash)->ntbl);
st_clear(RHASH(hash)->ntbl);
}

return hash;
Expand Down
12 changes: 8 additions & 4 deletions include/ruby/st.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,11 @@ struct st_hash_type {

struct st_table {
const struct st_hash_type *type;
st_index_t num_bins;
unsigned int safe_mode : 2;
#ifdef __GNUC__
__extension__
#endif
st_index_t num_bins : ST_INDEX_BITS - 2;
unsigned int entries_packed : 1;
#ifdef __GNUC__
/*
Expand Down Expand Up @@ -106,6 +110,7 @@ struct st_table {
#define st_is_member(table,key) st_lookup((table),(key),(st_data_t *)0)

enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK};
enum st_safe_mode {ST_REGULAR = 0, ST_SAFEMODE, ST_HAS_DELETED = 3};

st_table *st_init_table(const struct st_hash_type *);
st_table *st_init_table_with_size(const struct st_hash_type *, st_index_t);
Expand All @@ -116,18 +121,17 @@ st_table *st_init_strtable_with_size(st_index_t);
st_table *st_init_strcasetable(void);
st_table *st_init_strcasetable_with_size(st_index_t);
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_update(st_table *table, st_data_t key, int (*func)(st_data_t key, st_data_t *value, st_data_t arg), st_data_t arg);
int st_foreach(st_table *, int (*)(ANYARGS), st_data_t);
int st_foreach_check(st_table *, int (*)(ANYARGS), st_data_t, st_data_t);
int st_foreach_check(st_table *, int (*)(ANYARGS), st_data_t);
int st_reverse_foreach(st_table *, int (*)(ANYARGS), st_data_t);
void st_add_direct(st_table *, st_data_t, st_data_t);
void st_free_table(st_table *);
void st_cleanup_safe(st_table *, st_data_t);
void st_cleanup_safe(st_table *);
void st_clear(st_table *);
st_table *st_copy(st_table *);
int st_numcmp(st_data_t, st_data_t);
Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy