Skip to content

Commit

Permalink
Impl GetHashCode in value comparer
Browse files Browse the repository at this point in the history
  • Loading branch information
ArchLeaders committed Feb 4, 2024
1 parent 913a9c8 commit 0de65c1
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 30 deletions.
2 changes: 1 addition & 1 deletion src/BymlLibrary.Runner/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"profiles": {
"BymlLibrary.Runner": {
"commandName": "Project",
"commandLineArgs": "\"D:\\bin\\nxe\\(src)-GameDataList.Product.110.byml\" \"D:\\bin\\nxe\\GameDataList.Product.110.byml\" \"D:\\bin\\nxe\\output.yml\""
"commandLineArgs": "\"D:\\bin\\Byml-v7\\ActorInfo.product.byml\" \"D:\\bin\\Byml-v7\\(md)-ActorInfo.product.byml\" \"D:\\bin\\Byml-v7\\ActorInfo.product.yml\""
}
}
}
36 changes: 34 additions & 2 deletions src/BymlLibrary/Byml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Revrs;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace BymlLibrary;

Expand Down Expand Up @@ -366,9 +367,40 @@ public bool Equals(Byml? x, Byml? y)
};
}

public int GetHashCode([DisallowNull] Byml obj)
public int GetHashCode([DisallowNull] Byml byml)
{
throw new NotImplementedException();
if (byml.Value is IBymlNode container) {
return container.GetValueHash();
}
else {
return byml.Type switch {
BymlNodeType.Binary => GetBinaryNodeHashCode((byml.GetBinary(), null), byml.Type),
BymlNodeType.BinaryAligned => GetBinaryNodeHashCode(byml.GetBinaryAligned(), byml.Type),
_ => GetValueNodeHashCode(byml)
};
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetBinaryNodeHashCode((byte[] data, int? alignment) value, BymlNodeType bymlNodeType)
{
HashCode hashCode = new();
if (value.alignment.HasValue) {
hashCode.Add(value.alignment.Value);
}

hashCode.Add(bymlNodeType.GetHashCode());
hashCode.AddBytes(value.data);
return hashCode.ToHashCode();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetValueNodeHashCode(Byml byml)
{
HashCode hashCode = new();
hashCode.Add(byml.Type.GetHashCode());
hashCode.Add(byml.Value?.GetHashCode());
return hashCode.ToHashCode();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down
10 changes: 10 additions & 0 deletions src/BymlLibrary/Nodes/Containers/BymlArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ namespace BymlLibrary.Nodes.Containers;

public class BymlArray : List<Byml>, IBymlNode
{
public int GetValueHash()
{
HashCode hashCode = new();
foreach (var node in this) {
hashCode.Add(Byml.ValueEqualityComparer.Default.GetHashCode(node));
}

return hashCode.ToHashCode();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
int IBymlNode.Collect(in BymlWriter writer)
{
Expand Down
11 changes: 11 additions & 0 deletions src/BymlLibrary/Nodes/Containers/BymlMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ namespace BymlLibrary.Nodes.Containers;

public class BymlMap : Dictionary<string, Byml>, IBymlNode
{
public int GetValueHash()
{
HashCode hashCode = new();
foreach ((var key, var node) in this) {
hashCode.Add(key);
hashCode.Add(Byml.ValueEqualityComparer.Default.GetHashCode(node));
}

return hashCode.ToHashCode();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
int IBymlNode.Collect(in BymlWriter writer)
{
Expand Down
11 changes: 11 additions & 0 deletions src/BymlLibrary/Nodes/Containers/HashMap/BymlHashMap32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ namespace BymlLibrary.Nodes.Containers.HashMap;

public class BymlHashMap32 : SortedDictionary<uint, Byml>, IBymlNode
{
public int GetValueHash()
{
HashCode hashCode = new();
foreach ((var key, var node) in this) {
hashCode.Add(key);
hashCode.Add(Byml.ValueEqualityComparer.Default.GetHashCode(node));
}

return hashCode.ToHashCode();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
int IBymlNode.Collect(in BymlWriter writer)
{
Expand Down
11 changes: 11 additions & 0 deletions src/BymlLibrary/Nodes/Containers/HashMap/BymlHashMap64.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ namespace BymlLibrary.Nodes.Containers.HashMap;

public class BymlHashMap64 : SortedDictionary<ulong, Byml>, IBymlNode
{
public int GetValueHash()
{
HashCode hashCode = new();
foreach ((var key, var node) in this) {
hashCode.Add(key);
hashCode.Add(Byml.ValueEqualityComparer.Default.GetHashCode(node));
}

return hashCode.ToHashCode();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
int IBymlNode.Collect(in BymlWriter writer)
{
Expand Down
3 changes: 3 additions & 0 deletions src/BymlLibrary/Nodes/Containers/IBymlNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ namespace BymlLibrary.Nodes.Containers;

internal interface IBymlNode
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetValueHash();

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal int Collect(in BymlWriter writer);

Expand Down
32 changes: 5 additions & 27 deletions src/BymlLibrary/Writers/BymlWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -215,25 +215,25 @@ public int Collect(in Byml byml)
}
else if (byml.Value is string str) {
_strings.TryAdd(str, 0);
return GetValueNodeHashCode(byml);
return Byml.ValueEqualityComparer.GetValueNodeHashCode(byml);
}
else if (byml.Value is byte[] data) {
int hash = CollectBytes((data, null), byml.Type);
int hash = Byml.ValueEqualityComparer.GetBinaryNodeHashCode((data, null), byml.Type);
_nodeCache[byml] = hash;
return hash;
}
else if (byml.Type == BymlNodeType.BinaryAligned) {
int hash = CollectBytes(byml.GetBinaryAligned(), byml.Type);
int hash = Byml.ValueEqualityComparer.GetBinaryNodeHashCode(byml.GetBinaryAligned(), byml.Type);
_nodeCache[byml] = hash;
return hash;
}
else if (byml.Type.IsSpecialValueType()) {
int hash = GetValueNodeHashCode(byml);
int hash = Byml.ValueEqualityComparer.GetValueNodeHashCode(byml);
_nodeCache[byml] = hash;
return hash;
}
else {
return GetValueNodeHashCode(byml);
return Byml.ValueEqualityComparer.GetValueNodeHashCode(byml);
}
}

Expand All @@ -242,26 +242,4 @@ public int Collect(in Byml byml)

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetKeyIndex(string key) => _keys[key];

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int CollectBytes((byte[] data, int? alignment) value, BymlNodeType bymlNodeType)
{
HashCode hashCode = new();
if (value.alignment.HasValue) {
hashCode.Add(value.alignment.Value);
}

hashCode.Add(bymlNodeType.GetHashCode());
hashCode.AddBytes(value.data);
return hashCode.ToHashCode();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int GetValueNodeHashCode(Byml byml)
{
HashCode hashCode = new();
hashCode.Add(byml.Type.GetHashCode());
hashCode.Add(byml.Value?.GetHashCode());
return hashCode.ToHashCode();
}
}

0 comments on commit 0de65c1

Please sign in to comment.