fp: Use improved binary search

This commit is contained in:
doyle 2023-09-20 00:21:05 +10:00
parent d2d4f3cfa7
commit 528a79548b
2 changed files with 319 additions and 1 deletions

2
External/tely vendored

@ -1 +1 @@
Subproject commit 964aa47a6ed2e2bb1606dd576a57867d09ca8ba6 Subproject commit 7bdc04915a3cc320f920f2b9b25ad811463b6fd1

View File

@ -16,6 +16,318 @@ void TELY_DLL_Init(void *user_data)
TELY_Platform *platform = DQN_CAST(TELY_Platform *)user_data; TELY_Platform *platform = DQN_CAST(TELY_Platform *)user_data;
TELY_DLL_Reload(user_data); TELY_DLL_Reload(user_data);
{
uint32_t array[] = {1};
Dqn_BinarySearchResult result = {};
// NOTE: Match =============================================================================
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 0U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 1U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 2U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 1);
// NOTE: Lower bound =======================================================================
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 0U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 1U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 2U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 1);
// NOTE: Upper bound =======================================================================
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 0U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 1U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 1);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 2U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 1);
}
{
uint32_t array[] = {1, 2};
// NOTE: Match =============================================================================
Dqn_BinarySearchResult result = {};
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 0U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 1U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 2U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 1);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 3U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 2);
// NOTE: Lower bound =======================================================================
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 0U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 1U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 2U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 1);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 3U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 2);
// NOTE: Upper bound =======================================================================
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 0U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 1U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 1);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 2U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 2);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 3U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 2);
}
{
uint32_t array[] = {1, 2, 3};
Dqn_BinarySearchResult result = {};
// NOTE: Match =============================================================================
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 0U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 1U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 2U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 1);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 3U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 2);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 4U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 3);
// NOTE: Lower bound =======================================================================
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 0U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 1U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 2U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 1);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 3U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 2);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 4U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 3);
// NOTE: Upper bound =======================================================================
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 0U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 1U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 1);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 2U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 2);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 3U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 3);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 4U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 3);
}
{
uint32_t array[] = {1, 2, 3, 4};
Dqn_BinarySearchResult result = {};
// NOTE: Match =============================================================================
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 0U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 1U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 2U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 1);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 3U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 2);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 4U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 3);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 5U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 4);
// NOTE: Lower bound =======================================================================
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 0U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 1U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 2U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 1);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 3U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 2);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 4U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 3);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 5U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 4);
// NOTE: Upper bound =======================================================================
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 0U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 1U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 1);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 2U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 2);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 3U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 3);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 4U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 4);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 5U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 4);
}
{
uint32_t array[] = {1, 1, 2, 2, 3};
Dqn_BinarySearchResult result = {};
// NOTE: Match =============================================================================
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 0U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 1U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 2U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 2);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 3U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 4);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 4U /*find*/, Dqn_BinarySearchType_Match);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 5);
// NOTE: Lower bound =======================================================================
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 0U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 1U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 2U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 2);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 3U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 4);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 4U /*find*/, Dqn_BinarySearchType_LowerBound);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 5);
// NOTE: Upper bound =======================================================================
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 0U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 0);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 1U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 2);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 2U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(result.found);
DQN_ASSERT(result.index == 4);
result = Dqn_BinarySearch<uint32_t>(array, DQN_ARRAY_UCOUNT(array), 3U /*find*/, Dqn_BinarySearchType_UpperBound);
DQN_ASSERT(!result.found);
DQN_ASSERT(result.index == 5);
}
{ {
Dqn_Arena_TempMemoryScope(&platform->arena); Dqn_Arena_TempMemoryScope(&platform->arena);
TELY_ChunkPool pool = {}; TELY_ChunkPool pool = {};
@ -275,6 +587,12 @@ Dqn_Slice<Dqn_V2I> AStarPathFind(Dqn_Arena *arena, TELY_Platform *platform, Dqn_
next_cost_result.value->came_from = curr_tile; next_cost_result.value->came_from = curr_tile;
next_cost_result.value->heuristic = new_cost + manhattan_dist; next_cost_result.value->heuristic = new_cost + manhattan_dist;
struct AStarBinarySearchContext
{
Dqn_DSMap<AStarNode> *astar_info;
Dqn_f32 heuristic;
};
// TODO(doyle): Find the insert location into the frontier // TODO(doyle): Find the insert location into the frontier
bool inserted = false; bool inserted = false;
DQN_FOR_UINDEX(index, frontier.size) { DQN_FOR_UINDEX(index, frontier.size) {