From ad021691bb5296f203ddeaba41241d8ca1317414 Mon Sep 17 00:00:00 2001 From: danielhanrahan Date: Tue, 17 Sep 2024 20:50:29 +0100 Subject: Reduce anchor lookups related to PrefixResolver (CPS-2417 #1) Instead of looking up same Anchor many times inside a for-loop, do it once outside the loop. This greatly improves performance in some cases, such as v2 GET API: - /cps/api/v2/dataspaces/{dataspace}/anchors/{anchor}/node Testing shows 3x faster response time. Issue-ID: CPS-2417 Signed-off-by: danielhanrahan Change-Id: I80d97d8cc24372eed70626ed840cad985cbe0a4b --- .../cps/rest/controller/DataRestController.java | 11 ++++++++--- .../cps/rest/controller/QueryRestController.java | 21 +++++++++++++-------- 2 files changed, 21 insertions(+), 11 deletions(-) (limited to 'cps-rest/src/main') diff --git a/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java b/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java index 6015e0e3ae..f86073fb06 100755 --- a/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java +++ b/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2020-2022 Bell Canada. * Modifications Copyright (C) 2021 Pantheon.tech - * Modifications Copyright (C) 2021-2023 Nordix Foundation + * Modifications Copyright (C) 2021-2024 Nordix Foundation * Modifications Copyright (C) 2022-2024 TechMahindra Ltd. * Modifications Copyright (C) 2022 Deutsche Telekom AG * ================================================================================ @@ -37,9 +37,11 @@ import java.util.List; import java.util.Map; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; +import org.onap.cps.api.CpsAnchorService; import org.onap.cps.api.CpsDataService; import org.onap.cps.rest.api.CpsDataApi; import org.onap.cps.spi.FetchDescendantsOption; +import org.onap.cps.spi.model.Anchor; import org.onap.cps.spi.model.DataNode; import org.onap.cps.spi.model.DeltaReport; import org.onap.cps.utils.ContentType; @@ -63,6 +65,7 @@ public class DataRestController implements CpsDataApi { private static final DateTimeFormatter ISO_TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern(ISO_TIMESTAMP_FORMAT); private final CpsDataService cpsDataService; + private final CpsAnchorService cpsAnchorService; private final JsonObjectMapper jsonObjectMapper; private final PrefixResolver prefixResolver; @@ -112,7 +115,8 @@ public class DataRestController implements CpsDataApi { ? FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS : FetchDescendantsOption.OMIT_DESCENDANTS; final DataNode dataNode = cpsDataService.getDataNodes(dataspaceName, anchorName, xpath, fetchDescendantsOption).iterator().next(); - final String prefix = prefixResolver.getPrefix(dataspaceName, anchorName, dataNode.getXpath()); + final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName); + final String prefix = prefixResolver.getPrefix(anchor, dataNode.getXpath()); return new ResponseEntity<>(DataMapUtils.toDataMapWithIdentifier(dataNode, prefix), HttpStatus.OK); } @@ -127,8 +131,9 @@ public class DataRestController implements CpsDataApi { final Collection dataNodes = cpsDataService.getDataNodes(dataspaceName, anchorName, xpath, fetchDescendantsOption); final List> dataMaps = new ArrayList<>(dataNodes.size()); + final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName); for (final DataNode dataNode: dataNodes) { - final String prefix = prefixResolver.getPrefix(dataspaceName, anchorName, dataNode.getXpath()); + final String prefix = prefixResolver.getPrefix(anchor, dataNode.getXpath()); final Map dataMap = DataMapUtils.toDataMapWithIdentifier(dataNode, prefix); dataMaps.add(dataMap); } diff --git a/cps-rest/src/main/java/org/onap/cps/rest/controller/QueryRestController.java b/cps-rest/src/main/java/org/onap/cps/rest/controller/QueryRestController.java index 5334b48143..547be669ae 100644 --- a/cps-rest/src/main/java/org/onap/cps/rest/controller/QueryRestController.java +++ b/cps-rest/src/main/java/org/onap/cps/rest/controller/QueryRestController.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation + * Copyright (C) 2021-2024 Nordix Foundation * Modifications Copyright (C) 2022 Bell Canada. * Modifications Copyright (C) 2022-2023 TechMahindra Ltd. * ================================================================================ @@ -29,10 +29,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import lombok.RequiredArgsConstructor; +import org.onap.cps.api.CpsAnchorService; import org.onap.cps.api.CpsQueryService; import org.onap.cps.rest.api.CpsQueryApi; import org.onap.cps.spi.FetchDescendantsOption; import org.onap.cps.spi.PaginationOption; +import org.onap.cps.spi.model.Anchor; import org.onap.cps.spi.model.DataNode; import org.onap.cps.utils.DataMapUtils; import org.onap.cps.utils.JsonObjectMapper; @@ -48,6 +50,7 @@ import org.springframework.web.bind.annotation.RestController; public class QueryRestController implements CpsQueryApi { private final CpsQueryService cpsQueryService; + private final CpsAnchorService cpsAnchorService; private final JsonObjectMapper jsonObjectMapper; private final PrefixResolver prefixResolver; @@ -87,14 +90,15 @@ public class QueryRestController implements CpsQueryApi { cpsPath, fetchDescendantsOption, paginationOption); final List> dataNodesAsListOfMaps = new ArrayList<>(dataNodes.size()); String prefix = null; - final Map> anchorDataNodeListMap = prepareDataNodesForAnchor(dataNodes); - for (final Map.Entry> anchorDataNodesMapEntry : anchorDataNodeListMap.entrySet()) { + final Map> dataNodesPerAnchor = groupDataNodesPerAnchor(dataNodes); + for (final Map.Entry> dataNodesPerAnchorEntry : dataNodesPerAnchor.entrySet()) { + final String anchorName = dataNodesPerAnchorEntry.getKey(); if (prefix == null) { - prefix = prefixResolver.getPrefix(dataspaceName, anchorDataNodesMapEntry.getKey(), - anchorDataNodesMapEntry.getValue().get(0).getXpath()); + final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName); + prefix = prefixResolver.getPrefix(anchor, dataNodesPerAnchorEntry.getValue().get(0).getXpath()); } final Map dataMap = DataMapUtils.toDataMapWithIdentifierAndAnchor( - anchorDataNodesMapEntry.getValue(), anchorDataNodesMapEntry.getKey(), prefix); + dataNodesPerAnchorEntry.getValue(), anchorName, prefix); dataNodesAsListOfMaps.add(dataMap); } final Integer totalPages = getTotalPages(dataspaceName, cpsPath, paginationOption); @@ -112,7 +116,7 @@ public class QueryRestController implements CpsQueryApi { : (int) Math.ceil((double) totalAnchors / paginationOption.getPageSize()); } - private Map> prepareDataNodesForAnchor(final Collection dataNodes) { + private Map> groupDataNodesPerAnchor(final Collection dataNodes) { final Map> dataNodesMapForAnchor = new HashMap<>(); for (final DataNode dataNode : dataNodes) { List dataNodesInAnchor = dataNodesMapForAnchor.get(dataNode.getAnchorName()); @@ -130,10 +134,11 @@ public class QueryRestController implements CpsQueryApi { final Collection dataNodes = cpsQueryService.queryDataNodes(dataspaceName, anchorName, cpsPath, fetchDescendantsOption); final List> dataNodesAsListOfMaps = new ArrayList<>(dataNodes.size()); + final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName); String prefix = null; for (final DataNode dataNode : dataNodes) { if (prefix == null) { - prefix = prefixResolver.getPrefix(dataspaceName, anchorName, dataNode.getXpath()); + prefix = prefixResolver.getPrefix(anchor, dataNode.getXpath()); } final Map dataMap = DataMapUtils.toDataMapWithIdentifier(dataNode, prefix); dataNodesAsListOfMaps.add(dataMap); -- cgit 1.2.3-korg