From 944be7b031c9e0afe8929a91997239b73d7ab3cc Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Mon, 21 Nov 2022 16:02:21 +0100 Subject: [PATCH] Avoid a cubed max search distance for POIs (#8576) The max search distance used to get the closest Poi data on X/Z axis is cubed instead of squared (one time in the parameter and another time in the function) for almost all search. Generally this has been hidden by another check that already does a pre distance check between the poi pos and the source pos for individual component but the issue still happens for diagonal distance search. Discovered by Samsuik --- .../server/Optimise-general-POI-access.patch | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/patches/server/Optimise-general-POI-access.patch b/patches/server/Optimise-general-POI-access.patch index d8a938df1b..1cefeed619 100644 --- a/patches/server/Optimise-general-POI-access.patch +++ b/patches/server/Optimise-general-POI-access.patch @@ -122,11 +122,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + final Predicate positionPredicate, + final BlockPos sourcePosition, + final int range, // distance on x y z axis -+ final double maxDistance, ++ final double maxDistanceSquared, + final PoiManager.Occupancy occupancy, + final boolean load) { + final PoiRecord ret = findClosestPoiDataRecord( -+ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistance, occupancy, load ++ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistanceSquared, occupancy, load + ); + + return ret == null ? null : ret.getPos(); @@ -140,11 +140,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + final Predicate positionPredicate, + final BlockPos sourcePosition, + final int range, // distance on x y z axis -+ final double maxDistance, ++ final double maxDistanceSquared, + final PoiManager.Occupancy occupancy, + final boolean load) { + final PoiRecord ret = findClosestPoiDataRecord( -+ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistance, occupancy, load ++ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistanceSquared, occupancy, load + ); + + return ret == null ? null : Pair.of(ret.getPoiType(), ret.getPos()); @@ -158,7 +158,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + final Predicate positionPredicate, + final BlockPos sourcePosition, + final int range, // distance on x y z axis -+ final double maxDistance, ++ final double maxDistanceSquared, + final PoiManager.Occupancy occupancy, + final boolean load, + final Set ret) { @@ -173,7 +173,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + final List toConvert = new ArrayList<>(); + findClosestPoiDataRecords( -+ poiStorage, villagePlaceType, newPredicate, sourcePosition, range, maxDistance, occupancy, load, toConvert ++ poiStorage, villagePlaceType, newPredicate, sourcePosition, range, maxDistanceSquared, occupancy, load, toConvert + ); + + for (final PoiRecord record : toConvert) { @@ -189,12 +189,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + final Predicate positionPredicate, + final BlockPos sourcePosition, + final int range, // distance on x y z axis -+ final double maxDistance, ++ final double maxDistanceSquared, + final PoiManager.Occupancy occupancy, + final boolean load) { + final List ret = new ArrayList<>(); + findClosestPoiDataRecords( -+ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistance, occupancy, load, ret ++ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistanceSquared, occupancy, load, ret + ); + return ret.isEmpty() ? null : ret.get(0); + } @@ -207,12 +207,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + final BiPredicate, BlockPos> predicate, + final BlockPos sourcePosition, + final int range, // distance on x y z axis -+ final double maxDistance, ++ final double maxDistanceSquared, + final PoiManager.Occupancy occupancy, + final boolean load) { + final List ret = new ArrayList<>(); + findClosestPoiDataRecords( -+ poiStorage, villagePlaceType, predicate, sourcePosition, range, maxDistance, occupancy, load, ret ++ poiStorage, villagePlaceType, predicate, sourcePosition, range, maxDistanceSquared, occupancy, load, ret + ); + return ret.isEmpty() ? null : ret.get(0); + } @@ -225,12 +225,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + final Predicate positionPredicate, + final BlockPos sourcePosition, + final int range, // distance on x y z axis -+ final double maxDistance, ++ final double maxDistanceSquared, + final PoiManager.Occupancy occupancy, + final boolean load, + final List ret) { + final BiPredicate, BlockPos> predicate = positionPredicate != null ? (type, pos) -> positionPredicate.test(pos) : null; -+ findClosestPoiDataRecords(poiStorage, villagePlaceType, predicate, sourcePosition, range, maxDistance, occupancy, load, ret); ++ findClosestPoiDataRecords(poiStorage, villagePlaceType, predicate, sourcePosition, range, maxDistanceSquared, occupancy, load, ret); + } + + public static void findClosestPoiDataRecords(final PoiManager poiStorage, @@ -239,14 +239,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + final BiPredicate, BlockPos> predicate, + final BlockPos sourcePosition, + final int range, // distance on x y z axis -+ final double maxDistance, ++ final double maxDistanceSquared, + final PoiManager.Occupancy occupancy, + final boolean load, + final List ret) { + final Predicate occupancyFilter = occupancy.getTest(); + + final List closestRecords = new ArrayList<>(); -+ double closestDistanceSquared = maxDistance * maxDistance; ++ double closestDistanceSquared = maxDistanceSquared; + + final int lowerX = Mth.floor(sourcePosition.getX() - range) >> 4; + final int lowerY = WorldUtil.getMinSection(poiStorage.world); @@ -413,11 +413,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + final Predicate positionPredicate, + final BlockPos sourcePosition, + final int range, // distance on x y z axis -+ final double maxDistance, ++ final double maxDistanceSquared, + final PoiManager.Occupancy occupancy, + final boolean load) { + final PoiRecord ret = findNearestPoiRecord( -+ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistance, occupancy, load ++ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistanceSquared, occupancy, load + ); + return ret == null ? null : ret.getPos(); + } @@ -429,7 +429,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + final Predicate positionPredicate, + final BlockPos sourcePosition, + final int range, // distance on x y z axis -+ final double maxDistance, ++ final double maxDistanceSquared, + final PoiManager.Occupancy occupancy, + final boolean load, + final int max, @@ -445,7 +445,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + final List toConvert = new ArrayList<>(); + findNearestPoiRecords( -+ poiStorage, villagePlaceType, newPredicate, sourcePosition, range, maxDistance, occupancy, load, max, toConvert ++ poiStorage, villagePlaceType, newPredicate, sourcePosition, range, maxDistanceSquared, occupancy, load, max, toConvert + ); + + for (final PoiRecord record : toConvert) { @@ -460,12 +460,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + final Predicate positionPredicate, + final BlockPos sourcePosition, + final int range, // distance on x y z axis -+ final double maxDistance, ++ final double maxDistanceSquared, + final PoiManager.Occupancy occupancy, + final boolean load) { + final List ret = new ArrayList<>(); + findNearestPoiRecords( -+ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistance, occupancy, load, ++ poiStorage, villagePlaceType, positionPredicate, sourcePosition, range, maxDistanceSquared, occupancy, load, + 1, ret + ); + return ret.isEmpty() ? null : ret.get(0); @@ -478,14 +478,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + final Predicate positionPredicate, + final BlockPos sourcePosition, + final int range, // distance on x y z axis -+ final double maxDistance, ++ final double maxDistanceSquared, + final PoiManager.Occupancy occupancy, + final boolean load, + final int max, + final List ret) { + final Predicate occupancyFilter = occupancy.getTest(); + -+ final double maxDistanceSquared = maxDistance * maxDistance; + final Double2ObjectRBTreeMap> closestRecords = new Double2ObjectRBTreeMap<>(); + int totalRecords = 0; + double furthestDistanceSquared = maxDistanceSquared;