From ed6c05157f60328b0215bde544f7a4e9894fd15f Mon Sep 17 00:00:00 2001 From: lukegleeson Date: Thu, 18 Aug 2022 17:47:24 +0100 Subject: Performance Improvement: Batch Update DataNodes Implemented methods to perform a batch operation on updating datanodes Refactored replace data node(s) tree methods to update data node(s) and descendants Issue-ID: CPS-1203 Signed-off-by: lukegleeson Change-Id: I365d657422b19c9ce384110c9a23d041eaed06f4 --- .../spi/impl/CpsDataPersistenceServiceImpl.java | 48 ++++++++++++++++------ 1 file changed, 36 insertions(+), 12 deletions(-) (limited to 'cps-ri/src/main/java') 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 9443355981..c4a2c2fe98 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 @@ -26,6 +26,7 @@ import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet.Builder; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -104,14 +105,16 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService final Collection newChildren) { final FragmentEntity parentFragmentEntity = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath); try { - for (final DataNode newChildAsDataNode : newChildren) { + final List fragmentEntities = new ArrayList<>(); + newChildren.forEach(newChildAsDataNode -> { final FragmentEntity newChildAsFragmentEntity = convertToFragmentWithAllDescendants( - parentFragmentEntity.getDataspace(), - parentFragmentEntity.getAnchor(), - newChildAsDataNode); + parentFragmentEntity.getDataspace(), + parentFragmentEntity.getAnchor(), + newChildAsDataNode); newChildAsFragmentEntity.setParentId(parentFragmentEntity.getId()); - fragmentRepository.save(newChildAsFragmentEntity); - } + fragmentEntities.add(newChildAsFragmentEntity); + }); + fragmentRepository.saveAll(fragmentEntities); } catch (final DataIntegrityViolationException exception) { final List conflictXpaths = newChildren.stream() .map(DataNode::getXpath) @@ -288,9 +291,10 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } @Override - public void replaceDataNodeTree(final String dataspaceName, final String anchorName, final DataNode dataNode) { + public void updateDataNodeAndDescendants(final String dataspaceName, final String anchorName, + final DataNode dataNode) { final FragmentEntity fragmentEntity = getFragmentByXpath(dataspaceName, anchorName, dataNode.getXpath()); - replaceDataNodeTree(fragmentEntity, dataNode); + updateFragmentEntityAndDescendantsWithDataNode(fragmentEntity, dataNode); try { fragmentRepository.save(fragmentEntity); } catch (final StaleStateException staleStateException) { @@ -301,8 +305,27 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService } } - private void replaceDataNodeTree(final FragmentEntity existingFragmentEntity, - final DataNode newDataNode) { + @Override + public void updateDataNodesAndDescendants(final String dataspaceName, + final String anchorName, + final List dataNodes) { + final Map dataNodeFragmentEntityMap = dataNodes.stream() + .collect(Collectors.toMap( + dataNode -> dataNode, dataNode -> getFragmentByXpath(dataspaceName, anchorName, dataNode.getXpath()))); + dataNodeFragmentEntityMap.forEach( + (dataNode, fragmentEntity) -> updateFragmentEntityAndDescendantsWithDataNode(fragmentEntity, dataNode)); + try { + fragmentRepository.saveAll(dataNodeFragmentEntityMap.values()); + } catch (final StaleStateException staleStateException) { + throw new ConcurrencyException("Concurrent Transactions", + String.format("A data node in dataspace :'%s' with Anchor : '%s' is updated by another transaction.", + dataspaceName, anchorName), + staleStateException); + } + } + + private void updateFragmentEntityAndDescendantsWithDataNode(final FragmentEntity existingFragmentEntity, + final DataNode newDataNode) { existingFragmentEntity.setAttributes(jsonObjectMapper.asJsonString(newDataNode.getLeaves())); @@ -318,10 +341,11 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService existingFragmentEntity.getDataspace(), existingFragmentEntity.getAnchor(), newDataNodeChild); } else { childFragment = existingChildrenByXpath.get(newDataNodeChild.getXpath()); - replaceDataNodeTree(childFragment, newDataNodeChild); + updateFragmentEntityAndDescendantsWithDataNode(childFragment, newDataNodeChild); } updatedChildFragments.add(childFragment); } + existingFragmentEntity.getChildFragments().clear(); existingFragmentEntity.getChildFragments().addAll(updatedChildFragments); } @@ -457,7 +481,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService copyAttributesFromNewListElement(existingListElementEntity, newListElement); existingListElementEntity.getChildFragments().clear(); } else { - replaceDataNodeTree(existingListElementEntity, newListElement); + updateFragmentEntityAndDescendantsWithDataNode(existingListElementEntity, newListElement); } return existingListElementEntity; } -- cgit 1.2.3-korg