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 +1 -1
- data/README.md +163 -104
- data/ext/oj/cache8.c +130 -0
- data/ext/oj/cache8.h +46 -0
- data/ext/oj/dump.c +270 -106
- data/ext/oj/load.c +266 -77
- data/ext/oj/oj.c +7 -0
- data/ext/oj/oj.h +3 -0
- data/lib/oj/version.rb +1 -1
- data/test/perf_obj.rb +3 -3
- data/test/perf_strict.rb +105 -35
- data/test/tests.rb +108 -7
- metadata +4 -2
data/LICENSE
CHANGED
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.
|
25
|
+
### Release 0.9.0
|
26
26
|
|
27
|
-
-
|
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
|
-
|
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
|
-
|
94
|
-
Skipping.
|
102
|
+
> perf_strict.rb
|
95
103
|
--------------------------------------------------------------------------------
|
96
104
|
Load/Parse Performance
|
97
|
-
Oj.load 100000 times in 1.
|
98
|
-
|
99
|
-
JSON::Ext.parse 100000 times in
|
100
|
-
JSON::Pure.parse 100000 times in
|
101
|
-
Ox.load 100000 times in 1.
|
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.
|
107
|
-
Ox 1.
|
108
|
-
|
109
|
-
JSON::Ext
|
110
|
-
JSON::Pure
|
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
|
122
|
+
Oj Ox Oj:compat JSON::Ext JSON::Pure
|
115
123
|
---------- ---------- ---------- ---------- ---------- ----------
|
116
|
-
Oj 1.00 1.
|
117
|
-
Ox 0.
|
118
|
-
|
119
|
-
JSON::Ext 0.
|
120
|
-
JSON::Pure 0.
|
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.
|
126
|
-
|
127
|
-
JSON::Ext.generate 100000 times in
|
128
|
-
|
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
|
-
|
135
|
-
|
136
|
-
|
137
|
-
JSON::Ext
|
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
|
148
|
+
Oj Ox Oj:compat JSON::Ext
|
142
149
|
--------- --------- --------- --------- ---------
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
JSON::Ext 0.10 0.
|
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.
|
153
|
-
|
154
|
-
|
155
|
-
JSON::
|
156
|
-
|
157
|
-
|
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.
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
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.
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
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.
|
184
|
-
|
185
|
-
|
186
|
-
JSON::
|
187
|
-
|
188
|
-
|
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
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
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
|
-
|
203
|
-
----------- ----------- ----------- ----------- ----------- ----------- -----------
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
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.
|
242
|
-
':' character.
|
259
|
+
2. A Symbol is encoded as a JSON string with a preceeding `:` character.
|
243
260
|
|
244
|
-
3. The
|
261
|
+
3. The `^` character denotes a special key value when in a JSON Object sequence.
|
245
262
|
|
246
|
-
4.
|
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.
|
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 "^
|
251
|
-
|
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
|
-
|
254
|
-
|
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
|
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
|
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.
|
276
|
-
|
277
|
-
|
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.
|
data/ext/oj/cache8.c
ADDED
@@ -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
|
+
}
|