Initial version of grid indexing base drawer search #1285
+337
−54
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The current implementation of block controllers has each block controller search for drawers that are in range (default range = 50). It does so by BFS searching blocks until it hits the range or unloaded blocks.
The maximal number of blocks it will search at default range is ~523,000 (volume of a sphere of radius 50). For each loaded chunks, it's about 25,000 max.
As the number of players, drawer controllers, and loaded chunks increases, this can get quite expensive to be processing.
This patch instead moves to simply keep track of the locations of loaded drawers (catually INetworked entities, to match what the search looked at before) using a spatial grid-index. When INetworked entities load or are created they are entered into the grid, and when they are removed or unloaded they are removed from the grid. This is done by using an event bus and loaded/unloaded events that are watched.
Block controllers then search for drawers in range by querying the grid index instead of doing their own block by block searches. To maintain compatibility with the current search, we use spherical shaped range queries.
With the grid index, even with 100 million drawers/etc, clustered into groups of 0-512 , you easily do 100 queries per second in less than a millisecond. The amount of memory used for the index is neglible even in ridiculous cases.
I also have an octree based version of this patch, which is often conceptually easier to follow but slower in practice and requires more code (Here we just reuse sectionpos which already does most of what we want).
In the end, this patch basically eliminates ~all time being used for drawer searches by controllers.