users can provide optional expression cache

This commit is contained in:
Michael Go
2025-01-07 14:32:46 -04:00
parent 2c7d686690
commit 42d822bda9
4 changed files with 47 additions and 4 deletions
+1 -2
View File
@@ -8,6 +8,7 @@ end
gemspec
gem "base64"
gem "lru_redux"
group :benchmark, :test do
gem 'benchmark-ips'
@@ -24,5 +25,3 @@ group :test do
gem 'rubocop-shopify', '~> 2.12.0', require: false
gem 'rubocop-performance', require: false
end
gem "lru_redux"
+3 -1
View File
@@ -89,7 +89,9 @@ module Liquid
# Cache only exists during parsing
if cache
cache.fetch(markup) { inner_parse(markup, ss, cache).freeze }
return cache[markup] if cache.key?(markup)
cache[markup] = inner_parse(markup, ss, cache).freeze
else
inner_parse(markup, ss, nil).freeze
end
+4 -1
View File
@@ -15,7 +15,10 @@ module Liquid
# constructing new StringScanner in Lexer, Tokenizer, etc is expensive
# This StringScanner will be shared by all of them
@string_scanner = StringScanner.new("")
@expression_cache = LruRedux::Cache.new(10_000)
@expression_cache = if options[:expression_cache] != false
options[:expression_cache] || LruRedux::Cache.new(10_000)
end
self.depth = 0
self.partial = false
+39
View File
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require 'test_helper'
require 'lru_redux'
class ExpressionTest < Minitest::Test
def test_keyword_literals
@@ -54,6 +55,44 @@ class ExpressionTest < Minitest::Test
)
end
def test_expression_cache
skip("Liquid-C does not support Expression caching") if defined?(Liquid::C) && Liquid::C.enabled
cache = LruRedux::Cache.new(10)
template = <<~LIQUID
{% assign x = 1 %}
{{ x }}
{% assign x = 2 %}
{{ x }}
{% assign y = 1 %}
{{ y }}
LIQUID
Liquid::Template.parse(template, expression_cache: cache).render
assert_equal(
["1", "2", "x", "y"],
cache.to_a.map { _1[0] }.sort,
)
end
def test_disable_expression_cache
skip("Liquid-C does not support Expression caching") if defined?(Liquid::C) && Liquid::C.enabled
template = <<~LIQUID
{% assign x = 1 %}
{{ x }}
{% assign x = 2 %}
{{ x }}
{% assign y = 1 %}
{{ y }}
LIQUID
parse_context = Liquid::ParseContext.new(expression_cache: false)
Liquid::Template.parse(template, parse_context).render
assert(parse_context.instance_variable_get(:@expression_cache).nil?)
end
private
def assert_expression_result(expect, markup, **assigns)