Skip to content

Commit ffb23f1

Browse files
authored
update cypher query to use less memory (#6580)
* update cypher query to use less memory * update to handle UNWIND on empty list ending query
1 parent eabfeed commit ffb23f1

File tree

2 files changed

+67
-40
lines changed

2 files changed

+67
-40
lines changed

backend/infrahub/core/diff/query/save.py

Lines changed: 66 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -131,57 +131,74 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa
131131
OPTIONAL MATCH (diff_node)-[:DIFF_HAS_CONFLICT]->(node_conflict:DiffConflict)
132132
SET node_conflict = node_conflict_params
133133
}
134+
// -------------------------
135+
// resetting the UNWIND and starting over here reduces memory usage
136+
// -------------------------
137+
WITH root_uuid LIMIT 1
138+
UNWIND $node_details_list AS node_details
139+
WITH
140+
node_details.root_uuid AS root_uuid,
141+
node_details.node_map AS node_map,
142+
toString(node_details.node_map.node_properties.uuid) AS node_uuid,
143+
node_details.node_map.node_properties.db_id AS node_db_id
144+
MATCH (:DiffRoot {uuid: root_uuid})-[:DIFF_HAS_NODE]->(diff_node:DiffNode {uuid: node_uuid, db_id: node_db_id})
145+
WITH diff_node, node_map, %(attr_name_list_comp)s AS attr_names
146+
OPTIONAL MATCH (diff_node)-[:DIFF_HAS_ATTRIBUTE]->(attr_to_delete:DiffAttribute)
147+
WHERE NOT (attr_to_delete.name IN attr_names)
148+
OPTIONAL MATCH (attr_to_delete)-[*..6]->(next_to_delete)
149+
DETACH DELETE next_to_delete
150+
DETACH DELETE attr_to_delete
151+
// -------------------------
152+
// add attributes for this node
153+
// -------------------------
154+
WITH DISTINCT diff_node, node_map
134155
CALL (diff_node, node_map) {
135-
// -------------------------
136-
// remove stale attributes for this node
137-
// -------------------------
138-
CALL (diff_node, node_map) {
139-
WITH %(attr_name_list_comp)s AS attr_names
140-
OPTIONAL MATCH (diff_node)-[:DIFF_HAS_ATTRIBUTE]->(attr_to_delete:DiffAttribute)
141-
WHERE NOT (attr_to_delete.name IN attr_names)
142-
OPTIONAL MATCH (attr_to_delete)-[*..6]->(next_to_delete)
143-
DETACH DELETE next_to_delete
144-
DETACH DELETE attr_to_delete
145-
}
146-
// -------------------------
147-
// add attributes for this node
148-
// -------------------------
149156
UNWIND node_map.attributes AS node_attribute
150157
MERGE (diff_node)-[:DIFF_HAS_ATTRIBUTE]->(diff_attribute:DiffAttribute {name: node_attribute.node_properties.name})
151158
SET diff_attribute = node_attribute.node_properties
152159
// -------------------------
153-
// add properties for this attribute
160+
// remove stale properties for this attribute
154161
// -------------------------
155-
WITH diff_attribute, node_attribute
162+
WITH diff_attribute, node_attribute, %(attr_props_list_comp)s AS prop_types
163+
OPTIONAL MATCH (diff_attribute)-[:DIFF_HAS_PROPERTY]->(prop_to_delete:DiffProperty)
164+
WHERE NOT (prop_to_delete.property_type IN prop_types)
165+
OPTIONAL MATCH (prop_to_delete)-[*..4]->(next_to_delete)
166+
DETACH DELETE next_to_delete
167+
DETACH DELETE prop_to_delete
156168
// -------------------------
157-
// remove stale properties for this attribute
169+
// set attribute property values
158170
// -------------------------
159-
CALL (diff_attribute, node_attribute) {
160-
WITH %(attr_props_list_comp)s AS prop_types
161-
OPTIONAL MATCH (diff_attribute)-[:DIFF_HAS_PROPERTY]->(prop_to_delete:DiffProperty)
162-
WHERE NOT (prop_to_delete.property_type IN prop_types)
163-
OPTIONAL MATCH (prop_to_delete)-[*..4]->(next_to_delete)
164-
DETACH DELETE next_to_delete
165-
DETACH DELETE prop_to_delete
166-
}
171+
WITH DISTINCT diff_attribute, node_attribute
167172
UNWIND node_attribute.properties AS attr_property
168173
MERGE (diff_attribute)-[:DIFF_HAS_PROPERTY]->(diff_attr_prop:DiffProperty {property_type: attr_property.node_properties.property_type})
169174
SET diff_attr_prop = attr_property.node_properties
170-
// -------------------------
171-
// add/remove conflict for this property
172-
// -------------------------
173175
WITH diff_attr_prop, attr_property
174176
OPTIONAL MATCH (diff_attr_prop)-[:DIFF_HAS_CONFLICT]->(current_attr_prop_conflict:DiffConflict)
175177
WITH diff_attr_prop, attr_property, current_attr_prop_conflict, (attr_property.conflict_params IS NOT NULL) AS has_prop_conflict
176-
FOREACH (i in CASE WHEN has_prop_conflict = FALSE THEN [1] ELSE [] END |
178+
CALL (has_prop_conflict, current_attr_prop_conflict) {
179+
WITH has_prop_conflict, current_attr_prop_conflict
180+
WHERE has_prop_conflict = FALSE AND current_attr_prop_conflict IS NOT NULL
177181
DETACH DELETE current_attr_prop_conflict
178-
)
179-
FOREACH (i in CASE WHEN has_prop_conflict = TRUE THEN [1] ELSE [] END |
182+
}
183+
CALL (has_prop_conflict, diff_attr_prop, attr_property) {
184+
WITH has_prop_conflict
185+
WHERE has_prop_conflict = TRUE
180186
MERGE (diff_attr_prop)-[:DIFF_HAS_CONFLICT]->(diff_attr_prop_conflict:DiffConflict)
181187
SET diff_attr_prop_conflict = attr_property.conflict_params
182-
)
188+
}
183189
}
184190
// -------------------------
191+
// resetting the UNWIND and starting over here reduces memory usage
192+
// -------------------------
193+
WITH 1 AS resetting LIMIT 1
194+
UNWIND $node_details_list AS node_details
195+
WITH
196+
node_details.root_uuid AS root_uuid,
197+
node_details.node_map AS node_map,
198+
toString(node_details.node_map.node_properties.uuid) AS node_uuid,
199+
node_details.node_map.node_properties.db_id AS node_db_id
200+
MATCH (:DiffRoot {uuid: root_uuid})-[:DIFF_HAS_NODE]->(diff_node:DiffNode {uuid: node_uuid, db_id: node_db_id})
201+
// -------------------------
185202
// remove stale relationships for this node
186203
// -------------------------
187204
CALL (diff_node, node_map) {
@@ -226,13 +243,17 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa
226243
OPTIONAL MATCH (diff_relationship_element)-[:DIFF_HAS_CONFLICT]->(current_element_conflict:DiffConflict)
227244
WITH diff_relationship_element, node_single_relationship, current_element_conflict,
228245
(node_single_relationship.conflict_params IS NOT NULL) AS has_element_conflict
229-
FOREACH (i in CASE WHEN has_element_conflict = FALSE THEN [1] ELSE [] END |
246+
CALL (has_element_conflict, current_element_conflict) {
247+
WITH has_element_conflict
248+
WHERE has_element_conflict = FALSE
230249
DETACH DELETE current_element_conflict
231-
)
232-
FOREACH (i in CASE WHEN has_element_conflict = TRUE THEN [1] ELSE [] END |
250+
}
251+
CALL (has_element_conflict, diff_relationship_element, node_single_relationship) {
252+
WITH has_element_conflict
253+
WHERE has_element_conflict = TRUE
233254
MERGE (diff_relationship_element)-[:DIFF_HAS_CONFLICT]->(element_conflict:DiffConflict)
234255
SET element_conflict = node_single_relationship.conflict_params
235-
)
256+
}
236257
// -------------------------
237258
// remove stale properties for this relationship element
238259
// -------------------------
@@ -260,13 +281,18 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None: # noqa
260281
OPTIONAL MATCH (diff_relationship_property)-[:DIFF_HAS_CONFLICT]->(diff_relationship_property_conflict:DiffConflict)
261282
WITH diff_relationship_property, node_relationship_property, diff_relationship_property_conflict,
262283
(node_relationship_property.conflict_params IS NOT NULL) AS has_property_conflict
263-
FOREACH (i in CASE WHEN has_property_conflict = FALSE THEN [1] ELSE [] END |
284+
285+
CALL (has_property_conflict, diff_relationship_property_conflict) {
286+
WITH has_property_conflict
287+
WHERE has_property_conflict = FALSE
264288
DETACH DELETE diff_relationship_property_conflict
265-
)
266-
FOREACH (i in CASE WHEN has_property_conflict = TRUE THEN [1] ELSE [] END |
289+
}
290+
CALL (has_property_conflict, diff_relationship_property, node_relationship_property) {
291+
WITH has_property_conflict
292+
WHERE has_property_conflict = TRUE
267293
MERGE (diff_relationship_property)-[:DIFF_HAS_CONFLICT]->(property_conflict:DiffConflict)
268294
SET property_conflict = node_relationship_property.conflict_params
269-
)
295+
}
270296
""" % {
271297
"attr_name_list_comp": db.render_list_comprehension(
272298
items="node_map.attributes", item_name="node_properties.name"

changelog/6568.fixed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Update the cypher query that saves a diff to use less memory.

0 commit comments

Comments
 (0)