oj 3.11.8 → 3.12.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: 11978d74b0eadb223adb22a84e45374f96cfe8b7129ca802e36987129bf75187
4
- data.tar.gz: a6b6963003481173d338127337ac68c7d62630ee101e18676c7d5a71da7c8596
3
+ metadata.gz: 125ec67a260b09db65d47add3487d46c55ee805ebaa721d3bf841ef27fe3ade7
4
+ data.tar.gz: a1cd38c40217e8c5ffd24f8759ff00f0d6770dcab56a736bd0c4ba52d5f3a03a
5
5
  SHA512:
6
- metadata.gz: 93a515179416171a536d139f4e34a6b81b526800671bd123a91c721c083513c6187a45baba56d0280e8396e1fa0997bf96f9cf360b1917db994b79634cd86c4a
7
- data.tar.gz: b22e208d8d4b5676acc9d4fedf9411d4433f184268af411d43b5efd361610f0218d5a1ca9ececdc71a391eb4fd90df5e4657050e2fe3943ad5a397988ee5bd5d
6
+ metadata.gz: 63496098643062caf40131db78e9ef1ccd75f9fd56f32e49538ccb6e005a42dcc86198d202562edc0b149b7ee649492376584d21554423846ac078efec700899
7
+ data.tar.gz: 9d619857d1f9f217d5e7c27c8a999013516680de8e28bc835ee2e267e60eee5dacde1a69e2de694d99d8caf21eb7e5c0c5a51ab9407d03b509423af894913985
data/ext/oj/compat.c CHANGED
@@ -23,14 +23,34 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
23
23
  parent->classname = oj_strndup(str, len);
24
24
  parent->clen = len;
25
25
  } else {
26
- volatile VALUE rstr = rb_str_new(str, len);
26
+ volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
27
27
 
28
28
  if (Qundef == rkey) {
29
- rkey = rb_str_new(key, klen);
30
- rstr = oj_encode(rstr);
31
- rkey = oj_encode(rkey);
32
- if (Yes == pi->options.sym_key) {
33
- rkey = rb_str_intern(rkey);
29
+ if (Yes != pi->options.cache_keys) {
30
+ rkey = rb_str_new(key, klen);
31
+ rkey = oj_encode(rkey);
32
+ if (Yes == pi->options.sym_key) {
33
+ rkey = rb_str_intern(rkey);
34
+ }
35
+ } else {
36
+ VALUE *slot;
37
+
38
+ if (Yes == pi->options.sym_key) {
39
+ if (Qnil == (rkey = oj_sym_hash_get(key, klen, &slot))) {
40
+ rkey = rb_str_new(key, klen);
41
+ rkey = oj_encode(rkey);
42
+ rkey = rb_str_intern(rkey);
43
+ *slot = rkey;
44
+ rb_gc_register_address(slot);
45
+ }
46
+ } else {
47
+ if (Qnil == (rkey = oj_str_hash_get(key, klen, &slot))) {
48
+ rkey = rb_str_new(key, klen);
49
+ rkey = oj_encode(rkey);
50
+ *slot = rkey;
51
+ rb_gc_register_address(slot);
52
+ }
53
+ }
34
54
  }
35
55
  }
36
56
  if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
@@ -93,23 +113,9 @@ static void end_hash(struct _parseInfo *pi) {
93
113
  }
94
114
  }
95
115
 
96
- static VALUE calc_hash_key(ParseInfo pi, Val parent) {
97
- volatile VALUE rkey = parent->key_val;
98
-
99
- if (Qundef == rkey) {
100
- rkey = rb_str_new(parent->key, parent->klen);
101
- }
102
- rkey = oj_encode(rkey);
103
- if (Yes == pi->options.sym_key) {
104
- rkey = rb_str_intern(rkey);
105
- }
106
- return rkey;
107
- }
108
-
109
116
  static void add_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
110
- volatile VALUE rstr = rb_str_new(str, len);
117
+ volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
111
118
 
112
- rstr = oj_encode(rstr);
113
119
  if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
114
120
  VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, (int)len);
115
121
 
@@ -142,10 +148,10 @@ static void hash_set_num(struct _parseInfo *pi, Val parent, NumInfo ni) {
142
148
  rb_funcall(stack_peek(&pi->stack)->val,
143
149
  rb_intern("[]="),
144
150
  2,
145
- calc_hash_key(pi, parent),
151
+ oj_calc_hash_key(pi, parent),
146
152
  rval);
147
153
  } else {
148
- rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), rval);
154
+ rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), rval);
149
155
  }
