Пример #1
0
        /// <summary>Constructs a shard key using given object.</summary>
        /// <param name="value">Input object.</param>
        public ShardKey(object value)
        {
            ExceptionUtils.DisallowNullArgument(value, "value");

            // We can't detect the type if value is null.
            if (DBNull.Value.Equals(value))
            {
                throw new ArgumentNullException("value");
            }

            ShardKey shardKey = value as ShardKey;

            if (shardKey != null)
            {
                _keyType = shardKey._keyType;
                _value   = shardKey._value;
            }
            else
            {
                _keyType = ShardKey.DetectShardKeyType(value);
                _value   = ShardKey.Normalize(_keyType, value);
            }

            _hashCode = this.CalculateHashCode();
        }
Пример #2
0
        /// <summary>
        /// Take an object and convert it to its normalized representation as a byte array.
        /// </summary>
        /// <param name="keyType">The type of the <see cref="ShardKey"/>.</param>
        /// <param name="value">The value</param>
        /// <returns>The normalized <see cref="ShardKey"/> information</returns>
        private static byte[] Normalize(ShardKeyType keyType, object value)
        {
            switch (keyType)
            {
            case ShardKeyType.Int32:
                return(ShardKey.Normalize((int)value));

            case ShardKeyType.Int64:
                return(ShardKey.Normalize((long)value));

            case ShardKeyType.Guid:
                return(ShardKey.Normalize((Guid)value));

            case ShardKeyType.DateTime:
                return(ShardKey.Normalize((DateTime)value));

            case ShardKeyType.TimeSpan:
                return(ShardKey.Normalize((TimeSpan)value));

            case ShardKeyType.DateTimeOffset:
                return(ShardKey.Normalize((DateTimeOffset)value));

            default:
                Debug.Assert(keyType == ShardKeyType.Binary);
                return(ShardKey.Normalize((byte[])value));
            }
        }
Пример #3
0
        /// <summary>
        /// Constructs a shard key using given object and keyType.
        /// </summary>
        /// <param name="keyType">The key type of value in object.</param>
        /// <param name="value">Input object.</param>
        public ShardKey(ShardKeyType keyType, object value)
        {
            if (keyType == ShardKeyType.None)
            {
                throw new ArgumentOutOfRangeException(
                          "keyType",
                          keyType,
                          Errors._ShardKey_UnsupportedShardKeyType);
            }

            _keyType = keyType;

            if (value != null && !DBNull.Value.Equals(value))
            {
                ShardKeyType detectedKeyType = ShardKey.DetectShardKeyType(value);

                if (_keyType != detectedKeyType)
                {
                    throw new ArgumentException(
                              StringUtils.FormatInvariant(
                                  Errors._ShardKey_ValueDoesNotMatchShardKeyType,
                                  "keyType"),
                              "value");
                }

                _value = ShardKey.Normalize(_keyType, value);
            }
            else
            {
                // Null represents positive infinity.
                _value = null;
            }

            _hashCode = this.CalculateHashCode();
        }
        private void TestShardKeyGeneric <TKey>(ShardKeyType keyType, TKey inputValue, Type realType)
        {
            // Excercise DetectType
            //
            ShardKey k1 = new ShardKey(inputValue);

            Assert.AreEqual(realType, k1.DataType);

            // Go to/from raw value
            ShardKey k2 = new ShardKey(keyType, inputValue);

            byte[] k2raw = k2.RawValue;

            ShardKey k3 = ShardKey.FromRawValue(keyType, k2raw);

            Assert.AreEqual(inputValue, k2.Value);
            Assert.AreEqual(inputValue, k3.Value);
            Assert.AreEqual(k2, k3);

            // verify comparisons
            Assert.AreEqual(0, k2.CompareTo(k3));

            try
            {
                k3 = k2.GetNextKey();
                Assert.IsTrue(k3 > k2);
            }
            catch (InvalidOperationException)
            {
            }
        }
        /// <summary>
        /// Gets a shard range corresponding to a specified key type.
        /// </summary>
        /// <param name="keyType">Type of key.</param>
        /// <returns>Full range for given key type.</returns>
        internal static ShardRange GetFullRange(ShardKeyType keyType)
        {
            Debug.Assert(keyType != ShardKeyType.None);

            switch (keyType)
            {
            case ShardKeyType.Int32:
                return(ShardRange.FullRangeInt32);

            case ShardKeyType.Int64:
                return(ShardRange.FullRangeInt64);

            case ShardKeyType.Guid:
                return(ShardRange.FullRangeGuid);

            case ShardKeyType.Binary:
                return(ShardRange.FullRangeBinary);

            case ShardKeyType.DateTime:
                return(ShardRange.FullRangeDateTime);

            case ShardKeyType.TimeSpan:
                return(ShardRange.FullRangeTimeSpan);

            case ShardKeyType.DateTimeOffset:
                return(ShardRange.FullRangeDateTimeOffset);

            default:
                Debug.Fail("Unexpected ShardKeyType.");
                return(null);
            }
        }
