/// <summary>
        /// Performs the undo of LSM operation on the source shard.
        /// </summary>
        /// <param name="ts">Transaction scope.</param>
        /// <returns>Result of the operation.</returns>
        public override IStoreResults UndoLocalSourceExecute(IStoreTransactionScope ts)
        {
            DefaultStoreMapping dsmSource = new DefaultStoreMapping(
                _mappingSource.Id,
                _shardMap.Id,
                new DefaultStoreShard(
                    _mappingSource.StoreShard.Id,
                    this.OriginalShardVersionRemoves,
                    _shardMap.Id,
                    _mappingSource.StoreShard.Location,
                    _mappingSource.StoreShard.Status),
                _mappingSource.MinValue,
                _mappingSource.MaxValue,
                _mappingSource.Status,
                _lockOwnerId);

            if (_updateLocation)
            {
                return(ts.ExecuteOperation(
                           StoreOperationRequestBuilder.SpBulkOperationShardMappingsLocal,
                           StoreOperationRequestBuilder.AddShardMappingLocal(
                               this.Id,
                               true,
                               _shardMap,
                               dsmSource)));
            }
            else
            {
                DefaultStoreMapping dsmTarget = new DefaultStoreMapping(
                    _mappingTarget.Id,
                    _shardMap.Id,
                    new DefaultStoreShard(
                        _mappingTarget.StoreShard.Id,
                        this.OriginalShardVersionRemoves,
                        _shardMap.Id,
                        _mappingTarget.StoreShard.Location,
                        _mappingTarget.StoreShard.Status),
                    _mappingTarget.MinValue,
                    _mappingTarget.MaxValue,
                    _mappingTarget.Status,
                    _lockOwnerId);

                return(ts.ExecuteOperation(
                           StoreOperationRequestBuilder.SpBulkOperationShardMappingsLocal,
                           StoreOperationRequestBuilder.UpdateShardMappingLocal(
                               this.Id,
                               true,
                               _shardMap,
                               dsmTarget,
                               dsmSource)));
            }
        }
Beispiel #2
0
        /// <summary>
        /// Performs the undo of LSM operation on the source shard.
        /// </summary>
        /// <param name="ts">Transaction scope.</param>
        /// <returns>Result of the operation.</returns>
        public override IStoreResults UndoLocalSourceExecute(IStoreTransactionScope ts)
        {
            DefaultStoreShard dssOriginal = new DefaultStoreShard(
                _mappingsSource[0].Item1.StoreShard.Id,
                this.OriginalShardVersionAdds,
                _mappingsSource[0].Item1.ShardMapId,
                _mappingsSource[0].Item1.StoreShard.Location,
                _mappingsSource[0].Item1.StoreShard.Status);

            DefaultStoreMapping dsmSource = new DefaultStoreMapping(
                _mappingsSource[0].Item1.Id,
                _mappingsSource[0].Item1.ShardMapId,
                dssOriginal,
                _mappingsSource[0].Item1.MinValue,
                _mappingsSource[0].Item1.MaxValue,
                _mappingsSource[0].Item1.Status,
                _mappingsSource[0].Item2);

            DefaultStoreMapping dsmTarget = new DefaultStoreMapping(
                _mappingsTarget[0].Item1.Id,
                _mappingsTarget[0].Item1.ShardMapId,
                dssOriginal,
                _mappingsTarget[0].Item1.MinValue,
                _mappingsTarget[0].Item1.MaxValue,
                _mappingsTarget[0].Item1.Status,
                _mappingsTarget[0].Item2);

            IStoreMapping[] ms = new[] { dsmSource };
            IStoreMapping[] mt = new[] { dsmTarget };

            return(ts.ExecuteOperation(
                       StoreOperationRequestBuilder.SpBulkOperationShardMappingsLocal,
                       StoreOperationRequestBuilder.ReplaceShardMappingsLocal(
                           this.Id,
                           true,
                           _shardMap,
                           mt.Concat(_mappingsTarget.Skip(1).Select(m => m.Item1)).ToArray(),
                           ms.Concat(_mappingsSource.Skip(1).Select(m => m.Item1)).ToArray())));
        }
        /// <summary>
        /// Performs undo of LSM operation on the target shard.
        /// </summary>
        /// <param name="ts">Transaction scope.</param>
        /// <returns>Result of the operation.</returns>
        public override IStoreResults UndoLocalTargetExecute(IStoreTransactionScope ts)
        {
            DefaultStoreMapping dsmTarget = new DefaultStoreMapping(
                _mappingTarget.Id,
                _shardMap.Id,
                new DefaultStoreShard(
                    _mappingTarget.StoreShard.Id,
                    this.OriginalShardVersionAdds,
                    _shardMap.Id,
                    _mappingTarget.StoreShard.Location,
                    _mappingTarget.StoreShard.Status),
                _mappingTarget.MinValue,
                _mappingTarget.MaxValue,
                _mappingTarget.Status,
                _lockOwnerId);

            return(ts.ExecuteOperation(
                       StoreOperationRequestBuilder.SpBulkOperationShardMappingsLocal,
                       StoreOperationRequestBuilder.RemoveShardMappingLocal(
                           this.Id,
                           true,
                           _shardMap,
                           dsmTarget)));
        }
        /// <summary>
        /// Performs the undo of LSM operation on the source shard.
        /// </summary>
        /// <param name="ts">Transaction scope.</param>
        /// <returns>Result of the operation.</returns>
        public override IStoreResults UndoLocalSourceExecute(IStoreTransactionScope ts)
        {
            DefaultStoreMapping dsm = new DefaultStoreMapping(
                _mapping.Id,
                _shardMap.Id,
                new DefaultStoreShard(
                    _mapping.StoreShard.Id,
                    this.OriginalShardVersionAdds,
                    _shardMap.Id,
                    _mapping.StoreShard.Location,
                    _mapping.StoreShard.Status),
                _mapping.MinValue,
                _mapping.MaxValue,
                _mapping.Status,
                default(Guid));

            return ts.ExecuteOperation(
                StoreOperationRequestBuilder.SpBulkOperationShardMappingsLocal,
                StoreOperationRequestBuilder.RemoveShardMappingLocal(
                    this.Id,
                    true,
                    _shardMap,
                    dsm));
        }
