Esempio n. 1
0
        internal long BinarySearchUnchecked(int index, int length, T value, KeyComparer <T> comparer)
        {
            int lo = index;
            int hi = index + length - 1;

            while (lo <= hi)
            {
                int i     = lo + ((hi - lo) >> 1);
                int order = comparer.Compare(this[i], value);

                if (order == 0)
                {
                    return(i);
                }
                if (order < 0)
                {
                    lo = i + 1;
                }
                else
                {
                    hi = i - 1;
                }
            }
            return(~lo);
        }
Esempio n. 2
0
        public static int BinarySearch <T, TVec>(ref TVec vec, int start, int length, T value, KeyComparer <T> comparer = default)
            where TVec : IVector <T>
        {
            Debug.Assert(unchecked ((uint)start + (uint)length) <= vec.Length);
            unchecked
            {
                int lo = start;
                int hi = start + length - 1;
                while (lo <= hi)
                {
                    int i = (int)(((uint)hi + (uint)lo) >> 1);

                    int c = comparer.Compare(value, vec.DangerousGet(i));
                    if (c == 0)
                    {
                        return(i);
                    }
                    else if (c > 0)
                    {
                        lo = i + 1;
                    }
                    else
                    {
                        hi = i - 1;
                    }
                }

                return(~lo);
            }
        }
Esempio n. 3
0
        public static int BinarySearch <T>(this Span <T> span, int index, int length, T value, KeyComparer <T> comparer)
        {
            if ((uint)(index) + (uint)length > (uint)span.Length)
            {
                throw new ArgumentException("Index + Length fall outside the span boundary.");
            }

            if (comparer == null)
            {
                comparer = KeyComparer <T> .Default;
            }

            int lo = index;
            int hi = index + length - 1;

            while (lo <= hi)
            {
                int i     = lo + ((hi - lo) >> 1);
                int order = comparer.Compare(span[i], value);

                if (order == 0)
                {
                    return(i);
                }
                if (order < 0)
                {
                    lo = i + 1;
                }
                else
                {
                    hi = i - 1;
                }
            }
            return(~lo);
        }
Esempio n. 4
0
        /// <summary>
        /// Construct a tree from given storage, using the specified comparer of key
        /// </summary>
        /// <param name="keySerializer">Tool to serialize node keys.</param>
        /// <param name="valueSerializer">Tool to serialize node values<param>
        /// <param name="recordStorage">Underlying tool for storage.</param>
        /// <param name="keyComparer">Key comparer.</param>
        public TreeDiskNodeManager(ISerializer <K> keySerializer
                                   , ISerializer <V> valueSerializer
                                   , IRecordStorage recordStorage
                                   , IComparer <K> keyComparer)
        {
            if (recordStorage == null)
            {
                throw new ArgumentNullException("nodeStorge");
            }

            this.recordStorage = recordStorage;
            this.serializer    = new TreeDiskNodeSerializer <K, V> (this, keySerializer, valueSerializer);
            this.KeyComparer   = keyComparer;
            this.EntryComparer = Comparer <Tuple <K, V> > .Create((a, b) => {
                return(KeyComparer.Compare(a.Item1, b.Item1));
            });

            // The first record of nodeStorage stores id of root node,
            // if this record do not exist at the time this index instanitate,
            // then attempt to create it
            var firstBlockData = recordStorage.Find(1u);

            if (firstBlockData != null)
            {
                this.rootNode = Find(BufferHelper.ReadBufferUInt32(firstBlockData, 0));
            }
            else
            {
                this.rootNode = CreateFirstRoot();
            }
        }
Esempio n. 5
0
        private (bool isInvalid, int expand) IsInvalidWidth(ref TCursor lagged, ref TCursor current)
        {
            var diff = default(SubtractOp <TKey>).Apply(current.CurrentKey, lagged.CurrentKey);
            var cmp  = _cmp.Compare(diff, _width);

            if (cmp > 0)
            {
                // Diff is too big, should shrink if invalid
                return(_lookup != Lookup.GE && _lookup != Lookup.GT, -1);
            }

            if (cmp < 0)
            {
                // Diff is too small, should expand if invalid
                return(_lookup != Lookup.LE && _lookup != Lookup.LT, 1);
            }

            // cmp == 0

            if (_lookup == Lookup.LT)
            {
                // need to shrink, equal is not valid
                return(true, -1);
            }

            if (_lookup == Lookup.GT)
            {
                // need to expand, equal is not valid
                return(true, 1);
            }

            return(false, 0);
        }
Esempio n. 6
0
        public override int Compare(TObject x, TObject y)
        {
            var xValue = KeySelector(x);
            var yValue = KeySelector(y);

            return(KeyComparer.Compare(xValue, yValue));
        }
