/ src / Ryujinx.Memory / WindowsShared / MappingTree.cs
MappingTree.cs
 1  using Ryujinx.Common.Collections;
 2  using System;
 3  
 4  namespace Ryujinx.Memory.WindowsShared
 5  {
 6      /// <summary>
 7      /// A intrusive Red-Black Tree that also supports getting nodes overlapping a given range.
 8      /// </summary>
 9      /// <typeparam name="T">Type of the value stored on the node</typeparam>
10      class MappingTree<T> : IntrusiveRedBlackTree<RangeNode<T>>
11      {
12          private const int ArrayGrowthSize = 16;
13  
14          public int GetNodes(ulong start, ulong end, ref RangeNode<T>[] overlaps, int overlapCount = 0)
15          {
16              RangeNode<T> node = this.GetNodeByKey(start);
17  
18              for (; node != null; node = node.Successor)
19              {
20                  if (overlaps.Length <= overlapCount)
21                  {
22                      Array.Resize(ref overlaps, overlapCount + ArrayGrowthSize);
23                  }
24  
25                  overlaps[overlapCount++] = node;
26  
27                  if (node.End >= end)
28                  {
29                      break;
30                  }
31              }
32  
33              return overlapCount;
34          }
35      }
36  
37      class RangeNode<T> : IntrusiveRedBlackTreeNode<RangeNode<T>>, IComparable<RangeNode<T>>, IComparable<ulong>
38      {
39          public ulong Start { get; }
40          public ulong End { get; private set; }
41          public T Value { get; }
42  
43          public RangeNode(ulong start, ulong end, T value)
44          {
45              Start = start;
46              End = end;
47              Value = value;
48          }
49  
50          public void Extend(ulong sizeDelta)
51          {
52              End += sizeDelta;
53          }
54  
55          public int CompareTo(RangeNode<T> other)
56          {
57              if (Start < other.Start)
58              {
59                  return -1;
60              }
61              else if (Start <= other.End - 1UL)
62              {
63                  return 0;
64              }
65              else
66              {
67                  return 1;
68              }
69          }
70  
71          public int CompareTo(ulong address)
72          {
73              if (address < Start)
74              {
75                  return 1;
76              }
77              else if (address <= End - 1UL)
78              {
79                  return 0;
80              }
81              else
82              {
83                  return -1;
84              }
85          }
86      }
87  }