Skip to content

Commit e2d8910

Browse files
Caching various string manipulations
1 parent 1264f13 commit e2d8910

File tree

5 files changed

+91
-24
lines changed

5 files changed

+91
-24
lines changed

lib/jsonapi-resources.rb

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require 'jsonapi/naive_cache'
12
require 'jsonapi/resource'
23
require 'jsonapi/response_document'
34
require 'jsonapi/acts_as_resource_controller'

lib/jsonapi/formatter.rb

+46-12
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@ def unformat(arg)
99
arg
1010
end
1111

12+
@@format_to_formatter_cache = JSONAPI::NaiveCache.new do |format|
13+
"#{format.to_s.camelize}Formatter".safe_constantize
14+
end
15+
1216
def formatter_for(format)
13-
formatter_class_name = "#{format.to_s.camelize}Formatter"
14-
formatter_class_name.safe_constantize
17+
@@format_to_formatter_cache.calc(format)
1518
end
1619
end
1720
end
@@ -50,9 +53,12 @@ def unformat(value)
5053
super(value)
5154
end
5255

56+
@@value_type_to_formatter_cache = JSONAPI::NaiveCache.new do |type|
57+
"#{type.to_s.camelize}ValueFormatter".safe_constantize
58+
end
59+
5360
def value_formatter_for(type)
54-
formatter_name = "#{type.to_s.camelize}Value"
55-
formatter_for(formatter_name)
61+
@@value_type_to_formatter_cache.calc(type)
5662
end
5763
end
5864
end
@@ -63,24 +69,38 @@ class UnderscoredKeyFormatter < JSONAPI::KeyFormatter
6369

6470
class CamelizedKeyFormatter < JSONAPI::KeyFormatter
6571
class << self
72+
@@format_cache = JSONAPI::NaiveCache.new do |key|
73+
key.to_s.camelize(:lower)
74+
end
75+
@@unformat_cache = JSONAPI::NaiveCache.new do |formatted_key|
76+
formatted_key.to_s.underscore
77+
end
78+
6679
def format(key)
67-
super.camelize(:lower)
80+
@@format_cache.calc(key)
6881
end
6982

7083
def unformat(formatted_key)
71-
formatted_key.to_s.underscore
84+
@@unformat_cache.calc(formatted_key)
7285
end
7386
end
7487
end
7588

7689
class DasherizedKeyFormatter < JSONAPI::KeyFormatter
7790
class << self
91+
@@format_cache = JSONAPI::NaiveCache.new do |key|
92+
key.to_s.underscore.dasherize
93+
end
94+
@@unformat_cache = JSONAPI::NaiveCache.new do |formatted_key|
95+
formatted_key.to_s.underscore
96+
end
97+
7898
def format(key)
79-
super.underscore.dasherize
99+
@@format_cache.calc(key)
80100
end
81101

82102
def unformat(formatted_key)
83-
formatted_key.to_s.underscore
103+
@@unformat_cache.calc(formatted_key)
84104
end
85105
end
86106
end
@@ -107,24 +127,38 @@ class UnderscoredRouteFormatter < JSONAPI::RouteFormatter
107127

108128
class CamelizedRouteFormatter < JSONAPI::RouteFormatter
109129
class << self
130+
@@format_cache = JSONAPI::NaiveCache.new do |route|
131+
route.to_s.camelize(:lower)
132+
end
133+
@@unformat_cache = JSONAPI::NaiveCache.new do |formatted_route|
134+
formatted_route.to_s.underscore
135+
end
136+
110137
def format(route)
111-
super.camelize(:lower)
138+
@@format_cache.calc(route)
112139
end
113140

114141
def unformat(formatted_route)
115-
formatted_route.to_s.underscore
142+
@@unformat_cache.calc(formatted_route)
116143
end
117144
end
118145
end
119146

120147
class DasherizedRouteFormatter < JSONAPI::RouteFormatter
121148
class << self
149+
@@format_cache = JSONAPI::NaiveCache.new do |route|
150+
route.to_s.dasherize
151+
end
152+
@@unformat_cache = JSONAPI::NaiveCache.new do |formatted_route|
153+
formatted_route.to_s.underscore
154+
end
155+
122156
def format(route)
123-
super.dasherize
157+
@@format_cache.calc(route)
124158
end
125159

126160
def unformat(formatted_route)
127-
formatted_route.to_s.underscore
161+
@@unformat_cache.calc(formatted_route)
128162
end
129163
end
130164
end

lib/jsonapi/link_builder.rb

+10-9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ def initialize(config = {})
99
@primary_resource_klass = config[:primary_resource_klass]
1010
@route_formatter = config[:route_formatter]
1111
@is_engine = !!engine_name
12+
13+
@resources_path_cache = JSONAPI::NaiveCache.new do |source_klass|
14+
formatted_module_path_from_class(source_klass) + format_route(source_klass._type.to_s)
15+
end
1216
end
1317

1418
def engine?
@@ -113,23 +117,20 @@ def module_scopes_from_class(klass)
113117
klass.name.to_s.split("::")[0...-1]
114118
end
115119

120+
def regular_resources_path(source_klass)
121+
@resources_path_cache.calc(source_klass)
122+
end
123+
116124
def regular_primary_resources_path
117-
[
118-
formatted_module_path_from_class(primary_resource_klass),
119-
format_route(primary_resource_klass._type.to_s),
120-
].join
125+
regular_resources_path(primary_resource_klass)
121126
end
122127

123128
def regular_primary_resources_url
124129
"#{ base_url }#{ regular_primary_resources_path }"
125130
end
126131

127132
def regular_resource_path(source)
128-
[
129-
formatted_module_path_from_class(source.class),
130-
format_route(source.class._type.to_s),
131-
"/#{ source.id }",
132-
].join
133+
"#{regular_resources_path(source.class)}/#{source.id}"
133134
end
134135

135136
def regular_resource_url(source)

lib/jsonapi/naive_cache.rb

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module JSONAPI
2+
class NaiveCache
3+
def initialize(cap = 1024, &calculator)
4+
@data = {}
5+
@cap = cap
6+
@calculator = calculator
7+
end
8+
9+
def calc(key)
10+
value = @data.fetch(key, nil)
11+
return value unless value.nil?
12+
value = @calculator.call(key)
13+
raise "Cannot cache nil value (calculated for #{key})" if value.nil?
14+
@data[key] = value
15+
@data.shift if @data.length > @cap
16+
return value
17+
end
18+
end
19+
end

lib/jsonapi/resource.rb

+15-3
Original file line numberDiff line numberDiff line change
@@ -350,16 +350,28 @@ def resource_for_model(model)
350350
resource_for(resource_type_for(model))
351351
end
352352

353-
def _resource_name_from_type(type)
353+
@@type_name_to_resource_name_cache = JSONAPI::NaiveCache.new do |type|
354354
"#{type.to_s.underscore.singularize}_resource".camelize
355355
end
356356

357+
def _resource_name_from_type(type)
358+
@@type_name_to_resource_name_cache.calc(type)
359+
end
360+
361+
@@model_to_model_name_cache = JSONAPI::NaiveCache.new do |model|
362+
model.class.to_s.underscore
363+
end
364+
365+
@@model_name_to_resource_type_cache = JSONAPI::NaiveCache.new do |model_name|
366+
model_name.rpartition('/').last
367+
end
368+
357369
def resource_type_for(model)
358-
model_name = model.class.to_s.underscore
370+
model_name = @@model_to_model_name_cache.calc(model)
359371
if _model_hints[model_name]
360372
_model_hints[model_name]
361373
else
362-
model_name.rpartition('/').last
374+
@@model_name_to_resource_type_cache.calc(model_name)
363375
end
364376
end
365377

0 commit comments

Comments
 (0)