haystack_worker 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +42 -0
- data/bin/haystack +6 -0
- data/ext/haystack_worker/extconf.rb +3 -0
- data/ext/haystack_worker/haystack_worker.c +72 -0
- data/ext/haystack_worker/lookup.h +1794 -0
- data/ext/haystack_worker/macros.h +11 -0
- data/lib/haystack_worker/base.rb +19 -0
- data/lib/haystack_worker/benchmark.rb +28 -0
- data/lib/haystack_worker/haystack_worker.bundle +0 -0
- data/lib/haystack_worker/jobs.rb +35 -0
- data/lib/haystack_worker/surpluses.rb +15 -0
- data/lib/haystack_worker.rb +10 -0
- metadata +122 -0
data/README.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
## Haystack Worker
|
2
|
+
|
3
|
+
Works on behalf of a haystack server.
|
4
|
+
|
5
|
+
## Concept
|
6
|
+
|
7
|
+
A haystack worker's sole responsibility is to calculate surpluses of characters that satisfy self-enumerating pangrams. It does this as quickly as possible and therefore makes use of a C-extension for a ~200x speed increase over Ruby.
|
8
|
+
|
9
|
+
It receives 'jobs' from a haystack server which come in the form:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
{ 'id' => 123, 'ranges' => [1..10, 3..4, 8..14, etc] }
|
13
|
+
```
|
14
|
+
|
15
|
+
The ranges represent the search space that this worker has been assigned to explore. The ID is used by the haystack worker to keep track of jobs.
|
16
|
+
|
17
|
+
It posts data back to the haystack at /job/:id in the form:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
[[1,3,8,etc],[6,4,14,etc]]
|
21
|
+
```
|
22
|
+
|
23
|
+
It returns ```nil``` if the given search space doesn't contain any potential self-enumerating pangrams.
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
```
|
28
|
+
gem install haystack_worker
|
29
|
+
haystack worker haystack.example.com
|
30
|
+
```
|
31
|
+
|
32
|
+
At present, I haven't built the haystack server. When I have, I'll update the gem to point to it by default.
|
33
|
+
|
34
|
+
## Resources
|
35
|
+
|
36
|
+
For more information or to gain some context, please see my pangram and frequency related projects.
|
37
|
+
|
38
|
+
## Contribution
|
39
|
+
|
40
|
+
Feel free to contribute. No commit is too small.
|
41
|
+
|
42
|
+
You should follow me: [@cpatuzzo](https://twitter.com/cpatuzzo)
|
data/bin/haystack
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include "lookup.h"
|
3
|
+
#include "macros.h"
|
4
|
+
|
5
|
+
static VALUE surpluses(VALUE self, VALUE rb_ary) {
|
6
|
+
int i, j, ranges[26][2];
|
7
|
+
for (i = 0; i < 26; i++) {
|
8
|
+
for (j = 0; j < 2; j++) {
|
9
|
+
ranges[i][j] = FIX2INT(RARRAY_PTR(RARRAY_PTR(rb_ary)[i])[j]);
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
int blocks = 16, position = 0, *array = NULL, bytes;
|
14
|
+
|
15
|
+
YIELD_ATTEMPTS {
|
16
|
+
int total[26] = {};
|
17
|
+
for (i = 0; i < 26; i++) {
|
18
|
+
for (j = 0; j < 26; j++) {
|
19
|
+
total[j] += WORD_LOOKUP[attempt[i]][i][j];
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
int satisfiable = 1, surplus[26];
|
24
|
+
for (i = 0; i < 26; i++) {
|
25
|
+
surplus[i] = attempt[i] - total[i];
|
26
|
+
if (surplus[i] < 0) {
|
27
|
+
satisfiable = 0;
|
28
|
+
break;
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
if (satisfiable) {
|
33
|
+
if (position + 26 > blocks) {
|
34
|
+
blocks *= 2, bytes = blocks * sizeof(int);
|
35
|
+
array = realloc(array, bytes);
|
36
|
+
|
37
|
+
if (array == NULL) {
|
38
|
+
rb_raise(rb_eNoMemError, "Failed to allocate %d bytes", bytes);
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
for (i = 0; i < 26; i++) {
|
43
|
+
array[position + i] = attempt[i];
|
44
|
+
}
|
45
|
+
|
46
|
+
position += 26;
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
if (position == 0) {
|
51
|
+
return Qnil;
|
52
|
+
}
|
53
|
+
else {
|
54
|
+
VALUE rb_solutions = rb_ary_new(), rb_solution;
|
55
|
+
|
56
|
+
for (i = 0; i < position / 26; i++) {
|
57
|
+
rb_solution = rb_ary_new();
|
58
|
+
for (j = 0; j < 26; j++) {
|
59
|
+
rb_ary_push(rb_solution, INT2FIX(array[i * 26 + j]));
|
60
|
+
}
|
61
|
+
rb_ary_push(rb_solutions, rb_solution);
|
62
|
+
}
|
63
|
+
|
64
|
+
free(array);
|
65
|
+
return rb_solutions;
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
void Init_haystack_worker(void) {
|
70
|
+
VALUE klass = rb_define_class("HaystackWorker", rb_cObject);
|
71
|
+
rb_define_method(klass, "_surpluses", surpluses, 1);
|
72
|
+
}
|