Skip to content

Commit 593af5d

Browse files
SlimaneAmarSlimane AMAR
andauthored
Use a sql recursive query for node tree invalidation and dto tree building (#791)
Co-authored-by: Slimane AMAR <[email protected]>
1 parent 6ab00a9 commit 593af5d

File tree

8 files changed

+108
-86
lines changed

8 files changed

+108
-86
lines changed

src/main/java/org/gridsuite/study/server/repository/networkmodificationtree/NodeRepository.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,32 @@ public interface NodeRepository extends JpaRepository<NodeEntity, UUID> {
2929
List<NodeEntity> findAllByStudyIdAndTypeAndStashed(UUID id, NodeType type, boolean stashed);
3030

3131
@Query(nativeQuery = true, value =
32-
"WITH RECURSIVE NodeHierarchy (id_node, depth) AS ( " +
33-
" SELECT n0.id_node, 0 AS depth" +
32+
"WITH RECURSIVE NodeHierarchy (id_node) AS ( " +
33+
" SELECT n0.id_node" +
3434
" FROM NODE n0 " +
3535
" WHERE id_node = :nodeUuid " +
3636
" UNION ALL " +
37-
" SELECT n.id_node, nh.depth + 1 as depth" +
37+
" SELECT n.id_node" +
3838
" FROM NODE n " +
3939
" INNER JOIN NodeHierarchy nh ON n.parent_node = nh.id_node " +
4040
") " +
41-
"SELECT nh.id_node::text " +
42-
"FROM NodeHierarchy nh " +
43-
"ORDER BY nh.depth DESC")
44-
List<String> findAllDescendants(UUID nodeUuid);
41+
"SELECT cast(nh.id_node AS VARCHAR) " +
42+
"FROM NodeHierarchy nh where nh.id_node != :nodeUuid ")
43+
List<UUID> findAllChildrenUuids(UUID nodeUuid);
4544

46-
List<NodeEntity> findAllByIdNodeIn(List<UUID> uuids);
45+
@Query(nativeQuery = true, value =
46+
"WITH RECURSIVE NodeHierarchy (id_node) AS ( " +
47+
" SELECT n0.id_node" +
48+
" FROM NODE n0 " +
49+
" WHERE id_node = :nodeUuid " +
50+
" UNION ALL " +
51+
" SELECT n.id_node" +
52+
" FROM NODE n " +
53+
" INNER JOIN NodeHierarchy nh ON n.parent_node = nh.id_node " +
54+
") " +
55+
"SELECT * FROM NODE n " +
56+
"WHERE n.id_node IN (SELECT nh.id_node FROM NodeHierarchy nh) AND n.id_node != :nodeUuid")
57+
List<NodeEntity> findAllChildren(UUID nodeUuid);
4758

4859
List<NodeEntity> findAllByStudyIdAndStashedAndParentNodeIdNodeOrderByStashDateDesc(UUID id, boolean stashed, UUID parentNode);
4960

src/main/java/org/gridsuite/study/server/repository/rootnetwork/RootNetworkNodeInfoRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,6 @@ public interface RootNetworkNodeInfoRepository extends JpaRepository<RootNetwork
5757
@Query("select count(rnni) > 0 from RootNetworkNodeInfoEntity rnni LEFT JOIN rnni.rootNetwork rn LEFT JOIN rn.study s " +
5858
"where s.id = :studyUuid and (rnni.nodeBuildStatus.globalBuildStatus = :buildStatus or rnni.nodeBuildStatus.localBuildStatus = :buildStatus)")
5959
boolean existsByStudyUuidAndBuildStatus(UUID studyUuid, BuildStatus buildStatus);
60+
61+
List<RootNetworkNodeInfoEntity> getAllByRootNetworkIdAndNodeInfoIdIn(UUID rootNetworkUuid, List<UUID> nodesUuids);
6062
}

