refactor(task):优化设备照片限制筛选逻辑

- 使用LinkedHashMap和LinkedHashSet保持插入顺序
-重构筛选逻辑,提高代码可读性
- 优化设备样本分组处理流程
- 添加筛选原因追踪功能-保持原有筛选规则和日志记录- 提升代码执行效率和内存使用
This commit is contained in:
2025-10-28 16:21:30 +08:00
parent 6f8b3c8cdf
commit 5e2fe0329d

View File

@@ -52,6 +52,8 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.HashSet;
@@ -501,64 +503,75 @@ public class TaskFaceServiceImpl implements TaskFaceService {
return Collections.emptyList();
}
Map<Long, Integer> usedCount = new HashMap<>();
Map<Long, Integer> limitCache = new HashMap<>();
List<Long> result = new ArrayList<>();
Map<Long, List<FaceSampleEntity>> deviceSamplesMap = new LinkedHashMap<>();
Set<Long> passthroughSampleIds = new LinkedHashSet<>();
for (Long sampleId : acceptedSampleIds) {
FaceSampleEntity sample = sampleMap.get(sampleId);
if (sample == null) {
result.add(sampleId);
if (sample == null || sample.getDeviceId() == null) {
passthroughSampleIds.add(sampleId);
continue;
}
Long deviceId = sample.getDeviceId();
if (deviceId == null) {
result.add(sampleId);
continue;
deviceSamplesMap
.computeIfAbsent(sample.getDeviceId(), key -> new ArrayList<>())
.add(sample);
}
Map<Long, Integer> limitCache = new HashMap<>();
Set<Long> retainedSampleIds = new LinkedHashSet<>(passthroughSampleIds);
for (Map.Entry<Long, List<FaceSampleEntity>> entry : deviceSamplesMap.entrySet()) {
Long deviceId = entry.getKey();
List<FaceSampleEntity> deviceSamples = entry.getValue();
List<Long> deviceSampleIds = deviceSamples.stream()
.map(FaceSampleEntity::getId)
.toList();
Integer limitPhoto = limitCache.computeIfAbsent(deviceId, id -> {
DeviceConfigManager deviceConfig = deviceRepository.getDeviceConfigManager(id);
return deviceConfig != null ? deviceConfig.getInteger("limit_photo") : null;
});
List<Long> retainedForDevice;
if (limitPhoto == null || limitPhoto <= 0) {
List<Long> deviceSampleIds = deviceSamples.stream()
.map(FaceSampleEntity::getId)
.toList();
resultIds.addAll(deviceSampleIds);
log.debug("设备照片限制:设备ID={}, 无限制,保留{}张照片",
deviceId, deviceSampleIds.size());
} else {
// 根据样本数量与限制的关系进行不同处理
if (deviceSamples.size() > (limitPhoto + 2)) {
// 样本数大于(limit_photo+2)时,去掉首尾
List<Long> limitedIds = processDeviceSamples(deviceSamples, limitPhoto, true);
resultIds.addAll(limitedIds);
retainedForDevice = deviceSampleIds;
log.debug("设备照片限制:设备ID={}, 无限制,保留{}张照片", deviceId, deviceSampleIds.size());
} else if (deviceSamples.size() > (limitPhoto + 2)) {
retainedForDevice = processDeviceSamples(deviceSamples, limitPhoto, true);
log.debug("设备照片限制:设备ID={}, 限制={}张, 原始{}张,去首尾后最终{}张",
deviceId, limitPhoto, deviceSamples.size(), limitedIds.size());
deviceId, limitPhoto, deviceSamples.size(), retainedForDevice.size());
} else if (deviceSamples.size() > (limitPhoto + 1)) {
// 样本数大于(limit_photo+1)时,去掉尾部
List<Long> limitedIds = processDeviceSamples(deviceSamples, limitPhoto, false);
resultIds.addAll(limitedIds);
retainedForDevice = processDeviceSamples(deviceSamples, limitPhoto, false);
log.debug("设备照片限制:设备ID={}, 限制={}张, 原始{}张,去尾部后最终{}张",
deviceId, limitPhoto, deviceSamples.size(), limitedIds.size());
deviceId, limitPhoto, deviceSamples.size(), retainedForDevice.size());
} else if (deviceSamples.size() > limitPhoto) {
// 样本数大于limit_photo但小于等于(limit_photo+1),取前N张
List<Long> limitedIds = deviceSamples.stream()
retainedForDevice = deviceSamples.stream()
.limit(limitPhoto)
.map(FaceSampleEntity::getId)
.toList();
resultIds.addAll(limitedIds);
log.debug("设备照片限制:设备ID={}, 限制={}张, 原始{}张,取前{}张",
deviceId, limitPhoto, deviceSamples.size(), limitedIds.size());
deviceId, limitPhoto, deviceSamples.size(), retainedForDevice.size());
} else {
// 样本数小于等于limit_photo,不做操作
List<Long> limitedIds = deviceSamples.stream()
.map(FaceSampleEntity::getId)
.toList();
resultIds.addAll(limitedIds);
retainedForDevice = deviceSampleIds;
log.debug("设备照片限制:设备ID={}, 限制={}张, 原始{}张,无需筛选,保留全部",
deviceId, limitPhoto, deviceSamples.size());
}
retainedSampleIds.addAll(retainedForDevice);
if (trace != null) {
Set<Long> retainedSet = new HashSet<>(retainedForDevice);
for (Long sampleId : deviceSampleIds) {
if (!retainedSet.contains(sampleId)) {
trace.addReason(sampleId, FaceRecognitionFilterReason.DEVICE_PHOTO_LIMIT);
}
}
}
}
List<Long> resultIds = new ArrayList<>(acceptedSampleIds.size());
for (Long sampleId : acceptedSampleIds) {
if (retainedSampleIds.contains(sampleId)) {
resultIds.add(sampleId);
}
}