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