Skip to content

Commit 8976507

Browse files
authored
Merge pull request rails#35875 from Shopify/alloc-free-comparisons
Improve == and hash methods on various schema cache structs to be allocation free.
2 parents 21ce5cf + 6f26e99 commit 8976507

File tree

4 files changed

+38
-32
lines changed

4 files changed

+38
-32
lines changed

activerecord/lib/active_record/connection_adapters/column.rb

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,24 @@ def encode_with(coder)
6363

6464
def ==(other)
6565
other.is_a?(Column) &&
66-
attributes_for_hash == other.attributes_for_hash
66+
name == other.name &&
67+
default == other.default &&
68+
sql_type_metadata == other.sql_type_metadata &&
69+
null == other.null &&
70+
default_function == other.default_function &&
71+
collation == other.collation
6772
end
6873
alias :eql? :==
6974

7075
def hash
71-
attributes_for_hash.hash
76+
Column.hash ^
77+
name.hash ^
78+
default.hash ^
79+
sql_type_metadata.hash ^
80+
null.hash ^
81+
default_function.hash ^
82+
collation.hash
7283
end
73-
74-
protected
75-
76-
def attributes_for_hash
77-
[self.class, name, default, sql_type_metadata, null, default_function, collation, comment]
78-
end
7984
end
8085

8186
class NullColumn < Column

activerecord/lib/active_record/connection_adapters/mysql/type_metadata.rb

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,16 @@ def initialize(type_metadata, extra: "")
1616

1717
def ==(other)
1818
other.is_a?(MySQL::TypeMetadata) &&
19-
attributes_for_hash == other.attributes_for_hash
19+
__getobj__ == other.__getobj__ &&
20+
extra == other.extra
2021
end
2122
alias eql? ==
2223

2324
def hash
24-
attributes_for_hash.hash
25+
TypeMetadata.hash ^
26+
__getobj__.hash ^
27+
extra.hash
2528
end
26-
27-
protected
28-
29-
def attributes_for_hash
30-
[self.class, @type_metadata, extra]
31-
end
3229
end
3330
end
3431
end

activerecord/lib/active_record/connection_adapters/postgresql/type_metadata.rb

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,20 @@ def sql_type
2222

2323
def ==(other)
2424
other.is_a?(PostgreSQLTypeMetadata) &&
25-
attributes_for_hash == other.attributes_for_hash
25+
__getobj__ == other.__getobj__ &&
26+
oid == other.oid &&
27+
fmod == other.fmod &&
28+
array == other.array
2629
end
2730
alias eql? ==
2831

2932
def hash
30-
attributes_for_hash.hash
33+
PostgreSQLTypeMetadata.hash ^
34+
__getobj__.hash ^
35+
oid.hash ^
36+
fmod.hash ^
37+
array.hash
3138
end
32-
33-
protected
34-
35-
def attributes_for_hash
36-
[self.class, @type_metadata, oid, fmod]
37-
end
3839
end
3940
end
4041
end

activerecord/lib/active_record/connection_adapters/sql_type_metadata.rb

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,22 @@ def initialize(sql_type: nil, type: nil, limit: nil, precision: nil, scale: nil)
1616

1717
def ==(other)
1818
other.is_a?(SqlTypeMetadata) &&
19-
attributes_for_hash == other.attributes_for_hash
19+
sql_type == other.sql_type &&
20+
type == other.type &&
21+
limit == other.limit &&
22+
precision == other.precision &&
23+
scale == other.scale
2024
end
2125
alias eql? ==
2226

2327
def hash
24-
attributes_for_hash.hash
28+
SqlTypeMetadata.hash ^
29+
sql_type.hash ^
30+
type.hash ^
31+
limit.hash ^
32+
precision.hash >> 1 ^
33+
scale.hash >> 2
2534
end
26-
27-
protected
28-
29-
def attributes_for_hash
30-
[self.class, sql_type, type, limit, precision, scale]
31-
end
3235
end
3336
end
3437
end

0 commit comments

Comments
 (0)