Пример #6
0
        /// <summary>
        /// Constructs range based on its low boundary value. The low boundary value is
        /// set to the one specified in <paramref name="low"/> while the
        /// high boundary value is set to maximum possible value i.e. +infinity.
        /// </summary>
        /// <param name="low">Low boundary value (inclusive).</param>
        public Range(TKey low)
        {
            ShardKeyType k = ShardKey.ShardKeyTypeFromType(typeof(TKey));

            _r = new ShardRange(
                new ShardKey(k, low),
                new ShardKey(k, null));

            this.Low       = low;
            this.HighIsMax = true;
        }
Пример #7
0
        /// <summary>
        /// Constructs range based on its low and high boundary values.
        /// </summary>
        /// <param name="low">Low boundary value (inclusive).</param>
        /// <param name="high">High boundary value (exclusive).</param>
        public Range(TKey low, TKey high)
        {
            ShardKeyType k = ShardKey.ShardKeyTypeFromType(typeof(TKey));

            _r = new ShardRange(
                new ShardKey(k, low),
                new ShardKey(k, high));

            this.Low  = low;
            this.High = high;
        }
Пример #8
0
        /// <summary>
        /// Gets the CLR type corresponding to the specified ShardKeyType.
        /// </summary>
        /// <param name="keyType">Input ShardKeyType.</param>
        /// <returns>CLR type.</returns>
        public static Type TypeFromShardKeyType(ShardKeyType keyType)
        {
            if (keyType == ShardKeyType.None)
            {
                throw new ArgumentOutOfRangeException(
                          "keyType",
                          keyType,
                          Errors._ShardKey_UnsupportedShardKeyType);
            }

            return(s_shardKeyTypeToType.Value[keyType]);
        }
 /// <summary>
 /// Helper function to advance mapping iterators.
 /// </summary>
 /// <param name="iterator">The iterator to advance.</param>
 /// <param name="keyType">The data type of the map key.</param>
 /// <param name="nextMapping">Output value that will contain next mapping.</param>
 /// <param name="nextRange">Output value that will contain next range.</param>
 /// <param name="nextMinKey">Output value that will contain next min key.</param>
 private static void MoveToNextMapping(
     IEnumerator <IStoreMapping> iterator,
     ShardKeyType keyType,
     out IStoreMapping nextMapping,
     out ShardRange nextRange,
     out ShardKey nextMinKey)
 {
     nextMapping = iterator.MoveNext() ? iterator.Current : null;
     nextRange   = nextMapping != null ? new ShardRange(
         ShardKey.FromRawValue(keyType, nextMapping.MinValue),
         ShardKey.FromRawValue(keyType, nextMapping.MaxValue)) : null;
     nextMinKey = nextRange != null ? nextRange.Low : null;
 }
