oj 3.13.4 → 3.13.5

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: de6407e200d1233d9d36804f49cbd3827d6d318220c44221968dae032e80cc31
4
- data.tar.gz: 9b0c2f83be6a37ba83677a956e40ba2571128d5ae95efca8e24c56dfcb9fbfc9
3
+ metadata.gz: 0a287ba77407aab722c31cfa700b92a173015345bc619f4a95ef7baaeff4be93
4
+ data.tar.gz: b0286ae29d7dff1f71e5691feae47761ad6203f6bdbcf457486443c29b40c6c9
5
5
  SHA512:
6
- metadata.gz: 506be0671f0aecc01447f625e54eaf3a7e70d6a0d148771e94a8968c18224dae2b9e6c06cd0321dc41f1874e0663dae2c20e43b5e3e88a04d2bb23f160d93a27
7
- data.tar.gz: ab6b025efb11d2c5181a869dfa52755a4c891bc0625a9746a8f3b0189792b5e550829f602eb26c84b125b84657a7a4445f3e2b878a01334c26133a0b910edbab
6
+ metadata.gz: bd679fe51f8564ab17a24a842a7d7c31c097e6cd20b7f46c5949d19717aa24901750314426d2930752f78160bb25c157728b3ec8b1247376816b5dc2857ced27
7
+ data.tar.gz: 278065333f209b2ef3d10a94dc770f78ff50d9ca2090e39b522083deb1548902f81b8f9493d689401cc4106b21cf5e6d93f17f5cc8da383f86dc1a4d0418ae43
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 3.13.5 - 2021-09-08
4
+
5
+ - Assure value strings of zero length are not always cached.
6
+
3
7
  ## 3.13.4 - 2021-09-04
4
8
 
5
9
  - Fixed concurrent GC issue in the cache.
data/README.md CHANGED
@@ -64,7 +64,7 @@ links.
64
64
 
65
65
  ## Releases
66
66
 
67
- See [{file:CHANGELOG.md}](CHANGELOG.md)
67
+ See [{file:CHANGELOG.md}](CHANGELOG.md) and [{file:RELEASE_NOTES.md}](RELEASE_NOTES.md)
68
68
 
69
69
  ## Links
70
70
 
data/RELEASE_NOTES.md ADDED
@@ -0,0 +1,55 @@
1
+ # RELEASE NOTES
2
+
3
+ The release notes here are organized by release. For a list of changes
4
+ see the See [{file:CHANGELOG.md}](CHANGELOG.md) file. In this file are
5
+ the steps to take to aid in keeping things rolling after updating to
6
+ the latest version.
7
+
8
+ ## 3.13.x
9
+
10
+ This release included a new cache that performs better than the
11
+ earlier cache and a new high performance parser.
12
+
13
+ ### Cache
14
+
15
+ The new cache includes a least recently used expiration to reduce
16
+ memory use. The cache is also self adjusting and will expand as needed
17
+ for better performance. It also handles Hash keys and string values
18
+ with two options, `:cache_keys`, a boolean and `:cache_str` an
19
+ integer. The `:cache_str` if set to more than zero is the limit for
20
+ the length of string values to cache. The maximum value is 35 which
21
+ allows strings up to 34 bytes to be cached.
22
+
23
+ One interesting aspect of the cache is not so much the string caching
24
+ which performs similar to the Ruby intern functions but the caching of
25
+ symbols and object attribute names. There is a significant gain for
26
+ symbols and object attributes.
27
+
28
+ If the cache is not desired then setting the default options to turn
29
+ it off can be done with this line:
30
+
31
+ ``` ruby
32
+ Oj.default_options = { cache_keys: false, cache_str: 0 }
33
+ ```
34
+
35
+ ### Oj::Parser
36
+
37
+ The new parser uses a different core that follows the approach taken
38
+ by [OjC](https://github.com/ohler55/ojc) and
39
+ [OjG](https://github.com/ohler55/ojg). It also takes advantage of the
40
+ bulk Array and Hash functions. Another issue the new parser addresses
41
+ is option management. Instead of a single global default_options each
42
+ parser instance maintains it's own options.
43
+
44
+ There is a price to be paid when using the Oj::Parser. The API is not
45
+ the same the older parser. A single parser can only be used in a
46
+ single thread. This allows reuse of internal buffers for additional
47
+ improvements in performance.
48
+
49
+ The performane advantage of the Oj::Parse is that it is more than 3
50
+ times faster than the Oj::compat_load call and 6 times faster than the
51
+ JSON gem.
52
+
53
+ ### Dump Performance
54
+
55
+ Thanks to Watson1978 Oj.dump also received a speed boost.
data/ext/oj/custom.c CHANGED
@@ -955,8 +955,8 @@ 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);
959
- volatile VALUE rstr = rb_utf8_str_new(str, len);
958
+ volatile VALUE rstr = oj_cstr_to_value(str, len, (size_t)pi->options.cache_str);
959
+ //volatile VALUE rstr = rb_utf8_str_new(str, len);
960
960
 
961
961
  if (Qundef == rkey) {
962
962
  if (Yes == pi->options.sym_key) {
data/ext/oj/strict.c CHANGED
@@ -16,7 +16,7 @@
16
16
  VALUE oj_cstr_to_value(const char *str, size_t len, size_t cache_str) {
17
17
  volatile VALUE rstr = Qnil;
18
18
 
19
- if (len <= cache_str) {
19
+ if (len < cache_str) {
20
20
  rstr = oj_str_intern(str, len);
21
21
  } else {
22
22
  rstr = rb_str_new(str, len);
@@ -37,7 +37,7 @@ VALUE oj_calc_hash_key(ParseInfo pi, Val parent) {
37
37
  } else {
38
38
  rkey = rb_str_new(parent->key, parent->klen);
39
39
  rkey = oj_encode(rkey);
40
- OBJ_FREEZE(rkey);
40
+ OBJ_FREEZE(rkey); // frozen when used as a Hash key anyway
41
41
  }
42
42
  return rkey;
43
43
  }
data/lib/oj/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Oj
3
3
  # Current version of the module.
4
- VERSION = '3.13.4'
4
+ VERSION = '3.13.5'
5
5
  end
data/test/bar.rb ADDED
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << File.dirname(__FILE__)
4
+ $oj_dir = File.dirname(File.expand_path(File.dirname(__FILE__)))
5
+ %w(lib ext).each do |dir|
6
+ $: << File.join($oj_dir, dir)
7
+ end
8
+
9
+ require 'active_support'
10
+ require "active_support/json"
11
+
12
+ $s = "\u2014 & \n \u{1F618}"
13
+
14
+ =begin
15
+ def check(label)
16
+ puts "\n--- #{label} --------------------"
17
+
18
+ ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
19
+ puts "with standard_json == true: t.to_json - #{$t.to_json}"
20
+ ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
21
+ puts "with standard_json == false: t.to_json - #{$t.to_json}"
22
+ end
23
+
24
+ check('Before Oj')
25
+ =end
26
+
27
+ require 'oj'
28
+
29
+ ActiveSupport::JSON::Encoding.escape_html_entities_in_json = false
30
+ puts "ActiveSupport.encode(s) - #{ActiveSupport::JSON.encode($s)}"
31
+
32
+ Oj.optimize_rails
33
+ Oj.default_options = { mode: :rails }
34
+
35
+ puts "Oj.dump(s) - #{Oj.dump($s)}"
data/test/baz.rb ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << File.dirname(__FILE__)
4
+ $oj_dir = File.dirname(File.expand_path(File.dirname(__FILE__)))
5
+ %w(lib ext).each do |dir|
6
+ $: << File.join($oj_dir, dir)
7
+ end
8
+
9
+ require 'oj'
10
+ Oj.mimic_JSON()
11
+
12
+ begin
13
+ ::JSON.load('name=&email=&subject=&comment=&submit=Send+Message')
14
+ rescue ::JSON::ParserError
15
+ puts "*** Pass"
16
+ end
data/test/foo.rb CHANGED
@@ -1,11 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $: << '.'
4
- $: << '../lib'
5
- $: << '../ext'
6
-
7
3
  require 'oj'
8
4
 
9
- p = Oj::Parser.new(:debug)
5
+ Oj::default_options = {cache_str: 0, cache_keys: true, mode: :strict}
6
+
7
+ puts "Ruby version: #{RUBY_VERSION}"
8
+ puts "Oj version: #{Oj::VERSION}"
9
+
10
+ puts "cache_keys: #{Oj::default_options[:cache_keys]}"
11
+ puts "cache_str: #{Oj::default_options[:cache_str]}"
10
12
 
11
- p.parse("[true, false]")
13
+ Oj.load('{"":""}').each_pair {|k,v| puts "k.frozen?: #{k.frozen?}\nv.frozen?: #{v.frozen?}"}
data/test/prec.rb ADDED
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'oj'
4
+
5
+ extras = {"locationLng" => -97.14690769100295}
6
+
7
+ Oj.default_options = {float_precision: 17}
8
+
9
+ encoded = Oj.dump(extras)
10
+ puts encoded
11
+ puts Oj.load(encoded)
12
+
13
+ require "active_record"
14
+
15
+ Oj::Rails.set_encoder()
16
+ Oj::Rails.set_decoder()
17
+
18
+ Oj.default_options = {float_precision: 17}
19
+ # Using Oj rails encoder, gets the correct value: {"locationLng":-97.14690769100295}
20
+ encoded = ActiveSupport::JSON.encode(extras)
21
+ puts encoded
22
+ puts ActiveSupport::JSON.decode(encoded)
23
+ puts Oj.load(encoded)
data/test/zoo.rb ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #require 'json'
4
+
5
+ $: << File.dirname(__FILE__)
6
+ require 'helper'
7
+ require 'oj'
8
+
9
+ Oj.mimic_JSON
10
+ puts "\u3074"
11
+
12
+ puts JSON.dump(["\u3074"])
13
+ puts JSON.generate(["\u3074"])
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oj
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.13.4
4
+ version: 3.13.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Ohler
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-04 00:00:00.000000000 Z
11
+ date: 2021-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -94,6 +94,7 @@ files:
94
94
  - CHANGELOG.md
95
95
  - LICENSE
96
96
  - README.md
97
+ - RELEASE_NOTES.md
97
98
  - ext/oj/buf.h
98
99
  - ext/oj/cache.c
99
100
  - ext/oj/cache.h
@@ -195,8 +196,8 @@ files:
195
196
  - test/activesupport6/test_common.rb
196
197
  - test/activesupport6/test_helper.rb
197
198
  - test/activesupport6/time_zone_test_helpers.rb
198
- - test/benny.rb
199
- - test/big.rb
199
+ - test/bar.rb
200
+ - test/baz.rb
200
201
  - test/files.rb
201
202
  - test/foo.rb
202
203
  - test/helper.rb
@@ -232,6 +233,7 @@ files:
232
233
  - test/perf_simple.rb
233
234
  - test/perf_strict.rb
234
235
  - test/perf_wab.rb
236
+ - test/prec.rb
235
237
  - test/sample.rb
236
238
  - test/sample/change.rb
237
239
  - test/sample/dir.rb
@@ -258,7 +260,6 @@ files:
258
260
  - test/test_null.rb
259
261
  - test/test_object.rb
260
262
  - test/test_parser.rb
261
- - test/test_parser_memory.rb
262
263
  - test/test_parser_saj.rb
263
264
  - test/test_parser_usual.rb
264
265
  - test/test_rails.rb
@@ -271,6 +272,7 @@ files:
271
272
  - test/tests.rb
272
273
  - test/tests_mimic.rb
273
274
  - test/tests_mimic_addition.rb
275
+ - test/zoo.rb
274
276
  homepage: http://www.ohler.com/oj
275
277
  licenses:
276
278
  - MIT
@@ -281,7 +283,7 @@ metadata:
281
283
  homepage_uri: http://www.ohler.com/oj/
282
284
  source_code_uri: https://github.com/ohler55/oj
283
285
  wiki_uri: https://github.com/ohler55/oj/wiki
284
- post_install_message:
286
+ post_install_message:
285
287
  rdoc_options:
286
288
  - "--title"
287
289
  - Oj
@@ -301,7 +303,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
301
303
  version: '0'
302
304
  requirements: []
303
305
  rubygems_version: 3.2.22
304
- signing_key:
306
+ signing_key:
305
307
  specification_version: 4
306
308
  summary: A fast JSON parser and serializer.
307
309
  test_files:
@@ -325,8 +327,8 @@ test_files:
325
327
  - test/activesupport6/test_common.rb
326
328
  - test/activesupport6/test_helper.rb
327
329
  - test/activesupport6/time_zone_test_helpers.rb
328
- - test/benny.rb
329
- - test/big.rb
330
+ - test/bar.rb
331
+ - test/baz.rb
330
332
  - test/files.rb
331
333
  - test/foo.rb
332
334
  - test/helper.rb
@@ -362,6 +364,7 @@ test_files:
362
364
  - test/perf_simple.rb
363
365
  - test/perf_strict.rb
364
366
  - test/perf_wab.rb
367
+ - test/prec.rb
365
368
  - test/sample/change.rb
366
369
  - test/sample/dir.rb
367
370
  - test/sample/doc.rb
@@ -388,7 +391,6 @@ test_files:
388
391
  - test/test_null.rb
389
392
  - test/test_object.rb
390
393
  - test/test_parser.rb
391
- - test/test_parser_memory.rb
392
394
  - test/test_parser_saj.rb
393
395
  - test/test_parser_usual.rb
394
396
  - test/test_rails.rb
@@ -401,3 +403,4 @@ test_files:
401
403
  - test/tests.rb
402
404
  - test/tests_mimic.rb
403
405
  - test/tests_mimic_addition.rb
406
+ - test/zoo.rb
data/test/benny.rb DELETED
@@ -1,50 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal
3
-
4
- require 'bundler/inline'
5
-
6
- gemfile do
7
- source 'https://rubygems.org'
8
-
9
- gem 'oj'
10
- gem 'benchmark-ips', require: 'benchmark/ips'
11
- end
12
-
13
- require 'json'
14
- require 'open-uri'
15
-
16
- CANADA_DATA_JSON = URI.parse('https://raw.githubusercontent.com/serde-rs/json-benchmark/master/data/canada.json').read
17
- CANADA_DATA = JSON.parse(CANADA_DATA_JSON)
18
-
19
- Benchmark.ips do |x|
20
- x.config(:time => 10, :warmup => 5)
21
-
22
- x.report("marshall Canada data with Oj") do
23
- Oj.dump(CANADA_DATA)
24
- end
25
-
26
- x.report("marshall Canada data with JSON") do
27
- JSON.dump(CANADA_DATA)
28
- end
29
-
30
- x.compare!
31
- end
32
-
33
- Oj.default_options = {
34
- mode: :strict,
35
- bigdecimal_load: :fast
36
- }
37
-
38
- Benchmark.ips do |x|
39
- x.config(:time => 10, :warmup => 5)
40
-
41
- x.report("unmarshall Canada data with Oj") do
42
- Oj.load(CANADA_DATA_JSON)
43
- end
44
-
45
- x.report("unmarshall Canada data with JSON") do
46
- JSON.parse(CANADA_DATA_JSON)
47
- end
48
-
49
- x.compare!
50
- end
data/test/big.rb DELETED
@@ -1,15 +0,0 @@
1
- #require 'active_support'
2
- #require 'active_support/core_ext'
3
- #require 'active_support/json'
4
- require 'oj'
5
-
6
- #Oj.optimize_rails
7
- Oj.mimic_JSON
8
-
9
- h = {:type=>:record, :name=>:group, :namespace=>"com.salsify.identity", :fields=>[{:name=>"id", :type=>{:name=>:salsify_uuid, :type=>:fixed, :namespace=>"com.salsify", :size=>38}}, {:name=>"type", :type=>"string", :default=>"groups"}, {:name=>"external_id", :type=>[:null, "string"], :default=>nil}, {:name=>"created_at", :type=>{:type=>"long", :logicalType=>"timestamp-micros"}}, {:name=>"updated_at", :type=>{:type=>"long", :logicalType=>"timestamp-micros"}}, {:name=>"name", :type=>"string"}, {:name=>"policy", :type=>[:null, {:type=>:record, :name=>:policy, :namespace=>"com.salsify.security", :fields=>[{:name=>"created_at", :type=>{:type=>"long", :logicalType=>"timestamp-micros"}}, {:name=>"updated_at", :type=>{:type=>"long", :logicalType=>"timestamp-micros"}}, {:name=>"id", :type=>"com.salsify.salsify_uuid"}, {:name=>"type", :type=>"string", :default=>"policies"}, {:name=>"external_id", :type=>[:null, "string"], :default=>nil}, {:name=>"name", :type=>"string"}, {:name=>"statements", :type=>{:type=>:array, :items=>{:type=>:record, :name=>:statement, :namespace=>"com.salsify.security", :fields=>[{:name=>"created_at", :type=>{:type=>"long", :logicalType=>"timestamp-micros"}}, {:name=>"updated_at", :type=>{:type=>"long", :logicalType=>"timestamp-micros"}}, {:name=>"id", :type=>"com.salsify.salsify_uuid"}, {:name=>"type", :type=>"string", :default=>"statements"}, {:name=>"external_id", :type=>[:null, "string"], :default=>nil}, {:name=>"action", :type=>{:name=>"__statement_action_enum", :type=>:enum, :namespace=>"com.salsify.security", :symbols=>[:manage, :read]}}, {:name=>"resource", :type=>{:name=>"__statement_resource_enum", :type=>:enum, :namespace=>"com.salsify.security", :symbols=>[:product, :digital_asset]}}, {:name=>"conditions", :type=>{:type=>:array, :items=>{:type=>:record, :name=>:condition, :namespace=>"com.salsify.security", :fields=>[{:name=>"created_at", :type=>{:type=>"long", :logicalType=>"timestamp-micros"}}, {:name=>"updated_at", :type=>{:type=>"long", :logicalType=>"timestamp-micros"}}, {:name=>"id", :type=>"com.salsify.salsify_uuid"}, {:name=>"type", :type=>"string", :default=>"conditions"}, {:name=>"external_id", :type=>[:null, "string"], :default=>nil}, {:name=>"operator", :type=>{:name=>"__condition_operator_enum", :type=>:enum, :namespace=>"com.salsify.security", :symbols=>[:equals]}}, {:name=>"attribute_type", :type=>{:name=>"__condition_attribute_type_enum", :type=>:enum, :namespace=>"com.salsify.security", :symbols=>[:resource]}}, {:name=>"value", :type=>"string"}, {:name=>"attribute", :type=>[:null, {:type=>:record, :name=>:reference, :namespace=>"com.salsify", :fields=>[{:name=>"id", :type=>"com.salsify.salsify_uuid"}, {:name=>"type", :type=>"string", :doc=>"snake_case, plural name for the resource type"}, {:name=>"external_id", :type=>[:null, "string"], :default=>nil}]}], :default=>nil}, {:name=>"broken", :type=>[:null, "boolean"], :default=>nil}]}}}]}}}]}], :default=>nil}]}
10
-
11
- #Oj.dump(h)
12
- puts JSON.pretty_generate(h)
13
- #puts JSON.fast_generate(h)
14
- #puts JSON.generate(h)
15
-
@@ -1,45 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: utf-8
3
-
4
- %w(lib ext test).each do |dir|
5
- $LOAD_PATH.unshift File.expand_path("../../#{dir}", __FILE__)
6
- end
7
-
8
- require 'oj'
9
-
10
- json =<<-EOF
11
- {
12
- "$id": "https://example.com/person.schema.json",
13
- "$schema": "https://json-schema.org/draft/2020-12/schema",
14
- "title": "Person",
15
- "type": "object",
16
- "properties": {
17
- "firstName": {
18
- "type": "string",
19
- "description": "The person's first name."
20
- },
21
- "lastName": {
22
- "type": "string",
23
- "description": "The person's last name."
24
- },
25
- "age": {
26
- "description": "Age in years which must be equal to or greater than zero.",
27
- "type": "integer",
28
- "minimum": 0
29
- }
30
- }
31
- }
32
- EOF
33
-
34
- #json = '{"abc": true}'
35
- #json = '[true,false]'
36
-
37
- 100_001.times do |i|
38
- p = Oj::Parser.new(:usual).parse(json)
39
-
40
- if i % 10_000 == 0
41
- GC.start
42
- rss = Integer(`ps -o rss= -p #{Process.pid}`) / 1024.0
43
- puts "#{i},#{rss} MB"
44
- end
45
- end