Beispiel #5
0
        /// <summary>
        /// Allows for update to a mapping with the updates provided in
        /// the <paramref name="update"/> parameter.
        /// </summary>
        /// <param name="currentMapping">Mapping being updated.</param>
        /// <param name="update">Updated properties of the Shard.</param>
        /// <param name="constructMapping">Delegate to construct a mapping object.</param>
        /// <param name="statusAsInt">Delegate to get the mapping status as an integer value.</param>
        /// <param name="intAsStatus">Delegate to get the mapping status from an integer value.</param>
        /// <param name="lockOwnerId">Lock owner id of this mapping</param>
        /// <param name="options">Options for validation operations to perform on opened connection to affected shard.</param>
        /// <returns>New instance of mapping with updated information.</returns>
        protected TMapping Update <TMapping, TUpdate, TStatus>(
            TMapping currentMapping,
            TUpdate update,
            Func <ShardMapManager, ShardMap, IStoreMapping, TMapping> constructMapping,
            Func <TStatus, int> statusAsInt,
            Func <int, TStatus> intAsStatus,
            Guid lockOwnerId       = default(Guid),
            MappingOptions options = MappingOptions.Validate)
            where TUpdate : class, IMappingUpdate <TStatus>
            where TMapping : class, IShardProvider, IMappingInfoProvider
            where TStatus : struct
        {
            Debug.Assert(currentMapping != null);
            Debug.Assert(update != null);

            this.EnsureMappingBelongsToShardMap <TMapping>(currentMapping, "Update", "currentMapping");

            IMappingUpdate <TStatus> mu = update as IMappingUpdate <TStatus>;

            // CONSIDER(wbasheer): Have refresh semantics for trivial case when nothing is modified.
            if (!mu.IsAnyPropertySet(MappingUpdatedProperties.All))
            {
                return(currentMapping);
            }

            bool shardChanged = mu.IsAnyPropertySet(MappingUpdatedProperties.Shard) && !mu.Shard.Equals(currentMapping.ShardInfo);

            // Ensure that shard belongs to current shard map.
            if (shardChanged)
            {
                ExceptionUtils.EnsureShardBelongsToShardMap(
                    this.Manager,
                    this.ShardMap,
                    mu.Shard,
                    "UpdateMapping",
                    currentMapping.Kind == MappingKind.PointMapping ? "PointMapping" : "RangeMapping");
            }

            IStoreShard originalShard = new DefaultStoreShard(
                currentMapping.ShardInfo.Id,
                Guid.NewGuid(),
                currentMapping.ShardInfo.StoreShard.ShardMapId,
                currentMapping.ShardInfo.StoreShard.Location,
                currentMapping.ShardInfo.StoreShard.Status);

            IStoreMapping originalMapping = new DefaultStoreMapping(
                currentMapping.StoreMapping.Id,
                currentMapping.ShardMapId,
                originalShard,
                currentMapping.StoreMapping.MinValue,
                currentMapping.StoreMapping.MaxValue,
                currentMapping.StoreMapping.Status,
                lockOwnerId);

            IStoreShard updatedShard;

            if (shardChanged)
            {
                updatedShard = new DefaultStoreShard(
                    update.Shard.ShardInfo.Id,
                    Guid.NewGuid(),
                    update.Shard.ShardInfo.StoreShard.ShardMapId,
                    update.Shard.ShardInfo.StoreShard.Location,
                    update.Shard.ShardInfo.StoreShard.Status);
            }
            else
            {
                updatedShard = originalShard;
            }

            IStoreMapping updatedMapping = new DefaultStoreMapping(
                Guid.NewGuid(),
                currentMapping.ShardMapId,
                updatedShard,
                currentMapping.StoreMapping.MinValue,
                currentMapping.StoreMapping.MaxValue,
                mu.IsAnyPropertySet(MappingUpdatedProperties.Status) ?
                statusAsInt(update.Status) :
                currentMapping.StoreMapping.Status,
                lockOwnerId);

            bool fromOnlineToOffline = mu.IsMappingBeingTakenOffline(intAsStatus(currentMapping.StoreMapping.Status));

            StoreOperationCode opCode;

            if (fromOnlineToOffline)
            {
                opCode = currentMapping.Kind == MappingKind.PointMapping ?
                         StoreOperationCode.UpdatePointMappingWithOffline :
                         StoreOperationCode.UpdateRangeMappingWithOffline;
            }
            else
            {
                opCode = currentMapping.Kind == MappingKind.PointMapping ?
                         StoreOperationCode.UpdatePointMapping :
                         StoreOperationCode.UpdateRangeMapping;
            }

            var killConnection = options == MappingOptions.Validate;

            using (IStoreOperation op = this.Manager.StoreOperationFactory.CreateUpdateMappingOperation(
                       this.Manager,
                       opCode,
                       this.ShardMap.StoreShardMap,
                       originalMapping,
                       updatedMapping,
                       this.ShardMap.ApplicationNameSuffix,
                       lockOwnerId,
                       killConnection))
            {
                op.Do();
            }

            return(constructMapping(this.Manager, this.ShardMap, updatedMapping));
        }