Пример #10
0
 /// <summary>
 /// Constructs an instance of DefaultStoreShardMap used for creating new shard maps.
 /// </summary>
 /// <param name="id">Shard map Id.</param>
 /// <param name="name">Shard map name.</param>
 /// <param name="mapType">Shard map kind.</param>
 /// <param name="keyType">Shard map key type.</param>
 /// <param name="shardId">Optional argument for shardId if this instance is for a local shardmap.</param>
 internal DefaultStoreShardMap(
     Guid id,
     string name,
     ShardMapType mapType,
     ShardKeyType keyType,
     Guid?shardId = null)
 {
     this.Id      = id;
     this.Name    = name;
     this.MapType = mapType;
     this.KeyType = keyType;
     this.ShardId = shardId;
 }
 /// <summary>
 /// Constructs an instance of DefaultStoreShardMap used for creating new shard maps.
 /// </summary>
 /// <param name="id">Shard map Id.</param>
 /// <param name="name">Shard map name.</param>
 /// <param name="mapType">Shard map kind.</param>
 /// <param name="keyType">Shard map key type.</param>
 /// <param name="shardId">Optional argument for shardId if this instance is for a local shardmap.</param>
 internal DefaultStoreShardMap(
     Guid id,
     string name,
     ShardMapType mapType,
     ShardKeyType keyType,
     Guid? shardId = null)
 {
     this.Id = id;
     this.Name = name;
     this.MapType = mapType;
     this.KeyType = keyType;
     this.ShardId = shardId;
 }
        /// <summary>
        /// Helper function that produces a list of MappingComparisonResults from union of points in the gsmMappings and lsmMappings.
        /// </summary>
        /// <param name="ssm">StoreShardmap to be referenced in produced MappingComparisonResults</param>
        /// <param name="gsmMappings">List of mappings from the GSM.</param>
        /// <param name="lsmMappings">List of mappings from the LSM.</param>
        /// <returns>List of mappingcomparisonresults: one for each range arising from the union of boundaries in gsmMappings and lsmMappings.</returns>
        internal static List <MappingComparisonResult> ComparePointMappings(
            IStoreShardMap ssm,
            IEnumerable <IStoreMapping> gsmMappings,
            IEnumerable <IStoreMapping> lsmMappings)
        {
            ShardKeyType keyType = ssm.KeyType;
            // Get a Linq-able set of points from the input mappings.
            //
            IDictionary <ShardKey, IStoreMapping> gsmPoints =
                gsmMappings.ToDictionary(gsmMapping => ShardKey.FromRawValue(keyType, gsmMapping.MinValue));
            IDictionary <ShardKey, IStoreMapping> lsmPoints =
                lsmMappings.ToDictionary(lsmMapping => ShardKey.FromRawValue(keyType, lsmMapping.MinValue));

            // Construct the output list. This is the concatenation of 3 mappings:
            //  1.) Intersection (the key exists in both the shardmap and the shard.)
            //  2.) Shard only (the key exists only in the shard.)
            //  3.) Shardmap only (the key exists only in the shardmap.)
            //
            List <MappingComparisonResult> results = (new List <MappingComparisonResult>()).Concat(
                // Intersection.
                lsmPoints.Keys.Intersect(gsmPoints.Keys).Select(
                    commonPoint =>
                    new MappingComparisonResult(
                        ssm,
                        new ShardRange(commonPoint, commonPoint.GetNextKey()),
                        MappingLocation.MappingInShardMapAndShard,
                        gsmPoints[commonPoint],
                        lsmPoints[commonPoint]))
                ).Concat(
                // Lsm only.
                lsmPoints.Keys.Except(gsmPoints.Keys).Select(
                    lsmOnlyPoint =>
                    new MappingComparisonResult(
                        ssm,
                        new ShardRange(lsmOnlyPoint, lsmOnlyPoint.GetNextKey()),
                        MappingLocation.MappingInShardOnly,
                        null,
                        lsmPoints[lsmOnlyPoint]))
                ).Concat(
                // Gsm only.
                gsmPoints.Keys.Except(lsmPoints.Keys).Select(
                    gsmOnlyPoint =>
                    new MappingComparisonResult(
                        ssm,
                        new ShardRange(gsmOnlyPoint, gsmOnlyPoint.GetNextKey()),
                        MappingLocation.MappingInShardMapOnly,
                        gsmPoints[gsmOnlyPoint],
                        null))).ToList();

            return(results);
        }
