Skip to content

Commit 592ff9b

Browse files
authored
Small code reshuffle for diff minimization (#16569)
* Moving code around * Small code reshuffle for diff minimization * wat
1 parent 02d11c6 commit 592ff9b

File tree

1 file changed

+117
-120
lines changed

1 file changed

+117
-120
lines changed

src/FSharp.Core/prim-types.fs

Lines changed: 117 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,123 @@ namespace Microsoft.FSharp.Core
886886

887887
module HashCompare =
888888
889+
//-------------------------------------------------------------------------
890+
// LanguagePrimitives.HashCompare: HASHING.
891+
//-------------------------------------------------------------------------
892+
893+
let defaultHashNodes = 18
894+
895+
/// The implementation of IEqualityComparer, using depth-limited for hashing and PER semantics for NaN equality.
896+
type CountLimitedHasherPER(sz:int) =
897+
[<DefaultValue>]
898+
val mutable nodeCount : int
899+
900+
member x.Fresh() =
901+
if (System.Threading.Interlocked.CompareExchange(&(x.nodeCount), sz, 0) = 0) then
902+
x
903+
else
904+
new CountLimitedHasherPER(sz)
905+
906+
interface IEqualityComparer
907+
908+
/// The implementation of IEqualityComparer, using unlimited depth for hashing and ER semantics for NaN equality.
909+
type UnlimitedHasherER() =
910+
interface IEqualityComparer
911+
912+
/// The implementation of IEqualityComparer, using unlimited depth for hashing and PER semantics for NaN equality.
913+
type UnlimitedHasherPER() =
914+
interface IEqualityComparer
915+
916+
917+
/// The unique object for unlimited depth for hashing and ER semantics for equality.
918+
let fsEqualityComparerUnlimitedHashingER = UnlimitedHasherER()
919+
920+
/// The unique object for unlimited depth for hashing and PER semantics for equality.
921+
let fsEqualityComparerUnlimitedHashingPER = UnlimitedHasherPER()
922+
923+
let inline HashCombine nr x y = (x <<< 1) + y + 631 * nr
924+
925+
let GenericHashObjArray (iec : IEqualityComparer) (x: obj array) : int =
926+
let len = x.Length
927+
let mutable i = len - 1
928+
if i > defaultHashNodes then i <- defaultHashNodes // limit the hash
929+
let mutable acc = 0
930+
while (i >= 0) do
931+
// NOTE: GenericHash* call decreases nr
932+
acc <- HashCombine i acc (iec.GetHashCode(x.GetValue(i)));
933+
i <- i - 1
934+
acc
935+
936+
// optimized case - byte arrays
937+
let GenericHashByteArray (x: byte array) : int =
938+
let len = length x
939+
let mutable i = len - 1
940+
if i > defaultHashNodes then i <- defaultHashNodes // limit the hash
941+
let mutable acc = 0
942+
while (i >= 0) do
943+
acc <- HashCombine i acc (intOfByte (get x i));
944+
i <- i - 1
945+
acc
946+
947+
// optimized case - int arrays
948+
let GenericHashInt32Array (x: int array) : int =
949+
let len = length x
950+
let mutable i = len - 1
951+
if i > defaultHashNodes then i <- defaultHashNodes // limit the hash
952+
let mutable acc = 0
953+
while (i >= 0) do
954+
acc <- HashCombine i acc (get x i);
955+
i <- i - 1
956+
acc
957+
958+
// optimized case - int arrays
959+
let GenericHashInt64Array (x: int64 array) : int =
960+
let len = length x
961+
let mutable i = len - 1
962+
if i > defaultHashNodes then i <- defaultHashNodes // limit the hash
963+
let mutable acc = 0
964+
while (i >= 0) do
965+
acc <- HashCombine i acc (int32 (get x i));
966+
i <- i - 1
967+
acc
968+
969+
// special case - arrays do not by default have a decent structural hashing function
970+
let GenericHashArbArray (iec : IEqualityComparer) (x: System.Array) : int =
971+
match x.Rank with
972+
| 1 ->
973+
let b = x.GetLowerBound(0)
974+
let len = x.Length
975+
let mutable i = b + len - 1
976+
if i > b + defaultHashNodes then i <- b + defaultHashNodes // limit the hash
977+
let mutable acc = 0
978+
while (i >= b) do
979+
// NOTE: GenericHash* call decreases nr
980+
acc <- HashCombine i acc (iec.GetHashCode(x.GetValue(i)));
981+
i <- i - 1
982+
acc
983+
| _ ->
984+
HashCombine 10 (x.GetLength(0)) (x.GetLength(1))
985+
986+
// Core implementation of structural hashing, corresponds to pseudo-code in the
987+
// F# Language spec. Searches for the IStructuralHash interface, otherwise uses GetHashCode().
988+
// Arrays are structurally hashed through a separate technique.
989+
//
990+
// "iec" is either fsEqualityComparerUnlimitedHashingER, fsEqualityComparerUnlimitedHashingPER or a CountLimitedHasherPER.
991+
let rec GenericHashParamObj (iec : IEqualityComparer) (x: obj) : int =
992+
match x with
993+
| null -> 0
994+
| (:? System.Array as a) ->
995+
match a with
996+
| :? (obj array) as oa -> GenericHashObjArray iec oa
997+
| :? (byte array) as ba -> GenericHashByteArray ba
998+
| :? (int array) as ba -> GenericHashInt32Array ba
999+
| :? (int64 array) as ba -> GenericHashInt64Array ba
1000+
| _ -> GenericHashArbArray iec a
1001+
| :? IStructuralEquatable as a ->
1002+
a.GetHashCode(iec)
1003+
| _ ->
1004+
x.GetHashCode()
1005+
8891006
//-------------------------------------------------------------------------
8901007
// LanguagePrimitives.HashCompare: Physical Equality
8911008
//-------------------------------------------------------------------------
@@ -1663,126 +1780,6 @@ namespace Microsoft.FSharp.Core
16631780
when 'T : decimal = System.Decimal.op_Equality((# "" x:decimal #), (# "" y:decimal #))
16641781
when 'T : DateTime = DateTime.Equals((# "" x : DateTime #), (# "" y : DateTime #))
16651782

1666-
//-------------------------------------------------------------------------
1667-
// LanguagePrimitives.HashCompare: HASHING.
1668-
//-------------------------------------------------------------------------
1669-
1670-
1671-
1672-
let defaultHashNodes = 18
1673-
1674-
/// The implementation of IEqualityComparer, using depth-limited for hashing and PER semantics for NaN equality.
1675-
type CountLimitedHasherPER(sz:int) =
1676-
[<DefaultValue>]
1677-
val mutable nodeCount : int
1678-
1679-
member x.Fresh() =
1680-
if (System.Threading.Interlocked.CompareExchange(&(x.nodeCount), sz, 0) = 0) then
1681-
x
1682-
else
1683-
new CountLimitedHasherPER(sz)
1684-
1685-
interface IEqualityComparer
1686-
1687-
/// The implementation of IEqualityComparer, using unlimited depth for hashing and ER semantics for NaN equality.
1688-
type UnlimitedHasherER() =
1689-
interface IEqualityComparer
1690-
1691-
/// The implementation of IEqualityComparer, using unlimited depth for hashing and PER semantics for NaN equality.
1692-
type UnlimitedHasherPER() =
1693-
interface IEqualityComparer
1694-
1695-
1696-
/// The unique object for unlimited depth for hashing and ER semantics for equality.
1697-
let fsEqualityComparerUnlimitedHashingER = UnlimitedHasherER()
1698-
1699-
/// The unique object for unlimited depth for hashing and PER semantics for equality.
1700-
let fsEqualityComparerUnlimitedHashingPER = UnlimitedHasherPER()
1701-
1702-
let inline HashCombine nr x y = (x <<< 1) + y + 631 * nr
1703-
1704-
let GenericHashObjArray (iec : IEqualityComparer) (x: obj array) : int =
1705-
let len = x.Length
1706-
let mutable i = len - 1
1707-
if i > defaultHashNodes then i <- defaultHashNodes // limit the hash
1708-
let mutable acc = 0
1709-
while (i >= 0) do
1710-
// NOTE: GenericHash* call decreases nr
1711-
acc <- HashCombine i acc (iec.GetHashCode(x.GetValue(i)));
1712-
i <- i - 1
1713-
acc
1714-
1715-
// optimized case - byte arrays
1716-
let GenericHashByteArray (x: byte array) : int =
1717-
let len = length x
1718-
let mutable i = len - 1
1719-
if i > defaultHashNodes then i <- defaultHashNodes // limit the hash
1720-
let mutable acc = 0
1721-
while (i >= 0) do
1722-
acc <- HashCombine i acc (intOfByte (get x i));
1723-
i <- i - 1
1724-
acc
1725-
1726-
// optimized case - int arrays
1727-
let GenericHashInt32Array (x: int array) : int =
1728-
let len = length x
1729-
let mutable i = len - 1
1730-
if i > defaultHashNodes then i <- defaultHashNodes // limit the hash
1731-
let mutable acc = 0
1732-
while (i >= 0) do
1733-
acc <- HashCombine i acc (get x i);
1734-
i <- i - 1
1735-
acc
1736-
1737-
// optimized case - int arrays
1738-
let GenericHashInt64Array (x: int64 array) : int =
1739-
let len = length x
1740-
let mutable i = len - 1
1741-
if i > defaultHashNodes then i <- defaultHashNodes // limit the hash
1742-
let mutable acc = 0
1743-
while (i >= 0) do
1744-
acc <- HashCombine i acc (int32 (get x i));
1745-
i <- i - 1
1746-
acc
1747-
1748-
// special case - arrays do not by default have a decent structural hashing function
1749-
let GenericHashArbArray (iec : IEqualityComparer) (x: System.Array) : int =
1750-
match x.Rank with
1751-
| 1 ->
1752-
let b = x.GetLowerBound(0)
1753-
let len = x.Length
1754-
let mutable i = b + len - 1
1755-
if i > b + defaultHashNodes then i <- b + defaultHashNodes // limit the hash
1756-
let mutable acc = 0
1757-
while (i >= b) do
1758-
// NOTE: GenericHash* call decreases nr
1759-
acc <- HashCombine i acc (iec.GetHashCode(x.GetValue(i)));
1760-
i <- i - 1
1761-
acc
1762-
| _ ->
1763-
HashCombine 10 (x.GetLength(0)) (x.GetLength(1))
1764-
1765-
// Core implementation of structural hashing, corresponds to pseudo-code in the
1766-
// F# Language spec. Searches for the IStructuralHash interface, otherwise uses GetHashCode().
1767-
// Arrays are structurally hashed through a separate technique.
1768-
//
1769-
// "iec" is either fsEqualityComparerUnlimitedHashingER, fsEqualityComparerUnlimitedHashingPER or a CountLimitedHasherPER.
1770-
let rec GenericHashParamObj (iec : IEqualityComparer) (x: obj) : int =
1771-
match x with
1772-
| null -> 0
1773-
| (:? System.Array as a) ->
1774-
match a with
1775-
| :? (obj array) as oa -> GenericHashObjArray iec oa
1776-
| :? (byte array) as ba -> GenericHashByteArray ba
1777-
| :? (int array) as ba -> GenericHashInt32Array ba
1778-
| :? (int64 array) as ba -> GenericHashInt64Array ba
1779-
| _ -> GenericHashArbArray iec a
1780-
| :? IStructuralEquatable as a ->
1781-
a.GetHashCode(iec)
1782-
| _ ->
1783-
x.GetHashCode()
1784-
1785-
17861783
/// Fill in the implementation of CountLimitedHasherPER
17871784
type CountLimitedHasherPER with
17881785

0 commit comments

Comments
 (0)