Class: HaystackWorker

Inherits:
Object
  • Object
show all
Includes:
Benchmark, Jobs, Surpluses
Defined in:
lib/haystack_worker/base.rb,
ext/haystack_worker/haystack_worker.c

Defined Under Namespace

Modules: Benchmark, Jobs, Surpluses

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Jobs

#request_job, #respond_with

Methods included from Surpluses

#surpluses

Methods included from Benchmark

#benchmark

Constructor Details

#initialize(haystack_domain) ⇒ HaystackWorker

Returns a new instance of HaystackWorker.



4
5
6
# File 'lib/haystack_worker/base.rb', line 4

def initialize(haystack_domain)
  @haystack_domain = haystack_domain
end

Class Method Details

.work(haystack_domain) ⇒ Object



8
9
10
# File 'lib/haystack_worker/base.rb', line 8

def self.work(haystack_domain)
  new(haystack_domain).work
end

Instance Method Details

#_surpluses(rb_ary) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'ext/haystack_worker/haystack_worker.c', line 5

static VALUE surpluses(VALUE self, VALUE rb_ary) {
  int i, j, ranges[26][2];
  for (i = 0; i < 26; i++) {
    for (j = 0; j < 2; j++) {
      ranges[i][j] = FIX2INT(RARRAY_PTR(RARRAY_PTR(rb_ary)[i])[j]);
    }
  }

  int blocks = 16, position = 0, *array = NULL, bytes;

  YIELD_ATTEMPTS {
    int total[26] = {};
    for (i = 0; i < 26; i++) {
      for (j = 0; j < 26; j++) {
        total[j] += WORD_LOOKUP[attempt[i]][i][j];
      }
    }

    int satisfiable = 1, surplus[26];
    for (i = 0; i < 26; i++) {
      surplus[i] = attempt[i] - total[i];
      if (surplus[i] < 0) {
        satisfiable = 0;
        break;
      }
    }

    if (satisfiable) {
      if (position + 26 > blocks) {
        blocks *= 2, bytes = blocks * sizeof(int);
        array = realloc(array, bytes);

        if (array == NULL) {
          rb_raise(rb_eNoMemError, "Failed to allocate %d bytes", bytes);
        }
      }

      for (i = 0; i < 26; i++) {
        array[position + i] = attempt[i];
      }

      position += 26;
    }
  }

  VALUE rb_solutions = rb_ary_new();
  if (position != 0) {
    VALUE  rb_solution;

    for (i = 0; i < position / 26; i++) {
      rb_solution = rb_ary_new();
      for (j = 0; j < 26; j++) {
        rb_ary_push(rb_solution, INT2FIX(array[i * 26 + j]));
      }
      rb_ary_push(rb_solutions, rb_solution);
    }

    free(array);
  }

  return rb_solutions;
}

#workObject



12
13
14
15
16
17
18
# File 'lib/haystack_worker/base.rb', line 12

def work
  id, ranges = request_job
  loop do
    results = surpluses(ranges)
    id, ranges = respond_with(id, results)
  end
end