Пример #13
0
        private void Verify(ShardKeyType kind)
        {
            byte[]   bytes  = null;
            ShardKey key    = null;
            ShardKey result = null;

            switch (kind)
            {
            case ShardKeyType.Int32:
                bytes = new byte[sizeof(int)];
                rValGen.NextBytes(bytes);
                Int32 int32 = BitConverter.ToInt32(bytes, 0);
                key    = new ShardKey(int32);
                result = key.GetNextKey();
                Debug.Assert(result.IsMax || result == new ShardKey(int32 + 1));
                break;

            case ShardKeyType.Int64:
                bytes = new byte[sizeof(long)];
                rValGen.NextBytes(bytes);
                Int64 int64 = BitConverter.ToInt64(bytes, 0);
                key    = new ShardKey(int64);
                result = key.GetNextKey();
                Debug.Assert(result.IsMax || result == new ShardKey(int64 + 1));
                break;

            case ShardKeyType.Guid:
                Guid guid = Guid.NewGuid();
                key    = new ShardKey(guid);
                result = key.GetNextKey();
                // verify only the API call
                break;

            case ShardKeyType.Binary:
                bytes = new byte[128];
                rValGen.NextBytes(bytes);
                key    = new ShardKey(bytes);
                result = key.GetNextKey();
                // verify only the API call
                break;

            default:
                throw new ArgumentOutOfRangeException(
                          "kind",
                          kind,
                          Errors._ShardKey_UnsupportedShardKeyType);
            }
        }
Пример #14
0
        /// <summary>
        /// Takes a byte array and a shard key type and convert it to its native denormalized C# type.
        /// </summary>
        /// <returns>The denormalized object</returns>
        private static object DeNormalize(ShardKeyType keyType, byte[] value)
        {
            // Return null for positive infinity.
            if (value == null)
            {
                return(null);
            }

            switch (keyType)
            {
            case ShardKeyType.Int32:
                return(ShardKey.DenormalizeInt32(value));

            case ShardKeyType.Int64:
                return(ShardKey.DenormalizeInt64(value));

            case ShardKeyType.Guid:
                return(ShardKey.DenormalizeGuid(value));

            case ShardKeyType.DateTime:
                long dtTicks = ShardKey.DenormalizeInt64(value);
                return(new DateTime(dtTicks));

            case ShardKeyType.TimeSpan:
                long tsTicks = ShardKey.DenormalizeInt64(value);
                return(new TimeSpan(tsTicks));

            case ShardKeyType.DateTimeOffset:
                return(DenormalizeDateTimeOffset(value));

            default:
                // For varbinary type, we simply keep it as a VarBytes object
                Debug.Assert(keyType == ShardKeyType.Binary);
                return(ShardKey.DenormalizeByteArray(value));
            }
        }
Пример #15
0
        /// <summary>
        /// Instantiates the key with given type and raw value and optionally validates
        /// the key type and raw representation of the value.
        /// </summary>
        /// <param name="keyType">Type of shard key.</param>
        /// <param name="rawValue">Raw value of the key.</param>
        /// <param name="validate">Whether to validate the key type and raw value.</param>
        private ShardKey(ShardKeyType keyType, byte[] rawValue, bool validate)
        {
            _keyType  = keyType;
            _value    = rawValue;
            _hashCode = this.CalculateHashCode();

            if (validate)
            {
                int expectedLength;

                switch (keyType)
                {
                case ShardKeyType.Int32:
                    expectedLength = sizeof(int);
                    break;

                case ShardKeyType.Int64:
                case ShardKeyType.DateTime:
                case ShardKeyType.TimeSpan:
                    expectedLength = sizeof(long);
                    break;

                case ShardKeyType.Guid:
                    expectedLength = ShardKey.SizeOfGuid;
                    break;

                case ShardKeyType.Binary:
                    expectedLength = ShardKey.MaximumVarBytesKeySize;
                    break;

                case ShardKeyType.DateTimeOffset:
                    expectedLength = SizeOfDateTimeOffset;
                    break;

                default:
                    throw new ArgumentOutOfRangeException(
                              "keyType",
                              keyType,
                              Errors._ShardKey_UnsupportedShardKeyType);
                }

                // +ve & -ve infinity. Correct size provided.
                if (_value == null ||
                    _value.Length == 0 ||
                    _value.Length == expectedLength)
                {
                    return;
                }

                // Only allow byte[] values to be of different length than expected,
                // since there could be smaller values than 128 bytes. For anything
                // else any non-zero length should match the expected length.
                if (_keyType != ShardKeyType.Binary || _value.Length > expectedLength)
                {
                    throw new ArgumentOutOfRangeException(
                              "rawValue",
                              rawValue,
                              string.Format(CultureInfo.InvariantCulture,
                                            Errors._ShardKey_ValueLengthUnexpected,
                                            _value.Length,
                                            expectedLength,
                                            _keyType));
                }
            }
        }
