oj 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of oj might be problematic. Click here for more details.

data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011, Peter Ohler
1
+ Copyright (c) 2012, Peter Ohler
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
data/README.md CHANGED
@@ -22,9 +22,9 @@ A fast JSON parser and Object marshaller as a Ruby gem.
22
22
 
23
23
  ## <a name="release">Release Notes</a>
24
24
 
25
- ### Release 0.8.0
25
+ ### Release 0.9.0
26
26
 
27
- - Auto creation of data classes when unmarshalling Objects if the Class is not defined
27
+ - Added support for circular references.
28
28
 
29
29
  ## <a name="description">Description</a>
30
30
 
@@ -57,8 +57,6 @@ Oj is compatible with Ruby 1.8.7, 1.9.2, 1.9.3, JRuby, and RBX.
57
57
 
58
58
  ## <a name="plans">Planned Releases</a>
59
59
 
60
- - Release 0.9: Support for circular references.
61
-
62
60
  - Release 1.0: A JSON stream parser.
63
61
 
64
62
  ## <a name="compare">Comparisons</a>
@@ -86,128 +84,148 @@ It is also worth noting that although Oj is slightly behind MessagePack for
86
84
  parsing, Oj serialization is much faster than MessagePack even though Oj uses
87
85
  human readable JSON vs the binary MessagePack format.
88
86
 
89
- The results:
87
+ UOj supports circular references when in :object mode and when the :circular
88
+ flag is true. None of the other gems tested supported circular
89
+ references. They failed in the following manners when the input included
90
+ circular references.
91
+
92
+ - Yajl core dumps Ruby
93
+
94
+ - JSON fails and raises an Exception
95
+
96
+ - MessagePack fails and raises an Exception
97
+
98
+ The benchmark results are:
90
99
 
91
100
  with Object and Bignum encoding:
92
101
 
