MappingTree.cs 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. using Ryujinx.Common.Collections;
  2. using System;
  3. namespace Ryujinx.Memory.WindowsShared
  4. {
  5. /// <summary>
  6. /// A intrusive Red-Black Tree that also supports getting nodes overlapping a given range.
  7. /// </summary>
  8. /// <typeparam name="T">Type of the value stored on the node</typeparam>
  9. class MappingTree<T> : IntrusiveRedBlackTree<RangeNode<T>>
  10. {
  11. public int GetNodes(ulong start, ulong end, ref RangeNode<T>[] overlaps, int overlapCount = 0)
  12. {
  13. RangeNode<T> node = GetNode(new RangeNode<T>(start, start + 1UL, default));
  14. for (; node != null; node = node.Successor)
  15. {
  16. if (overlaps.Length <= overlapCount)
  17. {
  18. Array.Resize(ref overlaps, overlapCount + 1);
  19. }
  20. overlaps[overlapCount++] = node;
  21. if (node.End >= end)
  22. {
  23. break;
  24. }
  25. }
  26. return overlapCount;
  27. }
  28. }
  29. class RangeNode<T> : IntrusiveRedBlackTreeNode<RangeNode<T>>, IComparable<RangeNode<T>>
  30. {
  31. public ulong Start { get; }
  32. public ulong End { get; private set; }
  33. public T Value { get; }
  34. public RangeNode(ulong start, ulong end, T value)
  35. {
  36. Start = start;
  37. End = end;
  38. Value = value;
  39. }
  40. public void Extend(ulong sizeDelta)
  41. {
  42. End += sizeDelta;
  43. }
  44. public int CompareTo(RangeNode<T> other)
  45. {
  46. if (Start < other.Start)
  47. {
  48. return -1;
  49. }
  50. else if (Start <= other.End - 1UL)
  51. {
  52. return 0;
  53. }
  54. else
  55. {
  56. return 1;
  57. }
  58. }
  59. }
  60. }