src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ private NetworkModificationNode createAndInsertNode(StudyEntity study, UUID node
128128
if (insertMode.equals(InsertMode.BEFORE)) {
129129
reference.setParentNode(node);
130130
} else if (insertMode.equals(InsertMode.AFTER)) {
131-
nodesRepository.findAllByParentNodeIdNode(nodeId).stream()
131+
getChildren(nodeId).stream()
132132
.filter(n -> !n.getIdNode().equals(node.getIdNode()))
133133
.forEach(child -> child.setParentNode(node));
134134
}
@@ -238,7 +238,7 @@ public void moveStudyNode(UUID nodeToMoveUuid, UUID anchorNodeUuid, InsertMode i
238238
private UUID moveNode(UUID nodeToMoveUuid, UUID anchorNodeUuid, InsertMode insertMode) {
239239
NodeEntity nodeToMoveEntity = getNodeEntity(nodeToMoveUuid);
240240

241-
nodesRepository.findAllByParentNodeIdNode(nodeToMoveUuid)
241+
getChildren(nodeToMoveUuid)
242242
.forEach(child -> child.setParentNode(nodeToMoveEntity.getParentNode()));
243243

244244
NodeEntity anchorNodeEntity = getNodeEntity(anchorNodeUuid);
@@ -253,7 +253,7 @@ private UUID moveNode(UUID nodeToMoveUuid, UUID anchorNodeUuid, InsertMode inser
253253
if (insertMode.equals(InsertMode.BEFORE)) {
254254
anchorNodeEntity.setParentNode(nodeToMoveEntity);
255255
} else if (insertMode.equals(InsertMode.AFTER)) {
256-
nodesRepository.findAllByParentNodeIdNode(anchorNodeUuid).stream()
256+
getChildren(anchorNodeUuid).stream()
257257
.filter(n -> !n.getIdNode().equals(nodeToMoveEntity.getIdNode()))
258258
.forEach(child -> child.setParentNode(nodeToMoveEntity));
259259
}
@@ -264,7 +264,7 @@ private UUID moveNode(UUID nodeToMoveUuid, UUID anchorNodeUuid, InsertMode inser
264264

265265
@Transactional
266266
public void moveStudySubtree(UUID parentNodeToMoveUuid, UUID anchorNodeUuid) {
267-
List<NodeEntity> children = getChildrenByParentUuid(parentNodeToMoveUuid);
267+
List<NodeEntity> children = getChildren(parentNodeToMoveUuid);
268268
moveNode(parentNodeToMoveUuid, anchorNodeUuid, InsertMode.CHILD);
269269
children.forEach(child -> self.moveStudySubtree(child.getIdNode(), parentNodeToMoveUuid));
270270
}
@@ -299,9 +299,9 @@ private void stashNodes(UUID id, boolean stashChildren, List<UUID> stashedNodes,
299299
UUID modificationGroupUuid = self.getModificationGroupUuid(nodeToStash.getIdNode());
300300
networkModificationService.deleteStashedModifications(modificationGroupUuid);
301301
if (!stashChildren) {
302-
nodesRepository.findAllByParentNodeIdNode(id).forEach(node -> node.setParentNode(nodeToStash.getParentNode()));
302+
getChildren(id).forEach(node -> node.setParentNode(nodeToStash.getParentNode()));
303303
} else {
304-
nodesRepository.findAllByParentNodeIdNode(id)
304+
getChildren(id)
305305
.forEach(child -> stashNodes(child.getIdNode(), true, stashedNodes, false));
306306
}
307307
stashedNodes.add(id);
@@ -329,9 +329,9 @@ private void deleteNodes(UUID id, boolean deleteChildren, boolean allowDeleteRoo
329329
rootNetworkNodeInfoService.fillDeleteNodeInfo(id, deleteNodeInfos);
330330

331331
if (!deleteChildren) {
332-
nodesRepository.findAllByParentNodeIdNode(id).forEach(node -> node.setParentNode(nodeToDelete.getParentNode()));
332+
getChildren(id).forEach(node -> node.setParentNode(nodeToDelete.getParentNode()));
333333
} else {
334-
nodesRepository.findAllByParentNodeIdNode(id)
334+
getChildren(id)
335335
.forEach(child -> deleteNodes(child.getIdNode(), true, false, removedNodes, deleteNodeInfos));
336336
}
337337
removedNodes.add(id);
@@ -344,12 +344,28 @@ private void deleteNodes(UUID id, boolean deleteChildren, boolean allowDeleteRoo
344344
});
345345
}
346346

347-
public List<NodeEntity> getChildrenByParentUuid(UUID parentUuid) {
347+
public List<NodeEntity> getChildren(UUID parentUuid) {
348348
return nodesRepository.findAllByParentNodeIdNode(parentUuid);
349349
}
350350

351-
public List<String> getAllChildrenFromParentUuid(UUID parentUuid) {
352-
return nodesRepository.findAllDescendants(parentUuid);
351+
public List<UUID> getAllChildrenUuids(UUID parentUuid) {
352+
return nodesRepository.findAllChildrenUuids(parentUuid);
353+
}
354+
355+
// TODO Remove this method and use getAllChildrenUuids
356+
public List<UUID> getChildrenUuids(UUID parentUuid) {
357+
List<UUID> children = new ArrayList<>();
358+
doGetChildrenUuids(parentUuid, children);
359+
return children;
360+
}
361+
362+
private void doGetChildrenUuids(UUID parentUuid, List<UUID> children) {
363+
Optional<NodeEntity> optNode = nodesRepository.findById(parentUuid);
364+
optNode.ifPresent(node -> getChildren(parentUuid)
365+
.forEach(child -> {
366+
children.add(child.getIdNode());
367+
doGetChildrenUuids(child.getIdNode(), children);
368+
}));
353369
}
354370

355371
@Transactional
@@ -411,10 +427,7 @@ private void completeNodeInfos(List<AbstractNode> nodes, UUID rootNetworkUuid) {
411427

412428
@Transactional
413429
public AbstractNode getStudySubtree(UUID studyId, UUID parentNodeUuid, UUID rootNetworkUuid) {
414-
// TODO: not working because of proxy appearing in tests TOFIX later
415-
// List<UUID> nodeUuids = nodesRepository.findAllDescendants(parentNodeUuid).stream().map(UUID::fromString).toList();
416-
// List<NodeEntity> nodes = nodesRepository.findAllById(nodeUuids);
417-
List<NodeEntity> nodes = nodesRepository.findAllByStudyId(studyId);
430+
List<NodeEntity> nodes = nodesRepository.findAllChildren(parentNodeUuid);
418431

419432
List<AbstractNode> allNodeInfos = new ArrayList<>();
420433
allNodeInfos.addAll(rootNodeInfoRepository.findAllByNodeStudyId(studyId).stream().map(RootNodeInfoEntity::toDto).toList());
@@ -561,7 +574,7 @@ private AbstractNode getSimpleNode(UUID nodeId) {
561574
@Transactional
562575
public AbstractNode getNode(UUID nodeId, UUID rootNetworkUuid) {
563576
AbstractNode node = getSimpleNode(nodeId);
564-
nodesRepository.findAllByParentNodeIdNode(node.getId()).stream().map(NodeEntity::getIdNode).forEach(node.getChildrenIds()::add);
577+
getChildren(node.getId()).stream().map(NodeEntity::getIdNode).forEach(node.getChildrenIds()::add);
565578
if (rootNetworkUuid != null) {
566579
completeNodeInfos(List.of(node), rootNetworkUuid);
567580
}
@@ -691,7 +704,7 @@ public List<Pair<AbstractNode, Integer>> getStashedNodes(UUID studyUuid) {
691704
nodes.stream().map(node -> networkModificationNodeInfos.get(node.getIdNode()))
692705
.forEach(abstractNode -> {
693706
ArrayList<UUID> children = new ArrayList<>();
694-
doGetChildren(abstractNode.getId(), children);
707+
doGetChildrenUuids(abstractNode.getId(), children);
695708
result.add(Pair.of(abstractNode, children.size()));
696709
});
697710
return result;
@@ -746,7 +759,7 @@ public Map<UUID, UUID> getModificationReports(UUID nodeUuid, UUID rootNetworkUui
746759
}
747760

748761
private void restoreNodeChildren(UUID studyId, UUID parentNodeId) {
749-
nodesRepository.findAllByParentNodeIdNode(parentNodeId).forEach(nodeEntity -> {
762+
getChildren(parentNodeId).forEach(nodeEntity -> {
750763
NetworkModificationNodeInfoEntity modificationNodeToRestore = networkModificationNodeInfoRepository.findById(nodeEntity.getIdNode()).orElseThrow(() -> new StudyException(NODE_NOT_FOUND));
751764
if (self.isNodeNameExists(studyId, modificationNodeToRestore.getName())) {
752765
String newName = getSuffixedNodeName(studyId, modificationNodeToRestore.getName());
@@ -883,7 +896,7 @@ private boolean hasAnyBuiltChildren(NodeEntity node, UUID rootNetworkUuid, Set<N
883896
}
884897
checkedChildren.add(node);
885898

886-
for (NodeEntity child : getChildrenByParentUuid(node.getIdNode())) {
899+
for (NodeEntity child : getChildren(node.getIdNode())) {
887900
if (!checkedChildren.contains(child)
888901
&& hasAnyBuiltChildren(child, rootNetworkUuid, checkedChildren)) {
889902
return true;
@@ -919,11 +932,12 @@ private void fillIndexedNodeTreeInfosToInvalidate(NodeEntity nodeEntity, UUID ro
919932

920933
private InvalidateNodeInfos invalidateChildrenNodes(UUID nodeUuid, UUID rootNetworkUuid) {
921934
InvalidateNodeInfos invalidateNodeInfos = new InvalidateNodeInfos();
922-
nodesRepository.findAllByParentNodeIdNode(nodeUuid)
923-
.forEach(child -> {
924-
invalidateNodeInfos.add(rootNetworkNodeInfoService.invalidateRootNetworkNode(child.getIdNode(), rootNetworkUuid, InvalidateNodeTreeParameters.ALL));
925-
invalidateNodeInfos.add(invalidateChildrenNodes(child.getIdNode(), rootNetworkUuid));
926-
});
935+
List<RootNetworkNodeInfoEntity> rootNetworkNodeInfoEntities = rootNetworkNodeInfoService.getRootNetworkNodes(rootNetworkUuid, getAllChildrenUuids(nodeUuid));
936+
937+
rootNetworkNodeInfoEntities.forEach(child ->
938+
invalidateNodeInfos.add(rootNetworkNodeInfoService.invalidateRootNetworkNode(child, InvalidateNodeTreeParameters.ALL))
939+
);
940+
927941
return invalidateNodeInfos;
928942
}
929943

@@ -1010,21 +1024,6 @@ public Boolean isReadOnly(UUID nodeUuid) {
10101024
return getNodeInfoEntity(nodeUuid).getReadOnly();
10111025
}
10121026

1013-
public List<UUID> getChildren(UUID id) {
1014-
List<UUID> children = new ArrayList<>();
1015-
doGetChildren(id, children);
1016-
return children;
1017-
}
1018-
1019-
private void doGetChildren(UUID id, List<UUID> children) {
1020-
Optional<NodeEntity> optNode = nodesRepository.findById(id);
1021-
optNode.ifPresent(node -> nodesRepository.findAllByParentNodeIdNode(id)
1022-
.forEach(child -> {
1023-
children.add(child.getIdNode());
1024-
doGetChildren(child.getIdNode(), children);
1025-
}));
1026-
}
1027-
10281027
// only used for tests
10291028
@Transactional
10301029
public UUID getParentNode(UUID nodeUuid, NodeType nodeType) {
@@ -1060,7 +1059,7 @@ private void fillIndexedNodeInfosToInvalidate(UUID parentNodeUuid, boolean inclu
10601059
if (includeParentNode) {
10611060
nodesToInvalidate.add(parentNodeUuid);
10621061
}
1063-
nodesToInvalidate.addAll(getChildren(parentNodeUuid));
1062+
nodesToInvalidate.addAll(getAllChildrenUuids(parentNodeUuid));
10641063
invalidateNodeInfos.addGroupUuids(
10651064
networkModificationNodeInfoRepository.findAllById(nodesToInvalidate).stream()
10661065
.map(NetworkModificationNodeInfoEntity::getModificationGroupUuid).toList()

src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,10 @@ public void fillDeleteNodeInfo(UUID nodeUuid, DeleteNodeInfos deleteNodeInfos) {
234234

235235
public InvalidateNodeInfos invalidateRootNetworkNode(UUID nodeUuid, UUID rootNetworUuid, InvalidateNodeTreeParameters invalidateTreeParameters) {
236236
RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity = rootNetworkNodeInfoRepository.findByNodeInfoIdAndRootNetworkId(nodeUuid, rootNetworUuid).orElseThrow(() -> new StudyException(ROOT_NETWORK_NOT_FOUND));
237+
return invalidateRootNetworkNode(rootNetworkNodeInfoEntity, invalidateTreeParameters);
238+
}
237239

240+
public InvalidateNodeInfos invalidateRootNetworkNode(RootNetworkNodeInfoEntity rootNetworkNodeInfoEntity, InvalidateNodeTreeParameters invalidateTreeParameters) {
238241
// No need to invalidate a node with a status different of "BUILT"
239242
if (!rootNetworkNodeInfoEntity.getNodeBuildStatus().toDto().isBuilt()) {
240243
return new InvalidateNodeInfos();
@@ -358,6 +361,10 @@ public List<UUID> getComputationResultUuids(UUID studyUuid, ComputationType comp
358361
.toList();
359362
}
360363

364+
public List<RootNetworkNodeInfoEntity> getRootNetworkNodes(UUID rootNetworkUuid, List<UUID> nodesUuids) {
365+
return rootNetworkNodeInfoRepository.getAllByRootNetworkIdAndNodeInfoIdIn(rootNetworkUuid, nodesUuids);
366+
}
367+
361368
public List<RootNetworkNodeInfoEntity> getAllByStudyUuidWithLoadFlowResultsNotNull(UUID studyUuid) {
362369
return rootNetworkNodeInfoRepository.findAllByRootNetworkStudyIdAndLoadFlowResultUuidNotNull(studyUuid);
363370
}

0 commit comments

Comments
 (0)