Garder un doublon de voisine si sa taille diffère de la copie d'input/

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Antoine Jacquin
2026-09-27 16:31:58 +02:00
parent 32d694bbd6
commit c9b7504346
2 changed files with 25 additions and 10 deletions

View File

@ -533,7 +533,9 @@ class LidarArchaeoPipeline:
voisines) ; l'exemplaire d'input/ fait foi (_neighbor_laz_files
cherche dans input/ avant edge_neighbors/), le doublon ne sert donc
à rien et peut peser plusieurs centaines de Mo. Les fichiers ".part"
(téléchargement en cours) ne sont jamais touchés.
(téléchargement en cours) ne sont jamais touchés, et un doublon de
taille différente est conservé (l'exemplaire d'input/ pourrait être
tronqué : on ne supprime jamais ce qui serait la seule copie saine).
"""
from .dtm import EDGE_NEIGHBORS_DIRNAME
if not edge_dir.is_dir():
@ -541,16 +543,23 @@ class LidarArchaeoPipeline:
removed = 0
freed = 0
for path in edge_dir.iterdir():
if not path.is_file() or path.suffix == ".part" or path.name.endswith(".part"):
if not path.is_file() or path.suffix == ".part":
continue
twin = self.input_dir / path.name
if twin.exists():
try:
freed += path.stat().st_size
path.unlink()
removed += 1
except OSError:
pass
if not twin.exists():
continue
try:
size = path.stat().st_size
if twin.stat().st_size != size:
logger.warning(f"Raccord des bords : {path.name} présent dans input/ "
f"et {EDGE_NEIGHBORS_DIRNAME}/ avec des tailles "
f"différentes — doublon conservé")
continue
path.unlink()
freed += size
removed += 1
except OSError:
pass
if removed:
logger.info(f"Raccord des bords : {removed} doublon(s) supprimé(s) de "
f"{EDGE_NEIGHBORS_DIRNAME}/ (déjà dans input/, "

View File

@ -121,9 +121,14 @@ class TestCleanupEdgeNeighborDuplicates:
dup_name = "LHD_FXX_1000_6779_PTS_LAMB93_IGN69.copc.laz"
unique_name = "LHD_FXX_1001_6779_PTS_LAMB93_IGN69.copc.laz"
part_name = "LHD_FXX_1002_6779_PTS_LAMB93_IGN69.copc.laz.part"
mismatch_name = "LHD_FXX_1003_6779_PTS_LAMB93_IGN69.copc.laz"
(input_dir / dup_name).write_bytes(b"authoritative")
(edge_dir / dup_name).write_bytes(b"duplicata")
(edge_dir / dup_name).write_bytes(b"authoritative")
# input/ tronqué (taille différente) : la voisine peut être la seule
# copie saine, elle doit rester.
(input_dir / mismatch_name).write_bytes(b"")
(edge_dir / mismatch_name).write_bytes(b"complete")
(edge_dir / unique_name).write_bytes(b"voisine-unique")
(edge_dir / part_name).write_bytes(b"en-cours")
@ -135,6 +140,7 @@ class TestCleanupEdgeNeighborDuplicates:
assert (input_dir / dup_name).read_bytes() == b"authoritative"
assert (edge_dir / unique_name).exists()
assert (edge_dir / part_name).exists()
assert (edge_dir / mismatch_name).read_bytes() == b"complete"
def test_noop_when_edge_dir_missing(self, tmp_path):
from lidar_pipeline.pipeline import LidarArchaeoPipeline