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); }
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); } }
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); }
/// <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(); } }
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); }
public override int Compare(TObject x, TObject y) { var xValue = KeySelector(x); var yValue = KeySelector(y); return(KeyComparer.Compare(xValue, yValue)); }
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)); } }
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); }
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); }
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)); }
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)); }
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>()); }
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); } }
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); }
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); }
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))); }
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); } }