Last active
March 18, 2016 13:45
-
-
Save bmulvihill/2fcecd605301d311ab5e to your computer and use it in GitHub Desktop.
Practicing Ruby C Extension - Linked List using Memory Pool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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