93
- MessagePack failed to pack! RangeError: bignum too big to convert into `unsigned long long'.
94
- Skipping.
102
+ > perf_strict.rb
95
103
  --------------------------------------------------------------------------------
96
104
  Load/Parse Performance
97
- Oj.load 100000 times in 1.384 seconds or 72230.276 load/sec.
98
- Yajl.parse 100000 times in 2.475 seconds or 40401.331 parse/sec.
99
- JSON::Ext.parse 100000 times in 2.562 seconds or 39037.263 parse/sec.
100
- JSON::Pure.parse 100000 times in 20.914 seconds or 4781.518 parse/sec.
101
- Ox.load 100000 times in 1.517 seconds or 65923.576 load/sec.
105
+ Oj:compat.load 100000 times in 1.481 seconds or 67513.146 load/sec.
106
+ Oj.load 100000 times in 1.066 seconds or 93796.400 load/sec.
107
+ JSON::Ext.parse 100000 times in 3.023 seconds or 33074.875 parse/sec.
108
+ JSON::Pure.parse 100000 times in 18.908 seconds or 5288.799 parse/sec.
109
+ Ox.load 100000 times in 1.240 seconds or 80671.900 load/sec.
102
110
 
103
111
  Summary:
104
112
  System time (secs) rate (ops/sec)
105
113
  ---------- ----------- --------------
106
- Oj 1.384 72230.276
107
- Ox 1.517 65923.576
108
- Yajl 2.475 40401.331
109
- JSON::Ext 2.562 39037.263
110
- JSON::Pure 20.914 4781.518
114
+ Oj 1.066 93796.400
115
+ Ox 1.240 80671.900
116
+ Oj:compat 1.481 67513.146
117
+ JSON::Ext 3.023 33074.875
118
+ JSON::Pure 18.908 5288.799
111
119
 
112
120
  Comparison Matrix
113
121
  (performance factor, 2.0 row is means twice as fast as column)
114
- Oj Ox Yajl JSON::Ext JSON::Pure
122
+ Oj Ox Oj:compat JSON::Ext JSON::Pure
115
123
  ---------- ---------- ---------- ---------- ---------- ----------
116
- Oj 1.00 1.10 1.79 1.85 15.11
117
- Ox 0.91 1.00 1.63 1.69 13.79
118
- Yajl 0.56 0.61 1.00 1.03 8.45
119
- JSON::Ext 0.54 0.59 0.97 1.00 8.16
120
- JSON::Pure 0.07 0.07 0.12 0.12 1.00
124
+ Oj 1.00 1.16 1.39 2.84 17.73
125
+ Ox 0.86 1.00 1.19 2.44 15.25
126
+ Oj:compat 0.72 0.84 1.00 2.04 12.77
127
+ JSON::Ext 0.35 0.41 0.49 1.00 6.25
128
+ JSON::Pure 0.06 0.07 0.08 0.16 1.00
121
129
 
122
130
 
123
131
  --------------------------------------------------------------------------------
124
132
  Dump/Encode/Generate Performance
125
- Oj.dump 100000 times in 0.819 seconds or 122096.842 dump/sec.
126
- Yajl.encode 100000 times in 2.221 seconds or 45014.913 encode/sec.
127
- JSON::Ext.generate 100000 times in 5.082 seconds or 19678.462 generate/sec.
128
- ***** JSON::Pure.generate failed! TypeError: wrong argument type JSON::Pure::Generator::State (expected Data)
129
- Ox.dump 100000 times in 0.532 seconds or 188014.455 dump/sec.
133
+ Oj:compat.dump 100000 times in 0.789 seconds or 126715.249 dump/sec.
134
+ Oj.dump 100000 times in 0.457 seconds or 218798.751 dump/sec.
135
+ JSON::Ext.generate 100000 times in 4.371 seconds or 22878.630 generate/sec.
136
+ Ox.dump 100000 times in 0.501 seconds or 199425.256 dump/sec.
130
137
 
131
138
  Summary:
132
139
  System time (secs) rate (ops/sec)
133
140
  --------- ----------- --------------
134
- Ox 0.532 188014.455
135
- Oj 0.819 122096.842
136
- Yajl 2.221 45014.913
137
- JSON::Ext 5.082 19678.462
141
+ Oj 0.457 218798.751
142
+ Ox 0.501 199425.256
143
+ Oj:compat 0.789 126715.249
144
+ JSON::Ext 4.371 22878.630
138
145
 
139
146
  Comparison Matrix
140
147
  (performance factor, 2.0 row is means twice as fast as column)
141
- Ox Oj Yajl JSON::Ext
148
+ Oj Ox Oj:compat JSON::Ext
142
149
  --------- --------- --------- --------- ---------
143
- Ox 1.00 1.54 4.18 9.55
144
- Oj 0.65 1.00 2.71 6.20
145
- Yajl 0.24 0.37 1.00 2.29
146
- JSON::Ext 0.10 0.16 0.44 1.00
150
+ Oj 1.00 1.10 1.73 9.56
151
+ Ox 0.91 1.00 1.57 8.72
152
+ Oj:compat 0.58 0.64 1.00 5.54
153
+ JSON::Ext 0.10 0.11 0.18 1.00
154
+
155
+
156
+ The following packages were not included for the reason listed
157
+ ***** MessagePack: RangeError: bignum too big to convert into `unsigned long long'
158
+ ***** Yajl: RuntimeError: Yajl parse and encode did not return the same object as the original.
159
+ ***** JSON::Pure: TypeError: wrong argument type JSON::Pure::Generator::State (expected Data)
147
160
 
148
- without Objects or numbers (for JSON Pure) JSON:
161
+ without Objects or numbers (for JSON Pure, Yajl, and Messagepack) JSON:
149
162
 
150
163
  --------------------------------------------------------------------------------
151
164
  Load/Parse Performance
152
- Oj.load 100000 times in 0.737 seconds or 135683.185 load/sec.
153
- Yajl.parse 100000 times in 1.352 seconds or 73978.778 parse/sec.
154
- JSON::Ext.parse 100000 times in 1.433 seconds or 69780.554 parse/sec.
155
- JSON::Pure.parse 100000 times in 12.974 seconds or 7707.624 parse/sec.
156
- Ox.load 100000 times in 0.904 seconds or 110596.591 load/sec.
157
- MessagePack.unpack 100000 times in 0.644 seconds or 155281.191 unpack/sec.
165
+ Oj:compat.load 100000 times in 0.806 seconds or 124051.164 load/sec.
166
+ Oj.load 100000 times in 0.810 seconds or 123384.587 load/sec.
167
+ Yajl.parse 100000 times in 1.441 seconds or 69385.996 parse/sec.
168
+ JSON::Ext.parse 100000 times in 1.567 seconds or 63797.848 parse/sec.
169
+ JSON::Pure.parse 100000 times in 13.500 seconds or 7407.247 parse/sec.
170
+ Ox.load 100000 times in 0.954 seconds or 104836.748 load/sec.
171
+ MessagePack.unpack 100000 times in 0.651 seconds or 153707.817 unpack/sec.
158
172
 
