Ejemplo n.º 1
0
 /// <summary>
 /// Incorporate one aggregatable value into the result.
 /// </summary>
 /// <remarks>
 /// If the <paramref name="isFinal"/> parameter is <b>true</b>, the
 /// given object is a partial result (returned by an individual
 /// parallel aggregator) that should be incorporated into the final
 /// result; otherwise, the object is a value extracted from an
 /// <see cref="IInvocableCacheEntry"/>.
 /// </remarks>
 /// <param name="o">
 /// The value to incorporate into the aggregated result.
 /// </param>
 /// <param name="isFinal">
 /// <b>true</b> to indicate that the given object is a partial
 /// result returned by a parallel aggregator.
 /// </param>
 protected override void Process(object o, bool isFinal)
 {
     if (o != null)
     {
         Object result = m_result;
         if (result == null ||
             SafeComparer.CompareSafe(m_comparer, result, o) < 0)
         {
             m_result = o;
         }
         m_count++;
     }
 }
        public void TestUnitComparisonValueExtractor()
        {
            IValueExtractor exByte    = new ReflectionExtractor("ByteValue");
            IValueExtractor exShort   = new ReflectionExtractor("ShortValue");
            IValueExtractor exInt     = new ReflectionExtractor("IntValue");
            IValueExtractor exLong    = new ReflectionExtractor("LongValue");
            IValueExtractor exFloat   = new ReflectionExtractor("FloatValue");
            IValueExtractor exDouble  = new ReflectionExtractor("DoubleValue");
            IValueExtractor exDecimal = new ReflectionExtractor("DecimalValue");
            IValueExtractor exInt128  = new ReflectionExtractor("RawInt128Value");

            IValueExtractor[] extractors = new IValueExtractor[] { exDouble, exInt };
            //different ways to instantiate same extractor
            ComparisonValueExtractor cve1 = new ComparisonValueExtractor(extractors);
            ComparisonValueExtractor cve2 = new ComparisonValueExtractor(exDouble, exInt);
            ComparisonValueExtractor cve3 = new ComparisonValueExtractor(exDouble, exInt, null);
            ComparisonValueExtractor cve4 = new ComparisonValueExtractor("DoubleValue", "IntValue");
            ComparisonValueExtractor cve5 = new ComparisonValueExtractor("DoubleValue", "IntValue", null);

            Assert.IsNotNull(cve1);
            Assert.IsNotNull(cve2);
            Assert.IsNotNull(cve3);
            Assert.IsNotNull(cve4);
            Assert.IsNotNull(cve5);
            Assert.IsTrue(cve1.Equals(cve2));
            Assert.IsTrue(cve1.Equals(cve3));
            Assert.IsTrue(cve1.Equals(cve4));
            Assert.IsTrue(cve1.Equals(cve5));
            Assert.IsNull(cve1.Comparer);
            Assert.AreEqual(cve1.Extractors.Length, 2);

            Score score = new Score(1, 1, 126, 10000L, 1.24f, 1432.55, new decimal(11223344), new RawInt128(new byte[] { 1 }), 1);

            Assert.AreEqual(cve1.Extract(score), score.DoubleValue - Convert.ToDouble(score.IntValue));
            cve1 = new ComparisonValueExtractor(exByte, exShort);
            Assert.AreEqual(cve1.Extract(score), Convert.ToInt32(score.ByteValue) - Convert.ToInt32(score.ShortValue));
            cve1 = new ComparisonValueExtractor(exLong, exInt);
            Assert.AreEqual(cve1.Extract(score), score.LongValue - Convert.ToInt64(score.IntValue));
            cve1 = new ComparisonValueExtractor(exLong, exFloat);
            Assert.AreEqual(cve1.Extract(score), Convert.ToDouble(score.LongValue) - Convert.ToDouble(score.FloatValue));
            cve1 = new ComparisonValueExtractor(exDecimal, exDouble);
            Assert.AreEqual(cve1.Extract(score), Decimal.Subtract(score.DecimalValue, Convert.ToDecimal(score.DoubleValue)));

            ComparisonValueExtractor cve6 = new ComparisonValueExtractor("ShortValue", "ShortValue", Comparer.Default);

            Assert.AreEqual(cve6.Extract(score),
                            SafeComparer.CompareSafe(Comparer.Default, score.ShortValue, score.ShortValue));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Compare two entries based on the rules specified by
        /// <b>IComparer</b>.
        /// </summary>
        /// <remarks>
        /// <p>
        /// If possible, use the <see cref="IQueryCacheEntry.Extract"/>
        /// method to optimize the value extraction process.</p>
        /// <p>
        /// This method is expected to be implemented by <b>IComparer</b>
        /// wrappers, which simply pass on this invocation to the wrapped
        /// <b>IComparer</b> objects if they too implement this interface, or
        /// to invoke their default compare method passing the actual objects
        /// (not the extracted values) obtained from the extractor using the
        /// passed entries.</p>
        /// <p>
        /// This interface is also expected to be implemented by
        /// <see cref="IValueExtractor"/> implementations that implement the
        /// <b>IComparer</b> interface. It is expected that in most cases,
        /// the <b>IComparer</b> wrappers will eventually terminate at (i.e.
        /// delegate to) <b>IValueExtractors</b> that also implement this
        /// interface.</p>
        /// </remarks>
        /// <param name="entry1">
        /// The first entry to compare values from; read-only.
        /// </param>
        /// <param name="entry2">
        /// The second entry to compare values from; read-only.
        /// </param>
        /// <returns>
        /// A negative integer, zero, or a positive integer as the first
        /// entry denotes a value that is is less than, equal to, or greater
        /// than the value denoted by the second entry.
        /// </returns>
        /// <exception cref="InvalidCastException">
        /// If the arguments' types prevent them from being compared by this
        /// <b>IComparer</b>.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// If the extractor cannot handle the passed objects for any other
        /// reason; an implementor should include a descriptive message.
        /// </exception>
        /// <since>Coherence 3.2</since>
        public override int CompareEntries(IQueryCacheEntry entry1, IQueryCacheEntry entry2)
        {
            IValueExtractor[] extractors = Extractors;

            for (int i = 0, c = extractors.Length; i < c; i++)
            {
                IValueExtractor extractor = extractors[i];

                int result = SafeComparer.CompareSafe(null, entry1.Extract(extractor), entry2.Extract(extractor));
                if (result != 0)
                {
                    return(result);
                }
            }
            return(0);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Extract the value from the passed object.
        /// </summary>
        /// <remarks>
        /// The returned value may be <c>null</c>.
        /// </remarks>
        /// <param name="obj">
        /// An object to retrieve the value from.
        /// </param>
        /// <returns>
        /// The extracted value as an object; <c>null</c> is an acceptable
        /// value.
        /// </returns>
        /// <exception cref="InvalidCastException">
        /// If this IValueExtractor is incompatible with the passed object to
        /// extract a value from and the implementation <b>requires</b> the
        /// passed object to be of a certain type.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// If this AbstractExtractor cannot handle the passed object for any
        /// other reason; an implementor should include a descriptive
        /// message.
        /// </exception>
        public override object Extract(object obj)
        {
            IValueExtractor[] extractors = Extractors;
            IComparer         comparer   = Comparer;

            object o1 = extractors[0].Extract(obj);
            object o2 = extractors[1].Extract(obj);

            if (NumberUtils.IsNumber(o1) && NumberUtils.IsNumber(o2) && comparer == null)
            {
                StreamFormat type;

                if (o1.GetType() == o2.GetType())
                {
                    // most common case; same types
                    type = GetStreamFormat(o1);
                }
                else
                {
                    StreamFormat[] types = new StreamFormat[] {
                        StreamFormat.Byte,          // 0
                        StreamFormat.Short,         // 1
                        StreamFormat.Int,           // 2
                        StreamFormat.Long,          // 3
                        StreamFormat.Float,         // 4
                        StreamFormat.Double,        // 5
                        StreamFormat.RawInt128,     // 6
                        StreamFormat.Decimal        // 7
                    };

                    StreamFormat type1 = GetStreamFormat(o1);
                    StreamFormat type2 = GetStreamFormat(o2);
                    int          typesCount, ix1, ix2;

                    ix1 = ix2 = typesCount = types.Length;
                    for (int i = 0; i < typesCount; i++)
                    {
                        StreamFormat t = types[i];
                        if (t == type1)
                        {
                            ix1 = i;
                        }
                        if (t == type2)
                        {
                            ix2 = i;
                        }
                    }

                    switch (Math.Max(ix1, ix2))
                    {
                    case 0:
                    case 1:
                    case 2:
                        type = StreamFormat.Int;
                        break;

                    case 3:
                        type = StreamFormat.Long;
                        break;

                    case 4:
                    case 5:
                        type = StreamFormat.Double;
                        break;

                    case 6:
                    case 7:
                        type = StreamFormat.Decimal;
                        o1   = EnsureDecimal(o1);
                        o2   = EnsureDecimal(o2);
                        break;

                    default:
                        type = StreamFormat.None;
                        break;
                    }
                }

                switch (type)
                {
                case StreamFormat.Byte:
                case StreamFormat.Short:
                case StreamFormat.Int:
                    return(Convert.ToInt32(o1) - Convert.ToInt32(o2));

                case StreamFormat.Long:
                    return(Convert.ToInt64(o1) - Convert.ToInt64(o2));

                case StreamFormat.Float:
                    return(Convert.ToSingle(o1) - Convert.ToSingle(o2));

                case StreamFormat.Double:
                    return(Convert.ToDouble(o1) - Convert.ToDouble(o2));

                case StreamFormat.RawInt128:
                    return(NumberUtils.DecimalToRawInt128(Decimal.Subtract(((RawInt128)o1).ToDecimal(), ((RawInt128)o2).ToDecimal())));

                case StreamFormat.Decimal:
                    return(Decimal.Subtract(Convert.ToDecimal(o1), Convert.ToDecimal(o2)));
                }
            }
            return(SafeComparer.CompareSafe(comparer, o1, o2));
        }
 /// <summary>
 /// Compare two entries.
 /// </summary>
 /// <param name="entry1">
 /// The first entry to compare values from; read-only.
 /// </param>
 /// <param name="entry2">
 /// The second entry to compare values from; read-only.
 /// </param>
 /// <returns>
 /// A negative integer, zero, or a positive integer as the first
 /// entry denotes a value that is is less than, equal to, or greater
 /// than the value denoted by the second entry
 /// </returns>
 /// <exception cref="InvalidCastException">
 /// If the arguments' types prevent them from being compared by this
 /// <b>IComparer</b>.
 /// </exception>
 /// <exception cref="ArgumentException">
 /// If the extractor cannot handle the passed objects for any other
 /// reason; an implementor should include a descriptive message.
 /// </exception>
 public virtual int CompareEntries(IQueryCacheEntry entry1, IQueryCacheEntry entry2)
 {
     return(SafeComparer.CompareSafe(null, entry1.Extract(this), entry2.Extract(this)));
 }
 /// <summary>
 /// Compares its two arguments for order.
 /// </summary>
 /// <remarks>
 /// Returns a negative integer, zero, or a positive integer as the
 /// first argument is less than, equal to, or greater than the
 /// second. <c>null</c> values are evaluated as "less then" any
 /// non-null value.
 /// </remarks>
 /// <param name="o1">
 /// The first object to be compared.
 /// </param>
 /// <param name="o2">
 /// The second object to be compared.
 /// </param>
 /// <returns>
 /// A negative integer, zero, or a positive integer as the first
 /// argument is less than, equal to, or greater than the second.
 /// </returns>
 public virtual int Compare(object o1, object o2)
 {
     return(SafeComparer.CompareSafe(null, Extract(o1), Extract(o2)));
 }