fairy 0.6.0 → 0.6.5

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.
Files changed (70) hide show
  1. data/Makefile +1 -0
  2. data/bin/fairy +35 -5
  3. data/ext/extconf.rb +3 -0
  4. data/ext/fairy.c +180 -0
  5. data/ext/fairy.h +94 -0
  6. data/ext/fiber_mon.h +32 -0
  7. data/ext/fixnum-buffer.c +483 -0
  8. data/ext/p-group-by.c +529 -0
  9. data/ext/p-xgroup-by.c +467 -0
  10. data/ext/simple-hash.c +44 -0
  11. data/ext/string-buffer.c +286 -0
  12. data/ext/xmarshaled-queue.c +699 -0
  13. data/ext/xsized-queue.c +528 -0
  14. data/ext/xthread.h +65 -0
  15. data/fairy.gemspec +5 -2
  16. data/lib/fairy.rb +10 -1
  17. data/lib/fairy/client/group-by.rb +57 -2
  18. data/lib/fairy/client/here.rb +2 -1
  19. data/lib/fairy/controller.rb +25 -4
  20. data/lib/fairy/master.rb +17 -3
  21. data/lib/fairy/master/c-basic-group-by.rb +4 -2
  22. data/lib/fairy/master/c-cat.rb +3 -2
  23. data/lib/fairy/master/c-direct-product.rb +5 -3
  24. data/lib/fairy/master/c-filter.rb +5 -3
  25. data/lib/fairy/master/c-group-by.rb +13 -0
  26. data/lib/fairy/master/c-junction.rb +3 -2
  27. data/lib/fairy/master/c-seg-join.rb +3 -1
  28. data/lib/fairy/master/c-seg-shuffle.rb +3 -2
  29. data/lib/fairy/master/c-seg-split.rb +1 -1
  30. data/lib/fairy/master/c-seg-zip.rb +3 -1
  31. data/lib/fairy/master/c-sort.rb +7 -2
  32. data/lib/fairy/master/c-wc.rb +5 -3
  33. data/lib/fairy/node.rb +13 -2
  34. data/lib/fairy/node/p-barrier.rb +1 -1
  35. data/lib/fairy/node/p-basic-group-by.rb +22 -12
  36. data/lib/fairy/node/p-direct-product.rb +4 -2
  37. data/lib/fairy/node/p-filter.rb +8 -7
  38. data/lib/fairy/node/p-find.rb +2 -1
  39. data/lib/fairy/node/p-group-by.rb +17 -6
  40. data/lib/fairy/node/p-inject.rb +3 -2
  41. data/lib/fairy/node/p-output-file.rb +1 -1
  42. data/lib/fairy/node/p-seg-join.rb +2 -1
  43. data/lib/fairy/node/p-seg-zip.rb +2 -1
  44. data/lib/fairy/node/p-single-exportable.rb +3 -1
  45. data/lib/fairy/node/p-sort.rb +4 -2
  46. data/lib/fairy/node/p-task.rb +1 -1
  47. data/lib/fairy/node/p-wc.rb +5 -2
  48. data/lib/fairy/processor.rb +25 -18
  49. data/lib/fairy/share/block-source.rb +12 -2
  50. data/lib/fairy/share/conf.rb +35 -5
  51. data/lib/fairy/share/hash-simple-hash.rb +1 -1
  52. data/lib/fairy/share/log.rb +11 -4
  53. data/lib/fairy/share/pool-dictionary.rb +2 -1
  54. data/lib/fairy/share/port-marshaled-queue.rb +8 -1
  55. data/lib/fairy/share/port.rb +55 -45
  56. data/lib/fairy/share/reference.rb +2 -1
  57. data/lib/fairy/share/varray.rb +3 -1
  58. data/lib/fairy/share/vfile.rb +4 -2
  59. data/lib/fairy/version.rb +1 -1
  60. data/sample/sort.rb +69 -3
  61. data/spec/fairy8_spec.rb +1 -1
  62. data/test/testc.rb +380 -2
  63. data/tools/cap_recipe/Capfile +3 -3
  64. data/tools/fairy_conf_wizard.rb +375 -0
  65. data/tools/fairy_perf_graph.rb +15 -3
  66. data/tools/git-tag +1 -0
  67. data/tools/log-analysis.rb +59 -11
  68. metadata +33 -34
  69. data/ext/simple_hash/extconf.rb +0 -4
  70. data/ext/simple_hash/simple_hash.c +0 -42
