diff options
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Memory/RangeList.cs')
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Memory/RangeList.cs | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.Gpu/Memory/RangeList.cs b/Ryujinx.Graphics.Gpu/Memory/RangeList.cs new file mode 100644 index 00000000..6114f15d --- /dev/null +++ b/Ryujinx.Graphics.Gpu/Memory/RangeList.cs @@ -0,0 +1,208 @@ +using System.Collections.Generic; + +namespace Ryujinx.Graphics.Gpu.Memory +{ + class RangeList<T> where T : IRange<T> + { + private List<T> _items; + + public RangeList() + { + _items = new List<T>(); + } + + public void Add(T item) + { + lock (_items) + { + int index = BinarySearch(item.Address); + + if (index < 0) + { + index = ~index; + } + + _items.Insert(index, item); + } + } + + public bool Remove(T item) + { + lock (_items) + { + int index = BinarySearch(item.Address); + + if (index >= 0) + { + while (index > 0 && _items[index - 1].Address == item.Address) + { + index--; + } + + while (index < _items.Count) + { + if (_items[index].Equals(item)) + { + _items.RemoveAt(index); + + return true; + } + + if (_items[index].Address > item.Address) + { + break; + } + + index++; + } + } + } + + return false; + } + + public T FindFirstOverlap(T item) + { + return FindFirstOverlap(item.Address, item.Size); + } + + public T FindFirstOverlap(ulong address, ulong size) + { + lock (_items) + { + int index = BinarySearch(address, size); + + if (index < 0) + { + return default(T); + } + + return _items[index]; + } + } + + public T[] FindOverlaps(T item) + { + return FindOverlaps(item.Address, item.Size); + } + + public T[] FindOverlaps(ulong address, ulong size) + { + List<T> overlapsList = new List<T>(); + + ulong endAddress = address + size; + + lock (_items) + { + foreach (T item in _items) + { + if (item.Address >= endAddress) + { + break; + } + + if (item.OverlapsWith(address, size)) + { + overlapsList.Add(item); + } + } + } + + return overlapsList.ToArray(); + } + + public T[] FindOverlaps(ulong address) + { + List<T> overlapsList = new List<T>(); + + lock (_items) + { + int index = BinarySearch(address); + + if (index >= 0) + { + while (index > 0 && _items[index - 1].Address == address) + { + index--; + } + + while (index < _items.Count) + { + T overlap = _items[index++]; + + if (overlap.Address != address) + { + break; + } + + overlapsList.Add(overlap); + } + } + } + + return overlapsList.ToArray(); + } + + private int BinarySearch(ulong address) + { + int left = 0; + int right = _items.Count - 1; + + while (left <= right) + { + int range = right - left; + + int middle = left + (range >> 1); + + T item = _items[middle]; + + if (item.Address == address) + { + return middle; + } + + if (address < item.Address) + { + right = middle - 1; + } + else + { + left = middle + 1; + } + } + + return ~left; + } + + private int BinarySearch(ulong address, ulong size) + { + int left = 0; + int right = _items.Count - 1; + + while (left <= right) + { + int range = right - left; + + int middle = left + (range >> 1); + + T item = _items[middle]; + + if (item.OverlapsWith(address, size)) + { + return middle; + } + + if (address < item.Address) + { + right = middle - 1; + } + else + { + left = middle + 1; + } + } + + return ~left; + } + } +}
\ No newline at end of file |