150
156
  if (Yes == pi->options.trace) {
151
157
  oj_trace_parse_call("set_number", pi, __FILE__, __LINE__, rval);
@@ -161,10 +167,10 @@ static void hash_set_value(ParseInfo pi, Val parent, VALUE value) {
161
167
  rb_funcall(stack_peek(&pi->stack)->val,
162
168
  rb_intern("[]="),
163
169
  2,
164
- calc_hash_key(pi, parent),
170
+ oj_calc_hash_key(pi, parent),
165
171
  value);
166
172
  } else {
167
- rb_hash_aset(stack_peek(&pi->stack)->val, calc_hash_key(pi, parent), value);
173
+ rb_hash_aset(stack_peek(&pi->stack)->val, oj_calc_hash_key(pi, parent), value);
168
174
  }
169
175
  if (Yes == pi->options.trace) {
170
176
  oj_trace_parse_call("set_value", pi, __FILE__, __LINE__, value);
@@ -199,9 +205,8 @@ static void array_append_num(ParseInfo pi, NumInfo ni) {
199
205
  }
200
206
 
201
207
  static void array_append_cstr(ParseInfo pi, const char *str, size_t len, const char *orig) {
202
- volatile VALUE rstr = rb_str_new(str, len);
208
+ volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
203
209
 
204
- rstr = oj_encode(rstr);
205
210
  if (Yes == pi->options.create_ok && NULL != pi->options.str_rx.head) {
206
211
  VALUE clas = oj_rxclass_match(&pi->options.str_rx, str, (int)len);
207
212
 
data/ext/oj/custom.c CHANGED
@@ -955,6 +955,7 @@ static void hash_set_cstr(ParseInfo pi, Val kval, const char *str, size_t len, c
955
955
  }
956
956
  }
957
957
  } else {
958
+ //volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
958
959
  volatile VALUE rstr = rb_str_new(str, len);
959
960
 
960
961
  if (Qundef == rkey) {
@@ -1010,19 +1011,6 @@ static void end_hash(struct _parseInfo *pi) {
1010
1011
  }
1011
1012
  }
1012
1013
 
1013
- static VALUE calc_hash_key(ParseInfo pi, Val parent) {
1014
- volatile VALUE rkey = parent->key_val;
1015
-
1016
- if (Qundef == rkey) {
1017
- rkey = rb_str_new(parent->key, parent->klen);
1018
- }
1019
- rkey = oj_encode(rkey);
1020
- if (Yes == pi->options.sym_key) {
1021
- rkey = rb_str_intern(rkey);
1022
- }
1023
- return rkey;
1024
- }
1025
-
1026
1014
  static void hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
1027
1015
  Val parent = stack_peek(&pi->stack);
1028
1016
  volatile VALUE rval = oj_num_as_value(ni);
@@ -1067,7 +1055,7 @@ static void hash_set_num(struct _parseInfo *pi, Val kval, NumInfo ni) {
1067
1055
  }
1068
1056
  rval = parent->val;
1069
1057
  } else {
1070
- rb_hash_aset(parent->val, calc_hash_key(pi, kval), rval);
1058
+ rb_hash_aset(parent->val, oj_calc_hash_key(pi, kval), rval);
1071
1059
  }
1072
1060
  break;
1073
1061
  default: break;
@@ -1082,7 +1070,7 @@ static void hash_set_value(ParseInfo pi, Val kval, VALUE value) {
1082
1070
 
1083
1071
  switch (rb_type(parent->val)) {
1084
1072
  case T_OBJECT: oj_set_obj_ivar(parent, kval, value); break;
1085
- case T_HASH: rb_hash_aset(parent->val, calc_hash_key(pi, kval), value); break;
1073
+ case T_HASH: rb_hash_aset(parent->val, oj_calc_hash_key(pi, kval), value); break;
1086
1074
  default: break;
1087
1075
  }
1088
1076
  if (Yes == pi->options.trace) {
data/ext/oj/dump.c CHANGED
@@ -535,59 +535,57 @@ void oj_dump_xml_time(VALUE obj, Out out) {
535
535
  }
536
536
  if ((0 == nsec && !out->opts->sec_prec_set) || 0 == out->opts->sec_prec) {
537
537
  if (0 == tzsecs && rb_funcall2(obj, oj_utcq_id, 0, 0)) {
538
- sprintf(buf,
539
- "%04d-%02d-%02dT%02d:%02d:%02dZ",
540
- ti.year,
541
- ti.mon,
542
- ti.day,
543
- ti.hour,
544
- ti.min,
545
- ti.sec);
546
- oj_dump_cstr(buf, 20, 0, 0, out);
538
+ int len = sprintf(buf,
539
+ "%04d-%02d-%02dT%02d:%02d:%02dZ",
540
+ ti.year,
541
+ ti.mon,
542
+ ti.day,
543
+ ti.hour,
544
+ ti.min,
545
+ ti.sec);
546
+ oj_dump_cstr(buf, len, 0, 0, out);
547
547
  } else {
548
- sprintf(buf,
549
- "%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d",
550
- ti.year,
551
- ti.mon,
552
- ti.day,
553
- ti.hour,
554
- ti.min,
555
- ti.sec,
556
- tzsign,
557
- tzhour,
558
- tzmin);
559
- oj_dump_cstr(buf, 25, 0, 0, out);
548
+ int len = sprintf(buf,
549
+ "%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d",
550
+ ti.year,
551
+ ti.mon,
552
+ ti.day,
553
+ ti.hour,
554
+ ti.min,
555
+ ti.sec,
556
+ tzsign,
557
+ tzhour,
558
+ tzmin);
559
+ oj_dump_cstr(buf, len, 0, 0, out);
560
560
  }
561
561
  } else if (0 == tzsecs && rb_funcall2(obj, oj_utcq_id, 0, 0)) {
562
562
  char format[64] = "%04d-%02d-%02dT%02d:%02d:%02d.%09ldZ";
563
- int len = 30;
563
+ int len;
564
564
 
565
565
  if (9 > out->opts->sec_prec) {
566
566
  format[32] = '0' + out->opts->sec_prec;
567
- len -= 9 - out->opts->sec_prec;
568
567
  }
569
- sprintf(buf, format, ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec, (long)nsec);
568
+ len = sprintf(buf, format, ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec, (long)nsec);
570
569
  oj_dump_cstr(buf, len, 0, 0, out);
571
570
  } else {
572
571
  char format[64] = "%04d-%02d-%02dT%02d:%02d:%02d.%09ld%c%02d:%02d";
573
- int len = 35;
572
+ int len;
574
573
 
575
574
  if (9 > out->opts->sec_prec) {
576
575
  format[32] = '0' + out->opts->sec_prec;
577
- len -= 9 - out->opts->sec_prec;
578
576
  }
579
- sprintf(buf,
580
- format,
581
- ti.year,
582
- ti.mon,
583
- ti.day,
584
- ti.hour,
585
- ti.min,
586
- ti.sec,
587
- (long)nsec,
588
- tzsign,
589
- tzhour,
590
- tzmin);
577
+ len = sprintf(buf,
578
+ format,
579
+ ti.year,
580
+ ti.mon,
581
+ ti.day,
582
+ ti.hour,
583
+ ti.min,
584
+ ti.sec,
585
+ (long)nsec,
586
+ tzsign,
587
+ tzhour,
588
+ tzmin);
591
589
  oj_dump_cstr(buf, len, 0, 0, out);
592
590
  }
593
591
  }
@@ -827,9 +825,8 @@ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out ou
827
825
  if (is_sym) {
828
826
  *out->cur++ = ':';
829
827
  }
830
- for (; '\0' != *str; str++) {
831
- *out->cur++ = *str;
832
- }
828
+ memcpy(out->cur, str, cnt);
829
+ out->cur += cnt;
833
830
  *out->cur++ = '"';
834
831
  } else {
835
832
  const char *end = str + cnt;
@@ -1206,7 +1203,7 @@ void oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1206
1203
  if ((int)sizeof(buf) <= cnt) {
1207
1204
  cnt = sizeof(buf) - 1;
1208
1205
  }
1209
- strncpy(buf, rb_string_value_ptr((VALUE *)&rstr), cnt);
1206
+ memcpy(buf, rb_string_value_ptr((VALUE *)&rstr), cnt);
1210
1207
  buf[cnt] = '\0';
1211
1208
  } else {
1212
1209
  cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, out->opts->float_fmt);
data/ext/oj/dump_strict.c CHANGED
@@ -98,7 +98,7 @@ static void dump_float(VALUE obj, int depth, Out out, bool as_ok) {
98
98
  if ((int)sizeof(buf) <= cnt) {
99
99
  cnt = sizeof(buf) - 1;
100
100
  }
101
- strncpy(buf, rb_string_value_ptr((VALUE *)&rstr), cnt);
101
+ memcpy(buf, rb_string_value_ptr((VALUE *)&rstr), cnt);
102
102
  buf[cnt] = '\0';
103
103
  } else {
104
104
  cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, out->opts->float_fmt);
data/ext/oj/hash.c CHANGED
@@ -5,8 +5,8 @@
5
5
 
6
6
  #include <stdint.h>
7
7
 
8
- #define HASH_MASK 0x000003FF
9
- #define HASH_SLOT_CNT 1024
8
+ #define HASH_SLOT_CNT ((uint32_t)8192)
9
+ #define HASH_MASK (HASH_SLOT_CNT - 1)
10
10
 
11
11
  typedef struct _keyVal {
12
12
  struct _keyVal *next;
@@ -20,6 +20,8 @@ struct _hash {
20
20
  };
21
21
 
22
22
  struct _hash class_hash;
23
+ struct _hash str_hash;
24
+ struct _hash sym_hash;
23
25
  struct _hash intern_hash;
24
26
 
25
27
  // almost the Murmur hash algorithm
@@ -64,6 +66,8 @@ static uint32_t hash_calc(const uint8_t *key, size_t len) {
64
66
 
65
67
  void oj_hash_init() {
66
68
  memset(class_hash.slots, 0, sizeof(class_hash.slots));
69
+ memset(str_hash.slots, 0, sizeof(str_hash.slots));
70
+ memset(sym_hash.slots, 0, sizeof(sym_hash.slots));
67
71
  memset(intern_hash.slots, 0, sizeof(intern_hash.slots));
68
72
  }
69
73
 
@@ -100,8 +104,8 @@ static VALUE hash_get(Hash hash, const char *key, size_t len, VALUE **slotp, VAL
100
104
  }
101
105
 
102
106
  void oj_hash_print() {
103
- int i;
104
- KeyVal b;
107
+ uint32_t i;
108
+ KeyVal b;
105
109
 
106
110
  for (i = 0; i < HASH_SLOT_CNT; i++) {
107
111
  printf("%4d:", i);
@@ -112,11 +116,44 @@ void oj_hash_print() {
112
116
  }
113
117
  }
114
118
 
119
+ void oj_hash_sizes() {
120
+ uint32_t i;
121
+ KeyVal b;
122
+ int max = 0;
123
+ int min = 1000000;
124
+
125
+ for (i = 0; i < HASH_SLOT_CNT; i++) {
126
+ int cnt = 0;
127
+
128
+ for (b = str_hash.slots + i; 0 != b && 0 != b->key; b = b->next) {
129
+ cnt++;
130
+ }
131
+ // printf(" %4d\n", cnt);
132
+ if (max < cnt) {
133
+ max = cnt;
134
+ }
135
+ if (cnt < min) {
136
+ min = cnt;
137
+ }
138
+ }
139
+ printf("min: %d max: %d\n", min, max);
140
+ }
141
+
115
142
  VALUE
116
143
  oj_class_hash_get(const char *key, size_t len, VALUE **slotp) {
117
144
  return hash_get(&class_hash, key, len, slotp, Qnil);
118
145
  }
119
146
 
147
+ VALUE
148
+ oj_str_hash_get(const char *key, size_t len, VALUE **slotp) {
149
+ return hash_get(&str_hash, key, len, slotp, Qnil);
150
+ }
151
+
152
+ VALUE
153
+ oj_sym_hash_get(const char *key, size_t len, VALUE **slotp) {
154
+ return hash_get(&sym_hash, key, len, slotp, Qnil);
155
+ }
156
+
120
157
  ID oj_attr_hash_get(const char *key, size_t len, ID **slotp) {
121
158
  return (ID)hash_get(&intern_hash, key, len, (VALUE **)slotp, 0);
122
159
  }
data/ext/oj/hash.h CHANGED
@@ -11,6 +11,8 @@ typedef struct _hash *Hash;
11
11
  extern void oj_hash_init();
12
12
 
13
13
  extern VALUE oj_class_hash_get(const char *key, size_t len, VALUE **slotp);
14
+ extern VALUE oj_str_hash_get(const char *key, size_t len, VALUE **slotp);
15
+ extern VALUE oj_sym_hash_get(const char *key, size_t len, VALUE **slotp);
14
16
  extern ID oj_attr_hash_get(const char *key, size_t len, ID **slotp);
15
17
 
16
18
  extern void oj_hash_print();
data/ext/oj/mimic_json.c CHANGED
@@ -389,9 +389,9 @@ static VALUE mimic_generate_core(int argc, VALUE *argv, Options copts) {
389
389
  } else {
390
390
  VALUE active_hack[1];
391
391
 
392
- if (Qundef == state_class) {
393
- oj_define_mimic_json(0, NULL, Qnil);
394
- }
392
+ if (Qundef == state_class) {
393
+ oj_define_mimic_json(0, NULL, Qnil);
394
+ }
395
395
  active_hack[0] = rb_funcall(state_class, oj_new_id, 0);
396
396
  oj_dump_obj_to_json_using_params(*argv, copts, &out, 1, active_hack);
397
397
  }
@@ -464,23 +464,23 @@ oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
464
464
  } else {
465
465
  h = argv[1];
466
466
  }
467
- if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_indent_sym)) {
467
+ if (!oj_hash_has_key(h, oj_indent_sym)) {
468
468
  rb_hash_aset(h, oj_indent_sym, rb_str_new2(" "));
469
469
  }
470
- if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_space_before_sym)) {
470
+ if (!oj_hash_has_key(h, oj_space_before_sym)) {
471
471
  rb_hash_aset(h, oj_space_before_sym, rb_str_new2(""));
472
472
  }
473
- if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_space_sym)) {
473
+ if (!oj_hash_has_key(h, oj_space_sym)) {
474
474
  rb_hash_aset(h, oj_space_sym, rb_str_new2(" "));
475
475
  }
476
- if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_object_nl_sym)) {
476
+ if (!oj_hash_has_key(h, oj_object_nl_sym)) {
477
477
  rb_hash_aset(h, oj_object_nl_sym, rb_str_new2("\n"));
478
478
  }
479
- if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_array_nl_sym)) {
479
+ if (!oj_hash_has_key(h, oj_array_nl_sym)) {
480
480
  rb_hash_aset(h, oj_array_nl_sym, rb_str_new2("\n"));
481
481
  }
482
482
  if (Qundef == state_class) {
483
- oj_define_mimic_json(0, NULL, Qnil);
483
+ oj_define_mimic_json(0, NULL, Qnil);
484
484
  }
485
485
  rargs[1] = rb_funcall(state_class, oj_new_id, 1, h);
486
486
 
@@ -548,7 +548,7 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
548
548
  pi.options.allow_nan = (Qtrue == v) ? Yes : No;
549
549
  }
