private IEnumerable<Bucket> CollectDelta(IDictionary<Address, long> versions)
{
// missing entries are represented by version 0
var filledOtherVersions = new Dictionary<Address, long>(versions);
foreach (var entry in OwnVersions)
if (filledOtherVersions.ContainsKey(entry.Key))
filledOtherVersions[entry.Key] = 0L;
else
filledOtherVersions.Add(entry.Key, 0L);
var count = 0;
foreach (var entry in filledOtherVersions)
{
var owner = entry.Key;
var v = entry.Value;
Bucket bucket;
if (!_registry.TryGetValue(owner, out bucket))
bucket = new Bucket(owner);
if (bucket.Version > v && count < _settings.MaxDeltaElements)
{
var deltaContent = bucket.Content
.Where(kv => kv.Value.Version > v)
.Aggregate(ImmutableDictionary<string, ValueHolder>.Empty,
(current, kv) => current.SetItem(kv.Key, kv.Value));
count += deltaContent.Count;
if (count <= _settings.MaxDeltaElements)
yield return new Bucket(bucket.Owner, bucket.Version, deltaContent);
else
{
// exceeded the maxDeltaElements, pick the elements with lowest versions
var sortedContent = deltaContent.OrderBy(x => x.Value.Version).ToArray();
var chunk = sortedContent.Take(_settings.MaxDeltaElements - (count - sortedContent.Length)).ToList();
var content = chunk.Aggregate(ImmutableDictionary<string, ValueHolder>.Empty,
(current, kv) => current.SetItem(kv.Key, kv.Value));
yield return new Bucket(bucket.Owner, chunk.Last().Value.Version, content);
}
}
}
}