Esempio n. 7
0
        internal static int BinarySearchHybrid <T>(ref T searchSpace, int offset, int length, T value, KeyComparer <T> comparer = default)
        {
            unchecked
            {
                int c;
                int lo = offset;
                int hi = offset + length - 1;
                while (hi - lo > 7)
                {
                    int i = (int)(((uint)hi + (uint)lo) >> 1);

                    c = comparer.Compare(value, UnsafeEx.ReadUnaligned(ref Unsafe.Add(ref searchSpace, i)));

                    if (c > 0)
                    {
                        lo = i + 1;
                    }
                    else
                    {
                        if (c == 0)
                        {
                            goto RETURN;
                        }

                        hi = i - 1;
                    }
                }

                while ((c = comparer.Compare(value, UnsafeEx.ReadUnaligned(ref Unsafe.Add(ref searchSpace, lo)))) > 0 &&
                       ++lo <= hi)
                {
                }

RETURN:
                var ceq1 = -UnsafeEx.Ceq(c, 0);
                return((ceq1 & lo) | (~ceq1 & ~lo));
            }
        }
Esempio n. 8
0
 private bool TryAddSorted(TKey key, TValue value)
 {
     if (keys.Count > 0)
     {
         var lastKey = keys.Last();
         if (KeyComparer.Compare(key, lastKey) <= 0)
         {
             return(false);
         }
     }
     keys.Add(key);
     values.Add(value);
     return(true);
 }
Esempio n. 9
0
        private object FindKey(IDictionary <object, object> dictionary, object key)
        {
            var tempContext = new ComparisonContext();

            foreach (var key2 in dictionary.Keys)
            {
                if (KeyComparer.Compare(tempContext, key, key2) == ComparisonResult.Pass)
                {
                    return(key2);
                }
            }

            return(null);
        }
Esempio n. 10
0
        private Node FindNodeRecursive(TKey key, Node node, ref Node resultNodeParent)
        {
            if (node == null)
            {
                return(null);
            }
            var cmpResult = KeyComparer.Compare(key, node.Key);

            if (cmpResult == 0)
            {
                return(node);
            }
            resultNodeParent = node; // Set parent, we continue searching
            return(FindNodeRecursive(key, cmpResult < 0 ? node.Left : node.Right, ref resultNodeParent));
        }
Esempio n. 11
0
        private Node InsertNewNode(TKey key, TValue value, Node parentNode)
        {
            var node = new Node(key, value, parentNode);

            if (KeyComparer.Compare(key, parentNode.Key) < 0)
            {
                parentNode.Left = node;
            }
            else
            {
                parentNode.Right = node;
            }
            Splay(node);
            Count++;
            return(node);
        }
        public void Can_Compare_Only_Keys_With_Given_Comparer()
        {
            var a = new KeyValuePair <int, int>(100, 200);
            var b = new KeyValuePair <int, int>(300, 400);
            var comparerResult = 123;

            var comparer = A.Fake <IComparer <int> >();

            A.CallTo(() => comparer.Compare(a.Key, b.Key))
            .Returns(comparerResult);

            var sut = new KeyComparer <int, int>(comparer);

            var result = sut.Compare(a, b);

            Assert.That(result, Is.EqualTo(comparerResult));
        }
Esempio n. 13
0
        public static IEnumerable <T> GetValuesOfKey <T>(List <KeyValuePair <String, T> > keyValuePairs,
                                                         string word)
        {
            var target   = new KeyValuePair <String, T>(word, default(T));
            var comparer = new KeyComparer <T>();
            int endIndex = keyValuePairs.BinarySearch(target, comparer);

            if (endIndex > -1 && endIndex < keyValuePairs.Count)
            {
                int startInex;
                for (startInex = endIndex; startInex > 0 && comparer.Compare(keyValuePairs.ElementAt(startInex - 1),
                                                                             target) == 0; startInex--)
                {
                    ;
                }
                return(keyValuePairs.GetRange(startInex, endIndex - startInex + 1).Select(p => p.Value));
            }
            return(Enumerable.Empty <T>());
        }
Esempio n. 14
0
        internal static int BinarySearchClassic <T>(ref T searchSpace, int offset, int length, T value, KeyComparer <T> comparer = default)
        {
            unchecked
            {
                int lo = offset;
                int hi = offset + length - 1;
                // If length == 0, hi == -1, and loop will not be entered
                while (lo <= hi)
                {
                    // PERF: `lo` or `hi` will never be negative inside the loop,
                    //       so computing median using uints is safe since we know
                    //       `length <= int.MaxValue`, and indices are >= 0
                    //       and thus cannot overflow an uint.
                    //       Saves one subtraction per loop compared to
                    //       `int i = lo + ((hi - lo) >> 1);`
                    int i = (int)(((uint)hi + (uint)lo) >> 1);

                    int c = comparer.Compare(value, UnsafeEx.ReadUnaligned(ref Unsafe.Add(ref searchSpace, i)));

                    if (c == 0)
                    {
                        return(i);
                    }

                    if (c > 0)
                    {
                        lo = i + 1;
                    }
                    else
                    {
                        hi = i - 1;
                    }
                }

                // If none found, then a negative number that is the bitwise complement
                // of the index of the next element that is larger than or, if there is
                // no larger element, the bitwise complement of `length`, which
                // is `lo` at this point.
                return(~lo);
            }
        }
