-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSimplePartialReplicationStrategy.cs
56 lines (51 loc) · 1.99 KB
/
SimplePartialReplicationStrategy.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using Nyris.Crdt.Distributed.Model;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Nyris.Crdt.Distributed.Strategies.PartialReplication
{
public sealed class SimplePartialReplicationStrategy : IPartialReplicationStrategy
{
/// <inheritdoc />
public IDictionary<TKey, IList<NodeInfo>> GetDistribution<TKey>(
IReadOnlyDictionary<TKey, ulong> collectionSizes,
IEnumerable<NodeInfo> nodes
)
where TKey : IEquatable<TKey>, IComparable<TKey>
{
var result = new Dictionary<TKey, IList<NodeInfo>>(collectionSizes.Count);
var orderedNodes = nodes.OrderBy(nodeInfo => nodeInfo.Id).ToList();
var orderedKeys = collectionSizes
.OrderByDescending(pair => Chunkify(pair.Value))
.ThenBy(pair => pair.Key)
.Select(pair => pair.Key)
.ToList();
var count = 0;
while (count < orderedKeys.Count)
{
for (var i = 0; i < orderedNodes.Count && count < orderedKeys.Count; ++i, ++count)
{
result[orderedKeys[count]] = new List<NodeInfo>(2)
{
orderedNodes[i],
orderedNodes[i == orderedNodes.Count - 1 ? 0 : i + 1]
};
}
for (var i = orderedNodes.Count - 1; i > 0 && count < orderedKeys.Count; --i, ++count)
{
result[orderedKeys[count]] = new List<NodeInfo>(2)
{
orderedNodes[i],
orderedNodes[i == orderedNodes.Count - 1 ? 0 : i + 1]
};
}
}
return result;
}
private static ulong Chunkify(ulong size) => size switch
{
< 1000 => 0,
_ => (ulong) Math.Log10(size)
};
}
}