159
173
  Summary:
160
174
  System time (secs) rate (ops/sec)
161
175
  ----------- ----------- --------------
162
- MessagePack 0.644 155281.191
163
- Oj 0.737 135683.185
164
- Ox 0.904 110596.591
165
- Yajl 1.352 73978.778
166
- JSON::Ext 1.433 69780.554
167
- JSON::Pure 12.974 7707.624
176
+ MessagePack 0.651 153707.817
177
+ Oj:compat 0.806 124051.164
178
+ Oj 0.810 123384.587
179
+ Ox 0.954 104836.748
180
+ Yajl 1.441 69385.996
181
+ JSON::Ext 1.567 63797.848
182
+ JSON::Pure 13.500 7407.247
168
183
 
169
184
  Comparison Matrix
170
185
  (performance factor, 2.0 row is means twice as fast as column)
171
- MessagePack Oj Ox Yajl JSON::Ext JSON::Pure
172
- ----------- ----------- ----------- ----------- ----------- ----------- -----------
173
- MessagePack 1.00 1.14 1.40 2.10 2.23 20.15
174
- Oj 0.87 1.00 1.23 1.83 1.94 17.60
175
- Ox 0.71 0.82 1.00 1.49 1.58 14.35
176
- Yajl 0.48 0.55 0.67 1.00 1.06 9.60
177
- JSON::Ext 0.45 0.51 0.63 0.94 1.00 9.05
178
- JSON::Pure 0.05 0.06 0.07 0.10 0.11 1.00
186
+ MessagePack Oj:compat Oj Ox Yajl JSON::Ext JSON::Pure
187
+ ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
188
+ MessagePack 1.00 1.24 1.25 1.47 2.22 2.41 20.75
189
+ Oj:compat 0.81 1.00 1.01 1.18 1.79 1.94 16.75
190
+ Oj 0.80 0.99 1.00 1.18 1.78 1.93 16.66
191
+ Ox 0.68 0.85 0.85 1.00 1.51 1.64 14.15
192
+ Yajl 0.45 0.56 0.56 0.66 1.00 1.09 9.37
193
+ JSON::Ext 0.42 0.51 0.52 0.61 0.92 1.00 8.61
194
+ JSON::Pure 0.05 0.06 0.06 0.07 0.11 0.12 1.00
179
195
 
180
196
 
181
197
  --------------------------------------------------------------------------------
182
198
  Dump/Encode/Generate Performance
183
- Oj.dump 100000 times in 0.161 seconds or 620058.906 dump/sec.
184
- Yajl.encode 100000 times in 0.765 seconds or 130637.498 encode/sec.
185
- JSON::Ext.generate 100000 times in 3.306 seconds or 30250.212 generate/sec.
186
- JSON::Pure.generate 100000 times in 7.067 seconds or 14150.026 generate/sec.
187
- Ox.dump 100000 times in 0.178 seconds or 561312.123 dump/sec.
188
- MessagePack.pack 100000 times in 0.306 seconds or 326301.535 pack/sec.
199
+ Oj:compat.dump 100000 times in 0.173 seconds or 578526.262 dump/sec.
200
+ Oj.dump 100000 times in 0.179 seconds or 558362.880 dump/sec.
201
+ Yajl.encode 100000 times in 0.776 seconds or 128794.279 encode/sec.
202
+ JSON::Ext.generate 100000 times in 3.511 seconds or 28483.812 generate/sec.
203
+ JSON::Pure.generate 100000 times in 7.389 seconds or 13533.717 generate/sec.
204
+ Ox.dump 100000 times in 0.196 seconds or 510589.629 dump/sec.
205
+ MessagePack.pack 100000 times in 0.317 seconds or 315307.220 pack/sec.
189
206
 
