Skip to content

Instantly share code, notes, and snippets.

@bmulvihill
Last active March 18, 2016 13:45
Show Gist options
  • Save bmulvihill/2fcecd605301d311ab5e to your computer and use it in GitHub Desktop.
Save bmulvihill/2fcecd605301d311ab5e to your computer and use it in GitHub Desktop.
Practicing Ruby C Extension - Linked List using Memory Pool
#include "ruby.h"
static VALUE cLinkedList;
typedef struct rb_node {
VALUE data;
struct rb_node *next;
} Node;
typedef struct rb_linked_list {
int p_top;
Node pool[10000];
Node *head;
Node *tail;
} LinkedList;
VALUE linked_list_alloc(VALUE rb_self)
{
LinkedList *list = ALLOC(LinkedList);
list->p_top = 0;
memset(list->pool, 0, sizeof(list->pool));
list->head = NULL;
list->tail = NULL;
return Data_Wrap_Struct(cLinkedList,0,free,list);
}
static
Node * create_node(LinkedList *list, VALUE val)
{
if(list->p_top == sizeof(list->pool)/sizeof(Node)) {
//list->pool = realloc(list->pool, 1000 * sizeof(Node));
//if(list->pool == NULL)
rb_raise(rb_eStandardError, "Allocation Error! %lu", sizeof(list->pool)/sizeof(Node));
}
Node *new = &list->pool[list->p_top++];
new->next = NULL;
new->data = val;
return new;
}
static
VALUE rb_linked_list_add(VALUE rb_self, VALUE val)
{
LinkedList *list;
Data_Get_Struct(rb_self, LinkedList, list);
Node *new = create_node(list, val);
if(list->head == NULL) {
list->head = list->tail = new;
} else {
list->tail = list->tail->next = new;
}
return rb_self;
}
static
VALUE rb_linked_list_head(VALUE rb_self)
{
LinkedList *list;
Node *n;
Data_Get_Struct(rb_self, LinkedList, list);
if(list->head == NULL)
return Qnil;
return (VALUE)list->head->data;
}
static
VALUE rb_linked_list_tail(VALUE rb_self)
{
LinkedList *list;
Node *n;
Data_Get_Struct(rb_self, LinkedList, list);
if(list->tail == NULL)
return Qnil;
return (VALUE)list->tail->data;
}
static
VALUE rb_linked_list_each(VALUE rb_self)
{
LinkedList *list;
Data_Get_Struct(rb_self, LinkedList, list);
Node *ptr = list->head;
while(ptr != NULL){
rb_yield(ptr->data);
ptr = ptr->next;
}
return rb_self;
}
void Init_linked_list()
{
cLinkedList = rb_define_class("LinkedList", rb_cObject);
rb_define_alloc_func(cLinkedList, linked_list_alloc);
rb_define_method(cLinkedList, "add", rb_linked_list_add, 1);
rb_define_method(cLinkedList, "head", rb_linked_list_head, 0);
rb_define_method(cLinkedList, "tail", rb_linked_list_tail, 0);
rb_define_method(cLinkedList, "each", rb_linked_list_each, 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment