refactor(ems): 优化监控信息树构建方法

- 添加了基于数据量的并行处理逻辑,提高大数据量处理效率
- 引入异步处理机制,优化数据库查询性能
- 保留了原有的方法逻辑,确保功能一致性
- 新增方法实现了更高效的温度数据加载和父子关系构建
IOT
zch 2 weeks ago
parent 9ada26f5b5
commit 2fc382585c

@ -2,7 +2,7 @@ package com.ruoyi.ems.base.service.impl;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -148,6 +148,88 @@ public class EmsBaseMonitorInfoServiceImpl implements IEmsBaseMonitorInfoService
* @return
*/
@Override
public List<EmsBaseMonitorInfo> buildMonitorInfoTree(List<EmsBaseMonitorInfo> baseMonitorInfos) {
// 数据量阈值,低于此值使用单线程,高于此值使用多线程
final int THRESHOLD = 100;
// 1. 提取监控类型为1L的设备编号 - 根据数据量选择是否并行
List<String> monitorCodes;
if(baseMonitorInfos.size() > THRESHOLD) {
monitorCodes = baseMonitorInfos.parallelStream()
.filter(item -> !ObjectUtils.isEmpty(item) && item.getMonitorType() == 1L)
.map(EmsBaseMonitorInfo::getMonitorCode)
.collect(Collectors.toList());
} else {
monitorCodes = baseMonitorInfos.stream()
.filter(item -> !ObjectUtils.isEmpty(item) && item.getMonitorType() == 1L)
.map(EmsBaseMonitorInfo::getMonitorCode)
.collect(Collectors.toList());
}
// 2. 创建温度数据Map - 异步执行耗时的数据库查询
Map<String, BigDecimal> tempDataMap = new HashMap<>();
// 数据库查询通常是IO密集型使用异步可以提高效率
if (CollectionUtils.isNotEmpty(monitorCodes)) {
// 使用CompletableFuture异步获取温度数据
List<TWTempertureData> tempDatas =
CompletableFuture.supplyAsync(() ->
tWTempertureDataMapper.selectLastTWTempertureDataByMonitorCodes(monitorCodes)
).join(); // 等待数据库查询完成
tempDataMap = tempDatas.stream()
.filter(data -> !ObjectUtils.isEmpty(data) && data.getTempreture() != null)
.collect(Collectors.toMap(
TWTempertureData::getMonitorId,
TWTempertureData::getTempreture,
(v1, v2) -> v1));
}
// 3. 收集所有设备ID和构建父子关系映射 - 单线程处理简单逻辑
Set<Long> allIds = baseMonitorInfos.stream()
.map(EmsBaseMonitorInfo::getObjId)
.collect(Collectors.toSet());
Map<Long, List<EmsBaseMonitorInfo>> parentChildMap = new HashMap<>();
// 4. 设置温度值并构建父子关系 - 简单循环,数据量不大时开销小
for (EmsBaseMonitorInfo info : baseMonitorInfos) {
// 设置温度值
if (info.getMonitorType() == 1L) {
BigDecimal temperature = tempDataMap.get(info.getMonitorCode());
if (temperature != null) {
info.setTemperature(temperature);
}
}
// 构建父子关系映射
Long parentId = info.getParentId();
if (parentId != null) {
parentChildMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(info);
}
}
// 5. 找出所有顶级节点
List<EmsBaseMonitorInfo> rootNodes = baseMonitorInfos.stream()
.filter(info -> info.getParentId() == null || !allIds.contains(info.getParentId()))
.collect(Collectors.toList());
// 6. 为顶级节点设置子节点
for (EmsBaseMonitorInfo root : rootNodes) {
setChildren(root, parentChildMap);
}
return rootNodes.isEmpty() ? baseMonitorInfos : rootNodes;
}
/**
*
*
* @param
* @return
*/
/*
@Override
public List<EmsBaseMonitorInfo> buildMonitorInfoTree(List<EmsBaseMonitorInfo> baseMonitorInfos) {
// 创建一个List来存储设备编号只获取监控类型为1L的设备编号
List<String> monitorCodes = baseMonitorInfos.stream()
@ -206,6 +288,7 @@ public class EmsBaseMonitorInfoServiceImpl implements IEmsBaseMonitorInfoService
return rootNodes.isEmpty() ? baseMonitorInfos : rootNodes;
}
*/
/**
*

Loading…
Cancel
Save