Browse Source

Use custom binary search in ValueStore.

refactor/style-priorities
Steven Kirk 4 years ago
parent
commit
72308f1f37
  1. 44
      src/Avalonia.Base/PropertyStore/ValueStore.cs

44
src/Avalonia.Base/PropertyStore/ValueStore.cs

@ -528,9 +528,8 @@ namespace Avalonia.PropertyStore
private void InsertFrame(IValueFrame frame)
{
Debug.Assert(!_frames.Contains(frame));
var index = _frames.BinarySearch(frame, FrameInsertionComparer.Instance);
if (index < 0)
index = ~index;
var index = BinarySearchFrame(frame.Priority);
_frames.Insert(index, frame);
++_frameGeneration;
frame.SetOwner(this);
@ -569,15 +568,12 @@ namespace Avalonia.PropertyStore
{
Debug.Assert(priority != BindingPriority.LocalValue);
// TODO: Binary search?
for (var i = _frames.Count - 1; i >= 0; --i)
{
var frame = _frames[i];
if (frame is ImmediateValueFrame immediate && !immediate.Contains(property))
return immediate;
if (frame.Priority > priority)
break;
}
var index = BinarySearchFrame(priority);
if (index > 0 && _frames[index - 1] is ImmediateValueFrame f &&
f.Priority == priority &&
!f.Contains(property))
return f;
var result = new ImmediateValueFrame(priority);
InsertFrame(result);
@ -915,14 +911,28 @@ namespace Avalonia.PropertyStore
}
}
private class FrameInsertionComparer : IComparer<IValueFrame>
private int BinarySearchFrame(BindingPriority priority)
{
public static readonly FrameInsertionComparer Instance = new FrameInsertionComparer();
public int Compare(IValueFrame? x, IValueFrame? y)
var lo = 0;
var hi = _frames.Count - 1;
// Binary search insertion point.
while (lo <= hi)
{
var result = y!.Priority - x!.Priority;
return result != 0 ? result : -1;
var i = lo + ((hi - lo) >> 1);
var order = priority - _frames[i].Priority;
if (order <= 0)
{
lo = i + 1;
}
else
{
hi = i - 1;
}
}
return lo;
}
private readonly struct OldNewValue

Loading…
Cancel
Save