Esempio n. 15
0
        private static TV Find <TK, TV>(KeyComparer <TK> comparer, TK k, MapTree <TK, TV> m)
        {
            while (true)
            {
                if (m == null)
                {
                    throw new KeyNotFoundException();
                }

                var c = comparer.Compare(k, m.Key);

                // Common for MapOne and MapNode
                if (c == 0)
                {
                    // do not return from loop.
                    // Even thought https://github.com/dotnet/coreclr/issues/9692
                    // closed/fixed in 2017 in this case it's very visible
                    break;
                }

                // This is pure isinst without casting.
                // Then using Unsafe for cast without a local var.
                m = m as MapTreeNode <TK, TV>;
                if (m != null)
                {
                    if (c < 0)
                    {
                        m = Unsafe.As <MapTreeNode <TK, TV> >(m).Left;
                    }
                    else
                    {
                        m = Unsafe.As <MapTreeNode <TK, TV> >(m).Right;
                    }
                }

                // m == null for MapOne case after `as` and we go to KeyNotFoundException
            }
            return(m.Value);
        }
Esempio n. 16
0
        internal bool TryFindBlockAtFromSource([NotNullWhen(true)] out DataBlock?db,
                                               DataBlockSource <TKey> ds,
                                               TKey key,
                                               Lookup sourceDirection)
        {
            if (!ds.TryFindAt(key, sourceDirection, out var kvp))
            {
                db = null;
                return(false);
            }

            if (AdditionalCorrectnessChecks.Enabled)
            {
                if (kvp.Value.RowCount <= 0 ||
                    _comparer.Compare(kvp.Key, kvp.Value.DangerousRowKey <TKey>(index: 0)) != 0)
                {
                    ThrowBadBlockFromSource();
                }
            }

            db = kvp.Value;
            return(true);
        }
Esempio n. 17
0
 public int Compare(KeyValuePair <TKey, TValue> x, KeyValuePair <TKey, TValue> y)
 {
     return(KeyComparer.Compare(x.Key, y.Key).IfEqual(0, ValueComparer.Compare(x.Value, y.Value)));
 }
Esempio n. 18
0
        internal static int InterpolationSearchGeneric <T>(ref T searchSpace, int offset, int length, T value, KeyComparer <T> comparer = default)
        {
            // Try interpolation only for big-enough lengths and do minimal job,
            // just find the range with exponential search with minimal branches
            // and switch to binary search.
            unchecked
            {
                int i;
                int lo = offset;
                int hi = offset + length - 1;

                if (hi - lo > 16)
                {
                    var  vlo    = UnsafeEx.ReadUnaligned(ref searchSpace);
                    var  vhi    = UnsafeEx.ReadUnaligned(ref Unsafe.Add(ref searchSpace, hi));
                    int  range  = hi - lo;
                    long vRange = comparer.Diff(vhi, vlo);

                    // (hi - lo) <= int32.MaxValue
                    // vlo could be zero while value could easily be close to int64.MaxValue (nanos in unix time, we are now between 60 and 61 bit at 60.4)
                    // convert to double here to avoid overflow and for much faster calculations
                    // (only 4 cycles vs 25 cycles https://lemire.me/blog/2017/11/16/fast-exact-integer-divisions-using-floating-point-operations/)
                    double nominator = (hi - lo) * (double)comparer.Diff(value, vlo);

                    i = (int)(nominator / vRange);

                    if ((uint)i > range)
                    {
                        i = i < 0 ? 0 : range;
                    }
                    // make i relative to vecStart
                    i += lo;

                    int c = comparer.Compare(value, UnsafeEx.ReadUnaligned(ref Unsafe.Add(ref searchSpace, i)));

                    if (c == 0)
                    {
                        goto FOUND;
                    }

                    var step = 1;

                    if (c > 0)
                    {
                        while (true)
                        {
                            i += step;

                            if (i > hi)
                            {
                                break;
                            }

                            c = comparer.Compare(value, UnsafeEx.ReadUnaligned(ref Unsafe.Add(ref searchSpace, i)));

                            if (c <= 0)
                            {
                                if (c == 0)
                                {
                                    goto FOUND;
                                }

                                hi = i - 1;
                                break;
                            }

                            step <<= 1;
                        }

                        lo = i - step + 1;
                    }
                    else
                    {
                        while (true)
                        {
                            i -= step;

                            if (i < lo)
                            {
                                break;
                            }

                            c = comparer.Compare(value, UnsafeEx.ReadUnaligned(ref Unsafe.Add(ref searchSpace, i)));

                            if (c >= 0)
                            {
                                if (c == 0)
                                {
                                    goto FOUND;
                                }

                                lo = i + 1;
                                break;
                            }

                            step <<= 1;
                        }

                        hi = i + step - 1;
                    }
                }

                return(BinarySearch(ref searchSpace, lo, 1 + hi - lo, value));

FOUND:
                return(i);
            }
        }