Map the guests to a ruby hash to avoid creating new ruby objects on each call of Guest.each or Guest[].

This commit is contained in:
Tobias Brunner
2010-10-12 15:04:38 +02:00
parent 9b0847dd9a
commit d679266fe1
+35 -41
View 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_find(VALUE class, VALUE key)
{
if (TYPE(key) != T_STRING)
{
key = rb_convert_type(key, T_STRING, "String", "to_s");
}
return rb_hash_aref(guest_hash(class), key);
}
static VALUE guest_get(VALUE class, VALUE key)
{
VALUE guest = guest_find(class, key);
if (NIL_P(guest))
{
rb_raise(rb_eRuntimeError, "guest not found");
}
return guest;
return guest_find(class, key);
}
static VALUE guest_each(int argc, VALUE *argv, VALUE class)
{
linked_list_t *list;
enumerator_t *enumerator;
guest_t *guest;
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)