java-topology/defects/freeciv-0001/patch/freeciv-0001.patch

46 lines
1.7 KiB
Diff

# UNDF: UNDF-2026-000000974
--- a/server/generator/mapgen_utils.c
+++ b/server/generator/mapgen_utils.c
@@ -289,7 +289,8 @@
/**********************************************************************//**
Number this tile and nearby tiles with the specified continent number 'nr'.
Due to the number of recursion for large maps a non-recursive algorithm is
- utilised.
+ utilised. Tiles are marked with their continent number when enqueued,
+ eliminating O(N) membership checks on the worklist.
is_land tells us whether we are assigning continent numbers or ocean
numbers.
@@ -308,6 +309,9 @@
&& T_UNKNOWN != pterrain
&& XOR(is_land, terrain_type_terrain_class(pterrain) == TC_OCEAN));
+ /* Mark the initial tile immediately to avoid re-enqueue. */
+ tile_set_continent(ptile, nr);
+
/* Create tile list and insert the initial tile. */
tlist = tile_list_new();
tile_list_append(tlist, ptile);
@@ -325,15 +329,16 @@
continue;
}
- /* Add the tile to the list of tiles to check. */
- if (!tile_list_search(tlist, ptile3)) {
- tile_list_append(tlist, ptile3);
- }
+ /* Mark and enqueue. The continent field serves as our visited set,
+ * replacing the O(N) tile_list_search() with an O(1) check above. */
+ tile_set_continent(ptile3, nr);
+ tile_list_append(tlist, ptile3);
} adjc_iterate_end;
- /* Set the continent data and remove the tile from the list. */
- tile_set_continent(ptile2, nr);
+ /* Remove the tile from the worklist. Continent was already set
+ * at enqueue time. */
tile_list_remove(tlist, ptile2);
+ /* Note: tile_list_get(tlist, 0) is O(1) for linked list head. */
/* Count the tile */
if (nr < 0) {