Skip to content

Commit

Permalink
[api] faster "not defined ownership" lookup of packages
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianschroeter committed Dec 14, 2012
1 parent e1c7ddd commit 4c2fc53
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 21 deletions.
9 changes: 7 additions & 2 deletions src/api/app/controllers/search_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,13 @@ def _owner(params, obj)
end
end

owners = project.find_assignees(obj, limit.to_i, devel, filter) if obj and obj.class == String
owners = project.find_containers(obj, limit.to_i, devel, filter) if obj.nil? or obj.class != String
if obj.nil?
owners = project.find_containers_without_definition(devel, filter)
elsif obj.class == String
owners = project.find_assignees(obj, limit.to_i, devel, filter)
else
owners = project.find_containers(obj, limit.to_i, devel, filter)
end

end

Expand Down
70 changes: 51 additions & 19 deletions src/api/app/models/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1187,7 +1187,7 @@ def find_package(package_name, processed={})
end

def expand_all_projects
projects = [self.name]
projects = [self]
p_map = Hash.new
projects.each { |i| p_map[i] = 1 } # existing projects map
# add all linked and indirect linked projects
Expand Down Expand Up @@ -1298,7 +1298,7 @@ def lookup_package_owner(pkg, owner, limit, devel, filter, deepest)
pkg_match = pkg
unless m
pkg.project.expand_all_projects.each do |prj|
p = Package.find_by_project_and_name( prj, pkg.name )
p = prj.packages.find_by_name(pkg.name )
next if p.nil?

m = extract_maintainer(self, p.resolve_devel_package, filter) if devel == true
Expand All @@ -1310,35 +1310,67 @@ def lookup_package_owner(pkg, owner, limit, devel, filter, deepest)
end
end

if owner.nil?
# special search for NOT maintained packages with given filter
# skip if maintainer is defined
return nil, limit if m
# found entry
return m, (limit-1)
end
private :lookup_package_owner

def find_containers_without_definition(devel=true, filter=["maintainer","bugowner"] )
projects=self.expand_all_projects

roles=[]
filter.each do |f|
roles << Role.find_by_title!(f)
end

# fast find packages with defintions
# user in package object
defined_packages = Package.joins(:package_user_role_relationships).where("db_project_id in (?) AND package_user_role_relationships.role_id in (?)", projects, roles).select(:name).map{ |p| p.name}
# group in package object
defined_packages += Package.joins(:package_group_role_relationships).where("db_project_id in (?) AND package_group_role_relationships.role_id in (?)", projects, roles).select(:name).map{ |p| p.name}
# user in project object
Project.joins(:project_user_role_relationships).where("projects.id in (?) AND project_user_role_relationships.role_id in (?)", projects, roles).each do |prj|
defined_packages += prj.packages.map{ |p| p.name }
end
# group in project object
Project.joins(:project_group_role_relationships).where("projects.id in (?) AND project_group_role_relationships.role_id in (?)", projects, roles).each do |prj|
defined_packages += prj.packages.map{ |p| p.name }
end
if devel == true
#FIXME add devel packages, but how do recursive lookup fast in SQL?
end
defined_packages.uniq!

all_packages = Package.where("db_project_id in (?)", projects).select(:name).map{ |p| p.name}

undefined_packages = all_packages - defined_packages
maintainers=[]

undefined_packages.each do |p|
next if p =~ /\A_product:\w[-+\w\.]*\z/

pkg = self.find_package(p)

m = {}
m[:rootproject] = self.name
m[:project] = pkg_match.project.name
m[:package] = pkg_match.name
m[:project] = pkg.project.name
m[:package] = pkg.name

limit = limit - 1
return m, limit
maintainers << m
end

# found entry
return m, (limit-1)
return maintainers
end
private :lookup_package_owner

def find_containers(owner=nil, limit=1, devel=true, filter=["maintainer","bugowner"] )
def find_containers(owner, limit=1, devel=true, filter=["maintainer","bugowner"] )
maintainers=[]
projects=self.expand_all_projects

match_all = (limit == 0)

matched_packages = {}
deepest_match = nil
projects.each do |prj| # project link order
project = Project.get_by_name(prj)
projects.each do |project| # project link order
next unless project.class == Project

project.packages.each do |pkg| # no order
Expand Down Expand Up @@ -1371,7 +1403,7 @@ def find_assignees(binary_name, limit=1, devel=true, filter=["maintainer","bugow
deepest = (limit < 0)

# binary search via all projects
prjlist = projects.map { |p| "@project='#{CGI.escape(p)}'" }
prjlist = projects.map { |p| "@project='#{CGI.escape(p.name)}'" }
path = "/search/published/binary/id?match=(@name='"+CGI.escape(binary_name)+"'"
path += "+and+("
path += prjlist.join("+or+")
Expand All @@ -1385,9 +1417,9 @@ def find_assignees(binary_name, limit=1, devel=true, filter=["maintainer","bugow
deepest_match = nil
projects.each do |prj| # project link order
data.elements("binary").each do |b| # no order
next unless b["project"] == prj
next unless b["project"] == prj.name

pkg = Package.find_by_project_and_name( prj, b["package"] )
pkg = prj.packages.find_by_name( b["package"] )
next if pkg.nil?

# the "" means any matching relationships will get taken
Expand Down

0 comments on commit 4c2fc53

Please sign in to comment.