panko_serializer 0.1.6 → 0.1.7

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
  SHA1:
3
- metadata.gz: 191ab315beed684a1a584eccdcfb500521e5f3b5
4
- data.tar.gz: bdc4bf8c0bdc1e66b09a0221d640ec033b21463c
3
+ metadata.gz: ae00bf37cb1dcce9c00df00c32e4f23bdba6081c
4
+ data.tar.gz: '08e3f85bd87fe2a6c94b4210d53c605c5f5c2f53'
5
5
  SHA512:
6
- metadata.gz: 1075d2458fc18945ece197e3c1b45ed19d7c37cfcad48beed72ee38d0b147b1a338b756ddce9a740d24681192a3a7159953daee5816d182678921d5c818b72ca
7
- data.tar.gz: 278b97815ce09041391744fd01c385e92b0b8bcc54edeecc1250a7f9cc459f19fe5df0d43d77e955e5b6d717677fd81ee67baaa2c5dc87da4b68551da28b921e
6
+ metadata.gz: 158ff5e032d418ae77b9758e9b84429029738c8cc09f40b3ac8d01c29490a1824e9785df97b066fd0bec83f9b2e17728a29680cf90966e0f3908d954e60990e7
7
+ data.tar.gz: 25d8c763c866c2987ad320a72c3a1d9ec93f10a82f6d909d1fe549479262211752c8e79bf70eb2626fba39554482262663b5b5c6c435ae5f2cbe7860dfc63a28
@@ -4,14 +4,14 @@ require "json"
4
4
  require "memory_profiler"
5
5
 
6
6
  module Benchmark
7
- module ActiveModelSerializers
7
+ module Runner
8
8
  def data
9
9
  posts = Post.all.includes(:author).to_a
10
10
  posts_50 = posts.first(50).to_a
11
11
  { all: posts, small: posts_50 }
12
12
  end
13
13
 
14
- def ams(label = nil, time: 10, disable_gc: true, warmup: 3, &block)
14
+ def run(label = nil, time: 10, disable_gc: true, warmup: 3, &block)
15
15
  fail ArgumentError.new, "block should be passed" unless block_given?
16
16
 
17
17
  GC.start
@@ -39,5 +39,5 @@ module Benchmark
39
39
  end
40
40
  end
41
41
 
42
- extend Benchmark::ActiveModelSerializers
42
+ extend Benchmark::Runner
43
43
  end
@@ -25,7 +25,7 @@ def benchmark_ams(prefix, serializer, options = {})
25
25
  posts_50 = data[:small]
26
26
 
27
27
 
28
- Benchmark.ams("AMS_#{prefix}_Posts_#{posts.count}") do
28
+ Benchmark.run("AMS_#{prefix}_Posts_#{posts.count}") do
29
29
  ActiveModel::ArraySerializer.new(posts, merged_options).serializable_object
30
30
  end
31
31
 
@@ -33,7 +33,7 @@ def benchmark_ams(prefix, serializer, options = {})
33
33
  posts = data[:all]
34
34
  posts_50 = data[:small]
35
35
 
36
- Benchmark.ams("AMS_#{prefix}_Posts_50") do
36
+ Benchmark.run("AMS_#{prefix}_Posts_50") do
37
37
  ActiveModel::ArraySerializer.new(posts_50, merged_options).serializable_object
38
38
  end
39
39
  end
@@ -75,7 +75,7 @@ def request(method, path)
75
75
  end
76
76
 
77
77
 
78
- Benchmark.ams("text") { request(:get, "/text") }
79
- Benchmark.ams("simple") { request(:get, "/simple") }
78
+ Benchmark.run("text") { request(:get, "/text") }
79
+ Benchmark.run("simple") { request(:get, "/simple") }
80
80
 
81
- Benchmark.ams("serialize_to_string") { request(:get, "/serialize_to_string") }
81
+ Benchmark.run("serialize_to_string") { request(:get, "/serialize_to_string") }
@@ -40,7 +40,7 @@ def benchmark(prefix, serializer, options = {})
40
40
 