Пример #16
0
 /// <summary>
 /// Constructs the mapper, notes the key type for lookups.
 /// </summary>
 /// <param name="keyType">Key type.</param>
 internal CacheRangeMapper(ShardKeyType keyType)
     : base(keyType)
 {
     _mappingsByRange = new SortedList<ShardRange, CacheMapping>(Comparer<ShardRange>.Default);
 }
Пример #17
0
 public ShardKeyInfo(ShardKeyType keyType, object value, byte[] rawValue)
 {
     KeyType = keyType;
     Value = value;
     RawValue = rawValue;
 }
        /// <summary>
        /// Helper function that produces a list of MappingComparisonResults from union of range boundaries in the gsmMappings and lsmMappings.
        /// </summary>
        /// <param name="ssm">StoreShardmap to be referenced in produced MappingComparisonResults</param>
        /// <param name="gsmMappings">List of mappings from the GSM.</param>
        /// <param name="lsmMappings">List of mappings from the LSM.</param>
        /// <returns>List of mappingcomparisonresults: one for each range arising from the union of boundaries in gsmMappings and lsmMappings.</returns>
        internal static List <MappingComparisonResult> CompareRangeMappings(
            IStoreShardMap ssm,
            IEnumerable <IStoreMapping> gsmMappings,
            IEnumerable <IStoreMapping> lsmMappings)
        {
            // Detect if these are point mappings and call the ComparePointMappings function below.

            List <MappingComparisonResult> result = new List <MappingComparisonResult>();

            // Identify the type of keys.
            ShardKeyType keyType = ssm.KeyType;

            using (IEnumerator <IStoreMapping> gsmMappingIterator = gsmMappings.GetEnumerator())
                using (IEnumerator <IStoreMapping> lsmMappingIterator = lsmMappings.GetEnumerator())
                {
                    IStoreMapping gsmMappingCurrent;
                    ShardRange    gsmRangeCurrent;
                    ShardKey      gsmMinKeyCurrent;

                    IStoreMapping lsmMappingCurrent;
                    ShardRange    lsmRangeCurrent;
                    ShardKey      lsmMinKeyCurrent;

                    MoveToNextMapping(
                        gsmMappingIterator,
                        keyType,
                        out gsmMappingCurrent,
                        out gsmRangeCurrent,
                        out gsmMinKeyCurrent);

                    MoveToNextMapping(
                        lsmMappingIterator,
                        keyType,
                        out lsmMappingCurrent,
                        out lsmRangeCurrent,
                        out lsmMinKeyCurrent);

                    while (gsmMinKeyCurrent != null)
                    {
                        // If there is something in LSM, consider the following 6 possibilities.
                        if (lsmMinKeyCurrent != null)
                        {
                            if (lsmMinKeyCurrent <= gsmMinKeyCurrent)
                            {
                                // Case 1. LSM starts to the left of or exactly at GSM.

                                if (lsmRangeCurrent.High <= gsmMinKeyCurrent)
                                {
                                    // Case 1.1: LSM is entirely to the left of Left.

                                    // Add the LSM only entry.
                                    result.Add(
                                        new MappingComparisonResult(
                                            ssm,
                                            new ShardRange(lsmMinKeyCurrent, lsmRangeCurrent.High),
                                            MappingLocation.MappingInShardOnly,
                                            null,
                                            lsmMappingCurrent));

                                    // LSM range exhausted for current iteration.
                                    MoveToNextMapping(
                                        lsmMappingIterator,
                                        keyType,
                                        out lsmMappingCurrent,
                                        out lsmRangeCurrent,
                                        out lsmMinKeyCurrent);
                                }
                                else
                                if (lsmRangeCurrent.High <= gsmRangeCurrent.High)
                                {
                                    // Case 1.2: LSM overlaps with GSM, with extra values to the left and finishing before GSM.
                                    if (lsmMinKeyCurrent != gsmMinKeyCurrent)
                                    {
                                        // Add the LSM only entry.
                                        result.Add(
                                            new MappingComparisonResult(
                                                ssm,
                                                new ShardRange(lsmMinKeyCurrent, gsmMinKeyCurrent),
                                                MappingLocation.MappingInShardOnly,
                                                null,
                                                lsmMappingCurrent));
                                    }

                                    // Add common entry.
                                    result.Add(
                                        new MappingComparisonResult(
                                            ssm,
                                            new ShardRange(gsmMinKeyCurrent, lsmRangeCurrent.High),
                                            MappingLocation.MappingInShardMapAndShard,
                                            gsmMappingCurrent,
                                            lsmMappingCurrent));

                                    gsmMinKeyCurrent = lsmRangeCurrent.High;

                                    // LSM range exhausted for current iteration.
                                    MoveToNextMapping(
                                        lsmMappingIterator,
                                        keyType,
                                        out lsmMappingCurrent,
                                        out lsmRangeCurrent,
                                        out lsmMinKeyCurrent);

                                    // Detect if GSM range exhausted for current iteration.
                                    if (gsmMinKeyCurrent == gsmRangeCurrent.High)
                                    {
                                        MoveToNextMapping(
                                            gsmMappingIterator,
                                            keyType,
                                            out gsmMappingCurrent,
                                            out gsmRangeCurrent,
                                            out gsmMinKeyCurrent);
                                    }
                                }
                                else // lsmRangeCurrent.High > gsmRangeCurrent.High
                                {
                                    // Case 1.3: LSM encompasses GSM.

                                    // Add the LSM only entry.
                                    if (lsmMinKeyCurrent != gsmMinKeyCurrent)
                                    {
                                        result.Add(
                                            new MappingComparisonResult(
                                                ssm,
                                                new ShardRange(lsmMinKeyCurrent, gsmMinKeyCurrent),
                                                MappingLocation.MappingInShardOnly,
                                                null,
                                                lsmMappingCurrent));
                                    }

                                    // Add common entry.
                                    result.Add(
                                        new MappingComparisonResult(
                                            ssm,
                                            new ShardRange(gsmMinKeyCurrent, gsmRangeCurrent.High),
                                            MappingLocation.MappingInShardMapAndShard,
                                            gsmMappingCurrent,
                                            lsmMappingCurrent));

                                    lsmMinKeyCurrent = gsmRangeCurrent.High;

                                    // GSM range exhausted for current iteration.
                                    MoveToNextMapping(
                                        gsmMappingIterator,
                                        keyType,
                                        out gsmMappingCurrent,
                                        out gsmRangeCurrent,
                                        out gsmMinKeyCurrent);
                                }
                            }
                            else
                            {
                                // Case 2. LSM starts to the right of GSM.

                                if (lsmRangeCurrent.High <= gsmRangeCurrent.High)
                                {
                                    // Case 2.1: GSM encompasses LSM.
                                    Debug.Assert(lsmMinKeyCurrent != gsmMinKeyCurrent, "Must have been handled by Case 1.3");

                                    // Add the GSM only entry.
                                    result.Add(
                                        new MappingComparisonResult(
                                            ssm,
                                            new ShardRange(gsmMinKeyCurrent, lsmMinKeyCurrent),
                                            MappingLocation.MappingInShardMapOnly,
                                            gsmMappingCurrent,
                                            null));

                                    gsmMinKeyCurrent = lsmRangeCurrent.Low;

                                    // Add common entry.
                                    result.Add(
                                        new MappingComparisonResult(
                                            ssm,
                                            new ShardRange(gsmMinKeyCurrent, gsmRangeCurrent.High),
                                            MappingLocation.MappingInShardMapAndShard,
                                            gsmMappingCurrent,
                                            lsmMappingCurrent));

                                    gsmMinKeyCurrent = lsmRangeCurrent.High;

                                    // LSM range exhausted for current iteration.
                                    MoveToNextMapping(
                                        lsmMappingIterator,
                                        keyType,
                                        out lsmMappingCurrent,
                                        out lsmRangeCurrent,
                                        out lsmMinKeyCurrent);

                                    // Detect if GSM range exhausted for current iteration.
                                    if (gsmMinKeyCurrent == gsmRangeCurrent.High)
                                    {
                                        MoveToNextMapping(
                                            gsmMappingIterator,
                                            keyType,
                                            out gsmMappingCurrent,
                                            out gsmRangeCurrent,
                                            out gsmMinKeyCurrent);
                                    }
                                }
                                else
                                if (lsmRangeCurrent.Low < gsmRangeCurrent.High)
                                {
                                    // Case 2.2: LSM overlaps with GSM, with extra values to the right and finishing after GSM.
                                    Debug.Assert(lsmMinKeyCurrent != gsmMinKeyCurrent, "Must have been handled by Case 1.3");

                                    // Add the GSM only entry.
                                    result.Add(
                                        new MappingComparisonResult(
                                            ssm,
                                            new ShardRange(gsmMinKeyCurrent, lsmMinKeyCurrent),
                                            MappingLocation.MappingInShardMapOnly,
                                            gsmMappingCurrent,
                                            null));

                                    // Add common entry.
                                    result.Add(
                                        new MappingComparisonResult(
                                            ssm,
                                            new ShardRange(lsmMinKeyCurrent, gsmRangeCurrent.High),
                                            MappingLocation.MappingInShardMapAndShard,
                                            gsmMappingCurrent,
                                            lsmMappingCurrent));

                                    lsmMinKeyCurrent = gsmRangeCurrent.High;

                                    // GSM range exhausted for current iteration.
                                    MoveToNextMapping(
                                        gsmMappingIterator,
                                        keyType,
                                        out gsmMappingCurrent,
                                        out gsmRangeCurrent,
                                        out gsmMinKeyCurrent);
                                }
                                else // lsmRangeCurrent.Low >= gsmRangeCurrent.High
                                {
                                    // Case 2.3: LSM is entirely to the right of GSM.

                                    // Add the GSM only entry.
                                    result.Add(
                                        new MappingComparisonResult(
                                            ssm,
                                            new ShardRange(gsmMinKeyCurrent, gsmRangeCurrent.High),
                                            MappingLocation.MappingInShardMapOnly,
                                            gsmMappingCurrent,
                                            null));

                                    // GSM range exhausted for current iteration.
                                    MoveToNextMapping(
                                        gsmMappingIterator,
                                        keyType,
                                        out gsmMappingCurrent,
                                        out gsmRangeCurrent,
                                        out gsmMinKeyCurrent);
                                }
                            }
                        }
                        else
                        {
                            // Nothing in LSM, we just keep going over the GSM entries.

                            // Add the GSM only entry.
                            result.Add(
                                new MappingComparisonResult(
                                    ssm,
                                    new ShardRange(gsmMinKeyCurrent, gsmRangeCurrent.High),
                                    MappingLocation.MappingInShardMapOnly,
                                    gsmMappingCurrent,
                                    null));

                            // GSM range exhausted for current iteration.
                            MoveToNextMapping(
                                gsmMappingIterator,
                                keyType,
                                out gsmMappingCurrent,
                                out gsmRangeCurrent,
                                out gsmMinKeyCurrent);
                        }
                    }

                    // Go over the partial remainder of LSM entry if any.
                    if (lsmRangeCurrent != null && lsmMinKeyCurrent > lsmRangeCurrent.Low)
                    {
                        // Add the LSM only entry.
                        result.Add(
                            new MappingComparisonResult(
                                ssm,
                                new ShardRange(lsmMinKeyCurrent, lsmRangeCurrent.High),
                                MappingLocation.MappingInShardOnly,
                                null,
                                lsmMappingCurrent));

                        // LSM range exhausted for current iteration.
                        MoveToNextMapping(
                            lsmMappingIterator,
                            keyType,
                            out lsmMappingCurrent,
                            out lsmRangeCurrent,
                            out lsmMinKeyCurrent);
                    }

                    // Go over remaining Right entries if any which have no matches on Left.
                    while (lsmMappingCurrent != null)
                    {
                        // Add the LSM only entry.
                        result.Add(
                            new MappingComparisonResult(
                                ssm,
                                lsmRangeCurrent,
                                MappingLocation.MappingInShardOnly,
                                null,
                                lsmMappingCurrent));

                        // LSM range exhausted for current iteration.
                        MoveToNextMapping(
                            lsmMappingIterator,
                            keyType,
                            out lsmMappingCurrent,
                            out lsmRangeCurrent,
                            out lsmMinKeyCurrent);
                    }
                }

            return(result);
        }
