Commit b6a530c9 authored by Andreas Brandl's avatar Andreas Brandl

Simplify to use models instead of tables.

parent f2ec9d2d
...@@ -26,24 +26,17 @@ module Gitlab ...@@ -26,24 +26,17 @@ module Gitlab
# @param [Array] # @param [Array]
# @return [Hash] of Model -> count mapping # @return [Hash] of Model -> count mapping
def self.approximate_counts(models) def self.approximate_counts(models)
table_to_model_map = models.each_with_object({}) do |model, hash| counts_by_model = {}
hash[model.table_name] = model
end
table_names = table_to_model_map.keys
counts_by_table_name = Gitlab::Database.postgresql? ? reltuples_from_recently_updated(table_names) : {}
# Convert table -> count to Model -> count if Gitlab::Database.postgresql?
counts_by_model = counts_by_table_name.each_with_object({}) do |pair, hash| #counts_by_model = ReltuplesCountStrategy.new(models).count
model = table_to_model_map[pair.first] counts_by_model = reltuples_from_recently_updated(models)
hash[model] = pair.second
end end
missing_tables = table_names - counts_by_table_name.keys missing_models = models - counts_by_model.keys
missing_tables.each do |table| ExactCountStrategy.new(missing_models).count.each do |model, count|
model = table_to_model_map[table] counts_by_model[model] = count
counts_by_model[model] = model.count
end end
counts_by_model counts_by_model
...@@ -51,10 +44,10 @@ module Gitlab ...@@ -51,10 +44,10 @@ module Gitlab
# Returns a hash of the table names that have recently updated tuples. # Returns a hash of the table names that have recently updated tuples.
# #
# @param [Array] table names # @param [Array] models to count
# @returns [Hash] Table name to count mapping (e.g. { 'projects' => 5, 'users' => 100 }) # @returns [Hash] Table name to count mapping (e.g. { 'projects' => 5, 'users' => 100 })
def self.reltuples_from_recently_updated(table_names) def self.reltuples_from_recently_updated(models)
ReltuplesCountStrategy.new(table_names).count ReltuplesCountStrategy.new(models).count
end end
class ExactCountStrategy class ExactCountStrategy
...@@ -71,11 +64,9 @@ module Gitlab ...@@ -71,11 +64,9 @@ module Gitlab
end end
class ReltuplesCountStrategy class ReltuplesCountStrategy
attr_reader :table_names attr_reader :models
def initialize(models)
# @param [Array] table names @models = models
def initialize(table_names)
@table_names = table_names
end end
# Returns a hash of the table names that have recently updated tuples. # Returns a hash of the table names that have recently updated tuples.
...@@ -91,13 +82,22 @@ module Gitlab ...@@ -91,13 +82,22 @@ module Gitlab
rows = ActiveRecord::Base.connection.select_all(query) rows = ActiveRecord::Base.connection.select_all(query)
end end
rows.each_with_object({}) { |row, data| data[row['table_name']] = row['estimate'].to_i } table_to_model = models.each_with_object({}) { |model, h| h[model.table_name] = model }
rows.each_with_object({}) do |row, data|
model = table_to_model[row['table_name']]
data[model] = row['estimate'].to_i
end
rescue *CONNECTION_ERRORS => e rescue *CONNECTION_ERRORS => e
{} {}
end end
private private
def table_names
models.map(&:table_name)
end
# Generates the PostgreSQL query to return the tuples for tables # Generates the PostgreSQL query to return the tuples for tables
# that have been vacuumed or analyzed in the last hour. # that have been vacuumed or analyzed in the last hour.
# #
......
...@@ -25,7 +25,7 @@ describe Gitlab::Database::Count do ...@@ -25,7 +25,7 @@ describe Gitlab::Database::Count do
context 'with PostgreSQL', :postgresql do context 'with PostgreSQL', :postgresql do
describe 'when reltuples have not been updated' do describe 'when reltuples have not been updated' do
it 'counts all models the normal way' do it 'counts all models the normal way' do
expect(described_class).to receive(:reltuples_from_recently_updated).with(%w(projects identities)).and_return({}) expect(described_class).to receive(:reltuples_from_recently_updated).with(models).and_return({})
expect(Project).to receive(:count).and_call_original expect(Project).to receive(:count).and_call_original
expect(Identity).to receive(:count).and_call_original expect(Identity).to receive(:count).and_call_original
...@@ -45,7 +45,7 @@ describe Gitlab::Database::Count do ...@@ -45,7 +45,7 @@ describe Gitlab::Database::Count do
describe 'when some reltuples have been updated' do describe 'when some reltuples have been updated' do
it 'counts projects in the fast way' do it 'counts projects in the fast way' do
expect(described_class).to receive(:reltuples_from_recently_updated).with(%w(projects identities)).and_return({ 'projects' => 3 }) expect(described_class).to receive(:reltuples_from_recently_updated).with(models).and_return({ Project => 3 })
expect(Project).not_to receive(:count).and_call_original expect(Project).not_to receive(:count).and_call_original
expect(Identity).to receive(:count).and_call_original expect(Identity).to receive(:count).and_call_original
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment