Exemple #1
0
            public IReplicatedData Merge(IReplicatedData other)
            {
                var atomic = other as AtomicDeltaOperation;

                if (atomic != null)
                {
                    var lastIndex = Operations.Length - 1;
                    var last      = Operations[lastIndex];
                    if (last is PutDeltaOperation || last is UpdateDeltaOperation)
                    {
                        var builder = this.Operations.ToList();
                        var merged  = (IDeltaOperation)last.Merge(atomic);
                        if (merged is AtomicDeltaOperation)
                        {
                            builder[lastIndex] = merged;
                            return(new DeltaGroup(builder));
                        }
                        else
                        {
                            builder.RemoveAt(lastIndex);
                            builder.AddRange(((DeltaGroup)merged).Operations);
                            return(new DeltaGroup(builder));
                        }
                    }
                    else
                    {
                        return(new DeltaGroup(Operations.Union(new[] { atomic })));
                    }
                }
                else
                {
                    var group = (DeltaGroup)other;
                    return(new DeltaGroup(this.Operations.Union(group.Operations)));
                }
            }
Exemple #2
0
 /// <summary>
 /// Modify value of local <see cref="Replicator"/> and replicate with given <see cref="IWriteConsistency"/>.
 ///
 /// The current value for the <see cref="Key"/> is passed to the <see cref="Modify"/> function.
 /// If there is no current data value for the <see cref="Key"/> the <paramref name="initial"/> value will be
 /// passed to the <see cref="Modify"/> function.
 ///
 /// The optional <paramref name="request"/> context is included in the reply messages. This is a convenient
 /// way to pass contextual information (e.g. original sender) without having to use `ask`
 /// or local correlation data structures.
 /// </summary>
 public Update(IKey key, IReplicatedData initial, IWriteConsistency consistency, Func <IReplicatedData, IReplicatedData> modify, object request = null)
 {
     Key         = key;
     Consistency = consistency;
     Request     = request;
     Modify      = x => ModifyWithInitial(initial, modify, x);
 }
Exemple #3
0
 private IReplicatedData Cleaned(IReplicatedData c, IImmutableDictionary <UniqueAddress, IPruningState> p) => p.Aggregate(c, (state, kvp) =>
 {
     if (c is IRemovedNodePruning pruning &&
         kvp.Value is PruningPerformed &&
         pruning.NeedPruningFrom(kvp.Key))
     {
         return(pruning.PruningCleanup(kvp.Key));
Exemple #4
0
            public override IReplicatedData Merge(IReplicatedData other)
            {
                switch (other)
                {
                case AddDeltaOperation operation:
                {
                    var u = operation.Underlying;
                    // Note that we only merge deltas originating from the same node
                    return(new AddDeltaOperation(new ORSet <T>(
                                                     ConcatElementsMap(u.ElementsMap),
                                                     Underlying.VersionVector.Merge(u.VersionVector))));
                }

                case AtomicDeltaOperation _:
                    return(new DeltaGroup(ImmutableArray.Create(this, other)));

                case DeltaGroup dg:
                {
                    var vector = dg.Operations;
                    return(new DeltaGroup(vector.Add(this)));
                }

                default:
                    throw new ArgumentException($"Unknown delta operation of type {other.GetType()}", nameof(other));
                }
            }
            public IReplicatedData Merge(IReplicatedData other)
            {
                if (other is ORMultiValueDictionaryDelta d)
                {
                    return(new ORMultiValueDictionaryDelta((ORDictionary <TKey, ORSet <TValue> > .IDeltaOperation)Underlying.Merge(d.Underlying), WithValueDeltas || d.WithValueDeltas));
                }

                return(new ORMultiValueDictionaryDelta((ORDictionary <TKey, ORSet <TValue> > .IDeltaOperation)Underlying.Merge(other), WithValueDeltas));
            }
Exemple #6
0
            public IReplicatedData Merge(IReplicatedData other)
            {
                if (other is PNCounterDictionaryDelta d)
                {
                    return(new PNCounterDictionaryDelta((ORDictionary <TKey, PNCounter> .IDeltaOperation)Underlying.Merge(d.Underlying)));
                }

                return(new PNCounterDictionaryDelta((ORDictionary <TKey, PNCounter> .IDeltaOperation)Underlying.Merge(other)));
            }
Exemple #7
0
            public IReplicatedData Merge(IReplicatedData other)
            {
                if (other is LWWDictionaryDelta d)
                {
                    return(new LWWDictionaryDelta((ORDictionary <TKey, LWWRegister <TValue> > .IDeltaOperation)Underlying.Merge(d.Underlying)));
                }

                return(new LWWDictionaryDelta((ORDictionary <TKey, LWWRegister <TValue> > .IDeltaOperation)Underlying.Merge(other)));
            }
Exemple #8
0
 private IReplicatedData PruningCleanupTombstoned(IReplicatedData data)
 {
     if (_tombstonedNodes.IsEmpty)
     {
         return(data);
     }
     else
     {
         return(_tombstonedNodes.Aggregate(data, (d, removed) => PruningCleanupTombstoned(removed, d)));
     }
 }
Exemple #9
0
        /// <summary>
        /// TBD
        /// </summary>
        /// <param name="otherData">TBD</param>
        /// <returns>TBD</returns>
        internal DataEnvelope Merge(IReplicatedData otherData)
        {
            if (otherData is DeletedData)
            {
                return(DeletedEnvelope);
            }

            var data = Data.Merge(Cleaned(otherData, Pruning));

            return(new DataEnvelope(data, Pruning));
        }
        public void Update(string key, IReplicatedData delta)
        {
            // bump the counter for each update
            var version = _deltaCounter.GetValueOrDefault(key, 0L) + 1;

            _deltaCounter = _deltaCounter.SetItem(key, version);

            var deltaEntriesForKey = _deltaEntries.GetValueOrDefault(key, ImmutableSortedDictionary <long, IReplicatedData> .Empty);

            _deltaEntries = _deltaEntries.SetItem(key, deltaEntriesForKey.SetItem(version, delta));
        }
Exemple #11
0
        private IReplicatedData PruningCleanupTombstoned(UniqueAddress removed, IReplicatedData data)
        {
            var d = data as IRemovedNodePruning;

            if (d != null)
            {
                if (d.NeedPruningFrom(removed))
                {
                    return(d.PruningCleanup(removed));
                }
            }
            return(data);
        }
Exemple #12
0
 private IReplicatedData PruningCleanupTombstoned(IReplicatedData data)
 {
     if (_tombstonedNodes.Count == 0)
     {
         return(data);
     }
     else
     {
         return(_tombstonedNodes.Aggregate(data, (d, removed) =>
         {
             return PruningCleanupTombstoned(removed, d);
         }));
     }
 }
Exemple #13
0
            public virtual IReplicatedData Merge(IReplicatedData other)
            {
                if (other is AtomicDeltaOperation)
                {
                    return(new DeltaGroup(ImmutableArray.Create(this, (IDeltaOperation)other)));
                }
                else
                {
                    var builder = ImmutableArray <IDeltaOperation> .Empty.ToBuilder();

                    builder.Add(this);
                    builder.AddRange(((DeltaGroup)other).Operations);
                    return(new DeltaGroup(builder.ToImmutable()));
                }
            }
Exemple #14
0
 public override IReplicatedData Merge(IReplicatedData other)
 {
     if (other is AtomicDeltaOperation)
     {
         return(new DeltaGroup(ImmutableArray.Create(this, other)));
     }
     else if (other is DeltaGroup)
     {
         var vector = ((DeltaGroup)other).Operations;
         return(new DeltaGroup(vector.Add(this)));
     }
     else
     {
         throw new ArgumentException($"Unknown delta operation of type {other.GetType()}", nameof(other));
     }
 }
Exemple #15
0
 public IReplicatedData Merge(IReplicatedData other)
 {
     if (other is AddDeltaOperation)
     {
         // merge AddDeltaOp into last AddDeltaOp in the group, if possible
         var last = Operations[Operations.Length - 1];
         return(last is AddDeltaOperation
             ? new DeltaGroup(Operations.SetItem(Operations.Length - 1, other.Merge(last)))
             : new DeltaGroup(Operations.Add(other)));
     }
     else if (other is DeltaGroup @group)
     {
         var otherVector = @group.Operations;
         return(new DeltaGroup(Operations.AddRange(otherVector)));
     }
     else
     {
         return(new DeltaGroup(Operations.Add(other)));
     }
 }
Exemple #16
0
            public override IReplicatedData Merge(IReplicatedData other)
            {
                PutDeltaOperation put;

                if (other is UpdateDeltaOperation)
                {
                    var update  = (UpdateDeltaOperation)other;
                    var builder = this.Values.ToBuilder();
                    foreach (var entry in update.Values)
                    {
                        IReplicatedData value;
                        if (this.Values.TryGetValue(entry.Key, out value))
                        {
                            builder[entry.Key] = value.Merge(entry.Value);
                        }
                        else
                        {
                            builder.Add(entry);
                        }
                    }
                    return(new UpdateDeltaOperation(
                               underlying: (ORSet <TKey> .IDeltaOperation) this.Underlying.Merge(update.Underlying),
                               values: builder.ToImmutable()));
                }
                else if ((put = other as PutDeltaOperation) != null && this.Values.Count == 1 && this.Values.ContainsKey(put.Key))
                {
                    return(new PutDeltaOperation((ORSet <TKey> .IDeltaOperation) this.Underlying.Merge(put.Underlying), put.Key, put.Value));
                }
                else if (other is AtomicDeltaOperation)
                {
                    return(new DeltaGroup(ImmutableArray.Create(this, (IDeltaOperation)other)));
                }
                else
                {
                    var builder = ImmutableArray <IDeltaOperation> .Empty.ToBuilder();

                    builder.Add(this);
                    builder.AddRange(((DeltaGroup)other).Operations);
                    return(new DeltaGroup(builder.ToImmutable()));
                }
            }
Exemple #17
0
        /// <summary>
        /// TBD
        /// </summary>
        /// <param name="otherData">TBD</param>
        /// <returns>TBD</returns>
        internal DataEnvelope Merge(IReplicatedData otherData)
        {
            if (otherData is DeletedData)
            {
                return(DeletedEnvelope);
            }

            var             cleanedData = Cleaned(otherData, Pruning);
            IReplicatedData mergedData;

            if (cleanedData is IReplicatedDelta d)
            {
                var delta = Data as IDeltaReplicatedData ?? throw new ArgumentException($"Expected {nameof(IDeltaReplicatedData)} but got '{Data}' instead.");

                mergedData = delta.MergeDelta(d);
            }
            else
            {
                mergedData = Data.Merge(cleanedData);
            }

            return(new DataEnvelope(mergedData, Pruning, DeltaVersions));
        }
Exemple #18
0
            public override IReplicatedData Merge(IReplicatedData other)
            {
                UpdateDeltaOperation update;
                var put = other as PutDeltaOperation;

                if (put != null && Equals(Key, put.Key))
                {
                    return(new PutDeltaOperation((ORSet <TKey> .IDeltaOperation)Underlying.Merge(put.Underlying), put.Key, put.Value));
                }
                else if ((update = other as UpdateDeltaOperation) != null && update.Values.Count == 1 && update.Values.ContainsKey(Key))
                {
                    var merged = (ORSet <TKey> .IDeltaOperation) this.Underlying.Merge(update.Underlying);
                    var e2     = update.Values.First().Value;
                    if (Value is IDeltaReplicatedData)
                    {
                        var mergedDelta = ((IDeltaReplicatedData)Value).MergeDelta((IReplicatedDelta)e2);
                        return(new PutDeltaOperation(merged, Key, (TValue)mergedDelta));
                    }
                    else
                    {
                        var mergedDelta = Value.Merge(e2);
                        return(new PutDeltaOperation(merged, Key, (TValue)mergedDelta));
                    }
                }
                else if (other is AtomicDeltaOperation)
                {
                    return(new DeltaGroup(ImmutableArray.Create(this, (IDeltaOperation)other)));
                }
                else
                {
                    var builder = ImmutableArray <IDeltaOperation> .Empty.ToBuilder();

                    builder.Add(this);
                    builder.AddRange(((DeltaGroup)other).Operations);
                    return(new DeltaGroup(builder.ToImmutable()));
                }
            }
Exemple #19
0
 public override IReplicatedData Merge(IReplicatedData other)
 {
     if (other is AddDeltaOperation)
     {
         var u = ((AddDeltaOperation)other).Underlying;
         // Note that we only merge deltas originating from the same node
         return(new AddDeltaOperation(new ORSet <T>(
                                          ConcatElementsMap(u.ElementsMap),
                                          Underlying.VersionVector.Merge(u.VersionVector))));
     }
     else if (other is AtomicDeltaOperation)
     {
         return(new DeltaGroup(ImmutableArray.Create(this, other)));
     }
     else if (other is DeltaGroup)
     {
         var vector = ((DeltaGroup)other).Operations;
         return(new DeltaGroup(vector.Add(this)));
     }
     else
     {
         throw new ArgumentException($"Unknown delta operation of type {other.GetType()}", nameof(other));
     }
 }
Exemple #20
0
 /// <summary>
 /// The <see cref="DataEnvelope"/> wraps a data entry and carries state of the pruning process for the entry.
 /// </summary>
 /// <param name="data">TBD</param>
 /// <param name="pruning">TBD</param>
 /// <param name="deltaVersions"></param>
 internal DataEnvelope(IReplicatedData data, ImmutableDictionary <UniqueAddress, IPruningState> pruning = null, VersionVector deltaVersions = null)
 {
     Data          = data;
     Pruning       = pruning ?? ImmutableDictionary <UniqueAddress, IPruningState> .Empty;
     DeltaVersions = deltaVersions ?? VersionVector.Empty;
 }
Exemple #21
0
 /// <summary>
 /// TBD
 /// </summary>
 /// <returns>TBD</returns>
 public IReplicatedData Merge(IReplicatedData other) => Merge((DeletedData)other);
Exemple #22
0
 public IReplicatedData Merge(IReplicatedData other) => Merge((VersionVector)other);
Exemple #23
0
 /// <summary>
 /// Reply from <see cref="Get"/>. The data value is retrieved with <see cref="Data"/>.
 /// </summary>
 public GetSuccess(IKey key, object request, IReplicatedData data)
 {
     Key     = key;
     Request = request;
     Data    = data;
 }
Exemple #24
0
 private IReplicatedData ModifyWithInitial(IReplicatedData initial, Func <IReplicatedData, IReplicatedData> modifier, IReplicatedData data) =>
 modifier(data ?? initial);
 public IReplicatedData Merge(IReplicatedData other) =>
 Merge((PNCounterDictionary <TKey>)other);
Exemple #26
0
 public IReplicatedData Merge(IReplicatedData other) => Merge((PNCounter)other);
 public IReplicatedData Merge(IReplicatedData other) =>
 Merge((ORMultiValueDictionary <TKey, TValue>)other);
Exemple #28
0
 internal DataEnvelope WithData(IReplicatedData data) =>
 new DataEnvelope(data, Pruning, DeltaVersions);
Exemple #29
0
 /// <summary>
 /// TBD
 /// </summary>
 /// <param name="other">TBD</param>
 /// <returns>TBD</returns>
 public IReplicatedData Merge(IReplicatedData other) => Merge((T)other);
Exemple #30
0
 /// <summary>
 /// TBD
 /// </summary>
 /// <param name="other">TBD</param>
 /// <returns>TBD</returns>
 public IReplicatedData Merge(IReplicatedData other) =>
 Merge((LWWDictionary <TKey, TValue>)other);