Пример #19
0
 /// <summary>
 /// Constructs the mapper, notes the key type for lookups.
 /// </summary>
 /// <param name="keyType">Key type.</param>
 internal CacheListMapper(ShardKeyType keyType)
     : base(keyType)
 {
     _mappingsByKey = new SortedDictionary<ShardKey, CacheMapping>();
 }
 /// <summary>
 /// Helper function to advance mapping iterators.
 /// </summary>
 /// <param name="iterator">The iterator to advance.</param>
 /// <param name="keyType">The data type of the map key.</param>
 /// <param name="nextMapping">Output value that will contain next mapping.</param>
 /// <param name="nextRange">Output value that will contain next range.</param>
 /// <param name="nextMinKey">Output value that will contain next min key.</param>
 private static void MoveToNextMapping(
     IEnumerator<IStoreMapping> iterator,
     ShardKeyType keyType,
     out IStoreMapping nextMapping,
     out ShardRange nextRange,
     out ShardKey nextMinKey)
 {
     nextMapping = iterator.MoveNext() ? iterator.Current : null;
     nextRange = nextMapping != null ? new ShardRange(
                         ShardKey.FromRawValue(keyType, nextMapping.MinValue),
                         ShardKey.FromRawValue(keyType, nextMapping.MaxValue)) : null;
     nextMinKey = nextRange != null ? nextRange.Low : null;
 }
