yeptris 0.1.13.2 → 0.1.13.3
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.
- checksums.yaml +4 -4
- data/ext/yeptris_native/extconf.rb +5 -1
- data/ext/yeptris_native/json_ruby.c +33 -5
- data/ext/yeptris_native/yeptris_native.c +21 -0
- data/lib/yeptris.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dfe67fff242e1aeaa61b4faed0633a90f4b2de0c70b630e733ae557a467cae2e
|
|
4
|
+
data.tar.gz: e8755921e9b5b8fe78c5db36a24727fee8d61e4742d56aa70ca939e13091034c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1f0443a1150f595e94eb6cf59afca9fd182a2ea269f2ca3a784260efb5d3cb1174325f48d056b06edaf50f2b30d4f90f641c90beebe456d0a862918b9edbdfe0
|
|
7
|
+
data.tar.gz: 0daf1afec8df455dd2bf72353b694f54003f6c3cbfbf1aa4dbf571c84083029362e0abeee5318f3fc22713199b9221650ac8bab1ca1705e39a0bab3a8f7d8467
|
|
@@ -35,7 +35,11 @@ end
|
|
|
35
35
|
abort "libyeptris not found (set YEPTRIS_LIB_PATH)" unless libdir
|
|
36
36
|
|
|
37
37
|
$LIBPATH << libdir
|
|
38
|
-
|
|
38
|
+
# Platform gems bake a RELATIVE rpath so the bundle finds the
|
|
39
|
+
# vendored libyeptris next to itself; absolute build-time paths
|
|
40
|
+
# would dangle on user machines.
|
|
41
|
+
rpath = ENV["YEPTRIS_RPATH"] || libdir
|
|
42
|
+
$LDFLAGS << " -Wl,-rpath,#{rpath}" if RUBY_PLATFORM =~ /linux|darwin/
|
|
39
43
|
have_library("yeptris", "yep_json_string") or abort "yep_json_string not exported — rebuild libyeptris"
|
|
40
44
|
have_library("yeptris", "yeptris_visit_json") or abort "yeptris_visit_json missing"
|
|
41
45
|
|
|
@@ -30,6 +30,7 @@ typedef struct {
|
|
|
30
30
|
} jr;
|
|
31
31
|
|
|
32
32
|
static VALUE jr_value(jr* j);
|
|
33
|
+
static VALUE jr_object_body(jr* j, VALUE h_pre);
|
|
33
34
|
|
|
34
35
|
static void jr_ws(jr* j) {
|
|
35
36
|
while (j->i < j->len) {
|
|
@@ -46,6 +47,13 @@ static void jr_ws(jr* j) {
|
|
|
46
47
|
enum { YEP_CACHE_ON = 0, YEP_CACHE_OFF = 1 };
|
|
47
48
|
static int yep_cache_mode = YEP_CACHE_ON;
|
|
48
49
|
|
|
50
|
+
/* Allocation-shape knob (TODO.restructure/39): pre = capa(8) up
|
|
51
|
+
* front (forces heap buffers even for tiny arrays); natural =
|
|
52
|
+
* rb_ary_new() so 3-element arrays stay EMBEDDED in the RVALUE, and
|
|
53
|
+
* bulk-path hashes get exact capacity from the counted pairs. */
|
|
54
|
+
enum { YEP_SHAPE_PRE = 0, YEP_SHAPE_NATURAL = 1 };
|
|
55
|
+
static int yep_shape_mode = YEP_SHAPE_PRE;
|
|
56
|
+
|
|
49
57
|
static uint64_t jr_hash(const char* sp, long sl) {
|
|
50
58
|
/* 8-byte-prefix key (the leptris nametab trick): one safe load
|
|
51
59
|
* of min(8, len) bytes + a multiply mix. Replaced byte-wise FNV
|
|
@@ -140,9 +148,20 @@ static int yep_ins_mode = YEP_INS_BULK;
|
|
|
140
148
|
|
|
141
149
|
static VALUE jr_object(jr* j) {
|
|
142
150
|
j->i++; j->depth++;
|
|
143
|
-
|
|
151
|
+
if (yep_shape_mode == YEP_SHAPE_PRE) {
|
|
152
|
+
VALUE h = rb_hash_new_capa(8);
|
|
153
|
+
jr_ws(j);
|
|
154
|
+
if (j->i < j->len && j->p[j->i] == '}') { j->i++; j->depth--; return h; }
|
|
155
|
+
return jr_object_body(j, h);
|
|
156
|
+
}
|
|
144
157
|
jr_ws(j);
|
|
145
|
-
if (j->i < j->len && j->p[j->i] == '}') { j->i++; j->depth--; return
|
|
158
|
+
if (j->i < j->len && j->p[j->i] == '}') { j->i++; j->depth--; return rb_hash_new(); }
|
|
159
|
+
return jr_object_body(j, Qundef); /* created post-loop with exact capa */
|
|
160
|
+
|
|
161
|
+
/* NOTREACHED */
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
static VALUE jr_object_body(jr* j, VALUE h_pre) {
|
|
146
165
|
VALUE pairs[64];
|
|
147
166
|
VALUE* pv = pairs;
|
|
148
167
|
size_t pcap = 64, pn = 0, heap_cap = 0;
|
|
@@ -157,7 +176,7 @@ static VALUE jr_object(jr* j) {
|
|
|
157
176
|
VALUE val = jr_value(j);
|
|
158
177
|
if (j->err) goto out;
|
|
159
178
|
if (yep_ins_mode == YEP_INS_ASET) {
|
|
160
|
-
rb_hash_aset(
|
|
179
|
+
rb_hash_aset(h_pre == Qundef ? (h_pre = rb_hash_new_capa(8)) : h_pre, key, val);
|
|
161
180
|
} else {
|
|
162
181
|
if (pn + 2 > pcap) {
|
|
163
182
|
size_t ncap = pcap * 2;
|
|
@@ -177,18 +196,23 @@ static VALUE jr_object(jr* j) {
|
|
|
177
196
|
j->err = -2; goto out;
|
|
178
197
|
}
|
|
179
198
|
if (yep_ins_mode == YEP_INS_BULK) {
|
|
199
|
+
VALUE h = (h_pre == Qundef) ? rb_hash_new_capa((long)(pn / 2)) : h_pre;
|
|
180
200
|
rb_hash_bulk_insert((long)pn, (const VALUE*)pv, h);
|
|
201
|
+
if (pv != pairs) { free(pv); }
|
|
202
|
+
j->depth--;
|
|
203
|
+
return h;
|
|
181
204
|
}
|
|
205
|
+
if (h_pre == Qundef) { h_pre = rb_hash_new_capa(8); }
|
|
182
206
|
out:
|
|
183
207
|
if (pv != pairs) { free(pv); (void)heap_cap; }
|
|
184
208
|
if (j->err) return Qnil;
|
|
185
209
|
j->depth--;
|
|
186
|
-
return
|
|
210
|
+
return h_pre;
|
|
187
211
|
}
|
|
188
212
|
|
|
189
213
|
static VALUE jr_array(jr* j) {
|
|
190
214
|
j->i++; j->depth++;
|
|
191
|
-
VALUE a = rb_ary_new_capa(8);
|
|
215
|
+
VALUE a = (yep_shape_mode == YEP_SHAPE_NATURAL) ? rb_ary_new() : rb_ary_new_capa(8);
|
|
192
216
|
jr_ws(j);
|
|
193
217
|
if (j->i < j->len && j->p[j->i] == ']') { j->i++; j->depth--; return a; }
|
|
194
218
|
for (;;) {
|
|
@@ -257,6 +281,10 @@ static int yep_gc_mode = YEP_GC_DEFAULT;
|
|
|
257
281
|
int yep_rb_gc_mode(void) { return yep_gc_mode; }
|
|
258
282
|
int yep_rb_ins_mode(void) { return yep_ins_mode; }
|
|
259
283
|
int yep_rb_cache_mode(void) { return yep_cache_mode; }
|
|
284
|
+
int yep_rb_shape_mode(void) { return yep_shape_mode; }
|
|
285
|
+
void yep_rb_set_shape_mode(int mode) {
|
|
286
|
+
if (mode == YEP_SHAPE_PRE || mode == YEP_SHAPE_NATURAL) yep_shape_mode = mode;
|
|
287
|
+
}
|
|
260
288
|
void yep_rb_set_cache_mode(int mode) {
|
|
261
289
|
if (mode == YEP_CACHE_ON || mode == YEP_CACHE_OFF) yep_cache_mode = mode;
|
|
262
290
|
}
|
|
@@ -331,6 +331,8 @@ extern int yep_rb_ins_mode(void);
|
|
|
331
331
|
extern void yep_rb_set_ins_mode(int mode);
|
|
332
332
|
extern int yep_rb_cache_mode(void);
|
|
333
333
|
extern void yep_rb_set_cache_mode(int mode);
|
|
334
|
+
extern int yep_rb_shape_mode(void);
|
|
335
|
+
extern void yep_rb_set_shape_mode(int mode);
|
|
334
336
|
extern double yep_rb_scan_time(const char* p, size_t len, int n);
|
|
335
337
|
|
|
336
338
|
static VALUE native_gc_mode(VALUE self) {
|
|
@@ -380,6 +382,21 @@ static VALUE native_scan_time(VALUE self, VALUE input, VALUE count) {
|
|
|
380
382
|
return DBL2NUM(secs / (double)n);
|
|
381
383
|
}
|
|
382
384
|
|
|
385
|
+
static VALUE native_shape_mode(VALUE self) {
|
|
386
|
+
(void)self;
|
|
387
|
+
return yep_rb_shape_mode() == 1 ? ID2SYM(rb_intern("natural")) : ID2SYM(rb_intern("pre"));
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
static VALUE native_shape_mode_set(VALUE self, VALUE mode) {
|
|
391
|
+
(void)self;
|
|
392
|
+
Check_Type(mode, T_SYMBOL);
|
|
393
|
+
ID id = rb_sym2id(mode);
|
|
394
|
+
if (id == rb_intern("pre")) yep_rb_set_shape_mode(0);
|
|
395
|
+
else if (id == rb_intern("natural")) yep_rb_set_shape_mode(1);
|
|
396
|
+
else rb_raise(rb_eArgError, "shape_mode must be :pre or :natural");
|
|
397
|
+
return mode;
|
|
398
|
+
}
|
|
399
|
+
|
|
383
400
|
static VALUE native_gc_mode_set(VALUE self, VALUE mode) {
|
|
384
401
|
(void)self;
|
|
385
402
|
Check_Type(mode, T_SYMBOL);
|
|
@@ -404,6 +421,8 @@ RUBY_FUNC_EXPORTED void Init_native(void) {
|
|
|
404
421
|
rb_define_singleton_method(mNat, "ins_mode=", native_ins_mode_set, 1);
|
|
405
422
|
rb_define_singleton_method(mNat, "cache_mode", native_cache_mode, 0);
|
|
406
423
|
rb_define_singleton_method(mNat, "cache_mode=", native_cache_mode_set, 1);
|
|
424
|
+
rb_define_singleton_method(mNat, "shape_mode", native_shape_mode, 0);
|
|
425
|
+
rb_define_singleton_method(mNat, "shape_mode=", native_shape_mode_set, 1);
|
|
407
426
|
rb_define_singleton_method(mNat, "scan_time", native_scan_time, 2);
|
|
408
427
|
rb_define_const(mNat, "AVAILABLE", Qtrue);
|
|
409
428
|
const char* env = getenv("YEPTRIS_NATIVE_GC");
|
|
@@ -414,4 +433,6 @@ RUBY_FUNC_EXPORTED void Init_native(void) {
|
|
|
414
433
|
if (ins != NULL && strcmp(ins, "aset") == 0) yep_rb_set_ins_mode(1);
|
|
415
434
|
const char* cache = getenv("YEPTRIS_NATIVE_CACHE");
|
|
416
435
|
if (cache != NULL && strcmp(cache, "off") == 0) yep_rb_set_cache_mode(1);
|
|
436
|
+
const char* shape = getenv("YEPTRIS_NATIVE_SHAPE");
|
|
437
|
+
if (shape != NULL && strcmp(shape, "natural") == 0) yep_rb_set_shape_mode(1);
|
|
417
438
|
}
|
data/lib/yeptris.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Yeptris
|
|
4
4
|
# The gem's version lives in the parent namespace's file — the last
|
|
5
5
|
# internal require (yeptris/version) retired with it.
|
|
6
|
-
VERSION = "0.1.13.
|
|
6
|
+
VERSION = "0.1.13.3".freeze
|
|
7
7
|
# The error hierarchy lives in THIS file (the parent namespace's
|
|
8
8
|
# own file): nested constants do not trigger a parent-constant
|
|
9
9
|
# autoload, and the law forbids internal requires — defining the
|