Adds normalized kademlia positions

This commit is contained in:
Ben 2024-08-14 15:10:33 +02:00
parent b5c8c55c72
commit cc9d04acd7
No known key found for this signature in database
GPG Key ID: 0F16E812E736C24B
3 changed files with 71 additions and 1 deletions

View File

@ -13,6 +13,7 @@ namespace CodexPlugin.OverwatchSupport
private readonly ITranscriptWriter writer;
private readonly CodexLogConverter converter;
private readonly IdentityMap identityMap = new IdentityMap();
private readonly KademliaPositionFinder positionFinder = new KademliaPositionFinder();
public CodexTranscriptWriter(ILog log, ITranscriptWriter transcriptWriter)
{
@ -76,7 +77,7 @@ namespace CodexPlugin.OverwatchSupport
{
return new OverwatchCodexHeader
{
Nodes = identityMap.Get()
Nodes = positionFinder.DeterminePositions(identityMap.Get())
};
}

View File

@ -0,0 +1,68 @@
using System.Numerics;
using Utils;
using YamlDotNet.Core.Tokens;
namespace CodexPlugin.OverwatchSupport
{
public class KademliaPositionFinder
{
public CodexNodeIdentity[] DeterminePositions(CodexNodeIdentity[] identities)
{
var zero = identities.First();
var distances = CalculateDistances(zero, identities);
var maxDistance = distances.Values.Max();
CalculateNormalizedPositions(distances, maxDistance);
return identities;
}
private Dictionary<CodexNodeIdentity, BigInteger> CalculateDistances(CodexNodeIdentity zero, CodexNodeIdentity[] identities)
{
var result = new Dictionary<CodexNodeIdentity, BigInteger>();
foreach (var id in identities.Skip(1))
{
result.Add(id, GetDistance(zero.NodeId, id.NodeId));
}
return result;
}
private BigInteger GetDistance(string id1, string id2)
{
var one = BigInteger.Parse(id1, System.Globalization.NumberStyles.HexNumber).ToByteArray();
var two = BigInteger.Parse(id2, System.Globalization.NumberStyles.HexNumber).ToByteArray();
var x = Xor(one, two);
return new BigInteger(x, isUnsigned: true);
}
private byte[] Xor(byte[] one, byte[] two)
{
if (one.Length != two.Length) throw new Exception("Not equal length");
var result = new byte[one.Length];
for (int i = 0; i < one.Length; i++)
{
uint a = one[i];
uint b = two[i];
uint c = (a ^ b);
result[i] = (byte)c;
}
return result;
}
private void CalculateNormalizedPositions(Dictionary<CodexNodeIdentity, BigInteger> distances, BigInteger maxDistance)
{
foreach (var pair in distances)
{
pair.Key.KademliaNormalizedPosition = DeterminePosition(pair.Value, maxDistance);
}
}
private float DeterminePosition(BigInteger value, BigInteger maxDistance)
{
var f = (value * 10000) / maxDistance;
return ((float)f) / 10000.0f;
}
}
}

View File

@ -52,6 +52,7 @@ namespace CodexPlugin.OverwatchSupport
public string Name { get; set; } = string.Empty;
public string PeerId { get; set; } = string.Empty;
public string NodeId { get; set; } = string.Empty;
public float KademliaNormalizedPosition { get; set; } = 0.0f;
}
#region Scenario Generated Events