190
207
  Summary:
191
208
  System time (secs) rate (ops/sec)
192
209
  ----------- ----------- --------------
193
- Oj 0.161 620058.906
194
- Ox 0.178 561312.123
195
- MessagePack 0.306 326301.535
196
- Yajl 0.765 130637.498
197
- JSON::Ext 3.306 30250.212
198
- JSON::Pure 7.067 14150.026
210
+ Oj:compat 0.173 578526.262
211
+ Oj 0.179 558362.880
212
+ Ox 0.196 510589.629
213
+ MessagePack 0.317 315307.220
214
+ Yajl 0.776 128794.279
215
+ JSON::Ext 3.511 28483.812
216
+ JSON::Pure 7.389 13533.717
199
217
 
200
218
  Comparison Matrix
201
219
  (performance factor, 2.0 row is means twice as fast as column)
202
- Oj Ox MessagePack Yajl JSON::Ext JSON::Pure
203
- ----------- ----------- ----------- ----------- ----------- ----------- -----------
204
- Oj 1.00 1.10 1.90 4.75 20.50 43.82
205
- Ox 0.91 1.00 1.72 4.30 18.56 39.67
206
- MessagePack 0.53 0.58 1.00 2.50 10.79 23.06
207
- Yajl 0.21 0.23 0.40 1.00 4.32 9.23
208
- JSON::Ext 0.05 0.05 0.09 0.23 1.00 2.14
209
- JSON::Pure 0.02 0.03 0.04 0.11 0.47 1.00
210
-
220
+ Oj:compat Oj Ox MessagePack Yajl JSON::Ext JSON::Pure
221
+ ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
222
+ Oj:compat 1.00 1.04 1.13 1.83 4.49 20.31 42.75
223
+ Oj 0.97 1.00 1.09 1.77 4.34 19.60 41.26
224
+ Ox 0.88 0.91 1.00 1.62 3.96 17.93 37.73
225
+ MessagePack 0.55 0.56 0.62 1.00 2.45 11.07 23.30
226
+ Yajl 0.22 0.23 0.25 0.41 1.00 4.52 9.52
227
+ JSON::Ext 0.05 0.05 0.06 0.09 0.22 1.00 2.10
228
+ JSON::Pure 0.02 0.02 0.03 0.04 0.11 0.48 1.00
211
229
 
212
230
  ### Simple JSON Writing and Parsing:
213
231
 
@@ -238,40 +256,81 @@ formating follows the following rules.
238
256
  1. JSON native types, true, false, nil, String, Hash, Array, and Number are
239
257
  encoded normally.
240
258
 
241
- 2. If a Hash uses Symbols as keys those keys appear as Strings with a leading
242
- ':' character.
259
+ 2. A Symbol is encoded as a JSON string with a preceeding `:` character.
243
260
 
244
- 3. The '^' character denotes a special key value when in a JSON Object sequence.
261
+ 3. The `^` character denotes a special key value when in a JSON Object sequence.
245
262
 
246
- 4. If a String begins with a ':' character such as ':abc' it is encoded as {"^s":":abc"}.
263
+ 4. A Ruby String that starts with `:` or the sequence `^i` or `^r` are encoded by
264
+ excaping the first character so that it appears as `\u005e` or `\u003a` instead of
265
+ `:` or `^`.
247
266
 
248
- 5. If a Symbol begins with a ':' character such as :":abc" is is encoded as {"^m":":abc"}.
267
+ 5. A `"^c"` JSON Object key indicates the value should be converted to a Ruby
268
+ class. The sequence `{"^c":"Oj::Bag"}` is read as the Oj::Bag class.
249
269
 
250
- 6. A "^c" JSON Object key indicates the value should be converted to a Ruby
251
- class. The sequence {"^c":"Oj::Bag"} is read as the Oj::Bag class.
270
+ 6. A `"^t"` JSON Object key indicates the value should be converted to a Ruby
271
+ Time. The sequence `{"^t":1325775487.000000}` is read as Jan 5, 2012 at 23:58:07.
252
272
 
