oj 3.11.8 → 3.12.3

Sign up to get free protection for your applications and to get access to all the features.
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