41
41
  merged_options = options.merge(each_serializer: serializer)
42
42
 
43
- Benchmark.ams("Panko_#{prefix}_Posts_#{posts.count}") do
43
+ Benchmark.run("Panko_#{prefix}_Posts_#{posts.count}") do
44
44
  Panko::ArraySerializer.new(posts, merged_options).to_json
45
45
  end
46
46
 
@@ -48,7 +48,7 @@ def benchmark(prefix, serializer, options = {})
48
48
  posts = data[:all]
49
49
  posts_50 = data[:small]
50
50
 
51
- Benchmark.ams("Panko_#{prefix}_Posts_50") do
51
+ Benchmark.run("Panko_#{prefix}_Posts_50") do
52
52
  Panko::ArraySerializer.new(posts_50, merged_options).to_json
53
53
  end
54
54
  end
@@ -32,7 +32,7 @@ def benchmark(prefix, serializer, options = {})
32
32
 
33
33
  merged_options = options.merge(each_serializer: serializer)
34
34
 
35
- Benchmark.ams("Panko_#{prefix}_Posts_#{posts.count}") do
35
+ Benchmark.run("Panko_#{prefix}_Posts_#{posts.count}") do
36
36
  Panko::ArraySerializer.new(posts, merged_options).to_a
37
37
  end
38
38
 
@@ -40,7 +40,7 @@ def benchmark(prefix, serializer, options = {})
40
40
  posts = data[:all]
41
41
  posts_50 = data[:small]
42
42
 
43
- Benchmark.ams("Panko_#{prefix}_Posts_50") do
43
+ Benchmark.run("Panko_#{prefix}_Posts_50") do
44
44
  Panko::ArraySerializer.new(posts_50, merged_options).to_a
45
45
  end
46
46
 
@@ -50,7 +50,7 @@ def benchmark(prefix, serializer, options = {})
50
50
  posts = data[:all]
51
51
  posts_50 = data[:small]
52
52
 
53
- Benchmark.ams("Panko_Reused_#{prefix}_Posts_#{posts.count}") do
53
+ Benchmark.run("Panko_Reused_#{prefix}_Posts_#{posts.count}") do
54
54
  posts_array_serializer.serialize posts
55
55
  end
56
56
 
@@ -58,7 +58,7 @@ def benchmark(prefix, serializer, options = {})
58
58
  posts = data[:all]
59
59
  posts_50 = data[:small]
60
60
 
61
- Benchmark.ams("Panko_Reused_#{prefix}_Posts_50") do
61
+ Benchmark.run("Panko_Reused_#{prefix}_Posts_50") do
62
62
  posts_array_serializer.serialize posts_50
63
63
  end
64
64
  end
data/benchmarks/sanity.rb CHANGED
@@ -40,7 +40,7 @@ def benchmark(prefix, serializer, options = {})
40
40
 
41
41
  merged_options = options.merge(each_serializer: serializer)
42
42
 
43
- Benchmark.ams("Panko_#{prefix}_Posts_#{posts.count}") do
43
+ Benchmark.run("Panko_#{prefix}_Posts_#{posts.count}") do
44
44
  Panko::ArraySerializer.new(posts, merged_options).to_json
45
45
  end
46
46
 
@@ -48,20 +48,14 @@ def benchmark(prefix, serializer, options = {})
48
48
  posts = data[:all]
49
49
  posts_50 = data[:small]
50
50
 
51
- Benchmark.ams("Panko_#{prefix}_Posts_50") do
51
+ Benchmark.run("Panko_#{prefix}_Posts_50") do
52
52
  Panko::ArraySerializer.new(posts_50, merged_options).to_json
53
53
  end
54
54
  end
55
55
 
56
- #puts "Waiting .. #{Process.pid}"
57
- #gets.chomp
58
56
 
59
- #puts "Starting!"
57
+
60
58
 
61
59
  benchmark 'SimpleWithMethodCall', PostFastWithMethodCallSerializer
62
60
  benchmark "HasOne", PostWithHasOneFastSerializer
63
61
  benchmark "Simple", PostFastSerializer
64
-
65
- # benchmark 'SimpleWithMethodCall', PostFastWithMethodCallSerializer
66
- # benchmark 'Except', PostWithHasOneFastSerializer, except: [:title]
67
- # benchmark 'Include', PostWithHasOneFastSerializer, include: [:id, :body, :author_id, :author]
@@ -5,11 +5,11 @@ def ar_type_convert(type_klass, from, to)
5
5
  converter = type_klass.new
6
6
  assert type_klass.name, converter.type_cast_from_database(from), to
7
7
 
8
- Benchmark.ams("#{type_klass.name}_TypeCast") do
8
+ Benchmark.run("#{type_klass.name}_TypeCast") do
9
9
  converter.type_cast_from_database(from)
10
10
  end
11
11
 
12
- Benchmark.ams("#{type_klass.name}_NoTypeCast") do
12
+ Benchmark.run("#{type_klass.name}_NoTypeCast") do
13
13
  converter.type_cast_from_database(to)
14
14
  end
15
15
  end
@@ -22,7 +22,7 @@ def utc_ar_time
22
22
  type = ActiveRecord::ConnectionAdapters::PostgreSQL::OID::DateTime.new
23
23
  converter = ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter.new(type)
24
24
 
25
- Benchmark.ams("#{tz}_#{type.class.name}_TypeCast") do
25
+ Benchmark.run("#{tz}_#{type.class.name}_TypeCast") do
26
26
  converter.type_cast_from_database(from).iso8601
27
27
  end
28
28
  end
@@ -35,7 +35,7 @@ def db_ar_time
35
35
 
36
36
  from = "2017-07-10 09:26:40.937392"
37
37
 
38
- Benchmark.ams("ActiveRecord_Time_TypeCast_WithISO8601") do
38
+ Benchmark.run("ActiveRecord_Time_TypeCast_WithISO8601") do
39
39
  converter.type_cast_from_database(from).iso8601
40
40
  end
41
41
  end
@@ -5,11 +5,11 @@ def panko_type_convert(type_klass, from, to)
5
5
  converter = type_klass.new
6
6
  assert "#{type_klass.name}", Panko::_type_cast(converter, from), to
7
7
 
8
- Benchmark.ams("#{type_klass.name}_TypeCast") do
8
+ Benchmark.run("#{type_klass.name}_TypeCast") do
9
9
  Panko::_type_cast(converter, from)
10
10
  end
11
11
 
12
- Benchmark.ams("#{type_klass.name}_NoTypeCast") do
12
+ Benchmark.run("#{type_klass.name}_NoTypeCast") do
13
13
  Panko::_type_cast(converter, to)
14
14
  end
15
15
  end
@@ -25,11 +25,11 @@ def utc_panko_time
25
25
 
26
26
  to = Panko::_type_cast(converter, from)
27
27
 
28
- Benchmark.ams("#{tz}_#{type.class.name}_TypeCast") do
28
+ Benchmark.run("#{tz}_#{type.class.name}_TypeCast") do
29
29
  Panko::_type_cast(converter, from)
30
30
  end
31
31
 
32
- Benchmark.ams("#{tz}_#{type.class.name}_NoTypeCast") do
32
+ Benchmark.run("#{tz}_#{type.class.name}_NoTypeCast") do
33
33
  Panko::_type_cast(converter, to)
34
34
  end
35
35
  end
@@ -40,7 +40,7 @@ def db_panko_time
40
40
 
41
41
  from = "2017-07-10 09:26:40.937392"
42
42
 
43
- Benchmark.ams("Panko_Time_TypeCast") do
43
+ Benchmark.run("Panko_Time_TypeCast") do
44
44
  Panko::_type_cast(converter, from)
45
45
  end
46
46
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  static ID attributes_id;
4
4
  static ID types_id;
5
+ static ID additional_types_id;
5
6
  static ID values_id;
6
7
  static ID delegate_hash_id;
7
8
 