253
- 7. A "^t" JSON Object key indicates the value should be converted to a Ruby
254
- Time. The sequence {"^t":1325775487.000000} is read as Jan 5, 2012 at
255
- 23:58:07.
256
-
257
- 8. A "^o" JSON Object key indicates the value should be converted to a Ruby
258
- Object. The first entry in the JSON Object must be a class with the "^o"
273
+ 87. A `"^o"` JSON Object key indicates the value should be converted to a Ruby
274
+ Object. The first entry in the JSON Object must be a class with the `"^o"`
259
275
  key. After that each entry is treated as a variable of the Object where the
260
- key is the variable name without the preceeding '@'. An example is
261
- {"^o":"Oj::Bag","x":58,"y":"marbles"}.
276
+ key is the variable name without the preceeding `@`. An example is
277
+ `{"^o":"Oj::Bag","x":58,"y":"marbles"}`.
278
+
279
+ 8. A `"^u"` JSON Object key indicates the value should be converted to a Ruby
280
+ Struct. The first entry in the JSON Object must be a class with the `"^u"`
281
+ key. After that each entry is is given a numeric position in the struct and
282
+ that is used as the key in the JSON Object. An example is `{"^u":["Range",1,7,false]}`.
262
283
 
263
- 9. When encoding an Object, if the variable name does not begin with an '@'
264
- character then the name preceeded by a '~' character. This occurs in the
265
- Exception class. An example is {"^o":"StandardError","~mesg":"A
266
- Message","~bt":[".\/tests.rb:345:in `test_exception'"]}
284
+ 9. When encoding an Object, if the variable name does not begin with an `@`
285
+ character then the name preceeded by a `~` character. This occurs in the
286
+ Exception class. An example is `{"^o":"StandardError","~mesg":"A Message","~bt":[".\/tests.rb:345:in `test_exception'"]}`.
267
287
 
268
288
  10. If a Hash entry has a key that is not a String or Symbol then the entry is
269
- encoded with a key of the form "^#n" where n is a hex number. The value that
289
+ encoded with a key of the form `"^#n"` where n is a hex number. The value that
270
290
  is an Array where the first element is the key in the Hash and the second is
271
- the value. An example is {"^#3":[2,5]}.
291
+ the value. An example is `{"^#3":[2,5]}`.
272
292
 
273
- 11. A "^i" JSON entry in either an Object or Array is the ID of the Ruby
293
+ 11. A `"^i"` JSON entry in either an Object or Array is the ID of the Ruby
274
294
  Object being encoded. It is used when the :circular flag is set. It can appear
275
- in either a JSON Object or in a JSON Array. If alone it represented a link to
276
- the original Hash or JSON. If an added attribute it is the ID of the original
277
- Object or Array. Examples are TBD.
295
+ in either a JSON Object or in a JSON Array. In an Object the `"^i"` key has a
296
+ corresponding reference Fixnum. In an array the sequence will include an
297
+ embedded reference number. An example is
298
+ `{"^o":"Oj::Bag","^i":1,"x":["^i2",true],"me":"^r1"}`.
299
+
300
+ 12. A `"^r"` JSON entry in an Object is a references to a Object or Array that
301
+ already appears in the JSON String. It must match up with a previous `"^i"`
302
+ ID. An example is `{"^o":"Oj::Bag","^i":1,"x":3,"me":"^r1"}`.
303
+
304
+ 13. If an Array element is a String and starts with `"^i"` then the first
305
+ character, the `^` is encoded as a hex character sequence. An example is
306
+ `["\u005ei37",3]`.
307
+
308
+ ### License:
309
+
310
+ Copyright (c) 2012, Peter Ohler
311
+ All rights reserved.
312
+
313
+ Redistribution and use in source and binary forms, with or without
314
+ modification, are permitted provided that the following conditions are met:
315
+
316
+ - Redistributions of source code must retain the above copyright notice, this
317
+ list of conditions and the following disclaimer.
318
+
319
+ - Redistributions in binary form must reproduce the above copyright notice,
320
+ this list of conditions and the following disclaimer in the documentation
321
+ and/or other materials provided with the distribution.
322
+
323
+ - Neither the name of Peter Ohler nor the names of its contributors may be
324
+ used to endorse or promote products derived from this software without
325
+ specific prior written permission.
326
+
327
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
328
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
329
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
330
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
331
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
332
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
333
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
334
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
335
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
336
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,130 @@
1
+ /* cache8.c
2
+ * Copyright (c) 2011, Peter Ohler
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are met:
7
+ *
8
+ * - Redistributions of source code must retain the above copyright notice, this
9
+ * list of conditions and the following disclaimer.
10
+ *
11
+ * - Redistributions in binary form must reproduce the above copyright notice,
12
+ * this list of conditions and the following disclaimer in the documentation
13
+ * and/or other materials provided with the distribution.
14
+ *
15
+ * - Neither the name of Peter Ohler nor the names of its contributors may be
16
+ * used to endorse or promote products derived from this software without
17
+ * specific prior written permission.
18
+ *
19
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ */
30
+
31
+ #include <stdlib.h>
32
+ #include <errno.h>
33
+ #include <stdio.h>
34
+ #include <string.h>
35
+ #include <stdarg.h>
36
+
37
+ #include "ruby.h"
38
+ #include "cache8.h"
39
+
40
+ #define BITS 4
41
+ #define MASK 0x000000000000000F
42
+ #define SLOT_CNT 16
43
+ #define DEPTH 16
44
+
45
+ struct _Cache8 {
46
+ union {
47
+ struct _Cache8 *slots[SLOT_CNT];
48
+ slot_t values[SLOT_CNT];
49
+ };
50
+ };
51
+
52
+ static void cache8_delete(Cache8 cache, int depth);
53
+ static void slot_print(Cache8 cache, VALUE key, unsigned int depth);
54
+
55
+ void
56
+ oj_cache8_new(Cache8 *cache) {
57
+ Cache8 *cp;
58
+ int i;
59
+
60
+ if (0 == (*cache = (Cache8)malloc(sizeof(struct _Cache8)))) {
61
+ rb_raise(rb_eNoMemError, "not enough memory\n");
62
+ }
63
+ for (i = SLOT_CNT, cp = (*cache)->slots; 0 < i; i--, cp++) {
64
+ *cp = 0;
65
+ }
66
+ }
67
+
68
+ void
69
+ oj_cache8_delete(Cache8 cache) {
70
+ cache8_delete(cache, 0);
71
+ }
72
+
73
+ static void
74
+ cache8_delete(Cache8 cache, int depth) {
75
+ Cache8 *cp;
76
+ unsigned int i;
77
+
78
+ for (i = 0, cp = cache->slots; i < SLOT_CNT; i++, cp++) {
79
+ if (0 != *cp) {
80
+ if (DEPTH - 1 != depth) {
81
+ cache8_delete(*cp, depth + 1);
82
+ }
83
+ }
84
+ }
85
+ free(cache);
86
+ }
87
+
88
+ slot_t
89
+ oj_cache8_get(Cache8 cache, VALUE key, slot_t **slot) {
90
+ Cache8 *cp;
91
+ int i;
92
+ VALUE k;
93
+
94
+ for (i = 64 - BITS; 0 < i; i -= BITS) {
95
+ k = (key >> i) & MASK;
96
+ cp = cache->slots + k;
97
+ if (0 == *cp) {
98
+ oj_cache8_new(cp);
99
+ }
100
+ cache = *cp;
101
+ }
102
+ *slot = cache->values + (key & MASK);
103
+
104
+ return **slot;
105
+ }
106
+
107
+ void
108
+ oj_cache8_print(Cache8 cache) {
109
+ //printf("-------------------------------------------\n");
110
+ slot_print(cache, 0, 0);
111
+ }
112
+
113
+ static void
114
+ slot_print(Cache8 c, VALUE key, unsigned int depth) {
115
+ Cache8 *cp;
116
+ unsigned int i;
117
+ unsigned long k;
118
+
119
+ for (i = 0, cp = c->slots; i < SLOT_CNT; i++, cp++) {
120
+ if (0 != *cp) {
121
+ k = (key << BITS) | i;
122
+ //printf("*** key: 0x%016lx depth: %u i: %u\n", k, depth, i);
123
+ if (DEPTH - 1 == depth) {
124
+ printf("0x%016lx: %4lu\n", k, (unsigned long)*cp);
125
+ } else {
126
+ slot_print(*cp, k, depth + 1);
127
+ }
128
+ }
129
+ }
130
+ }