44 lines
2.1 KiB
Diff
44 lines
2.1 KiB
Diff
# UNDF: UNDF-2026-000000247
|
||
Fixes rails-0008: ActiveRecord Enum — value_method_names Array#include? inside pairs.each loop O(E²).
|
||
|
||
--- a/activerecord/lib/active_record/enum.rb
|
||
+++ b/activerecord/lib/active_record/enum.rb
|
||
|
||
@@ DEFECT rails-0008: line 251-276
|
||
|
||
- value_method_names = [] # Array — O(E) include?
|
||
+ value_method_names = Set.new # FIX: Set for O(1) include?
|
||
_enum_methods_module.module_eval do
|
||
prefix = if prefix
|
||
prefix == true ? "#{name}_" : "#{prefix}_"
|
||
end
|
||
|
||
suffix = if suffix
|
||
suffix == true ? "_#{name}" : "_#{suffix}"
|
||
end
|
||
|
||
pairs = values.respond_to?(:each_pair) ? values.each_pair : values.each_with_index
|
||
pairs.each do |label, value|
|
||
enum_values[label] = value
|
||
label = label.to_s
|
||
|
||
value_method_name = "#{prefix}#{label}#{suffix}"
|
||
value_method_names << value_method_name
|
||
define_enum_methods(name, value_method_name, value, scopes, instance_methods)
|
||
|
||
method_friendly_label = label.gsub(/[\W&&[:ascii:]]+/, "_")
|
||
value_method_alias = "#{prefix}#{method_friendly_label}#{suffix}"
|
||
|
||
if value_method_alias != value_method_name && !value_method_names.include?(value_method_alias) # O(1) with Set
|
||
value_method_names << value_method_alias
|
||
define_enum_methods(name, value_method_alias, value, scopes, instance_methods)
|
||
end
|
||
end
|
||
end
|
||
- detect_negative_enum_conditions!(value_method_names) if scopes # works with Set (responds to each)
|
||
+ detect_negative_enum_conditions!(value_method_names.to_a) if scopes # convert back if Array needed
|
||
|
||
# BEFORE: value_method_names is Array; include? is O(E) called E times → O(E²)
|
||
# AFTER: value_method_names is Set; include? is O(1) → O(E)
|
||
# Note: detect_negative_enum_conditions! only iterates — to_a needed if it checks index/[]
|
||
# Speedup: ~E× at E=1000 enum values
|