forked from mirror/DotRecast
Changed RcSortedQueue.Remove() function to use binary search
This commit is contained in:
parent
a1b730da7d
commit
45e4426df6
|
@ -7,10 +7,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
## [Unreleased] - yyyy-mm-dd
|
## [Unreleased] - yyyy-mm-dd
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
- Added DtNodeQueue UnitTest [@ikpil](https://github.com/ikpil)
|
||||||
|
- Added RcSortedQueue UnitTest [@ikpil](https://github.com/ikpil)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
- Changed RcSortedQueue.Remove() function to use binary search.
|
||||||
- Update Microsoft.NET.Test.Sdk 17.8.0 to 17.9.0
|
- Update Microsoft.NET.Test.Sdk 17.8.0 to 17.9.0
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
|
@ -27,12 +27,12 @@ namespace DotRecast.Core.Collections
|
||||||
{
|
{
|
||||||
private bool _dirty;
|
private bool _dirty;
|
||||||
private readonly List<T> _items;
|
private readonly List<T> _items;
|
||||||
private readonly Comparison<T> _comparison;
|
private readonly Comparer<T> _comparer;
|
||||||
|
|
||||||
public RcSortedQueue(Comparison<T> comparison)
|
public RcSortedQueue(Comparison<T> comp)
|
||||||
{
|
{
|
||||||
_items = new List<T>();
|
_items = new List<T>();
|
||||||
_comparison = (x, y) => comparison.Invoke(x, y) * -1; // reverse
|
_comparer = Comparer<T>.Create((x, y) => comp.Invoke(x, y) * -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Count()
|
public int Count()
|
||||||
|
@ -40,16 +40,22 @@ namespace DotRecast.Core.Collections
|
||||||
return _items.Count;
|
return _items.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsEmpty()
|
||||||
|
{
|
||||||
|
return 0 == _items.Count;
|
||||||
|
}
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
_items.Clear();
|
_items.Clear();
|
||||||
|
_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Balance()
|
private void Balance()
|
||||||
{
|
{
|
||||||
if (_dirty)
|
if (_dirty)
|
||||||
{
|
{
|
||||||
_items.Sort(_comparison); // reverse
|
_items.Sort(_comparer); // reverse
|
||||||
_dirty = false;
|
_dirty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,13 +63,13 @@ namespace DotRecast.Core.Collections
|
||||||
public T Peek()
|
public T Peek()
|
||||||
{
|
{
|
||||||
Balance();
|
Balance();
|
||||||
return _items[_items.Count - 1];
|
return _items[^1];
|
||||||
}
|
}
|
||||||
|
|
||||||
public T Dequeue()
|
public T Dequeue()
|
||||||
{
|
{
|
||||||
var node = Peek();
|
var node = Peek();
|
||||||
_items.Remove(node);
|
_items.RemoveAt(_items.Count - 1);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,19 +79,17 @@ namespace DotRecast.Core.Collections
|
||||||
_dirty = true;
|
_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove(T item)
|
public bool Remove(T item)
|
||||||
{
|
{
|
||||||
int idx = _items.FindLastIndex(x => item.Equals(x));
|
Balance();
|
||||||
|
int idx = _items.BinarySearch(item, _comparer);
|
||||||
if (0 > idx)
|
if (0 > idx)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
_items.RemoveAt(idx);
|
_items.RemoveAt(idx);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsEmpty()
|
|
||||||
{
|
|
||||||
return 0 == _items.Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<T> ToList()
|
public List<T> ToList()
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,7 +24,12 @@ namespace DotRecast.Detour
|
||||||
{
|
{
|
||||||
public class DtNodeQueue
|
public class DtNodeQueue
|
||||||
{
|
{
|
||||||
private readonly RcSortedQueue<DtNode> m_heap = new RcSortedQueue<DtNode>((n1, n2) => n1.total.CompareTo(n2.total));
|
private readonly RcSortedQueue<DtNode> m_heap;
|
||||||
|
|
||||||
|
public DtNodeQueue()
|
||||||
|
{
|
||||||
|
m_heap = new RcSortedQueue<DtNode>((n1, n2) => n1.total.CompareTo(n2.total));
|
||||||
|
}
|
||||||
|
|
||||||
public int Count()
|
public int Count()
|
||||||
{
|
{
|
||||||
|
@ -43,9 +48,7 @@ namespace DotRecast.Detour
|
||||||
|
|
||||||
public DtNode Pop()
|
public DtNode Pop()
|
||||||
{
|
{
|
||||||
var node = Peek();
|
return m_heap.Dequeue();
|
||||||
m_heap.Remove(node);
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Push(DtNode node)
|
public void Push(DtNode node)
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using DotRecast.Core.Collections;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace DotRecast.Core.Test;
|
||||||
|
|
||||||
|
public class RcSortedQueueTest
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestEnqueueAndDequeue()
|
||||||
|
{
|
||||||
|
var sortedQueue = new RcSortedQueue<int>((a, b) => a.CompareTo(b));
|
||||||
|
|
||||||
|
var r = new RcRand();
|
||||||
|
var expectedList = new List<int>();
|
||||||
|
for (int i = 0; i < 999; ++i)
|
||||||
|
{
|
||||||
|
expectedList.Add(r.NextInt32() % 300); // allow duplication
|
||||||
|
}
|
||||||
|
|
||||||
|
// ready
|
||||||
|
foreach (var expected in expectedList)
|
||||||
|
{
|
||||||
|
sortedQueue.Enqueue(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedList.Sort();
|
||||||
|
|
||||||
|
// check count
|
||||||
|
Assert.That(sortedQueue.Count(), Is.EqualTo(expectedList.Count));
|
||||||
|
Assert.That(sortedQueue.IsEmpty(), Is.False);
|
||||||
|
|
||||||
|
Assert.That(sortedQueue.ToList(), Is.EqualTo(expectedList));
|
||||||
|
|
||||||
|
// check Peek and Dequeue
|
||||||
|
for (int i = 0; i < expectedList.Count; ++i)
|
||||||
|
{
|
||||||
|
Assert.That(sortedQueue.Peek(), Is.EqualTo(expectedList[i]));
|
||||||
|
Assert.That(sortedQueue.Count(), Is.EqualTo(expectedList.Count - i));
|
||||||
|
|
||||||
|
Assert.That(sortedQueue.Dequeue(), Is.EqualTo(expectedList[i]));
|
||||||
|
Assert.That(sortedQueue.Count(), Is.EqualTo(expectedList.Count - i - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// check count
|
||||||
|
Assert.That(sortedQueue.Count(), Is.EqualTo(0));
|
||||||
|
Assert.That(sortedQueue.IsEmpty(), Is.True);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestRemove()
|
||||||
|
{
|
||||||
|
var sortedQueue = new RcSortedQueue<int>((a, b) => a.CompareTo(b));
|
||||||
|
|
||||||
|
var r = new RcRand();
|
||||||
|
var expectedList = new List<int>();
|
||||||
|
for (int i = 0; i < 999; ++i)
|
||||||
|
{
|
||||||
|
expectedList.Add(r.NextInt32() % 300); // allow duplication
|
||||||
|
}
|
||||||
|
|
||||||
|
// ready
|
||||||
|
foreach (var expected in expectedList)
|
||||||
|
{
|
||||||
|
sortedQueue.Enqueue(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedList.Shuffle();
|
||||||
|
|
||||||
|
// check
|
||||||
|
Assert.That(sortedQueue.Count(), Is.EqualTo(expectedList.Count));
|
||||||
|
|
||||||
|
foreach (var expected in expectedList)
|
||||||
|
{
|
||||||
|
Assert.That(sortedQueue.Remove(expected), Is.True);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.That(sortedQueue.IsEmpty(), Is.True);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using DotRecast.Core.Collections;
|
using DotRecast.Core.Collections;
|
||||||
using NuGet.Frameworks;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Core.Test;
|
namespace DotRecast.Core.Test;
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using DotRecast.Core.Collections;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace DotRecast.Detour.Test;
|
||||||
|
|
||||||
|
public class DtNodeQueueTest
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestDtNodeQueue()
|
||||||
|
{
|
||||||
|
var queue = new DtNodeQueue();
|
||||||
|
|
||||||
|
// check count
|
||||||
|
Assert.That(queue.Count(), Is.EqualTo(0));
|
||||||
|
|
||||||
|
const int count = 1000;
|
||||||
|
var nodes = new List<DtNode>();
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
var node = new DtNode(i);
|
||||||
|
node.total = i;
|
||||||
|
nodes.Add(node);
|
||||||
|
}
|
||||||
|
nodes.Shuffle();
|
||||||
|
|
||||||
|
foreach (var node in nodes)
|
||||||
|
{
|
||||||
|
queue.Push(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.That(queue.Count(), Is.EqualTo(count));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue