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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 288c8f3951e7cd252310e271ed666996442d66d90f04fbdefc8fde57fc122826
4
- data.tar.gz: d52fb5127d673914f553b47449dbf2b57b2d1b581c5e0636c40c5faf99141222
3
+ metadata.gz: dfe67fff242e1aeaa61b4faed0633a90f4b2de0c70b630e733ae557a467cae2e
4
+ data.tar.gz: e8755921e9b5b8fe78c5db36a24727fee8d61e4742d56aa70ca939e13091034c
5
5
  SHA512:
6
- metadata.gz: fc3a2f57041c9f28ec5133a98cf8573cfd820f9451d321ae6d333e507b1f2b9d7ce51814a0380eadee799904e056d013eea70142ebb6031d9c7480762f91634c
7
- data.tar.gz: a6f0f5990a19597c1ac060e0dbb5abe2c921cdbdc2e49ec1fe70d04bfa91609c36c7b114e0d4e294e1175613a710fab722b1e524f6a1e5cd73f0340fbc2ead31
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
- $LDFLAGS << " -Wl,-rpath,#{libdir}" if RUBY_PLATFORM =~ /linux|darwin/
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
- VALUE h = rb_hash_new_capa(8);
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 h; }
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(h, key, val);
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 h;
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.2".freeze
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yeptris
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.13.2
4
+ version: 0.1.13.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.