forked from MoonsideGames/MoonTools.Bonk
optimize away a dictionary lookup in SpatialHash
parent
d9bc05ee32
commit
50e4b86029
|
@ -12,7 +12,7 @@ namespace MoonTools.Core.Bonk
|
||||||
{
|
{
|
||||||
private readonly int cellSize;
|
private readonly int cellSize;
|
||||||
|
|
||||||
private readonly Dictionary<int, Dictionary<int, HashSet<T>>> hashDictionary = new Dictionary<int, Dictionary<int, HashSet<T>>>();
|
private readonly Dictionary<long, HashSet<T>> hashDictionary = new Dictionary<long, HashSet<T>>();
|
||||||
private readonly Dictionary<T, (IShape2D, Transform2D)> IDLookup = new Dictionary<T, (IShape2D, Transform2D)>();
|
private readonly Dictionary<T, (IShape2D, Transform2D)> IDLookup = new Dictionary<T, (IShape2D, Transform2D)>();
|
||||||
|
|
||||||
public SpatialHash(int cellSize)
|
public SpatialHash(int cellSize)
|
||||||
|
@ -41,17 +41,13 @@ namespace MoonTools.Core.Bonk
|
||||||
{
|
{
|
||||||
for (int j = minHash.Item2; j <= maxHash.Item2; j++)
|
for (int j = minHash.Item2; j <= maxHash.Item2; j++)
|
||||||
{
|
{
|
||||||
if (!hashDictionary.ContainsKey(i))
|
var key = LongHelper.MakeLong(i, j);
|
||||||
|
if (!hashDictionary.ContainsKey(key))
|
||||||
{
|
{
|
||||||
hashDictionary.Add(i, new Dictionary<int, HashSet<T>>());
|
hashDictionary.Add(key, new HashSet<T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hashDictionary[i].ContainsKey(j))
|
hashDictionary[key].Add(id);
|
||||||
{
|
|
||||||
hashDictionary[i].Add(j, new HashSet<T>());
|
|
||||||
}
|
|
||||||
|
|
||||||
hashDictionary[i][j].Add(id);
|
|
||||||
IDLookup[id] = (shape, transform2D);
|
IDLookup[id] = (shape, transform2D);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,9 +66,10 @@ namespace MoonTools.Core.Bonk
|
||||||
{
|
{
|
||||||
for (int j = minHash.Item2; j <= maxHash.Item2; j++)
|
for (int j = minHash.Item2; j <= maxHash.Item2; j++)
|
||||||
{
|
{
|
||||||
if (hashDictionary.ContainsKey(i) && hashDictionary[i].ContainsKey(j))
|
var key = LongHelper.MakeLong(i, j);
|
||||||
|
if (hashDictionary.ContainsKey(key))
|
||||||
{
|
{
|
||||||
foreach (var t in hashDictionary[i][j])
|
foreach (var t in hashDictionary[key])
|
||||||
{
|
{
|
||||||
var (otherShape, otherTransform) = IDLookup[t];
|
var (otherShape, otherTransform) = IDLookup[t];
|
||||||
if (!id.Equals(t)) { yield return (t, otherShape, otherTransform); }
|
if (!id.Equals(t)) { yield return (t, otherShape, otherTransform); }
|
||||||
|
@ -87,12 +84,9 @@ namespace MoonTools.Core.Bonk
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
foreach (var innerDict in hashDictionary.Values)
|
foreach (var hash in hashDictionary.Values)
|
||||||
{
|
{
|
||||||
foreach (var set in innerDict.Values)
|
hash.Clear();
|
||||||
{
|
|
||||||
set.Clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IDLookup.Clear();
|
IDLookup.Clear();
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
namespace MoonTools.Core.Bonk
|
||||||
|
{
|
||||||
|
public static class LongHelper
|
||||||
|
{
|
||||||
|
public static long MakeLong(int left, int right)
|
||||||
|
{
|
||||||
|
return ((long)left << 32) | ((uint)right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,28 +13,28 @@ namespace Tests
|
||||||
{
|
{
|
||||||
var spatialHash = new SpatialHash<int>(16);
|
var spatialHash = new SpatialHash<int>(16);
|
||||||
|
|
||||||
var rectA = new MoonTools.Core.Bonk.Rectangle(-2, -2, 2, 2);
|
var rectA = new Rectangle(-2, -2, 2, 2);
|
||||||
var rectATransform = new Transform2D(new Vector2(-8, -8));
|
var rectATransform = new Transform2D(new Vector2(-8, -8));
|
||||||
|
|
||||||
var rectB = new MoonTools.Core.Bonk.Rectangle(-2, -2, 2, 2);
|
var rectB = new Rectangle(-2, -2, 2, 2);
|
||||||
var rectBTransform = new Transform2D(new Vector2(8, 8));
|
var rectBTransform = new Transform2D(new Vector2(8, 8));
|
||||||
|
|
||||||
var rectC = new MoonTools.Core.Bonk.Rectangle(-2, -2, 2, 2);
|
var rectC = new Rectangle(-2, -2, 2, 2);
|
||||||
var rectCTransform = new Transform2D(new Vector2(24, -4));
|
var rectCTransform = new Transform2D(new Vector2(24, -4));
|
||||||
|
|
||||||
var rectD = new MoonTools.Core.Bonk.Rectangle(-2, -2, 2, 2);
|
var rectD = new Rectangle(-2, -2, 2, 2);
|
||||||
var rectDTransform = new Transform2D(new Vector2(24, 24));
|
var rectDTransform = new Transform2D(new Vector2(24, 24));
|
||||||
|
|
||||||
var circleA = new MoonTools.Core.Bonk.Circle(2);
|
var circleA = new Circle(2);
|
||||||
var circleATransform = new Transform2D(new Vector2(24, -8));
|
var circleATransform = new Transform2D(new Vector2(24, -8));
|
||||||
|
|
||||||
var circleB = new MoonTools.Core.Bonk.Circle(8);
|
var circleB = new Circle(8);
|
||||||
var circleBTransform = new Transform2D(new Vector2(16, 16));
|
var circleBTransform = new Transform2D(new Vector2(16, 16));
|
||||||
|
|
||||||
var line = new MoonTools.Core.Bonk.Line(new Position2D(20, -4), new Position2D(22, -12));
|
var line = new Line(new Position2D(20, -4), new Position2D(22, -12));
|
||||||
var lineTransform = new Transform2D(new Vector2(0, 0));
|
var lineTransform = new Transform2D(new Vector2(0, 0));
|
||||||
|
|
||||||
var point = new MoonTools.Core.Bonk.Point(8, 8);
|
var point = new Point(8, 8);
|
||||||
var pointTransform = Transform2D.DefaultTransform;
|
var pointTransform = Transform2D.DefaultTransform;
|
||||||
|
|
||||||
spatialHash.Insert(0, rectA, rectATransform);
|
spatialHash.Insert(0, rectA, rectATransform);
|
||||||
|
@ -63,13 +63,13 @@ namespace Tests
|
||||||
{
|
{
|
||||||
var spatialHash = new SpatialHash<int>(16);
|
var spatialHash = new SpatialHash<int>(16);
|
||||||
|
|
||||||
var rectA = new MoonTools.Core.Bonk.Rectangle(-2, -2, 2, 2);
|
var rectA = new Rectangle(-2, -2, 2, 2);
|
||||||
var rectATransform = new Transform2D(new Vector2(-8, -8));
|
var rectATransform = new Transform2D(new Vector2(-8, -8));
|
||||||
|
|
||||||
var rectB = new MoonTools.Core.Bonk.Rectangle(-2, -2, 2, 2);
|
var rectB = new Rectangle(-2, -2, 2, 2);
|
||||||
var rectBTransform = new Transform2D(new Vector2(-8, -8));
|
var rectBTransform = new Transform2D(new Vector2(-8, -8));
|
||||||
|
|
||||||
var rectC = new MoonTools.Core.Bonk.Rectangle(-1, -1, 1, 1);
|
var rectC = new Rectangle(-1, -1, 1, 1);
|
||||||
var rectCTransform = new Transform2D(new Vector2(-8, -8));
|
var rectCTransform = new Transform2D(new Vector2(-8, -8));
|
||||||
|
|
||||||
spatialHash.Insert(0, rectA, rectATransform);
|
spatialHash.Insert(0, rectA, rectATransform);
|
||||||
|
@ -84,10 +84,10 @@ namespace Tests
|
||||||
{
|
{
|
||||||
var spatialHash = new SpatialHash<int>(16);
|
var spatialHash = new SpatialHash<int>(16);
|
||||||
|
|
||||||
var rectA = new MoonTools.Core.Bonk.Rectangle(-2, -2, 2, 2);
|
var rectA = new Rectangle(-2, -2, 2, 2);
|
||||||
var rectATransform = new Transform2D(new Vector2(-8, -8));
|
var rectATransform = new Transform2D(new Vector2(-8, -8));
|
||||||
|
|
||||||
var rectB = new MoonTools.Core.Bonk.Rectangle(-2, -2, 2, 2);
|
var rectB = new Rectangle(-2, -2, 2, 2);
|
||||||
var rectBTransform = new Transform2D(new Vector2(8, 8));
|
var rectBTransform = new Transform2D(new Vector2(8, 8));
|
||||||
|
|
||||||
spatialHash.Insert(0, rectA, rectATransform);
|
spatialHash.Insert(0, rectA, rectATransform);
|
||||||
|
|
Loading…
Reference in New Issue