new optimization: get all the page handles once when rendering the page (average 10% speed boost with the MongoDB adapter)

did committed Aug 26, 2015
commit bcaa54f3739f96decc4a8f16aa5c68c0c649026f
Showing 9 changed files with 46 additions and 17 deletions
locomotive/steam/adapters/mongodb/query.rb b/lib/locomotive/steam/adapters/mongodb/query.rb +6 -0
@@ @@ -59,6 +59,12 @@ module Locomotive::Steam
build_origin_query.only(@fields).where(@criteria).order_by(*@sort)
end
+ def key(name, operator)
+ :"#{name}".send(operator.to_sym)
+ end
+
+ alias :k :key
+
private
def build_origin_query
locomotive/steam/liquid/tags/concerns/i18n_page.rb b/lib/locomotive/steam/liquid/tags/concerns/i18n_page.rb +0 -9
@@ @@ -18,15 +18,6 @@ module Locomotive
end
end
- # def build_fullpath(page)
- # services.url_builder.url_for(page, locale).tap do |fullpath|
- # if page.templatized?
- # entry = page.send(:_source).content_entry
- # fullpath.gsub!('content_type_template', entry._slug)
- # end
- # end
- # end
-
end
end
locomotive/steam/liquid/tags/concerns/path.rb b/lib/locomotive/steam/liquid/tags/concerns/path.rb +1 -1
@@ @@ -66,7 +66,7 @@ module Locomotive
end
def _retrieve_page_drop_from(handle)
- if page = repository.by_handle(handle)
+ if page = services.page_finder.by_handle(handle)
page.to_liquid.tap { |d| d.context = @context }
end
end
locomotive/steam/repositories/page_repository.rb b/lib/locomotive/steam/repositories/page_repository.rb +7 -0
@@ @@ -26,6 +26,13 @@ module Locomotive
end.all
end
+ def only_handle_and_fullpath
+ query do
+ where(k(:handle, :ne) => nil).
+ only(:_id, :handle, :fullpath)
+ end.all
+ end
+
def by_handle(handle)
first { where(handle: handle) }
end
locomotive/steam/repositories/site_repository.rb b/lib/locomotive/steam/repositories/site_repository.rb +1 -2
@@ @@ -11,8 +11,7 @@ module Locomotive
end
def by_domain(domain)
- conditions = { k(:domains, :in) => [*domain] }
- first { where(conditions) }
+ first { where(k(:domains, :in) => [*domain]) }
end
def by_handle_or_domain(handle, domain)
locomotive/steam/services/page_finder_service.rb b/lib/locomotive/steam/services/page_finder_service.rb +21 -0
@@ @@ -17,8 +17,29 @@ module Locomotive
end
end
+ def by_handle(handle)
+ decorate { page_map[handle] }
+ end
+
private
+ # Instead of hitting the DB each time we want a page from its handle,
+ # just get all the handles at once and cache the result. (up to 20% boost)
+ #
+ def page_map
+ @page_map ||= {}
+
+ return @page_map[repository.locale] if @page_map[repository.locale]
+
+ {}.tap do |map|
+ repository.only_handle_and_fullpath.each do |page|
+ map[page.handle] = page
+ end
+
+ @page_map[repository.locale] = map
+ end
+ end
+
def path_combinations(path)
_path_combinations(path.split('/'))
end
spec/integration/repositories/page_repository_spec.rb +5 -0
@@ @@ -37,6 +37,11 @@ describe Locomotive::Steam::PageRepository do
it { expect(subject.title[:en]).to eq 'Music' }
end
+ describe '#only_handle_and_fullpath' do
+ subject { repository.only_handle_and_fullpath }
+ it { expect(subject.size).to eq 3 }
+ end
+
describe '#by_fullpath' do
subject { repository.by_fullpath('archives/news') }
it { expect(subject.title[:en]).to eq 'News archive' }
spec/unit/liquid/tags/link_to_spec.rb +2 -2
@@ @@ -30,7 +30,7 @@ describe Locomotive::Steam::Liquid::Tags::PathTo do
let(:source) { '{% link_to index %}' }
before do
- expect(services.repositories.page).to receive(:by_handle).with('index').and_return(nil)
+ expect(services.page_finder).to receive(:by_handle).with('index').and_return(nil)
end
it { is_expected.to eq '' }
@@ @@ -44,7 +44,7 @@ describe Locomotive::Steam::Liquid::Tags::PathTo do
let(:fullpath) { { en: 'index', fr: 'index' } }
before do
- allow(services.repositories.page).to receive(:by_handle).with('index').and_return(page)
+ allow(services.page_finder).to receive(:by_handle).with('index').and_return(page)
allow(page).to receive(:to_liquid).and_return(drop)
end
spec/unit/liquid/tags/path_to_spec.rb +3 -3
@@ @@ -4,7 +4,7 @@ describe Locomotive::Steam::Liquid::Tags::PathTo do
let(:assigns) { {} }
let(:services) { Locomotive::Steam::Services.build_instance }
- let(:site) { instance_double('Site', default_locale: 'en') }
+ let(:site) { instance_double('Site', locales: ['en'], default_locale: 'en') }
let(:context) { ::Liquid::Context.new(assigns, {}, { services: services, site: site, locale: 'en' }) }
subject { render_template(source, context) }
@@ @@ -23,7 +23,7 @@ describe Locomotive::Steam::Liquid::Tags::PathTo do
let(:source) { '{% path_to index %}' }
before do
- expect(services.repositories.page).to receive(:by_handle).with('index').and_return(nil)
+ expect(services.page_finder).to receive(:by_handle).with('index').and_return(nil)
end
it { is_expected.to eq '' }
@@ @@ -38,7 +38,7 @@ describe Locomotive::Steam::Liquid::Tags::PathTo do
let(:source) { '{% path_to index %}' }
before do
- expect(services.repositories.page).to receive(:by_handle).with('index').and_return(page)
+ expect(services.page_finder).to receive(:by_handle).with('index').and_return(page)
allow(page).to receive(:to_liquid).and_return(drop)
end