@@ -30,13 +31,16 @@ VALUE panko_read_lazy_attributes_hash(VALUE object) {
30
31
 
31
32
  void panko_read_types_and_value(VALUE attributes_hash,
32
33
  VALUE* types,
34
+ VALUE* additional_types,
33
35
  VALUE* values) {
34
36
  *types = rb_ivar_get(attributes_hash, types_id);
37
+ *additional_types = rb_ivar_get(attributes_hash, additional_types_id);
35
38
  *values = rb_ivar_get(attributes_hash, values_id);
36
39
  }
37
40
 
38
41
  VALUE panko_each_attribute(VALUE obj,
39
42
  VALUE attributes,
43
+ VALUE aliases,
40
44
  EachAttributeFunc func,
41
45
  VALUE context) {
42
46
  volatile VALUE attributes_hash, delegate_hash;
@@ -50,11 +54,16 @@ VALUE panko_each_attribute(VALUE obj,
50
54
  delegate_hash = rb_ivar_get(attributes_hash, delegate_hash_id);
51
55
  bool tryToReadFromDelegateHash = RHASH_SIZE(delegate_hash) > 0;
52
56
 
53
- VALUE types, values;
54
- panko_read_types_and_value(attributes_hash, &types, &values);
57
+ VALUE types, additional_types, values;
58
+ panko_read_types_and_value(attributes_hash, &types, &additional_types,
59
+ &values);
60
+ bool tryToReadFromAdditionalTypes = RHASH_SIZE(additional_types) > 0;
61
+
62
+ bool tryToReadFromAliases = RHASH_SIZE(aliases) > 0;
55
63
 
56
64
  for (i = 0; i < RARRAY_LEN(attributes); i++) {
57
- volatile VALUE member = rb_sym2str(RARRAY_AREF(attributes, i));
65
+ volatile VALUE member_raw = RARRAY_AREF(attributes, i);
66
+ volatile VALUE member = rb_sym2str(member_raw);
58
67
 
59
68
  volatile VALUE value = Qundef;
60
69
  volatile VALUE type_metadata = Qnil;
@@ -72,7 +81,20 @@ VALUE panko_each_attribute(VALUE obj,
72
81
 
73
82
  if (value == Qundef) {
74
83
  value = rb_hash_aref(values, member);
75
- type_metadata = rb_hash_aref(types, member);
84
+
85
+ if (tryToReadFromAdditionalTypes) {
86
+ type_metadata = rb_hash_aref(additional_types, member);
87
+ }
88
+ if (type_metadata == Qnil) {
89
+ type_metadata = rb_hash_aref(types, member);
90
+ }
91
+ }
92
+
93
+ if(tryToReadFromAliases) {
94
+ volatile VALUE alias_name = rb_hash_aref(aliases, member_raw);
95
+ if(alias_name != Qnil) {
96
+ member = rb_sym2str(alias_name);
97
+ }
76
98
  }
77
99
 
78
100
  func(obj, member, value, type_metadata, context);
@@ -86,6 +108,7 @@ void panko_init_attributes_iterator(VALUE mPanko) {
86
108
  delegate_hash_id = rb_intern("@delegate_hash");
87
109
  values_id = rb_intern("@values");
88
110
  types_id = rb_intern("@types");
111
+ additional_types_id = rb_intern("@additional_types");
89
112
  type_id = rb_intern("@type");
90
113
  value_before_type_cast_id = rb_intern("@value_before_type_cast");
91
114
  }
@@ -11,6 +11,7 @@ typedef void (*EachAttributeFunc)(VALUE object,
11
11
 
12
12
  extern VALUE panko_each_attribute(VALUE object,
13
13
  VALUE attributes,
14
+ VALUE aliases,
14
15
  EachAttributeFunc func,
15
16
  VALUE context);
16
17
 
@@ -48,16 +48,16 @@ void panko_attributes_iter(VALUE object,
48
48
  VALUE name,
49
49
  VALUE value,
50
50
  VALUE type_metadata,
51
- VALUE context) {
52
- write_value(context, name, value, type_metadata);
51
+ VALUE str_writer) {
52
+ write_value(str_writer, name, value, type_metadata);
53
53
  }
54
54
 
55
55
  void serialize_fields(VALUE subject,
56
56
  VALUE str_writer,
57
57
  SerializationDescriptor descriptor,
58
58
  VALUE context) {
59
- panko_each_attribute(subject, descriptor->fields, panko_attributes_iter,
60
- str_writer);
59
+ panko_each_attribute(subject, descriptor->fields, descriptor->aliases,
60
+ panko_attributes_iter, str_writer);
61
61
 
62
62
  serialize_method_fields(subject, str_writer, descriptor, context);
63
63
  }
@@ -18,6 +18,7 @@ static void serialization_descriptor_free(void* ptr) {
18
18
  sd->method_fields = Qnil;
19
19
  sd->has_one_associations = Qnil;
20
20
  sd->has_many_associations = Qnil;
21
+ sd->aliases = Qnil;
21
22
  }
22
23
 
23
24
  void serialization_descriptor_mark(SerializationDescriptor data) {
@@ -27,6 +28,7 @@ void serialization_descriptor_mark(SerializationDescriptor data) {
27
28
  rb_gc_mark(data->method_fields);
28
29
  rb_gc_mark(data->has_one_associations);
29
30
  rb_gc_mark(data->has_many_associations);
31
+ rb_gc_mark(data->aliases);
30
32
  }
31
33
 
32
34
  static VALUE serialization_descriptor_new(int argc, VALUE* argv, VALUE self) {
@@ -38,6 +40,7 @@ static VALUE serialization_descriptor_new(int argc, VALUE* argv, VALUE self) {
38
40
  sd->method_fields = Qnil;
39
41
  sd->has_one_associations = Qnil;
40
42
  sd->has_many_associations = Qnil;
43
+ sd->aliases = Qnil;
41
44
 
42
45
  return Data_Wrap_Struct(cSerializationDescriptor,
43
46
  serialization_descriptor_mark,
@@ -126,6 +129,17 @@ VALUE serialization_descriptor_type_aref(VALUE self, VALUE type) {
126
129
  return sd->serializer_type;
127
130
  }
128
131
 
132
+ VALUE serialization_descriptor_aliases_set(VALUE self, VALUE aliases) {
133
+ SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
134
+ sd->aliases = aliases;
135
+ return Qnil;
136
+ }
137
+
138
+ VALUE serialization_descriptor_aliases_aref(VALUE self, VALUE aliases) {
139
+ SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
140
+ return sd->aliases;
141
+ }
142
+
129
143
  // Exposing this for testing
130
144
  VALUE serialization_descriptor_build_serializer(VALUE self) {
131
145
  SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
@@ -165,8 +179,13 @@ void panko_init_serialization_descriptor(VALUE mPanko) {
165
179
 
166
180
  rb_define_method(cSerializationDescriptor,
167
181
  "type=", serialization_descriptor_type_set, 1);
182
+ rb_define_method(cSerializationDescriptor, "type",
183
+ serialization_descriptor_type_aref, 0);
184
+
168
185
  rb_define_method(cSerializationDescriptor,
169
- "type", serialization_descriptor_type_aref, 0);
186
+ "aliases=", serialization_descriptor_aliases_set, 1);
187
+ rb_define_method(cSerializationDescriptor, "aliases",
188
+ serialization_descriptor_aliases_aref, 0);
170
189
 
171
190
  rb_define_method(cSerializationDescriptor, "build_serializer",
172
191
  serialization_descriptor_build_serializer, 0);
@@ -12,6 +12,7 @@ typedef struct _SerializationDescriptor {
12
12
  // Metadata
13
13
  VALUE fields;
14
14
  VALUE method_fields;
15
+ VALUE aliases;
15
16
  VALUE has_one_associations;
16
17
  VALUE has_many_associations;
17
18
  } * SerializationDescriptor;
@@ -26,6 +26,8 @@ module Panko
26
26
  backend.has_many_associations = descriptor.has_many_associations
27
27
  backend.has_one_associations = descriptor.has_one_associations
28
28
 
29
+ backend.aliases = descriptor.aliases
30
+
29
31
  backend
30
32
  end
31
33
 
@@ -108,10 +110,5 @@ module Panko
108
110
 
109
111
  fields
110
112
  end
111
-
112
-
113
- def self.resolve_serializer(serializer)
114
- Object.const_get(serializer.name)
115
- end
116
113
  end
117
114
  end
@@ -9,6 +9,7 @@ module Panko
9
9
  base._descriptor = Panko::SerializationDescriptor.new
10
10
  base._descriptor.type = base
11
11
 
12
+ base._descriptor.aliases = {}
12
13
  base._descriptor.fields = []
13
14
  base._descriptor.method_fields = []
14
15
  base._descriptor.has_many_associations = []
@@ -21,6 +22,11 @@ module Panko
21
22
  @_descriptor.fields.push(*attrs).uniq!
22
23
  end
23
24
 
25
+ def aliases(aliases = {})
26
+ @_descriptor.aliases = aliases
27
+ attributes(*aliases.keys)
28
+ end
29
+
24
30
  def method_added(method)
25
31
  return if @_descriptor.nil?
26
32
  @_descriptor.fields.delete(method)
@@ -28,7 +34,7 @@ module Panko
28
34
  end
29
35
 
30
36
  def has_one(name, options)
31
- serializer_const = Panko::SerializationDescriptor.resolve_serializer(options[:serializer])
37
+ serializer_const = options[:serializer]
32
38
 
33
39
  @_descriptor.has_one_associations << [
34
40
  name,
@@ -37,7 +43,7 @@ module Panko
37
43
  end
38
44
 
39
45
  def has_many(name, options)
40
- serializer_const = Panko::SerializationDescriptor.resolve_serializer(options[:serializer])
46
+ serializer_const = options[:serializer] || options[:each_serializer]
41
47
 
42
48
  @_descriptor.has_many_associations << [
43
49
  name,
data/lib/panko/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Panko
3
- VERSION = "0.1.6"
3
+ VERSION = "0.1.7"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: panko_serializer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yosi Attias
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-17 00:00:00.000000000 Z
11
+ date: 2017-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -110,7 +110,6 @@ files:
110
110
  - benchmarks/setup.rb
111
111
  - benchmarks/type_casts/bm_active_record.rb
112
112
  - benchmarks/type_casts/bm_panko.rb
113
- - benchmarks/type_casts/bm_pg.rb
114
113
  - benchmarks/type_casts/support.rb
115
114
  - ext/panko_serializer/attributes_iterator.c
116
115
  - ext/panko_serializer/attributes_iterator.h
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
- require_relative "./support"
3
-
4
- def pg_type_convert(type_klass, from, to)
5
- converter = type_klass.new
6
- assert type_klass.name, converter.decode(from), to
7
-
8
- Benchmark.ams("#{type_klass.name}_TypeCast") do
9
- converter.decode(from)
10
- end
11
- end
12
-
13
- def pg_time
14
- decoder = PG::TextDecoder::TimestampWithoutTimeZone.new
15
-
16
- from = "2017-07-10 09:26:40.937392"
17
-
18
- Benchmark.ams("#{decoder.class.name}_TypeCast") do
19
- decoder.decode(from)
20
- end
21
-
22
- Benchmark.ams("#{decoder.class.name}_TypeCast_InTimeZone") do
23
- decoder.decode(from).in_time_zone
24
- end
25
- end
26
-
27
-
28
-
29
-
30
- pg_type_convert PG::TextDecoder::Integer, "1", 1
31
- pg_type_convert PG::TextDecoder::Float, "1.23", 1.23
32
- pg_type_convert PG::TextDecoder::Float, "Infinity", ::Float::INFINITY
33
- pg_type_convert PG::TextDecoder::Float, "-Infinity", ::Float::INFINITY
34
- pg_type_convert PG::TextDecoder::Float, "NaN", ::Float::NaN
35
- pg_time