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.
- data/Makefile +1 -0
- data/bin/fairy +35 -5
- data/ext/extconf.rb +3 -0
- data/ext/fairy.c +180 -0
- data/ext/fairy.h +94 -0
- data/ext/fiber_mon.h +32 -0
- data/ext/fixnum-buffer.c +483 -0
- data/ext/p-group-by.c +529 -0
- data/ext/p-xgroup-by.c +467 -0
- data/ext/simple-hash.c +44 -0
- data/ext/string-buffer.c +286 -0
- data/ext/xmarshaled-queue.c +699 -0
- data/ext/xsized-queue.c +528 -0
- data/ext/xthread.h +65 -0
- data/fairy.gemspec +5 -2
- data/lib/fairy.rb +10 -1
- data/lib/fairy/client/group-by.rb +57 -2
- data/lib/fairy/client/here.rb +2 -1
- data/lib/fairy/controller.rb +25 -4
- data/lib/fairy/master.rb +17 -3
- data/lib/fairy/master/c-basic-group-by.rb +4 -2
- data/lib/fairy/master/c-cat.rb +3 -2
- data/lib/fairy/master/c-direct-product.rb +5 -3
- data/lib/fairy/master/c-filter.rb +5 -3
- data/lib/fairy/master/c-group-by.rb +13 -0
- data/lib/fairy/master/c-junction.rb +3 -2
- data/lib/fairy/master/c-seg-join.rb +3 -1
- data/lib/fairy/master/c-seg-shuffle.rb +3 -2
- data/lib/fairy/master/c-seg-split.rb +1 -1
- data/lib/fairy/master/c-seg-zip.rb +3 -1
- data/lib/fairy/master/c-sort.rb +7 -2
- data/lib/fairy/master/c-wc.rb +5 -3
- data/lib/fairy/node.rb +13 -2
- data/lib/fairy/node/p-barrier.rb +1 -1
- data/lib/fairy/node/p-basic-group-by.rb +22 -12
- data/lib/fairy/node/p-direct-product.rb +4 -2
- data/lib/fairy/node/p-filter.rb +8 -7
- data/lib/fairy/node/p-find.rb +2 -1
- data/lib/fairy/node/p-group-by.rb +17 -6
- data/lib/fairy/node/p-inject.rb +3 -2
- data/lib/fairy/node/p-output-file.rb +1 -1
- data/lib/fairy/node/p-seg-join.rb +2 -1
- data/lib/fairy/node/p-seg-zip.rb +2 -1
- data/lib/fairy/node/p-single-exportable.rb +3 -1
- data/lib/fairy/node/p-sort.rb +4 -2
- data/lib/fairy/node/p-task.rb +1 -1
- data/lib/fairy/node/p-wc.rb +5 -2
- data/lib/fairy/processor.rb +25 -18
- data/lib/fairy/share/block-source.rb +12 -2
- data/lib/fairy/share/conf.rb +35 -5
- data/lib/fairy/share/hash-simple-hash.rb +1 -1
- data/lib/fairy/share/log.rb +11 -4
- data/lib/fairy/share/pool-dictionary.rb +2 -1
- data/lib/fairy/share/port-marshaled-queue.rb +8 -1
- data/lib/fairy/share/port.rb +55 -45
- data/lib/fairy/share/reference.rb +2 -1
- data/lib/fairy/share/varray.rb +3 -1
- data/lib/fairy/share/vfile.rb +4 -2
- data/lib/fairy/version.rb +1 -1
- data/sample/sort.rb +69 -3
- data/spec/fairy8_spec.rb +1 -1
- data/test/testc.rb +380 -2
- data/tools/cap_recipe/Capfile +3 -3
- data/tools/fairy_conf_wizard.rb +375 -0
- data/tools/fairy_perf_graph.rb +15 -3
- data/tools/git-tag +1 -0
- data/tools/log-analysis.rb +59 -11
- metadata +33 -34
- data/ext/simple_hash/extconf.rb +0 -4
- data/ext/simple_hash/simple_hash.c +0 -42
data/ext/xsized-queue.c
ADDED
@@ -0,0 +1,528 @@
|
|
1
|
+
/**********************************************************************
|
2
|
+
|
3
|
+
xmarshaled_queue.c -
|
4
|
+
Copyright (C) 2007-2011 Rakuten, Inc.
|
5
|
+
|
6
|
+
**********************************************************************/
|
7
|
+
|
8
|
+
#include "ruby.h"
|
9
|
+
|
10
|
+
#include "xthread.h"
|
11
|
+
#include "fiber_mon.h"
|
12
|
+
|
13
|
+
#include "fairy.h"
|
14
|
+
|
15
|
+
extern VALUE rb_cXThreadMonitor;
|
16
|
+
extern VALUE rb_cFiberMon;
|
17
|
+
|
18
|
+
static VALUE rb_cFairyFastTempfile;
|
19
|
+
|
20
|
+
static VALUE SET_NO_IMPORT;
|
21
|
+
|
22
|
+
VALUE rb_cFairyXSizedQueue;
|
23
|
+
|
24
|
+
#define xsq(name) fairy_xsized_queue##name
|
25
|
+
#define rb_xsq(name) rb_fairy_xsized_queue##name
|
26
|
+
|
27
|
+
typedef struct rb_xsq(_struct)
|
28
|
+
{
|
29
|
+
long chunk_size;
|
30
|
+
long min_chunk_no;
|
31
|
+
long queues_limit;
|
32
|
+
|
33
|
+
char use_string_buffer_p;
|
34
|
+
|
35
|
+
VALUE push_queue;
|
36
|
+
VALUE push_cv;
|
37
|
+
|
38
|
+
VALUE queues;
|
39
|
+
VALUE queues_mon;
|
40
|
+
|
41
|
+
VALUE pop_queue;
|
42
|
+
VALUE pop_cv;
|
43
|
+
|
44
|
+
VALUE (*queue_push)(VALUE, VALUE);
|
45
|
+
|
46
|
+
VALUE (*mon_synchronize)();
|
47
|
+
VALUE (*cv_wait)();
|
48
|
+
VALUE (*cv_signal)();
|
49
|
+
VALUE (*cv_broadcast)();
|
50
|
+
|
51
|
+
} xsq(_t);
|
52
|
+
|
53
|
+
#define GetFairyXSizedQueuePtr(obj, tobj) \
|
54
|
+
TypedData_Get_Struct((obj), xsq(_t), &xsq(_data_type), (tobj))
|
55
|
+
|
56
|
+
static void
|
57
|
+
xsq(_mark)(void *ptr)
|
58
|
+
{
|
59
|
+
xsq(_t) *sq = (xsq(_t)*)ptr;
|
60
|
+
|
61
|
+
rb_gc_mark(sq->push_queue);
|
62
|
+
rb_gc_mark(sq->push_cv);
|
63
|
+
rb_gc_mark(sq->queues);
|
64
|
+
rb_gc_mark(sq->queues_mon);
|
65
|
+
rb_gc_mark(sq->pop_queue);
|
66
|
+
rb_gc_mark(sq->pop_cv);
|
67
|
+
}
|
68
|
+
|
69
|
+
static void
|
70
|
+
xsq(_free)(void *ptr)
|
71
|
+
{
|
72
|
+
ruby_xfree(ptr);
|
73
|
+
}
|
74
|
+
|
75
|
+
static size_t
|
76
|
+
xsq(_memsize)(const void *ptr)
|
77
|
+
{
|
78
|
+
return ptr ? sizeof(xsq(_t)) : 0;
|
79
|
+
}
|
80
|
+
|
81
|
+
#ifdef HAVE_RB_DATA_TYPE_T_FUNCTION
|
82
|
+
static const rb_data_type_t xsq(_data_type) = {
|
83
|
+
"fairy_xsized_queue",
|
84
|
+
{xsq(_mark), xsq(_free), xsq(_memsize),},
|
85
|
+
};
|
86
|
+
#else
|
87
|
+
static const rb_data_type_t xsq(_data_type) = {
|
88
|
+
"fairy_xsized_queue",
|
89
|
+
xsq(_mark),
|
90
|
+
xsq(_free),
|
91
|
+
xsq(_memsize),
|
92
|
+
};
|
93
|
+
#endif
|
94
|
+
|
95
|
+
static VALUE
|
96
|
+
xsq(_alloc)(VALUE klass)
|
97
|
+
{
|
98
|
+
VALUE volatile obj;
|
99
|
+
xsq(_t) *sq;
|
100
|
+
|
101
|
+
obj = TypedData_Make_Struct(klass, xsq(_t), &xsq(_data_type), sq);
|
102
|
+
|
103
|
+
sq->chunk_size = 0;
|
104
|
+
sq->min_chunk_no = 0;
|
105
|
+
sq->queues_limit = 0;
|
106
|
+
|
107
|
+
sq->push_queue = Qnil;
|
108
|
+
sq->push_cv = Qnil;
|
109
|
+
|
110
|
+
sq->queues = Qnil;
|
111
|
+
sq->queues_mon = Qnil;
|
112
|
+
|
113
|
+
sq->pop_queue = Qnil;
|
114
|
+
sq->pop_cv = Qnil;
|
115
|
+
|
116
|
+
sq->queue_push = NULL;
|
117
|
+
|
118
|
+
sq->mon_synchronize = NULL;
|
119
|
+
sq->cv_wait = NULL;
|
120
|
+
sq->cv_broadcast = NULL;
|
121
|
+
|
122
|
+
return obj;
|
123
|
+
}
|
124
|
+
|
125
|
+
static VALUE rb_xsq(_monitor_cond_wait)(VALUE);
|
126
|
+
static VALUE rb_xsq(_genmon_synchronize)(VALUE, VALUE (*)(VALUE), VALUE);
|
127
|
+
static VALUE rb_xsq(_gencond_wait)(VALUE);
|
128
|
+
static VALUE rb_xsq(_gencond_broadcast)(VALUE);
|
129
|
+
static VALUE rb_xsq(_gencond_signal)(VALUE);
|
130
|
+
|
131
|
+
static VALUE rb_xsq(_empty_push)(VALUE, VALUE);
|
132
|
+
static VALUE rb_xsq(_str_push)(VALUE, VALUE);
|
133
|
+
static VALUE rb_xsq(_obj_push)(VALUE, VALUE);
|
134
|
+
|
135
|
+
static VALUE
|
136
|
+
rb_xsq(_initialize)(VALUE self, VALUE policy, VALUE queues_mon, VALUE pop_cv)
|
137
|
+
{
|
138
|
+
VALUE sz;
|
139
|
+
VALUE flag;
|
140
|
+
VALUE dir;
|
141
|
+
xsq(_t) *sq;
|
142
|
+
|
143
|
+
GetFairyXSizedQueuePtr(self, sq);
|
144
|
+
|
145
|
+
sz = rb_fairy_conf("XSIZED_QUEUE_CHUNK_SIZE", policy, "chunk_size");
|
146
|
+
sq->chunk_size = NUM2LONG(sz);
|
147
|
+
|
148
|
+
sz = rb_fairy_conf("XSIZED_QUEUE_QUEUES_LIMIT",
|
149
|
+
policy, "queues_limit");
|
150
|
+
sq->queues_limit = NUM2LONG(sz);
|
151
|
+
|
152
|
+
flag = rb_fairy_conf("XSIZED_QUEUE_USE_STRING_BUFFER",
|
153
|
+
policy, "use_string_buffer");
|
154
|
+
sq->use_string_buffer_p = RTEST(flag);
|
155
|
+
|
156
|
+
sq->queues = rb_xthread_fifo_new();
|
157
|
+
if (NIL_P(queues_mon)) {
|
158
|
+
queues_mon = rb_xthread_monitor_new();
|
159
|
+
}
|
160
|
+
sq->queues_mon = queues_mon;
|
161
|
+
|
162
|
+
sq->push_queue = Qnil;
|
163
|
+
sq->push_cv = rb_funcall(queues_mon, rb_intern("new_cond"), 0);
|
164
|
+
|
165
|
+
if (NIL_P(pop_cv)) {
|
166
|
+
pop_cv = rb_funcall(queues_mon, rb_intern("new_cond"), 0);
|
167
|
+
}
|
168
|
+
sq->pop_cv = pop_cv;
|
169
|
+
sq->pop_queue = Qnil;
|
170
|
+
|
171
|
+
sq->queue_push = rb_xsq(_empty_push);
|
172
|
+
|
173
|
+
if (CLASS_OF(sq->queues_mon) == rb_cXThreadMonitor) {
|
174
|
+
sq->mon_synchronize = rb_xthread_monitor_synchronize;
|
175
|
+
sq->cv_wait = rb_xsq(_monitor_cond_wait);
|
176
|
+
sq->cv_broadcast = rb_xthread_monitor_cond_broadcast;
|
177
|
+
sq->cv_signal = rb_xthread_monitor_cond_signal;
|
178
|
+
}
|
179
|
+
else if (CLASS_OF(sq->queues_mon) == rb_cFiberMonMonitor) {
|
180
|
+
sq->mon_synchronize = rb_fibermon_monitor_synchronize;
|
181
|
+
sq->cv_wait = rb_fibermon_cond_wait;
|
182
|
+
sq->cv_signal = rb_fibermon_cond_signal;
|
183
|
+
sq->cv_broadcast = rb_fibermon_cond_broadcast;
|
184
|
+
}
|
185
|
+
else {
|
186
|
+
sq->mon_synchronize = rb_xsq(_genmon_synchronize);
|
187
|
+
sq->cv_wait = rb_xsq(_gencond_wait);
|
188
|
+
sq->cv_signal = rb_xsq(_gencond_signal);
|
189
|
+
sq->cv_broadcast = rb_xsq(_gencond_broadcast);
|
190
|
+
}
|
191
|
+
|
192
|
+
return self;
|
193
|
+
}
|
194
|
+
|
195
|
+
static VALUE
|
196
|
+
rb_xsq(_monitor_cond_wait)(VALUE arg)
|
197
|
+
{
|
198
|
+
return rb_xthread_monitor_cond_wait(arg, Qnil);
|
199
|
+
}
|
200
|
+
|
201
|
+
static VALUE
|
202
|
+
rb_xsq(_genmon_synchronize)(VALUE arg1, VALUE (*arg2)(VALUE), VALUE arg3)
|
203
|
+
{
|
204
|
+
static ID id_synchronize;
|
205
|
+
if (!id_synchronize) id_synchronize = rb_intern("synchronize");
|
206
|
+
|
207
|
+
return rb_funcall(arg1, id_synchronize, 2, arg2, arg3);
|
208
|
+
}
|
209
|
+
|
210
|
+
static VALUE
|
211
|
+
rb_xsq(_gencond_wait)(VALUE arg)
|
212
|
+
{
|
213
|
+
static ID id_wait;
|
214
|
+
if (!id_wait) id_wait = rb_intern("wait");
|
215
|
+
|
216
|
+
return rb_funcall(arg, id_wait, 1, Qnil);
|
217
|
+
}
|
218
|
+
|
219
|
+
static VALUE
|
220
|
+
rb_xsq(_gencond_signal)(VALUE arg1)
|
221
|
+
{
|
222
|
+
static ID id_signal;
|
223
|
+
if (!id_signal) id_signal = rb_intern("signal");
|
224
|
+
|
225
|
+
return rb_funcall(arg1, id_signal, 0);
|
226
|
+
}
|
227
|
+
|
228
|
+
static VALUE
|
229
|
+
rb_xsq(_gencond_broadcast)(VALUE arg1)
|
230
|
+
{
|
231
|
+
static ID id_broadcast;
|
232
|
+
if (!id_broadcast) id_broadcast = rb_intern("broadcast");
|
233
|
+
|
234
|
+
return rb_funcall(arg1, id_broadcast, 0);
|
235
|
+
}
|
236
|
+
|
237
|
+
|
238
|
+
static VALUE
|
239
|
+
xsq(_initialize)(int argc, VALUE *argv, VALUE self)
|
240
|
+
{
|
241
|
+
VALUE policy;
|
242
|
+
VALUE queues_mon;
|
243
|
+
VALUE pop_cv;
|
244
|
+
|
245
|
+
rb_scan_args(argc, argv, "12", &policy, &queues_mon, &pop_cv);
|
246
|
+
return rb_xsq(_initialize)(self, policy, queues_mon, pop_cv);
|
247
|
+
}
|
248
|
+
|
249
|
+
VALUE
|
250
|
+
rb_xsq(_new)(VALUE policy, VALUE queues_mon, VALUE pop_cv)
|
251
|
+
{
|
252
|
+
VALUE self;
|
253
|
+
|
254
|
+
self = xsq(_alloc)(rb_cFairyXSizedQueue);
|
255
|
+
rb_xsq(_initialize)(self, policy, queues_mon, pop_cv);
|
256
|
+
return self;
|
257
|
+
}
|
258
|
+
|
259
|
+
static VALUE rb_xsq(_queues_push)(VALUE, VALUE);
|
260
|
+
static VALUE rb_xsq(_broadcast)(VALUE);
|
261
|
+
static VALUE rb_xsq(_store)(VALUE, VALUE);
|
262
|
+
static VALUE rb_xsq(_restore)(VALUE, VALUE);
|
263
|
+
|
264
|
+
VALUE
|
265
|
+
rb_xsq(_push)(VALUE self, VALUE e)
|
266
|
+
{
|
267
|
+
xsq(_t) *sq;
|
268
|
+
|
269
|
+
GetFairyXSizedQueuePtr(self, sq);
|
270
|
+
return sq->queue_push(self, e);
|
271
|
+
}
|
272
|
+
|
273
|
+
static VALUE
|
274
|
+
rb_xsq(_empty_push)(VALUE self, VALUE e)
|
275
|
+
{
|
276
|
+
xsq(_t) *sq;
|
277
|
+
GetFairyXSizedQueuePtr(self, sq);
|
278
|
+
|
279
|
+
if (EOS_P(e)) {
|
280
|
+
rb_xthread_fifo_push(sq->queues, e);
|
281
|
+
return self;
|
282
|
+
}
|
283
|
+
|
284
|
+
if (sq->use_string_buffer_p && CLASS_OF(e) == rb_cString) {
|
285
|
+
sq->push_queue = rb_fairy_string_buffer_new();
|
286
|
+
sq->queue_push = rb_xsq(_str_push);
|
287
|
+
}
|
288
|
+
else {
|
289
|
+
sq->push_queue = rb_ary_new2(sq->min_chunk_no);
|
290
|
+
sq->queue_push = rb_xsq(_obj_push);
|
291
|
+
}
|
292
|
+
return sq->queue_push(self, e);
|
293
|
+
}
|
294
|
+
|
295
|
+
static VALUE
|
296
|
+
rb_xsq(_obj_push)(VALUE self, VALUE e)
|
297
|
+
{
|
298
|
+
xsq(_t) *sq;
|
299
|
+
GetFairyXSizedQueuePtr(self, sq);
|
300
|
+
|
301
|
+
if (EOS_P(e)) {
|
302
|
+
rb_xsq(_queues_push)(self, sq->push_queue);
|
303
|
+
sq->push_queue = Qnil;
|
304
|
+
rb_xsq(_queues_push)(self, e);
|
305
|
+
return self;
|
306
|
+
}
|
307
|
+
|
308
|
+
if (sq->use_string_buffer_p && CLASS_OF(e) == rb_cString) {
|
309
|
+
rb_xsq(_queues_push)(self, sq->push_queue);
|
310
|
+
sq->push_queue = Qnil;
|
311
|
+
sq->queue_push = rb_xsq(_empty_push);
|
312
|
+
return sq->queue_push(self, e);
|
313
|
+
}
|
314
|
+
|
315
|
+
rb_ary_push(sq->push_queue, e);
|
316
|
+
if (RARRAY_LEN(sq->push_queue) >= sq->chunk_size || e == SET_NO_IMPORT) {
|
317
|
+
rb_xsq(_queues_push)(self, sq->push_queue);
|
318
|
+
sq->push_queue = Qnil;
|
319
|
+
sq->queue_push = rb_xsq(_empty_push);
|
320
|
+
}
|
321
|
+
return self;
|
322
|
+
}
|
323
|
+
|
324
|
+
static VALUE
|
325
|
+
rb_xsq(_str_push)(VALUE self, VALUE e)
|
326
|
+
{
|
327
|
+
xsq(_t) *sq;
|
328
|
+
|
329
|
+
GetFairyXSizedQueuePtr(self, sq);
|
330
|
+
if (EOS_P(e)) {
|
331
|
+
rb_xsq(_queues_push)(self, sq->push_queue);
|
332
|
+
rb_xsq(_queues_push)(self, e);
|
333
|
+
return self;
|
334
|
+
}
|
335
|
+
|
336
|
+
if (CLASS_OF(e) != rb_cString) {
|
337
|
+
rb_xsq(_queues_push)(self, sq->push_queue);
|
338
|
+
sq->push_queue = Qnil;
|
339
|
+
sq->queue_push = rb_xsq(_empty_push);
|
340
|
+
}
|
341
|
+
rb_fairy_string_buffer_push(sq->push_queue, e);
|
342
|
+
if (NUM2LONG(rb_fairy_string_buffer_size(sq->push_queue)) >= sq->chunk_size) {
|
343
|
+
rb_xsq(_queues_push)(self, sq->push_queue);
|
344
|
+
sq->push_queue = Qnil;
|
345
|
+
sq->queue_push = rb_xsq(_empty_push);
|
346
|
+
}
|
347
|
+
return self;
|
348
|
+
}
|
349
|
+
|
350
|
+
static VALUE
|
351
|
+
rb_xsq(_push_raw)(VALUE self, VALUE raw)
|
352
|
+
{
|
353
|
+
xsq(_t) *sq;
|
354
|
+
|
355
|
+
GetFairyXSizedQueuePtr(self, sq);
|
356
|
+
|
357
|
+
if (!NIL_P(sq->push_queue)) {
|
358
|
+
rb_xsq(_queues_push)(self, sq->push_queue);
|
359
|
+
sq->push_queue = Qnil;
|
360
|
+
}
|
361
|
+
rb_xsq(_queues_push)(self, raw);
|
362
|
+
|
363
|
+
return self;
|
364
|
+
}
|
365
|
+
|
366
|
+
struct rb_xsq(_queues_push_arg)
|
367
|
+
{
|
368
|
+
VALUE self;
|
369
|
+
VALUE buf;
|
370
|
+
};
|
371
|
+
|
372
|
+
static VALUE rb_xsq(_push_sync)(struct rb_xsq(_queues_push_arg) *);
|
373
|
+
|
374
|
+
static VALUE
|
375
|
+
rb_xsq(_queues_push)(VALUE self, VALUE buf)
|
376
|
+
{
|
377
|
+
xsq(_t) *sq;
|
378
|
+
struct rb_xsq(_queues_push_arg) arg;
|
379
|
+
|
380
|
+
GetFairyXSizedQueuePtr(self, sq);
|
381
|
+
|
382
|
+
arg.self = self;
|
383
|
+
arg.buf = buf;
|
384
|
+
|
385
|
+
sq->mon_synchronize(sq->queues_mon,
|
386
|
+
rb_xsq(_push_sync), &arg);
|
387
|
+
}
|
388
|
+
|
389
|
+
static VALUE
|
390
|
+
rb_xsq(_push_sync)(struct rb_xsq(_queues_push_arg) *arg)
|
391
|
+
{
|
392
|
+
xsq(_t) *sq;
|
393
|
+
GetFairyXSizedQueuePtr(arg->self, sq);
|
394
|
+
|
395
|
+
if (NUM2LONG(rb_xthread_fifo_length(sq->queues)) > sq->queues_limit) {
|
396
|
+
while(NUM2LONG(rb_xthread_fifo_length(sq->queues)) > sq->queues_limit) {
|
397
|
+
sq->cv_wait(sq->push_cv);
|
398
|
+
}
|
399
|
+
}
|
400
|
+
|
401
|
+
rb_xthread_fifo_push(sq->queues, arg->buf);
|
402
|
+
sq->cv_broadcast(sq->pop_cv);
|
403
|
+
return arg->self;
|
404
|
+
}
|
405
|
+
|
406
|
+
struct rb_xsq(_pop_arg)
|
407
|
+
{
|
408
|
+
VALUE self;
|
409
|
+
VALUE buf;
|
410
|
+
};
|
411
|
+
|
412
|
+
static VALUE rb_xsq(_pop_wait)(struct rb_xsq(_pop_arg) *arg);
|
413
|
+
|
414
|
+
VALUE
|
415
|
+
rb_xsq(_pop)(VALUE self)
|
416
|
+
{
|
417
|
+
xsq(_t) *sq;
|
418
|
+
VALUE buf;
|
419
|
+
struct rb_xsq(_pop_arg) arg;
|
420
|
+
GetFairyXSizedQueuePtr(self, sq);
|
421
|
+
|
422
|
+
while (NIL_P(sq->pop_queue) || RARRAY_LEN(sq->pop_queue) == 0) {
|
423
|
+
{
|
424
|
+
arg.self = self;
|
425
|
+
arg.buf = Qnil;
|
426
|
+
sq->mon_synchronize(sq->queues_mon,
|
427
|
+
rb_xsq(_pop_wait), &arg);
|
428
|
+
buf = arg.buf;
|
429
|
+
}
|
430
|
+
|
431
|
+
if (EOS_P(buf)) {
|
432
|
+
sq->pop_queue = rb_ary_new3(1, buf);
|
433
|
+
}
|
434
|
+
else {
|
435
|
+
if (CLASS_OF(buf) == rb_cString) {
|
436
|
+
buf = rb_marshal_load(buf);
|
437
|
+
}
|
438
|
+
if (CLASS_OF(buf) == rb_cFairyStringBuffer) {
|
439
|
+
sq->pop_queue = rb_fairy_string_buffer_to_a(buf);
|
440
|
+
}
|
441
|
+
else {
|
442
|
+
sq->pop_queue = buf;
|
443
|
+
}
|
444
|
+
}
|
445
|
+
}
|
446
|
+
return rb_ary_shift(sq->pop_queue);
|
447
|
+
}
|
448
|
+
|
449
|
+
static VALUE
|
450
|
+
rb_xsq(_pop_wait)(struct rb_xsq(_pop_arg) *arg)
|
451
|
+
{
|
452
|
+
VALUE self = arg->self;
|
453
|
+
xsq(_t) *sq;
|
454
|
+
VALUE buf = Qnil;
|
455
|
+
|
456
|
+
GetFairyXSizedQueuePtr(self, sq);
|
457
|
+
|
458
|
+
buf = rb_xthread_fifo_pop(sq->queues);
|
459
|
+
while (NIL_P(buf)) {
|
460
|
+
sq->cv_wait(sq->pop_cv);
|
461
|
+
buf = rb_xthread_fifo_pop(sq->queues);
|
462
|
+
}
|
463
|
+
sq->cv_signal(sq->push_cv);
|
464
|
+
arg->buf = buf;
|
465
|
+
return arg->self;
|
466
|
+
}
|
467
|
+
|
468
|
+
VALUE
|
469
|
+
rb_xsq(_pop_raw)(VALUE self)
|
470
|
+
{
|
471
|
+
xsq(_t) *sq;
|
472
|
+
VALUE pop_raw = Qnil;
|
473
|
+
VALUE buf;
|
474
|
+
struct rb_xsq(_pop_arg) arg;
|
475
|
+
|
476
|
+
GetFairyXSizedQueuePtr(self, sq);
|
477
|
+
{
|
478
|
+
arg.self = self;
|
479
|
+
arg.buf = Qnil;
|
480
|
+
sq->mon_synchronize(sq->queues_mon,
|
481
|
+
rb_xsq(_pop_wait), &arg);
|
482
|
+
buf = arg.buf;
|
483
|
+
}
|
484
|
+
return buf;
|
485
|
+
}
|
486
|
+
|
487
|
+
VALUE
|
488
|
+
rb_xsq(_inspect)(VALUE self)
|
489
|
+
{
|
490
|
+
VALUE str;
|
491
|
+
xsq(_t) *sq;
|
492
|
+
|
493
|
+
GetFairyXSizedQueuePtr(self, sq);
|
494
|
+
|
495
|
+
str = rb_sprintf("<%s:%p chunk_size=%d, min_chunk_no=%d, queues_limit=%d use_string_bffer_p=%d>",
|
496
|
+
rb_obj_classname(self),
|
497
|
+
(void*)self,
|
498
|
+
sq->chunk_size,
|
499
|
+
sq->min_chunk_no,
|
500
|
+
sq->queues_limit,
|
501
|
+
sq->use_string_buffer_p);
|
502
|
+
return str;
|
503
|
+
}
|
504
|
+
|
505
|
+
|
506
|
+
void
|
507
|
+
Init_xsized_queue()
|
508
|
+
{
|
509
|
+
VALUE xsq;
|
510
|
+
|
511
|
+
rb_cFairyFastTempfile = rb_const_get(rb_mFairy, rb_intern("FastTempfile"));
|
512
|
+
|
513
|
+
|
514
|
+
SET_NO_IMPORT = rb_const_get(rb_cFairyImport, rb_intern("SET_NO_IMPORT"));
|
515
|
+
|
516
|
+
rb_cFairyXSizedQueue = rb_define_class_under(rb_mFairy, "XSizedQueue", rb_cObject);
|
517
|
+
|
518
|
+
xsq = rb_cFairyXSizedQueue;
|
519
|
+
|
520
|
+
rb_define_alloc_func(xsq, xsq(_alloc));
|
521
|
+
rb_define_method(xsq, "initialize", xsq(_initialize), -1);
|
522
|
+
rb_define_method(xsq, "push", rb_xsq(_push), 1);
|
523
|
+
rb_define_method(xsq, "push_raw", rb_xsq(_push_raw), 1);
|
524
|
+
rb_define_method(xsq, "pop", rb_xsq(_pop), 0);
|
525
|
+
rb_define_method(xsq, "pop_raw", rb_xsq(_pop_raw), 0);
|
526
|
+
rb_define_method(xsq, "inspect", rb_xsq(_inspect), 0);
|
527
|
+
}
|
528
|
+
|