Пример #21
0
 /// <summary>
 /// Instantiates a new shard key using the specified type and binary representation.
 /// </summary>
 /// <param name="keyType">Type of the shard key (Int32, Int64, Guid, byte[] etc.).</param>
 /// <param name="rawValue">Binary representation of the key.</param>
 /// <returns>A new shard key instance.</returns>
 public static ShardKey FromRawValue(ShardKeyType keyType, byte[] rawValue)
 {
     return(new ShardKey(keyType, rawValue, true));
 }
Пример #22
0
 /// <summary>
 /// Constructs the mapper, notes the key type for lookups.
 /// </summary>
 /// <param name="keyType">Key type.</param>
 internal CacheMapper(ShardKeyType keyType)
 {
     this.KeyType = keyType;
 }
 public ShardKeyInfo(ShardKeyType keyType, object value, byte[] rawValue)
 {
     KeyType  = keyType;
     Value    = value;
     RawValue = rawValue;
 }
 /// <summary>
 /// Constructs the mapper, notes the key type for lookups.
 /// </summary>
 /// <param name="keyType">Key type.</param>
 internal CacheRangeMapper(ShardKeyType keyType)
     : base(keyType)
 {
     _mappingsByRange = new SortedList <ShardRange, CacheMapping>(Comparer <ShardRange> .Default);
 }
 /// <summary>
 /// Constructs the mapper, notes the key type for lookups.
 /// </summary>
 /// <param name="keyType">Key type.</param>
 internal CacheMapper(ShardKeyType keyType)
 {
     this.KeyType = keyType;
 }
 /// <summary>
 /// Constructs the mapper, notes the key type for lookups.
 /// </summary>
 /// <param name="keyType">Key type.</param>
 internal CacheListMapper(ShardKeyType keyType)
     : base(keyType)
 {
     _mappingsByKey = new SortedDictionary <ShardKey, CacheMapping>();
 }
