Change user prefs search logic to use index (#2644)
Sadly, array index failed to cover "unset bits" case, so excluded bits are merged into bigint, and &'d with column, which turned out more readable and simpler than bit string.
This commit is contained in:
@@ -759,7 +759,6 @@ class User < ActiveRecord::Base
|
|||||||
q = q.where("id in (?)", params[:id].split(",").map(&:to_i))
|
q = q.where("id in (?)", params[:id].split(",").map(&:to_i))
|
||||||
end
|
end
|
||||||
|
|
||||||
bitprefs_length = BOOLEAN_ATTRIBUTES.length
|
|
||||||
bitprefs_include = nil
|
bitprefs_include = nil
|
||||||
bitprefs_exclude = nil
|
bitprefs_exclude = nil
|
||||||
|
|
||||||
@@ -767,25 +766,21 @@ class User < ActiveRecord::Base
|
|||||||
if params[x].present?
|
if params[x].present?
|
||||||
attr_idx = BOOLEAN_ATTRIBUTES.index(x.to_s)
|
attr_idx = BOOLEAN_ATTRIBUTES.index(x.to_s)
|
||||||
if params[x] == "true"
|
if params[x] == "true"
|
||||||
bitprefs_include ||= "0"*bitprefs_length
|
bitprefs_include ||= []
|
||||||
bitprefs_include[attr_idx] = '1'
|
bitprefs_include << attr_idx
|
||||||
elsif params[x] == "false"
|
elsif params[x] == "false"
|
||||||
bitprefs_exclude ||= "0"*bitprefs_length
|
bitprefs_exclude ||= 0
|
||||||
bitprefs_exclude[attr_idx] = '1'
|
bitprefs_exclude |= (1 << attr_idx)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if bitprefs_include
|
if bitprefs_include
|
||||||
bitprefs_include.reverse!
|
q = q.where("bit_position_array(bit_prefs) @> ARRAY[?]::integer[]", bitprefs_include)
|
||||||
q = q.where("bit_prefs::bit(:len) & :bits::bit(:len) = :bits::bit(:len)",
|
|
||||||
{:len => bitprefs_length, :bits => bitprefs_include})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if bitprefs_exclude
|
if bitprefs_exclude
|
||||||
bitprefs_exclude.reverse!
|
q = q.where("bit_prefs & ? = 0", bitprefs_exclude)
|
||||||
q = q.where("bit_prefs::bit(:len) & :bits::bit(:len) = 0::bit(:len)",
|
|
||||||
{:len => bitprefs_length, :bits => bitprefs_exclude})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:current_user_first] == "true" && !CurrentUser.is_anonymous?
|
if params[:current_user_first] == "true" && !CurrentUser.is_anonymous?
|
||||||
|
|||||||
Reference in New Issue
Block a user