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
@@ -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
+