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:
+35
-41
@@ -120,79 +120,73 @@ static void dumm_init()
|
|||||||
/**
|
/**
|
||||||
* Guest bindings
|
* Guest bindings
|
||||||
*/
|
*/
|
||||||
static VALUE guest_find(VALUE class, VALUE key)
|
static VALUE guest_hash_create(VALUE class)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
guest_t *guest, *found = NULL;
|
guest_t *guest;
|
||||||
|
VALUE hash = rb_hash_new();
|
||||||
if (TYPE(key) == T_SYMBOL)
|
|
||||||
{
|
|
||||||
key = rb_convert_type(key, T_STRING, "String", "to_s");
|
|
||||||
}
|
|
||||||
enumerator = dumm->create_guest_enumerator(dumm);
|
enumerator = dumm->create_guest_enumerator(dumm);
|
||||||
while (enumerator->enumerate(enumerator, &guest))
|
while (enumerator->enumerate(enumerator, &guest))
|
||||||
{
|
{
|
||||||
if (streq(guest->get_name(guest), StringValuePtr(key)))
|
rb_hash_aset(hash, rb_str_new2(guest->get_name(guest)),
|
||||||
{
|
Data_Wrap_Struct(class, NULL, NULL, guest));
|
||||||
found = guest;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
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)
|
static VALUE guest_get(VALUE class, VALUE key)
|
||||||
{
|
{
|
||||||
VALUE guest = guest_find(class, key);
|
return guest_find(class, key);
|
||||||
if (NIL_P(guest))
|
|
||||||
{
|
|
||||||
rb_raise(rb_eRuntimeError, "guest not found");
|
|
||||||
}
|
|
||||||
return guest;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE guest_each(int argc, VALUE *argv, VALUE class)
|
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())
|
if (!rb_block_given_p())
|
||||||
{
|
{
|
||||||
rb_raise(rb_eArgError, "must be called with a block");
|
rb_raise(rb_eArgError, "must be called with a block");
|
||||||
}
|
}
|
||||||
list = linked_list_create();
|
rb_block_call(guest_hash(class), rb_intern("each_value"), 0, 0,
|
||||||
enumerator = dumm->create_guest_enumerator(dumm);
|
rb_yield, 0);
|
||||||
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);
|
|
||||||
return class;
|
return class;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE guest_new(VALUE class, VALUE name, VALUE kernel,
|
static VALUE guest_new(VALUE class, VALUE name, VALUE kernel,
|
||||||
VALUE master, VALUE args)
|
VALUE master, VALUE args)
|
||||||
{
|
{
|
||||||
|
VALUE self;
|
||||||
guest_t *guest;
|
guest_t *guest;
|
||||||
|
guest = dumm->create_guest(dumm, StringValuePtr(name),
|
||||||
guest = dumm->create_guest(dumm, StringValuePtr(name), StringValuePtr(kernel),
|
StringValuePtr(kernel), StringValuePtr(master),
|
||||||
StringValuePtr(master), StringValuePtr(args));
|
StringValuePtr(args));
|
||||||
if (!guest)
|
if (!guest)
|
||||||
{
|
{
|
||||||
rb_raise(rb_eRuntimeError, "creating guest failed");
|
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)
|
static VALUE guest_to_s(VALUE self)
|
||||||
|
|||||||
Reference in New Issue
Block a user