public void Add(int key, Element elem) { if (elem == null) { throw new Exception("Invalid element to add"); } RegionLock.EnterWriteLock(); try { // get region to insert into GetRegion(elem.X, elem.Y, out int row, out int column); // check if this is an item that would span multiple regions if (IsOversized(elem) || IsOutofRange(row, column)) { Oversized.Add(key, elem); return; } // add to the region specified (or span multiple regions) Regions[row][column].Add(key, elem); } finally { RegionLock.ExitWriteLock(); } }
public void Move(int key, Region src, Region dst) { RegionLock.EnterWriteLock(); try { // get element (either in oversized or a Region) Element elem; if (Oversized.TryGetValue(key, out elem)) { // if elment is Oversized or the dst is out of range, keep it here if (IsOversized(elem)) { return; } // assert that this element is currently out of range if (!IsOutofRange(src)) { throw new Exception("Invalid state in internal datastructures"); } // if it remains out of range, keep it here if (IsOutofRange(dst)) { return; } // remove it from the oversized, as it is moving to a region if (!Oversized.Remove(key)) { throw new Exception("Failed to remove this element"); } } else { // find it and remove it if (!Regions[src.Row][src.Col].TryGetValue(key, out elem)) { throw new Exception("Failed to location the element to move"); } if (!Regions[src.Row][src.Col].Remove(key)) { throw new Exception("Failed to remove this element"); } } // add element (either oversized or a Region) if (IsOutofRange(dst)) { Oversized.Add(key, elem); } else { Regions[dst.Row][dst.Col].Add(key, elem); } } finally { RegionLock.ExitWriteLock(); } }