Map the guests to a ruby hash to avoid creating new ruby objects on each call of...
authorTobias Brunner <tobias@strongswan.org>
Thu, 24 Sep 2009 16:39:12 +0000 (18:39 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 12 Oct 2010 13:04:38 +0000 (15:04 +0200)
src/dumm/ext/dumm.c

index a970046..3916229 100644 (file)
@@ -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)