mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 11:00:32 +00:00
HistoryBounds data structure - wip
This commit is contained in:
parent
6395b9e637
commit
e344091c33
@ -8,30 +8,50 @@
|
|||||||
|
|
||||||
namespace Mirror
|
namespace Mirror
|
||||||
{
|
{
|
||||||
public static class HistoryBounds
|
public class HistoryBounds
|
||||||
|
{
|
||||||
|
public readonly Queue<Bounds> history; // TODO not public
|
||||||
|
public int Count => history.Count;
|
||||||
|
|
||||||
|
public readonly int limit;
|
||||||
|
|
||||||
|
public HistoryBounds(int limit)
|
||||||
|
{
|
||||||
|
// initialize queue with maximum capacity to avoid runtime resizing
|
||||||
|
this.limit = limit;
|
||||||
|
history = new Queue<Bounds>(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
history.Clear();
|
||||||
|
// TODO reset total etc.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class HistoryBoundsAlgo
|
||||||
{
|
{
|
||||||
// insert current bounds into history. returns new total bounds.
|
// insert current bounds into history. returns new total bounds.
|
||||||
// Queue.Dequeue() always has the oldest bounds.
|
// Queue.Dequeue() always has the oldest bounds.
|
||||||
public static Bounds Insert(
|
public static Bounds Insert(
|
||||||
Queue<Bounds> history,
|
HistoryBounds history,
|
||||||
int limit,
|
|
||||||
Bounds bounds)
|
Bounds bounds)
|
||||||
{
|
{
|
||||||
// optimization: only insert if
|
// optimization: only insert if
|
||||||
|
|
||||||
// remove oldest if limit reached
|
// remove oldest if limit reached
|
||||||
if (history.Count >= limit)
|
if (history.Count >= history.limit)
|
||||||
history.Dequeue();
|
history.history.Dequeue();
|
||||||
|
|
||||||
// insert the new bounds
|
// insert the new bounds
|
||||||
history.Enqueue(bounds);
|
history.history.Enqueue(bounds);
|
||||||
|
|
||||||
// summarize total bounds.
|
// summarize total bounds.
|
||||||
// starting at latest bounds, not at 'new Bounds' because that would
|
// starting at latest bounds, not at 'new Bounds' because that would
|
||||||
// encapsulate (0,0) too.
|
// encapsulate (0,0) too.
|
||||||
// TODO make this not be O(N)
|
// TODO make this not be O(N)
|
||||||
Bounds total = bounds;
|
Bounds total = bounds;
|
||||||
foreach (Bounds b in history)
|
foreach (Bounds b in history.history)
|
||||||
total.Encapsulate(b);
|
total.Encapsulate(b);
|
||||||
|
|
||||||
return total;
|
return total;
|
||||||
|
@ -6,13 +6,8 @@ namespace Mirror.Tests.LagCompensationTests
|
|||||||
{
|
{
|
||||||
public class HistoryBoundsTests
|
public class HistoryBoundsTests
|
||||||
{
|
{
|
||||||
Queue<Bounds> history;
|
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp()
|
public void SetUp() {}
|
||||||
{
|
|
||||||
history = new Queue<Bounds>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper function to construct (min, max) bounds
|
// helper function to construct (min, max) bounds
|
||||||
public static Bounds MinMax(Vector3 min, Vector3 max)
|
public static Bounds MinMax(Vector3 min, Vector3 max)
|
||||||
@ -34,6 +29,8 @@ public static Bounds MinMax(float min, float max) =>
|
|||||||
[TestCase(10_000, 64, 8)]
|
[TestCase(10_000, 64, 8)]
|
||||||
public void Benchmark(int iterations, int insertions, int limit)
|
public void Benchmark(int iterations, int insertions, int limit)
|
||||||
{
|
{
|
||||||
|
HistoryBounds history = new HistoryBounds(limit);
|
||||||
|
|
||||||
// always use the same seed so we get the same test.
|
// always use the same seed so we get the same test.
|
||||||
Random.InitState(0);
|
Random.InitState(0);
|
||||||
|
|
||||||
@ -42,13 +39,13 @@ public void Benchmark(int iterations, int insertions, int limit)
|
|||||||
{
|
{
|
||||||
// each test captures 'insertions' bounds,
|
// each test captures 'insertions' bounds,
|
||||||
// with a history of 'limit' bounds.
|
// with a history of 'limit' bounds.
|
||||||
history.Clear();
|
history.Reset();
|
||||||
for (int i = 0; i < insertions; ++i)
|
for (int i = 0; i < insertions; ++i)
|
||||||
{
|
{
|
||||||
float min = Random.Range(-1, 1);
|
float min = Random.Range(-1, 1);
|
||||||
float max = Random.Range(min, 1);
|
float max = Random.Range(min, 1);
|
||||||
Bounds bounds = MinMax(min, max);
|
Bounds bounds = MinMax(min, max);
|
||||||
Bounds total = HistoryBounds.Insert(history, limit, bounds);
|
Bounds total = HistoryBoundsAlgo.Insert(history, bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,30 +55,31 @@ public void Benchmark(int iterations, int insertions, int limit)
|
|||||||
public void Insert_Basic()
|
public void Insert_Basic()
|
||||||
{
|
{
|
||||||
const int limit = 3;
|
const int limit = 3;
|
||||||
|
HistoryBounds history = new HistoryBounds(limit);
|
||||||
|
|
||||||
// insert initial [-1, 1].
|
// insert initial [-1, 1].
|
||||||
// should calculate new bounds == initial.
|
// should calculate new bounds == initial.
|
||||||
Bounds total = HistoryBounds.Insert(history, limit, MinMax(-1, 1));
|
Bounds total = HistoryBoundsAlgo.Insert(history, MinMax(-1, 1));
|
||||||
Assert.That(history.Count, Is.EqualTo(1));
|
Assert.That(history.Count, Is.EqualTo(1));
|
||||||
Assert.That(total, Is.EqualTo(MinMax(-1, 1)));
|
Assert.That(total, Is.EqualTo(MinMax(-1, 1)));
|
||||||
|
|
||||||
// insert [0, 2]
|
// insert [0, 2]
|
||||||
// should calculate new bounds == [-1, 2].
|
// should calculate new bounds == [-1, 2].
|
||||||
total = HistoryBounds.Insert(history, limit, MinMax(0, 2));
|
total = HistoryBoundsAlgo.Insert(history, MinMax(0, 2));
|
||||||
Assert.That(history.Count, Is.EqualTo(2));
|
Assert.That(history.Count, Is.EqualTo(2));
|
||||||
Assert.That(total, Is.EqualTo(MinMax(-1, 2)));
|
Assert.That(total, Is.EqualTo(MinMax(-1, 2)));
|
||||||
|
|
||||||
// insert one that's smaller than current bounds [-.5, 0]
|
// insert one that's smaller than current bounds [-.5, 0]
|
||||||
// history needs to contain it even if smaller, because once the oldest
|
// history needs to contain it even if smaller, because once the oldest
|
||||||
// largest one gets removed, this one matters too.
|
// largest one gets removed, this one matters too.
|
||||||
total = HistoryBounds.Insert(history, limit, MinMax(-0.5f, 0));
|
total = HistoryBoundsAlgo.Insert(history, MinMax(-0.5f, 0));
|
||||||
Assert.That(history.Count, Is.EqualTo(3));
|
Assert.That(history.Count, Is.EqualTo(3));
|
||||||
Assert.That(total, Is.EqualTo(MinMax(-1, 2)));
|
Assert.That(total, Is.EqualTo(MinMax(-1, 2)));
|
||||||
|
|
||||||
// insert more than 'limit': [0, 0]
|
// insert more than 'limit': [0, 0]
|
||||||
// the oldest one [-1, 1] should be discarded.
|
// the oldest one [-1, 1] should be discarded.
|
||||||
// new bounds should be [-0.5, 2]
|
// new bounds should be [-0.5, 2]
|
||||||
total = HistoryBounds.Insert(history, limit, MinMax(0, 0));
|
total = HistoryBoundsAlgo.Insert(history, MinMax(0, 0));
|
||||||
Assert.That(history.Count, Is.EqualTo(3));
|
Assert.That(history.Count, Is.EqualTo(3));
|
||||||
Assert.That(total, Is.EqualTo(MinMax(-0.5f, 2)));
|
Assert.That(total, Is.EqualTo(MinMax(-0.5f, 2)));
|
||||||
}
|
}
|
||||||
@ -92,28 +90,29 @@ public void Insert_Basic()
|
|||||||
public void Insert_Revisit()
|
public void Insert_Revisit()
|
||||||
{
|
{
|
||||||
const int limit = 3;
|
const int limit = 3;
|
||||||
|
HistoryBounds history = new HistoryBounds(limit);
|
||||||
|
|
||||||
// insert initial [-1, 1].
|
// insert initial [-1, 1].
|
||||||
// should calculate new bounds == initial.
|
// should calculate new bounds == initial.
|
||||||
Bounds total = HistoryBounds.Insert(history, limit, MinMax(-1, 1));
|
Bounds total = HistoryBoundsAlgo.Insert(history, MinMax(-1, 1));
|
||||||
Assert.That(history.Count, Is.EqualTo(1));
|
Assert.That(history.Count, Is.EqualTo(1));
|
||||||
Assert.That(total, Is.EqualTo(MinMax(-1, 1)));
|
Assert.That(total, Is.EqualTo(MinMax(-1, 1)));
|
||||||
|
|
||||||
// insert [0, 2]
|
// insert [0, 2]
|
||||||
// should calculate new bounds == [-1, 2].
|
// should calculate new bounds == [-1, 2].
|
||||||
total = HistoryBounds.Insert(history, limit, MinMax(0, 2));
|
total = HistoryBoundsAlgo.Insert(history, MinMax(0, 2));
|
||||||
Assert.That(history.Count, Is.EqualTo(2));
|
Assert.That(history.Count, Is.EqualTo(2));
|
||||||
Assert.That(total, Is.EqualTo(MinMax(-1, 2)));
|
Assert.That(total, Is.EqualTo(MinMax(-1, 2)));
|
||||||
|
|
||||||
// visit [-1, 1] again
|
// visit [-1, 1] again
|
||||||
total = HistoryBounds.Insert(history, limit, MinMax(-1, 1));
|
total = HistoryBoundsAlgo.Insert(history, MinMax(-1, 1));
|
||||||
Assert.That(history.Count, Is.EqualTo(3));
|
Assert.That(history.Count, Is.EqualTo(3));
|
||||||
Assert.That(total, Is.EqualTo(MinMax(-1, 2)));
|
Assert.That(total, Is.EqualTo(MinMax(-1, 2)));
|
||||||
|
|
||||||
// insert beyond limit.
|
// insert beyond limit.
|
||||||
// oldest one [-1, 1] should be removed.
|
// oldest one [-1, 1] should be removed.
|
||||||
// total should still include it because we revisited [1, 1].
|
// total should still include it because we revisited [1, 1].
|
||||||
total = HistoryBounds.Insert(history, limit, MinMax(0, 0));
|
total = HistoryBoundsAlgo.Insert(history, MinMax(0, 0));
|
||||||
Assert.That(history.Count, Is.EqualTo(3));
|
Assert.That(history.Count, Is.EqualTo(3));
|
||||||
Assert.That(total, Is.EqualTo(MinMax(-1, 2)));
|
Assert.That(total, Is.EqualTo(MinMax(-1, 2)));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user