Add min heap #48

Closed
wants to merge 7 commits into
from

Conversation

Projects
None yet
2 participants
Contributor

sprsquish commented Dec 7, 2012

No description provided.

@bitbckt bitbckt commented on an outdated diff Dec 7, 2012

ext/thrift_client/min_heap.c
+#include <stdlib.h>
+#include <stdio.h>
+
+#define THRESHOLD 100
+
+#define is_available(heap, node) ( \
+ (heap->is_available == Qnil) || \
+ (rb_funcall(heap->is_available, id_call, 1, node->obj) == Qtrue) \
+)
+
+#define MAX(a, b) ((a) < (b) ? (b) : (a))
+
+static ID id_call;
+static ID id_inspect;
+
+typedef struct node {
@bitbckt

bitbckt Dec 7, 2012

Contributor

Naming the struct is unnecessary if you're immediately typedef'ing it.

@bitbckt bitbckt commented on an outdated diff Dec 7, 2012

ext/thrift_client/min_heap.c
+static ID id_inspect;
+
+typedef struct node {
+ VALUE obj;
+ int index;
+ double load;
+ long int samples;
+ int weight;
+} node_t;
+
+typedef struct heap {
+ int size;
+ VALUE is_available;
+ int cur_index;
+ node_t *nodes;
+} heap_t;
@bitbckt

bitbckt Dec 7, 2012

Contributor

Use minheap_t; heap_t will collide with some other things happening in certain Ruby runtimes. ;-)

@bitbckt bitbckt commented on the diff Dec 7, 2012

ext/thrift_client/min_heap.c
+ int cur_index;
+ node_t *nodes;
+} heap_t;
+
+static void _fix_down(heap_t *, int, int);
+static node_t *_get(heap_t *, int);
+
+static void *
+zalloc(size_t size)
+{
+ void *p;
+
+ p = malloc(size);
+
+ if (p != NULL) {
+ memset(p, 0, size);
@bitbckt

bitbckt Dec 7, 2012

Contributor

No string.h for memset?

@bitbckt bitbckt commented on an outdated diff Dec 7, 2012

ext/thrift_client/min_heap.c
+
+ if (p != NULL) {
+ memset(p, 0, size);
+ }
+
+ return p;
+}
+
+static int
+compare(heap_t *heap, node_t *i, node_t *j)
+{
+ int i_avail = is_available(heap, i);
+ int j_avail = is_available(heap, j);
+
+ if (i_avail && !j_avail)
+ return 1;
@bitbckt

bitbckt Dec 7, 2012

Contributor

Include stdbool and use bools. You're in C99.

@bitbckt bitbckt commented on an outdated diff Dec 7, 2012

test/min_heap_test.rb
@@ -0,0 +1,14 @@
+require File.expand_path('test_helper.rb', File.dirname(__FILE__))
+
+class MinHeapTest < Test::Unit::TestCase
+ def test_checkout_checkin
+ h = ThriftHelpers::MinHeap.new(50, ('a'..'z').to_a)
+ 100000.times do
+ #print h.checkout
@bitbckt

bitbckt Dec 7, 2012

Contributor

Remove the debug comments.

@bitbckt bitbckt commented on an outdated diff Dec 7, 2012

ext/thrift_client/min_heap.c
+}
+
+static VALUE
+heap_initialize(VALUE self, VALUE w, VALUE items)
+{
+ assert(TYPE(w) == T_FIXNUM);
+ assert(TYPE(items) == T_ARRAY);
+
+ int weight = FIX2INT(w);
+ if (weight < 0 || weight > 100)
+ rb_raise(rb_eRuntimeError, "Weight must be between 0 and 100");
+
+ tc_heap_t *heap;
+ Data_Get_Struct(self, tc_heap_t, heap);
+
+ long int size = RARRAY_LEN(items);
@bitbckt

bitbckt Dec 7, 2012

Contributor

Just use "long", "long int" is a bit... dated.

@bitbckt bitbckt commented on the diff Dec 7, 2012

ext/thrift_client/min_heap.c
+ long int samples;
+ int weight;
+} tc_node_t;
+
+typedef struct heap {
+ int size;
+ VALUE is_available;
+ int cur_index;
+ tc_node_t *nodes;
+} tc_heap_t;
+
+static void _fix_down(tc_heap_t *, int, int);
+static tc_node_t *_get(tc_heap_t *, int);
+
+static void *
+zalloc(size_t size)
@bitbckt

bitbckt Dec 7, 2012

Contributor

Use calloc?

@bitbckt bitbckt commented on an outdated diff Dec 7, 2012

ext/thrift_client/min_heap.c
+ int m = (j == i*2 || compare(heap, &heap->nodes[2*i], &heap->nodes[2*i+1])) ? (2*i) : (2*i+1);
+ if (compare(heap, &heap->nodes[m], &heap->nodes[i])) {
+ swap(heap, i, m);
+ _fix_down(heap, m, j);
+ }
+}
+
+static VALUE
+heap_initialize(VALUE self, VALUE w, VALUE items)
+{
+ assert(TYPE(w) == T_FIXNUM);
+ assert(TYPE(items) == T_ARRAY);
+
+ int weight = FIX2INT(w);
+ if (weight < 0 || weight > 100)
+ rb_raise(rb_eRuntimeError, "Weight must be between 0 and 100");
@bitbckt

bitbckt Dec 7, 2012

Contributor

We don't have an ERANGE available?

@bitbckt bitbckt and 1 other commented on an outdated diff Dec 7, 2012

ext/thrift_client/min_heap.c
+ heap->nodes[j] = tmp;
+ heap->nodes[i].index = i;
+ heap->nodes[j].index = j;
+}
+
+static void
+heap_mark(tc_heap_t *heap)
+{
+ if (heap == NULL)
+ return;
+
+ rb_gc_mark(heap->is_available);
+
+ if (heap->nodes != NULL) {
+ tc_node_t *node = &heap->nodes[1];
+ for (int i = 1; i <= heap->size; i++, node++)
@bitbckt

bitbckt Dec 7, 2012

Contributor

1-based iteration?

@sprsquish

sprsquish Dec 7, 2012

Contributor

oops. a holdover from a previous implementation.

sprsquish closed this Sep 26, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment