search: cache timed out search counts.
When a search is performed, we cache the post count so we don't have to calculate it again every time the user switches pages. However, if the count times out, we didn't cache it before, causing us to do a slow count on every page load. This usually happens on multi-tag searches that return a lot of results, `1girl solo` for example. This changes it so that the count is cached even when it times out. This will speed up large multi-tag searches. This also changes it so that the count is cached for a fixed 5 minutes. Before it was variable based on the size of the count, but this probably didn't make much difference.
This commit is contained in:
@@ -902,8 +902,8 @@ class PostQueryBuilder
|
||||
def fast_count(timeout: 1_000, estimate_count: true, skip_cache: false)
|
||||
count = nil
|
||||
count = estimated_count if estimate_count
|
||||
count = cached_count if count.nil? && !skip_cache
|
||||
count = exact_count(timeout) if count.nil?
|
||||
count = cached_count(timeout) if count.nil? && !skip_cache
|
||||
count = exact_count(timeout) if count.nil? && skip_cache
|
||||
count
|
||||
end
|
||||
|
||||
@@ -936,22 +936,16 @@ class PostQueryBuilder
|
||||
ExplainParser.new(build).row_count
|
||||
end
|
||||
|
||||
def cached_count
|
||||
Cache.get(count_cache_key)
|
||||
def cached_count(timeout, duration: 5.minutes)
|
||||
Cache.get(count_cache_key, duration) do
|
||||
exact_count(timeout)
|
||||
end
|
||||
end
|
||||
|
||||
def exact_count(timeout)
|
||||
count = Post.with_timeout(timeout, nil) do
|
||||
Post.with_timeout(timeout) do
|
||||
build.count
|
||||
end
|
||||
|
||||
set_cached_count(count) if count.present?
|
||||
count
|
||||
end
|
||||
|
||||
def set_cached_count(count)
|
||||
expiry = count.seconds.clamp(3.minutes, 20.hours).to_i
|
||||
Cache.put(count_cache_key, count, expiry)
|
||||
end
|
||||
|
||||
def count_cache_key
|
||||
|
||||
@@ -1199,7 +1199,7 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
|
||||
context "for a single metatag" do
|
||||
should "return the correct cached count" do
|
||||
build(:tag, name: "score:42", post_count: -100).save(validate: false)
|
||||
PostQueryBuilder.new("score:42").set_cached_count(100)
|
||||
Cache.put("pfc:score:42", 100)
|
||||
assert_fast_count(100, "score:42")
|
||||
end
|
||||
|
||||
@@ -1207,7 +1207,7 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
|
||||
pool = create(:pool, post_ids: [1, 2, 3])
|
||||
|
||||
build(:tag, name: "pool:#{pool.id}", post_count: -100).save(validate: false)
|
||||
PostQueryBuilder.new("pool:1234").set_cached_count(100)
|
||||
Cache.put("pfc:pool:1234", 100)
|
||||
|
||||
assert_fast_count(3, "pool:#{pool.id}")
|
||||
assert_fast_count(3, "pool:#{pool.name}")
|
||||
@@ -1237,7 +1237,7 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
|
||||
|
||||
context "for a multi-tag search" do
|
||||
should "return the cached count, if it exists" do
|
||||
PostQueryBuilder.new("score:42 aaa").set_cached_count(100)
|
||||
Cache.put("pfc:score:42 aaa", 100)
|
||||
assert_fast_count(100, "aaa score:42")
|
||||
end
|
||||
|
||||
@@ -1245,11 +1245,6 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
|
||||
assert_fast_count(1, "aaa score:42")
|
||||
end
|
||||
|
||||
should "set the expiration time" do
|
||||
Cache.expects(:put).with(PostQueryBuilder.new("score:42 aaa").count_cache_key, 1, 180)
|
||||
assert_fast_count(1, "aaa score:42")
|
||||
end
|
||||
|
||||
should "work with the hide_deleted_posts option turned on" do
|
||||
create(:post, tag_string: "aaa", score: 42, is_deleted: true)
|
||||
assert_fast_count(1, "aaa score:42", { hide_deleted_posts: true })
|
||||
|
||||
Reference in New Issue
Block a user