data/ext/p-group-by.c ADDED
@@ -0,0 +1,529 @@
1
+ /**********************************************************************
2
+
3
+ p-group-by-buffer.c -
4
+ Copyright (C) 2007-2011 Rakuten, Inc.
5
+
6
+ **********************************************************************/
7
+
8
+ #include "ruby.h"
9
+ #include "xthread.h"
10
+
11
+ #include "fairy.h"
12
+
13
+ static ID id_yield;
14
+ static ID id_each;
15
+
16
+ static ID id_sort_by_bang;
17
+ static ID id_open_buffer;
18
+ static ID id_io;
19
+ static ID id_close;
20
+
21
+ static VALUE rb_cFairyPGroupBy;
22
+ static VALUE PPostFilter;
23
+ static VALUE MergeSortBuffer;
24
+ static VALUE MSBMerger;
25
+ static VALUE MSBCachedBuffer;
26
+
27
+ VALUE rb_cFairyPGbXDirctMergeSortBuffer;
28
+ VALUE rb_cFairyPGbXDirctMergeSortBufferCachedBuffer;
29
+
30
+ #define xmsb(name) fairy_pgb_xdirect_merge_sort_buffer##name
31
+ #define rb_xmsb(name) rb_fairy_pgb_xdirect_merge_sort_buffer##name
32
+
33
+ typedef struct rb_xmsb(_struct)
34
+ {
35
+ VALUE njob;
36
+ VALUE buffers;
37
+
38
+ VALUE threshold;
39
+ long CHUNK_SIZE;
40
+
41
+ VALUE hash_proc;
42
+
43
+ } xmsb(_t);
44
+
45
+ #define GetFairyPGbXDirectMergeSortBufferPtr(obj, tobj) \
46
+ TypedData_Get_Struct((obj), xmsb(_t), &xmsb(_data_type), (tobj))
47
+
48
+ #define GetFXMSBPtr(obj, tobj) \
49
+ GetFairyPGbXDirectMergeSortBufferPtr(obj, tobj)
50
+
51
+ static void
52
+ xmsb(_mark)(void *ptr)
53
+ {
54
+ xmsb(_t) *db = (xmsb(_t)*)ptr;
55
+ rb_gc_mark(db->njob);
56
+ rb_gc_mark(db->buffers);
57
+ rb_gc_mark(db->threshold);
58
+ rb_gc_mark(db->hash_proc);
59
+ }
60
+
61
+ static void
62
+ xmsb(_free)(void *ptr)
63
+ {
64
+ ruby_xfree(ptr);
65
+ }
66
+
67
+ static size_t
68
+ xmsb(_memsize)(const void *ptr)
69
+ {
70
+ xmsb(_t) *gb = (xmsb(_t)*)ptr;
71
+
72
+ return ptr ? sizeof(xmsb(_t)) : 0;
73
+ }
74
+
75
+ #ifdef HAVE_RB_DATA_TYPE_T_FUNCTION
76
+ static const rb_data_type_t xmsb(_data_type) = {
77
+ "fairy_p_xgroup_by_direct_merge_sort_buffer",
78
+ {xmsb(_mark), xmsb(_free), xmsb(_memsize),},
79
+ };
80
+ #else
81
+ static const rb_data_type_t xmsb(_data_type) = {
82
+ "fairy_p_xgroup_by_direct_merge_sort_buffer",
83
+ xmsb(_mark),
84
+ xmsb(_free),
85
+ xmsb(_memsize),
86
+ };
87
+ #endif
88
+
89
+ static VALUE
90
+ xmsb(_alloc)(VALUE klass)
91
+ {
92
+ VALUE volatile obj;
93
+ xmsb(_t) *db;
94
+
95
+ obj = TypedData_Make_Struct(klass, xmsb(_t), &xmsb(_data_type), db);
96
+
97
+ db->njob = Qnil;
98
+ db->buffers = Qnil;
99
+ db->threshold = Qnil;
100
+ db->CHUNK_SIZE = 0;
101
+
102
+ db->hash_proc = Qnil;
103
+
104
+ return obj;
105
+ }
106
+
107
+ static VALUE
108
+ rb_xmsb(_initialize)(VALUE self, VALUE njob, VALUE policy)
109
+ {
110
+ xmsb(_t) *db;
111
+
112
+ VALUE argv[] = {
113
+ njob,
114
+ policy,
115
+ };
116
+
117
+ GetFXMSBPtr(self, db);
118
+ rb_call_super(2, argv);
119
+
120
+ db->njob = rb_iv_get(self, "@njob");
121
+ db->threshold = rb_iv_get(self, "@threshold");
122
+ db->CHUNK_SIZE = NUM2LONG(rb_iv_get(self, "@CHUNK_SIZE"));
123
+
124
+ return self;
125
+ }
126
+
127
+ static VALUE
128
+ rb_xmsb(_init_2ndmemory)(VALUE self)
129
+ {
130
+ xmsb(_t) *db;
131
+
132
+ GetFXMSBPtr(self, db);
133
+
134
+ rb_call_super(0, NULL);
135
+ db->buffers = rb_iv_get(self, "@buffers");
136
+ }
137
+
138
+ static VALUE rb_xmsb(_store_2ndmemory_sort_b)(VALUE, VALUE, int, VALUE *);
139
+ static VALUE rb_xmsb(_store_2ndmemory_str)(VALUE, VALUE, VALUE, long *);
140
+ static VALUE rb_xmsb(_store_2ndmemory_obj)(VALUE, VALUE, VALUE, long *);
141
+
142
+ VALUE
143
+ rb_xmsb(_store_2ndmemory)(VALUE self, VALUE key_values)
144
+ {
145
+ VALUE buffer = Qnil;
146
+ VALUE io;
147
+ long i;
148
+ VALUE e;
149
+ VALUE element_class = Qnil;
150
+ xmsb(_t) *db;
151
+
152
+ GetFXMSBPtr(self, db);
153
+
154
+ rb_fairy_debug(self, "START STORE");
155
+
156
+ if (NIL_P(db->hash_proc)) {
157
+ db->hash_proc = rb_iv_get(db->njob, "@hash_proc");
158
+ }
159
+
160
+ rb_block_call(key_values, id_sort_by_bang, 0, 0,
161
+ rb_xmsb(_store_2ndmemory_sort_b), self);
162
+
163
+ buffer = rb_funcall(self, id_open_buffer, 0);
164
+ io = rb_funcall(buffer, id_io, 0);
165
+ i = 0;
166
+ while (i < RARRAY_LEN(key_values)) {
167
+ e = RARRAY_PTR(key_values)[i];
168
+ if (CLASS_OF(e) == rb_cString) {
169
+ rb_xmsb(_store_2ndmemory_str)(self, io, key_values, &i);
170
+ }
171
+ else {
172
+ rb_xmsb(_store_2ndmemory_obj)(self, io, key_values, &i);
173
+ }
174
+ }
175
+ rb_funcall(buffer, id_close, 0);
176
+
177
+ rb_fairy_debug(self, "FINISH STORE");
178
+ return self;
179
+ }
180
+
181
+ static VALUE
182
+ rb_xmsb(_store_2ndmemory_sort_b)(VALUE e, VALUE self, int argc, VALUE *argv)
183
+ {
184
+ xmsb(_t) *db;
185
+ VALUE key;
186
+
187
+ GetFXMSBPtr(self, db);
188
+ if (CLASS_OF(db->hash_proc) == rb_cProc) {
189
+ key = rb_proc_call(db->hash_proc, rb_ary_new3(1, e));
190
+ }
191
+ else {
192
+ key = rb_funcall(db->hash_proc, id_yield, 1, e);
193
+ }
194
+ return key;
195
+ }
196
+
197
+
198
+ static VALUE
199
+ rb_xmsb(_store_2ndmemory_str)(VALUE self, VALUE io, VALUE key_values, long *i)
200
+ {
201
+ xmsb(_t) *db;
202
+ VALUE sb;
203
+ long start = *i;
204
+ long j;
205
+ VALUE e;
206
+
207
+ GetFXMSBPtr(self, db);
208
+
209
+ sb = rb_fairy_string_buffer_new();
210
+
211
+ for (j = start;
212
+ j < RARRAY_LEN(key_values) && j - start <= db->CHUNK_SIZE;
213
+ j++) {
214
+ e = RARRAY_PTR(key_values)[j];
215
+ if (CLASS_OF(e) != rb_cString) {
216
+ break;
217
+ }
218
+ rb_fairy_string_buffer_push(sb, e);
219
+ }
220
+ *i = j;
221
+ rb_marshal_dump(sb, io);
222
+ rb_fairy_string_buffer_clear(sb);
223
+ return self;
224
+ }
225
+
226
+ static VALUE
227
+ rb_xmsb(_store_2ndmemory_obj)(VALUE self, VALUE io, VALUE key_values, long *i)
228
+ {
229
+
230
+ xmsb(_t) *db;
231
+ long start = *i;
232
+ long j;
233
+ VALUE e;
234
+
235
+ GetFXMSBPtr(self, db);
236
+
237
+ for (j = start;
238
+ j < RARRAY_LEN(key_values) && j - start <= db->CHUNK_SIZE;
239
+ j++) {
240
+ e = RARRAY_PTR(key_values)[j];
241
+ if (CLASS_OF(e) == rb_cString) {
242
+ break;
243
+ }
244
+ }
245
+ *i = j;
246
+
247
+ if (start == 0 && j == RARRAY_LEN(key_values) -1) {
248
+ rb_marshal_dump(key_values, io);
249
+ }
250
+ else {
251
+ rb_marshal_dump(rb_ary_subseq(key_values, start, j - start), io);
252
+ }
253
+
254
+ return self;
255
+ }
256
+
257
+ static VALUE
258
+ rb_xmsb(_each_2ndmemory_sub)(VALUE values, VALUE self, int argc, VALUE *argv)
259
+ {
260
+ return rb_yield(values);
261
+ }
262
+
263
+
264
+ static VALUE
265
+ rb_xmsb(_each_2ndmemory)(VALUE self)
266
+ {
267
+ xmsb(_t) *db;
268
+ VALUE key_values = rb_iv_get(self, "@key_values");
269
+ VALUE m;
270
+
271
+ GetFXMSBPtr(self, db);
272
+
273
+ if (RARRAY_LEN(key_values) > 0) {
274
+ rb_xmsb(_store_2ndmemory)(self, key_values);
275
+ rb_iv_set(self, "@key_values", Qnil);
276
+ }
277
+ {
278
+ VALUE arg[] = {
279
+ db->njob,
280
+ db->buffers,
281
+ rb_cFairyPGbXDirctMergeSortBufferCachedBuffer,
282
+ };
283
+ m = rb_class_new_instance(3, arg, MSBMerger);
284
+ return rb_block_call(m, id_each, 0, 0, rb_xmsb(_each_2ndmemory_sub), self);
285
+ }
286
+ }
287
+
288
+ #define xmsbcb(name) fairy_pxg_direct_merge_sort_buffer_cached_buffer##name
289
+ #define rb_xmsbcb(name) rb_fairy_pxg_direct_merge_sort_buffer_cached_buffer##name
290
+
291
+ typedef struct rb_xmsbcb(_struct)
292
+ {
293
+ VALUE tmpbuf;
294
+ VALUE io;
295
+ } xmsbcb(_t);
296
+
297
+ #define GetFairyPXGDirectMergeSortBufferCachedBufferPtr(obj, tobj) \
298
+ TypedData_Get_Struct((obj), xmsbcb(_t), &xmsbcb(_data_type), (tobj))
299
+
300
+ #define GetFXMSBCBPtr(obj, tobj) \
301
+ GetFairyPXGDirectMergeSortBufferCachedBufferPtr(obj, tobj)
302
+
303
+ static void
304
+ xmsbcb(_mark)(void *ptr)
305
+ {
306
+ xmsbcb(_t) *cb = (xmsbcb(_t)*)ptr;
307
+ rb_gc_mark(cb->tmpbuf);
308
+ rb_gc_mark(cb->io);
309
+ }
310
+
311
+ static void
312
+ xmsbcb(_free)(void *ptr)
313
+ {
314
+ ruby_xfree(ptr);
315
+ }
316
+
317
+ static size_t
318
+ xmsbcb(_memsize)(const void *ptr)
319
+ {
320
+ xmsbcb(_t) *cb = (xmsbcb(_t)*)ptr;
321
+
322
+ return ptr ? sizeof(xmsbcb(_t)) : 0;
323
+ }
324
+
325
+ #ifdef HAVE_RB_DATA_TYPE_T_FUNCTION
326
+ static const rb_data_type_t xmsbcb(_data_type) = {
327
+ "fairy_p_xgroup_by_direct_merge_sort_buffer_cached_buffer",
328
+ {xmsbcb(_mark), xmsbcb(_free), xmsbcb(_memsize),},
329
+ };
330
+ #else
331
+ static const rb_data_type_t xmsbcb(_data_type) = {
332
+ "fairy_p_xgroup_by_direct_merge_sort_buffer_cached_buffer",
333
+ xmsbcb(_mark),
334
+ xmsbcb(_free),
335
+ xmsbcb(_memsize),
336
+ };
337
+ #endif
338
+
339
+ static VALUE
340
+ xmsbcb(_alloc)(VALUE klass)
341
+ {
342
+ VALUE volatile obj;
343
+ xmsbcb(_t) *cb;
344
+
345
+ obj = TypedData_Make_Struct(klass, xmsbcb(_t), &xmsbcb(_data_type), cb);
346
+
347
+ cb->tmpbuf = Qnil;
348
+ cb->io = Qnil;
349
+
350
+ return obj;
351
+ }
352
+
353
+ static VALUE
354
+ rb_xmsbcb(_initialize)(VALUE self, VALUE njob, VALUE io)
355
+ {
356
+ xmsbcb(_t) *cb;
357
+ VALUE tmpbuf;
358
+
359
+ VALUE argv[] = {
360
+ njob,
361
+ io,
362
+ };
363
+
364
+ GetFXMSBCBPtr(self, cb);
365
+ cb->tmpbuf = io;
366
+ rb_call_super(2, argv);
367
+
368
+ return self;
369
+ }
370
+
371
+ /*
372
+ * copy from eval_intern.h
373
+ */
374
+
375
+ enum ruby_tag_type {
376
+ RUBY_TAG_RETURN = 0x1,
377
+ RUBY_TAG_BREAK = 0x2,
378
+ RUBY_TAG_NEXT = 0x3,
379
+ RUBY_TAG_RETRY = 0x4,
380
+ RUBY_TAG_REDO = 0x5,
381
+ RUBY_TAG_RAISE = 0x6,
382
+ RUBY_TAG_THROW = 0x7,
383
+ RUBY_TAG_FATAL = 0x8,
384
+ RUBY_TAG_MASK = 0xf
385
+ };
386
+ #define TAG_RETURN RUBY_TAG_RETURN
387
+ #define TAG_BREAK RUBY_TAG_BREAK
388
+ #define TAG_NEXT RUBY_TAG_NEXT
389
+ #define TAG_RETRY RUBY_TAG_RETRY
390
+ #define TAG_REDO RUBY_TAG_REDO
391
+ #define TAG_RAISE RUBY_TAG_RAISE
392
+ #define TAG_THROW RUBY_TAG_THROW
393
+ #define TAG_FATAL RUBY_TAG_FATAL
394
+ #define TAG_MASK RUBY_TAG_MASK
395
+
396
+
397
+ static VALUE rb_xmsbcb(_read_buffer_sub)(VALUE);
398
+
399
+ #define DEBUG_MSG(msg) "rb_xmsbcb(_readbuffer): " #msg
400
+
401
+ VALUE
402
+ rb_xmsbcb(_read_buffer)(VALUE self)
403
+ {
404
+ VALUE result;
405
+ int state;
406
+ xmsbcb(_t) *cb;
407
+
408
+ GetFXMSBCBPtr(self, cb);
409
+
410
+ rb_iv_set(self, "@cache_pv", INT2FIX(0));
411
+
412
+ if (NIL_P(cb->io)) {
413
+ cb->io = rb_funcall(cb->tmpbuf, id_io, 0);
414
+ }
415
+ /*
416
+ if (RTEST(rb_io_eof(cb->io))) {
417
+ rb_fairy_debugf(self, DEBUG_MSG(EOF reached: %s), RSTRING_PTR(rb_inspect(cb->io)));
418
+ rb_iv_set(self, "@eof", Qtrue);
419
+ rb_iv_set(self, "@cache", rb_ary_new());
420
+ return self;
421
+ }
422
+ */
423
+ result = rb_protect(rb_xmsbcb(_read_buffer_sub), self, &state);
424
+ if (state) {
425
+ VALUE exp = rb_errinfo(); /* まず, 例外を取らないとまずい */
426
+
427
+ rb_fairy_debug(self, DEBUG_MSG(1 - rb_protext return non zero state!!));
428
+ rb_fairy_debugf(self, DEBUG_MSG(state: %d), state);
429
+
430
+ if (state == TAG_RAISE) {
431
+ rb_fairy_debug(self, DEBUG_MSG(2));
432
+ rb_fairy_debugf(self, DEBUG_MSG(Exeption: %s), RSTRING_PTR(rb_inspect(exp)));
433
+ if (CLASS_OF(exp) == rb_eEOFError) {
434
+ rb_fairy_debug(self, DEBUG_MSG(3 - EOF reached));
435
+ rb_iv_set(self, "@eof", Qtrue);
436
+ rb_iv_set(self, "@cache", rb_ary_new());
437
+ }
438
+ else if (CLASS_OF(exp) == rb_eArgError) {
439
+ const char *head = "File Contents: ";
440
+ /* VALUE SEEK_CUR = rb_const_get(rb_cIO, rb_intern("SEEK_CUR")); */
441
+ char *buf = ALLOCA_N(char, strlen(head) + 2048 + 1);
442
+ VALUE readed;
443
+ VALUE io;
444
+
445
+ rb_fairy_debug(self, DEBUG_MSG(4 - MARSHAL ERROR OCCURED!!));
446
+
447
+ io = rb_funcall(cb->tmpbuf, id_io, 0);
448
+ rb_funcall(io, rb_intern("seek"), 2, INT2NUM(-1024), SEEK_CUR);
449
+ readed = rb_funcall(io, rb_intern("read"), 1, INT2NUM(2048));
450
+
451
+ strcat(buf, head);
452
+ strncat(buf, RSTRING_PTR(readed), RSTRING_LEN(readed));
453
+ rb_fairy_debug(self, buf);
454
+ rb_exc_raise(exp);
455
+ }
456
+ else {
457
+ rb_fairy_debug(self, DEBUG_MSG(5));
458
+ /* 例外の情報が消えているので, rb_jump_tag(state) は使えない. */
459
+ rb_exc_raise(exp);
460
+ }
461
+ rb_fairy_debug(self, DEBUG_MSG(6));
462
+ }
463
+ else {
464
+ rb_fairy_debug(self, DEBUG_MSG(7));
465
+ rb_exc_raise(exp);
466
+ }
467
+ }
468
+ return self;
469
+ }
470
+
471
+ static VALUE
472
+ rb_xmsbcb(_read_buffer_sub)(VALUE self)
473
+ {
474
+ xmsbcb(_t) *cb;
475
+ VALUE cache;
476
+
477
+ GetFXMSBCBPtr(self, cb);
478
+
479
+ cache = rb_marshal_load(cb->io);
480
+ if (CLASS_OF(cache) == rb_cFairyStringBuffer) {
481
+ VALUE tmp = cache;
482
+ cache = rb_fairy_string_buffer_to_a(tmp);
483
+ rb_fairy_string_buffer_clear(tmp);
484
+ }
485
+ rb_iv_set(self, "@cache", cache);
486
+ return self;
487
+ }
488
+
489
+ void
490
+ Init_p_group_by()
491
+ {
492
+ VALUE msb;
493
+ VALUE xmsb;
494
+ VALUE xmsbcb;
495
+
496
+ if (!rb_const_defined(rb_mFairy, rb_intern("PGroupBy"))) {
497
+ return;
498
+ }
499
+ rb_cFairyPGroupBy = rb_const_get(rb_mFairy, rb_intern("PGroupBy"));
500
+
501
+ id_yield = rb_intern("yield");
502
+ id_each = rb_intern("each");
503
+
504
+ id_sort_by_bang = rb_intern("sort_by!");
505
+ id_open_buffer = rb_intern("open_buffer");
506
+ id_io = rb_intern("io");
507
+ id_close = rb_intern("close");
508
+
509
+ msb= rb_const_get(rb_cFairyPGroupBy, rb_intern("DirectMergeSortBuffer"));
510
+ MergeSortBuffer = msb;
511
+ MSBMerger = rb_const_get(msb, rb_intern("Merger"));
512
+ MSBCachedBuffer = rb_const_get(msb, rb_intern("CachedBuffer"));
513
+
514
+ xmsb = rb_define_class_under(rb_cFairyPGroupBy,
515
+ "XDirectMergeSortBuffer", MergeSortBuffer);
516
+ rb_cFairyPGbXDirctMergeSortBuffer = xmsb;
517
+ rb_define_alloc_func(xmsb, xmsb(_alloc));
518
+ rb_define_method(xmsb, "initialize", rb_xmsb(_initialize), 2);
519
+ rb_define_method(xmsb, "init_2ndmemory", rb_xmsb(_init_2ndmemory), 0);
520
+ rb_define_method(xmsb, "store_2ndmemory", rb_xmsb(_store_2ndmemory), 1);
521
+ rb_define_method(xmsb, "each_2ndmemory", rb_xmsb(_each_2ndmemory), 0);
522
+
523
+ xmsbcb = rb_define_class_under(xmsb, "CachedBuffer", MSBCachedBuffer);
524
+ rb_cFairyPGbXDirctMergeSortBufferCachedBuffer = xmsbcb;
525
+ rb_define_alloc_func(xmsbcb, xmsbcb(_alloc));
526
+ rb_define_method(xmsbcb, "initialize", rb_xmsbcb(_initialize), 2);
527
+ rb_define_method(xmsbcb, "read_buffer", rb_xmsbcb(_read_buffer), 0);
528
+ }
529
+