550
550
 
551
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_hash_class_sym)) {
551
+ if (oj_hash_has_key(ropts, oj_hash_class_sym)) {
552
552
  if (Qnil == (v = rb_hash_lookup(ropts, oj_hash_class_sym))) {
553
553
  pi.options.hash_class = Qnil;
554
554
  } else {
@@ -556,7 +556,7 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
556
556
  pi.options.hash_class = v;
557
557
  }
558
558
  }
559
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_object_class_sym)) {
559
+ if (oj_hash_has_key(ropts, oj_object_class_sym)) {
560
560
  if (Qnil == (v = rb_hash_lookup(ropts, oj_object_class_sym))) {
561
561
  pi.options.hash_class = Qnil;
562
562
  } else {
@@ -564,7 +564,7 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
564
564
  pi.options.hash_class = v;
565
565
  }
566
566
  }
567
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_array_class_sym)) {
567
+ if (oj_hash_has_key(ropts, oj_array_class_sym)) {
568
568
  if (Qnil == (v = rb_hash_lookup(ropts, oj_array_class_sym))) {
569
569
  pi.options.array_class = Qnil;
570
570
  } else {
@@ -572,7 +572,7 @@ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
572
572
  pi.options.array_class = v;
573
573
  }
574
574
  }
575
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_decimal_class_sym)) {
575
+ if (oj_hash_has_key(ropts, oj_decimal_class_sym)) {
576
576
  pi.options.compat_bigdec = (oj_bigdecimal_class ==
577
577
  rb_hash_lookup(ropts, oj_decimal_class_sym));
578
578
  }
@@ -713,6 +713,8 @@ static struct _options mimic_object_to_json_options = {0, // indent
713
713
  No, // safe
714
714
  false, // sec_prec_set
715
715
  No, // ignore_under
716
+ Yes, // cache_keys
717
+ 3, // cache_str
716
718
  0, // int_range_min
717
719
  0, // int_range_max
718
720
  oj_json_class, // create_id