diff options
author | Tobias Brunner <tobias@strongswan.org> | 2009-09-24 18:39:12 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2010-10-12 15:04:38 +0200 |
commit | d679266fe1babaacfbcff2901a4d031d614f90df (patch) | |
tree | 9678650ca16a3536ebcea67d61d8633bc1a46160 /src/dumm/ext | |
parent | 9b0847dd9a4be17cc667aa7e2cdea14092609053 (diff) | |
download | strongswan-d679266fe1babaacfbcff2901a4d031d614f90df.tar.bz2 strongswan-d679266fe1babaacfbcff2901a4d031d614f90df.tar.xz |
Map the guests to a ruby hash to avoid creating new ruby objects on each call of Guest.each or Guest[].
Diffstat (limited to 'src/dumm/ext')
-rw-r--r-- | src/dumm/ext/dumm.c | 74 |
1 files changed, 34 insertions, 40 deletions
diff --git a/src/dumm/ext/dumm.c b/src/dumm/ext/dumm.c index a970046fe..39162293d 100644 --- a/src/dumm/ext/dumm.c +++ b/src/dumm/ext/dumm.c @@ -120,79 +120,73 @@ static void dumm_init() /** * Guest bindings */ -static VALUE guest_find(VALUE class, VALUE key) +static VALUE guest_hash_create(VALUE class) { enumerator_t *enumerator; - guest_t *guest, *found = NULL; - - if (TYPE(key) == T_SYMBOL) - { - key = rb_convert_type(key, T_STRING, "String", "to_s"); - } + guest_t *guest; + VALUE hash = rb_hash_new(); enumerator = dumm->create_guest_enumerator(dumm); while (enumerator->enumerate(enumerator, &guest)) { - if (streq(guest->get_name(guest), StringValuePtr(key))) - { - found = guest; - break; - } + rb_hash_aset(hash, rb_str_new2(guest->get_name(guest)), + Data_Wrap_Struct(class, NULL, NULL, guest)); } enumerator->destroy(enumerator); - if (!found) + return hash; +} + +static VALUE guest_hash(VALUE class) +{ + ID id = rb_intern("@@guests"); + if (!rb_cvar_defined(class, id)) { - return Qnil; + VALUE hash = guest_hash_create(class); + rb_cvar_set(class, id, hash, 0); + return hash; } - return Data_Wrap_Struct(class, NULL, NULL, found); + return rb_cvar_get(class, id); } -static VALUE guest_get(VALUE class, VALUE key) +static VALUE guest_find(VALUE class, VALUE key) { - VALUE guest = guest_find(class, key); - if (NIL_P(guest)) + if (TYPE(key) != T_STRING) { - rb_raise(rb_eRuntimeError, "guest not found"); + key = rb_convert_type(key, T_STRING, "String", "to_s"); } - return guest; + return rb_hash_aref(guest_hash(class), key); } -static VALUE guest_each(int argc, VALUE *argv, VALUE class) +static VALUE guest_get(VALUE class, VALUE key) { - linked_list_t *list; - enumerator_t *enumerator; - guest_t *guest; + return guest_find(class, key); +} +static VALUE guest_each(int argc, VALUE *argv, VALUE class) +{ if (!rb_block_given_p()) { rb_raise(rb_eArgError, "must be called with a block"); } - list = linked_list_create(); - enumerator = dumm->create_guest_enumerator(dumm); - while (enumerator->enumerate(enumerator, &guest)) - { - list->insert_last(list, guest); - } - enumerator->destroy(enumerator); - while (list->remove_first(list, (void**)&guest) == SUCCESS) - { - rb_yield(Data_Wrap_Struct(class, NULL, NULL, guest)); - } - list->destroy(list); + rb_block_call(guest_hash(class), rb_intern("each_value"), 0, 0, + rb_yield, 0); return class; } static VALUE guest_new(VALUE class, VALUE name, VALUE kernel, VALUE master, VALUE args) { + VALUE self; guest_t *guest; - - guest = dumm->create_guest(dumm, StringValuePtr(name), StringValuePtr(kernel), - StringValuePtr(master), StringValuePtr(args)); + guest = dumm->create_guest(dumm, StringValuePtr(name), + StringValuePtr(kernel), StringValuePtr(master), + StringValuePtr(args)); if (!guest) { rb_raise(rb_eRuntimeError, "creating guest failed"); } - return Data_Wrap_Struct(class, NULL, NULL, guest); + self = Data_Wrap_Struct(class, NULL, NULL, guest); + rb_hash_aset(guest_hash(class), name, self); + return self; } static VALUE guest_to_s(VALUE self) |