Beispiel #6
0
        internal RangeMapping <TKey> Merge(RangeMapping <TKey> left, RangeMapping <TKey> right, Guid leftLockOwnerId, Guid rightLockOwnerId)
        {
            this.EnsureMappingBelongsToShardMap <RangeMapping <TKey> >(left, "Merge", "left");
            this.EnsureMappingBelongsToShardMap <RangeMapping <TKey> >(right, "Merge", "right");

            if (!left.Shard.Location.Equals(right.Shard.Location))
            {
                throw new ArgumentException(
                          StringUtils.FormatInvariant(
                              Errors._ShardMapping_MergeDifferentShards,
                              this.ShardMap.Name,
                              left.Shard.Location,
                              right.Shard.Location),
                          "left");
            }

            if (left.Range.Intersects(right.Range) || left.Range.High != right.Range.Low)
            {
                throw new ArgumentOutOfRangeException(
                          "left",
                          Errors._ShardMapping_MergeNotAdjacent);
            }

            if (left.Status != right.Status)
            {
                throw new ArgumentException(
                          StringUtils.FormatInvariant(
                              Errors._ShardMapping_DifferentStatus,
                              this.ShardMap.Name),
                          "left");
            }

            IStoreShard newShard = new DefaultStoreShard(
                left.Shard.StoreShard.Id,
                Guid.NewGuid(),
                left.Shard.StoreShard.ShardMapId,
                left.Shard.StoreShard.Location,
                left.Shard.StoreShard.Status);

            IStoreMapping mappingToRemoveLeft = new DefaultStoreMapping(
                left.StoreMapping.Id,
                left.StoreMapping.ShardMapId,
                newShard,
                left.StoreMapping.MinValue,
                left.StoreMapping.MaxValue,
                left.StoreMapping.Status,
                left.StoreMapping.LockOwnerId);

            IStoreMapping mappingToRemoveRight = new DefaultStoreMapping(
                right.StoreMapping.Id,
                right.StoreMapping.ShardMapId,
                newShard,
                right.StoreMapping.MinValue,
                right.StoreMapping.MaxValue,
                right.StoreMapping.Status,
                right.StoreMapping.LockOwnerId);

            IStoreMapping mappingToAdd = new DefaultStoreMapping(
                Guid.NewGuid(),
                newShard.ShardMapId,
                newShard,
                left.Range.Low.RawValue,
                right.Range.High.RawValue,
                (int)left.Status,
                leftLockOwnerId);

            using (IStoreOperation op = this.Manager.StoreOperationFactory.CreateReplaceMappingsOperation(
                       this.Manager,
                       StoreOperationCode.MergeMappings,
                       this.ShardMap.StoreShardMap,
                       new[]
            {
                new Tuple <IStoreMapping, Guid> (mappingToRemoveLeft, leftLockOwnerId),
                new Tuple <IStoreMapping, Guid> (mappingToRemoveRight, rightLockOwnerId)
            },
                       new[]
            {
                new Tuple <IStoreMapping, Guid>(mappingToAdd, leftLockOwnerId)
            }))
            {
                op.Do();
            }

            return(new RangeMapping <TKey>(this.Manager, this.ShardMap, mappingToAdd));
        }
