posts: move fast_count to PostQueryBuilder.

This commit is contained in:
evazion
2020-05-06 14:47:16 -05:00
parent d3bd0a9cb5
commit a753ebbea9
9 changed files with 206 additions and 234 deletions

View File

@@ -588,6 +588,14 @@ class Post < ApplicationRecord
end
end
def fix_post_counts(post)
post.set_tag_counts(false)
if post.changes_saved?
args = Hash[TagCategory.categories.map {|x| ["tag_count_#{x}", post.send("tag_count_#{x}")]}].update(:tag_count => post.tag_count)
post.update_columns(args)
end
end
def merge_old_changes
reset_tag_array_cache
@removed_tags = []
@@ -1065,97 +1073,6 @@ class Post < ApplicationRecord
end
end
module CountMethods
def fast_count(tags = "", timeout: 1_000, raise_on_timeout: false, skip_cache: false)
tags = tags.to_s
tags += " rating:s" if CurrentUser.safe_mode?
tags += " -status:deleted" if CurrentUser.hide_deleted_posts? && !PostQueryBuilder.new(tags).has_metatag?("status")
tags = PostQueryBuilder.new(tags).normalize_query(normalize_aliases: true)
# Optimize some cases. these are just estimates but at these
# quantities being off by a few hundred doesn't matter much
if Danbooru.config.estimate_post_counts
if tags == ""
return (Post.maximum(:id).to_i * (2200402.0 / 2232212)).floor
elsif tags =~ /^rating:s(?:afe)?$/
return (Post.maximum(:id).to_i * (1648652.0 / 2200402)).floor
elsif tags =~ /^rating:q(?:uestionable)?$/
return (Post.maximum(:id).to_i * (350101.0 / 2200402)).floor
elsif tags =~ /^rating:e(?:xplicit)?$/
return (Post.maximum(:id).to_i * (201650.0 / 2200402)).floor
end
end
count = nil
unless skip_cache
count = get_count_from_cache(tags)
end
if count.nil?
count = fast_count_search(tags, timeout: timeout, raise_on_timeout: raise_on_timeout)
end
count
rescue SearchError
0
end
def fast_count_search(tags, timeout:, raise_on_timeout:)
count = Post.with_timeout(timeout, nil, tags: tags) do
Post.tag_match(tags).count
end
if count.nil?
# give up
if raise_on_timeout
raise TimeoutError.new("timed out")
end
count = Danbooru.config.blank_tag_search_fast_count
else
set_count_in_cache(tags, count)
end
count ? count.to_i : nil
rescue PG::ConnectionBad
return nil
end
def fix_post_counts(post)
post.set_tag_counts(false)
if post.changes_saved?
args = Hash[TagCategory.categories.map {|x| ["tag_count_#{x}", post.send("tag_count_#{x}")]}].update(:tag_count => post.tag_count)
post.update_columns(args)
end
end
def get_count_from_cache(tags)
if PostQueryBuilder.new(tags).is_simple_tag?
count = Tag.find_by(name: tags).try(:post_count)
else
# this will only have a value for multi-tag searches or single metatag searches
count = Cache.get(count_cache_key(tags))
end
count.try(:to_i)
end
def set_count_in_cache(tags, count, expiry = nil)
expiry ||= count.seconds.clamp(3.minutes, 20.hours).to_i
Cache.put(count_cache_key(tags), count, expiry)
end
def count_cache_key(tags)
"pfc:#{Cache.hash(tags)}"
end
end
module ParentMethods
# A parent has many children. A child belongs to a parent.
# A parent cannot have a parent.
@@ -1715,7 +1632,6 @@ class Post < ApplicationRecord
include FavoriteMethods
include PoolMethods
include VoteMethods
extend CountMethods
include ParentMethods
include DeletionMethods
include VersionMethods