From: danielhanrahan Date: Wed, 21 Jun 2023 12:53:32 +0000 (+0100) Subject: Improve performance of updateDataLeaves X-Git-Tag: 3.3.3~23^2 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=8d08b0eebb1e6f002c29bc88a70c2a60e26d56ed;p=cps.git Improve performance of updateDataLeaves Avoid fetching descendants during batchUpdateDataLeaves, as descendants are not needed: - Remove prefetch descendants step from getFragmentEntities; - Explicitly prefetch descendants in operations requiring it; - Update performance tests (5x faster for batch update). Issue-ID: CPS-1675 Signed-off-by: danielhanrahan Change-Id: I7442a6f799cc0803b3a78f09d1ee53377f24b0b7 --- diff --git a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java index e6e250f08..7fed534b7 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/impl/CpsDataPersistenceServiceImpl.java @@ -243,14 +243,14 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService final Collection xpaths, final FetchDescendantsOption fetchDescendantsOption) { final AnchorEntity anchorEntity = getAnchorEntity(dataspaceName, anchorName); - final Collection fragmentEntities = - getFragmentEntities(anchorEntity, xpaths, fetchDescendantsOption); + Collection fragmentEntities = getFragmentEntities(anchorEntity, xpaths); + fragmentEntities = fragmentRepository.prefetchDescendantsOfFragmentEntities(fetchDescendantsOption, + fragmentEntities); return createDataNodesFromFragmentEntities(fetchDescendantsOption, fragmentEntities); } private Collection getFragmentEntities(final AnchorEntity anchorEntity, - final Collection xpaths, - final FetchDescendantsOption fetchDescendantsOption) { + final Collection xpaths) { final Collection nonRootXpaths = new HashSet<>(xpaths); final boolean haveRootXpath = nonRootXpaths.removeIf(CpsDataPersistenceServiceImpl::isRootXpath); @@ -266,10 +266,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService normalizedXpaths.addAll(fragmentRepository.findAllXpathByAnchorAndParentIdIsNull(anchorEntity)); } - final List fragmentEntities = fragmentRepository.findByAnchorAndXpathIn(anchorEntity, - normalizedXpaths); - - return fragmentRepository.prefetchDescendantsOfFragmentEntities(fetchDescendantsOption, fragmentEntities); + return fragmentRepository.findByAnchorAndXpathIn(anchorEntity, normalizedXpaths); } private FragmentEntity getFragmentEntity(final AnchorEntity anchorEntity, final String xpath) { @@ -407,8 +404,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService final AnchorEntity anchorEntity = getAnchorEntity(dataspaceName, anchorName); final Collection xpathsOfUpdatedLeaves = updatedLeavesPerXPath.keySet(); - final Collection fragmentEntities = getFragmentEntities(anchorEntity, xpathsOfUpdatedLeaves, - FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS); + final Collection fragmentEntities = getFragmentEntities(anchorEntity, xpathsOfUpdatedLeaves); for (final FragmentEntity fragmentEntity : fragmentEntities) { final Map updatedLeaves = updatedLeavesPerXPath.get(fragmentEntity.getXpath()); @@ -432,8 +428,9 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService .collect(Collectors.toMap(DataNode::getXpath, dataNode -> dataNode)); final Collection xpaths = xpathToUpdatedDataNode.keySet(); - final Collection existingFragmentEntities = - getFragmentEntities(anchorEntity, xpaths, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS); + Collection existingFragmentEntities = getFragmentEntities(anchorEntity, xpaths); + existingFragmentEntities = fragmentRepository.prefetchDescendantsOfFragmentEntities( + FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS, existingFragmentEntities); for (final FragmentEntity existingFragmentEntity : existingFragmentEntities) { final DataNode updatedDataNode = xpathToUpdatedDataNode.get(existingFragmentEntity.getXpath()); diff --git a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/UpdatePerfTest.groovy b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/UpdatePerfTest.groovy index b3c884127..6d856cc88 100644 --- a/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/UpdatePerfTest.groovy +++ b/integration-test/src/test/groovy/org/onap/cps/integration/performance/cps/UpdatePerfTest.groovy @@ -70,8 +70,8 @@ class UpdatePerfTest extends CpsPerfTestBase { objectUnderTest.updateNodeLeaves(CPS_PERFORMANCE_TEST_DATASPACE, 'openroadm3', "/openroadm-devices", jsonDataOriginal, now) stopWatch.stop() def updateDurationInMillis = stopWatch.getTotalTimeMillis() - then: 'update duration is under 750 milliseconds' - recordAndAssertPerformance('Update leaves for 1 data node', 750, updateDurationInMillis) + then: 'update duration is under 650 milliseconds' + recordAndAssertPerformance('Update leaves for 1 data node', 650, updateDurationInMillis) } def 'Batch update leaves for 50 data nodes'() { @@ -84,8 +84,8 @@ class UpdatePerfTest extends CpsPerfTestBase { objectUnderTest.updateNodeLeaves(CPS_PERFORMANCE_TEST_DATASPACE, 'openroadm4', "/openroadm-devices", jsonDataOriginal, now) stopWatch.stop() def updateDurationInMillis = stopWatch.getTotalTimeMillis() - then: 'update duration is under 3500 milliseconds' - recordAndAssertPerformance('Batch update leaves for 50 data nodes', 3500, updateDurationInMillis) + then: 'update duration is under 700 milliseconds' + recordAndAssertPerformance('Batch update leaves for 50 data nodes', 700, updateDurationInMillis) } }