Skip to content

Commit 4356c0c

Browse files
authored
Improve signature generation algorithm (#193)
1 parent 8a8cd00 commit 4356c0c

File tree

1 file changed

+22
-31
lines changed

1 file changed

+22
-31
lines changed

MetadataProcessor.Shared/Tables/nanoSignaturesTable.cs

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ static nanoSignaturesTable()
108108
/// </summary>
109109
private readonly IDictionary<byte[], ushort> _idsBySignatures =
110110
new Dictionary<byte[], ushort>(new ByteArrayComparer());
111+
/// <summary>
112+
/// The signatures as they are written to the output stream.
113+
/// </summary>
114+
private readonly List<byte> _signatureTable = new List<byte>();
111115

112116
/// <summary>
113117
/// Assembly tables context - contains all tables used for building target assembly.
@@ -116,11 +120,6 @@ static nanoSignaturesTable()
116120

117121
private readonly bool _verbose = false;
118122

119-
/// <summary>
120-
/// Last available signature id (offset in resulting table).
121-
/// </summary>
122-
private ushort _lastAvailableId;
123-
124123
/// <summary>
125124
/// Creates new instance of <see cref="nanoSignaturesTable"/> object.
126125
/// </summary>
@@ -468,12 +467,7 @@ public void WriteDataTypeForTypeDef(TypeDefinition typeDefinition, nanoBinaryWri
468467
public void Write(
469468
nanoBinaryWriter writer)
470469
{
471-
foreach (var signature in _idsBySignatures
472-
.OrderBy(item => item.Value)
473-
.Select(item => item.Key))
474-
{
475-
writer.WriteBytes(signature);
476-
}
470+
writer.WriteBytes(_signatureTable.ToArray());
477471
}
478472

479473
private byte[] GetSignature(
@@ -736,18 +730,29 @@ private ushort GetOrCreateSignatureIdImpl(
736730
return id;
737731
}
738732

739-
var fullSignatures = GetFullSignaturesArray();
740-
for (var i = 0; i <= fullSignatures.Length - signature.Length; ++i)
733+
for (int i = 0; i < _signatureTable.Count - signature.Length; i++)
741734
{
742-
if (signature.SequenceEqual(fullSignatures.Skip(i).Take(signature.Length)))
735+
bool found = true;
736+
for (int j = 0; j < signature.Length; ++j)
743737
{
744-
return (ushort)i;
738+
if (_signatureTable[i + j] != signature[j])
739+
{
740+
found = false;
741+
break;
742+
}
743+
}
744+
745+
if (found)
746+
{
747+
id = (ushort)i;
748+
_idsBySignatures.Add(signature, id);
749+
return id;
745750
}
746751
}
747752

748-
id = _lastAvailableId;
753+
id = (ushort)_signatureTable.Count;
749754
_idsBySignatures.Add(signature, id);
750-
_lastAvailableId += (ushort)signature.Length;
755+
_signatureTable.AddRange(signature);
751756

752757
return id;
753758
}
@@ -775,20 +780,6 @@ private void WriteTypeInfo(
775780
}
776781
}
777782

778-
private byte[] GetFullSignaturesArray()
779-
{
780-
return _idsBySignatures
781-
.OrderBy(item => item.Value)
782-
.Select(item => item.Key)
783-
.Aggregate(new List<byte>(),
784-
(current, item) =>
785-
{
786-
current.AddRange(item);
787-
return current;
788-
})
789-
.ToArray();
790-
}
791-
792783
private void WriteSubTypeInfo(TypeReference typeDefinition, nanoBinaryWriter writer)
793784
{
794785
ushort referenceId;

0 commit comments

Comments
 (0)