Пример #27
0
        private void Verify(ShardKeyType kind)
        {
            byte[] bytes = null;
            ShardKey key = null;
            ShardKey result = null;

            switch (kind)
            {
                case ShardKeyType.Int32:
                    bytes = new byte[sizeof(int)];
                    rValGen.NextBytes(bytes);
                    Int32 int32 = BitConverter.ToInt32(bytes, 0);
                    key = new ShardKey(int32);
                    result = key.GetNextKey();
                    Debug.Assert(result.IsMax || result == new ShardKey(int32 + 1));
                    break;

                case ShardKeyType.Int64:
                    bytes = new byte[sizeof(long)];
                    rValGen.NextBytes(bytes);
                    Int64 int64 = BitConverter.ToInt64(bytes, 0);
                    key = new ShardKey(int64);
                    result = key.GetNextKey();
                    Debug.Assert(result.IsMax || result == new ShardKey(int64 + 1));
                    break;

                case ShardKeyType.Guid:
                    Guid guid = Guid.NewGuid();
                    key = new ShardKey(guid);
                    result = key.GetNextKey();
                    // verify only the API call
                    break;

                case ShardKeyType.Binary:
                    bytes = new byte[128];
                    rValGen.NextBytes(bytes);
                    key = new ShardKey(bytes);
                    result = key.GetNextKey();
                    // verify only the API call
                    break;

                default:
                    throw new ArgumentOutOfRangeException(
                        "kind",
                        kind,
                        Errors._ShardKey_UnsupportedShardKeyType);
            }
        }