Beispiel #7
0
        /// <summary>
        /// Splits the given mapping into 2 at the given key. The new mappings point to the same shard
        /// as the existing mapping.
        /// </summary>
        /// <param name="existingMapping">Given existing mapping.</param>
        /// <param name="splitAt">Split point.</param>
        /// <param name="lockOwnerId">Lock owner id of this mapping</param>
        /// <returns>Read-only collection of 2 new mappings thus created.</returns>
        internal IReadOnlyList <RangeMapping <TKey> > Split(RangeMapping <TKey> existingMapping, TKey splitAt, Guid lockOwnerId)
        {
            this.EnsureMappingBelongsToShardMap <RangeMapping <TKey> >(
                existingMapping,
                "Split",
                "existingMapping");

            ShardKey shardKey = new ShardKey(ShardKey.ShardKeyTypeFromType(typeof(TKey)), splitAt);

            if (!existingMapping.Range.Contains(shardKey) ||
                existingMapping.Range.Low == shardKey ||
                existingMapping.Range.High == shardKey)
            {
                throw new ArgumentOutOfRangeException(
                          "splitAt",
                          Errors._ShardMapping_SplitPointOutOfRange);
            }

            IStoreShard newShard = new DefaultStoreShard(
                existingMapping.Shard.StoreShard.Id,
                Guid.NewGuid(),
                existingMapping.ShardMapId,
                existingMapping.Shard.StoreShard.Location,
                existingMapping.Shard.StoreShard.Status);

            IStoreMapping mappingToRemove = new DefaultStoreMapping(
                existingMapping.StoreMapping.Id,
                existingMapping.StoreMapping.ShardMapId,
                newShard,
                existingMapping.StoreMapping.MinValue,
                existingMapping.StoreMapping.MaxValue,
                existingMapping.StoreMapping.Status,
                existingMapping.StoreMapping.LockOwnerId);

            IStoreMapping[] mappingsToAdd = new IStoreMapping[2]
            {
                new DefaultStoreMapping(
                    Guid.NewGuid(),
                    newShard.ShardMapId,
                    newShard,
                    existingMapping.Range.Low.RawValue,
                    shardKey.RawValue,
                    (int)existingMapping.Status,
                    lockOwnerId),
                new DefaultStoreMapping(
                    Guid.NewGuid(),
                    newShard.ShardMapId,
                    newShard,
                    shardKey.RawValue,
                    existingMapping.Range.High.RawValue,
                    (int)existingMapping.Status,
                    lockOwnerId)
            };

            using (IStoreOperation op = this.Manager.StoreOperationFactory.CreateReplaceMappingsOperation(
                       this.Manager,
                       StoreOperationCode.SplitMapping,
                       this.ShardMap.StoreShardMap,
                       new[] { new Tuple <IStoreMapping, Guid>(mappingToRemove, lockOwnerId) },
                       mappingsToAdd.Select(mappingToAdd => new Tuple <IStoreMapping, Guid>(mappingToAdd, lockOwnerId)).ToArray()))
            {
                op.Do();
            }

            return(mappingsToAdd
                   .Select(m => new RangeMapping <TKey>(this.Manager, this.ShardMap, m))
                   .ToList()
                   .AsReadOnly());
        }
        /// <summary>
        /// Performs the undo of LSM operation on the source shard.
        /// </summary>
        /// <param name="ts">Transaction scope.</param>
        /// <returns>Result of the operation.</returns>
        public override IStoreResults UndoLocalSourceExecute(IStoreTransactionScope ts)
        {
            DefaultStoreMapping dsmSource = new DefaultStoreMapping(
                _mappingSource.Id,
                _shardMap.Id,
                new DefaultStoreShard(
                    _mappingSource.StoreShard.Id,
                    this.OriginalShardVersionRemoves,
                    _shardMap.Id,
                    _mappingSource.StoreShard.Location,
                    _mappingSource.StoreShard.Status),
                _mappingSource.MinValue,
                _mappingSource.MaxValue,
                _mappingSource.Status,
                _lockOwnerId);

            if (_updateLocation)
            {
                return ts.ExecuteOperation(
                    StoreOperationRequestBuilder.SpBulkOperationShardMappingsLocal,
                    StoreOperationRequestBuilder.AddShardMappingLocal(
                        this.Id,
                        true,
                        _shardMap,
                        dsmSource));
            }
            else
            {
                DefaultStoreMapping dsmTarget = new DefaultStoreMapping(
                    _mappingTarget.Id,
                    _shardMap.Id,
                    new DefaultStoreShard(
                        _mappingTarget.StoreShard.Id,
                        this.OriginalShardVersionRemoves,
                        _shardMap.Id,
                        _mappingTarget.StoreShard.Location,
                        _mappingTarget.StoreShard.Status),
                    _mappingTarget.MinValue,
                    _mappingTarget.MaxValue,
                    _mappingTarget.Status,
                    _lockOwnerId);

                return ts.ExecuteOperation(
                    StoreOperationRequestBuilder.SpBulkOperationShardMappingsLocal,
                    StoreOperationRequestBuilder.UpdateShardMappingLocal(
                        this.Id,
                        true,
                        _shardMap,
                        dsmTarget,
                        dsmSource));
            }
        }
        /// <summary>
        /// Performs the undo of LSM operation on the source shard.
        /// </summary>
        /// <param name="ts">Transaction scope.</param>
        /// <returns>Result of the operation.</returns>
        public override IStoreResults UndoLocalSourceExecute(IStoreTransactionScope ts)
        {
            DefaultStoreShard dssOriginal = new DefaultStoreShard(
                _mappingsSource[0].Item1.StoreShard.Id,
                this.OriginalShardVersionAdds,
                _mappingsSource[0].Item1.ShardMapId,
                _mappingsSource[0].Item1.StoreShard.Location,
                _mappingsSource[0].Item1.StoreShard.Status);

            DefaultStoreMapping dsmSource = new DefaultStoreMapping(
                _mappingsSource[0].Item1.Id,
                _mappingsSource[0].Item1.ShardMapId,
                dssOriginal,
                _mappingsSource[0].Item1.MinValue,
                _mappingsSource[0].Item1.MaxValue,
                _mappingsSource[0].Item1.Status,
                _mappingsSource[0].Item2);

            DefaultStoreMapping dsmTarget = new DefaultStoreMapping(
                _mappingsTarget[0].Item1.Id,
                _mappingsTarget[0].Item1.ShardMapId,
                dssOriginal,
                _mappingsTarget[0].Item1.MinValue,
                _mappingsTarget[0].Item1.MaxValue,
                _mappingsTarget[0].Item1.Status,
                _mappingsTarget[0].Item2);

            IStoreMapping[] ms = new[] { dsmSource };
            IStoreMapping[] mt = new[] { dsmTarget };

            return ts.ExecuteOperation(
                StoreOperationRequestBuilder.SpBulkOperationShardMappingsLocal,
                StoreOperationRequestBuilder.ReplaceShardMappingsLocal(
                    this.Id,
                    true,
                    _shardMap,
                    mt.Concat(_mappingsTarget.Skip(1).Select(m => m.Item1)).ToArray(),
                    ms.Concat(_mappingsSource.Skip(1).Select(m => m.Item1)).ToArray()));
        }