Skip to content

Commit

Permalink
Faster module searches (CPS-2190 #3)
Browse files Browse the repository at this point in the history
This greatly improves performance of module searches by eliminating
unneeded SQL queries via Hibernate lazy fetching.

Issue-ID: CPS-2190
Signed-off-by: danielhanrahan <[email protected]>
Change-Id: Ie9e65017d0027366456f1741cc37b10679317b25
  • Loading branch information
danielhanrahan committed Apr 26, 2024
1 parent 2b979f6 commit 2830723
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,10 @@ public Collection<Anchor> getAnchors(final String dataspaceName, final Collectio
}

@Override
public Collection<Anchor> queryAnchors(final String dataspaceName, final Collection<String> inputModuleNames) {
public Collection<String> queryAnchorNames(final String dataspaceName, final Collection<String> inputModuleNames) {
final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
final Collection<AnchorEntity> anchorEntities = anchorRepository
.getAnchorsByDataspaceIdAndModuleNames(dataspaceEntity.getId(), inputModuleNames, inputModuleNames.size());
return anchorEntities.stream().map(CpsAdminPersistenceServiceImpl::toAnchor).collect(Collectors.toSet());
return anchorRepository.getAnchorNamesByDataspaceIdAndModuleNames(dataspaceEntity.getId(), inputModuleNames,
inputModuleNames.size());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ default Collection<AnchorEntity> findAllByDataspaceAndSchemaSetNameIn(final Data

@Query(value = """
SELECT
anchor.*
anchor.name
FROM
yang_resource
JOIN schema_set_yang_resources ON schema_set_yang_resources.yang_resource_id = yang_resource.id
Expand All @@ -89,15 +89,15 @@ default Collection<AnchorEntity> findAllByDataspaceAndSchemaSetNameIn(final Data
HAVING
COUNT(DISTINCT module_name) = :sizeOfModuleNames
""", nativeQuery = true)
Collection<AnchorEntity> getAnchorsByDataspaceIdAndModuleNames(@Param("dataspaceId") int dataspaceId,
@Param("moduleNames") String[] moduleNames,
@Param("sizeOfModuleNames") int sizeOfModuleNames);
Collection<String> getAnchorNamesByDataspaceIdAndModuleNames(@Param("dataspaceId") int dataspaceId,
@Param("moduleNames") String[] moduleNames,
@Param("sizeOfModuleNames") int sizeOfModuleNames);

default Collection<AnchorEntity> getAnchorsByDataspaceIdAndModuleNames(final int dataspaceId,
final Collection<String> moduleNames,
final int sizeOfModuleNames) {
default Collection<String> getAnchorNamesByDataspaceIdAndModuleNames(final int dataspaceId,
final Collection<String> moduleNames,
final int sizeOfModuleNames) {
final String[] moduleNamesArray = moduleNames.toArray(new String[0]);
return getAnchorsByDataspaceIdAndModuleNames(dataspaceId, moduleNamesArray, sizeOfModuleNames);
return getAnchorNamesByDataspaceIdAndModuleNames(dataspaceId, moduleNamesArray, sizeOfModuleNames);
}

@Modifying
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
package org.onap.cps.api.impl;

import java.util.Collection;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.onap.cps.api.CpsAnchorService;
import org.onap.cps.spi.CpsAdminPersistenceService;
Expand Down Expand Up @@ -87,8 +86,7 @@ public void deleteAnchors(final String dataspaceName, final Collection<String> a
@Override
public Collection<String> queryAnchorNames(final String dataspaceName, final Collection<String> moduleNames) {
cpsValidator.validateNameCharacters(dataspaceName);
final Collection<Anchor> anchors = cpsAdminPersistenceService.queryAnchors(dataspaceName, moduleNames);
return anchors.stream().map(Anchor::getName).collect(Collectors.toList());
return cpsAdminPersistenceService.queryAnchorNames(dataspaceName, moduleNames);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public interface CpsAdminPersistenceService {
* @return a collection of anchor names in the given dataspace. The schema set for each anchor must include all the
* given module names
*/
Collection<Anchor> queryAnchors(String dataspaceName, Collection<String> moduleNames);
Collection<String> queryAnchorNames(String dataspaceName, Collection<String> moduleNames);

/**
* Get an anchor in the given dataspace using the anchor name.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class CpsAnchorServiceImplSpec extends Specification {

def 'Query all anchor identifiers for a dataspace and module names.'() {
given: 'the persistence service is invoked with the expected parameters and returns a list of anchors'
mockCpsAdminPersistenceService.queryAnchors('some-dataspace-name', ['some-module-name']) >> [new Anchor(name:'some-anchor-identifier')]
mockCpsAdminPersistenceService.queryAnchorNames('some-dataspace-name', ['some-module-name']) >> ['some-anchor-identifier']
when: 'query anchor names is called using a dataspace name and module name'
def result = objectUnderTest.queryAnchorNames('some-dataspace-name', ['some-module-name'])
then: 'get anchor identifiers returns the same anchor identifier returned by the persistence layer'
Expand All @@ -130,7 +130,7 @@ class CpsAnchorServiceImplSpec extends Specification {
def 'Query all anchors with Module Names Not Found Exception in persistence layer.'() {
given: 'the persistence layer throws a Module Names Not Found Exception'
def originalException = new ModuleNamesNotFoundException('exception-ds', ['m1', 'm2'])
mockCpsAdminPersistenceService.queryAnchors(*_) >> { throw originalException}
mockCpsAdminPersistenceService.queryAnchorNames(*_) >> { throw originalException}
when: 'attempt query anchors'
objectUnderTest.queryAnchorNames('some-dataspace-name', [])
then: 'the same exception is thrown (up)'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@ class ModuleQueryPerfTest extends CpsPerfTestBase {
and: 'operation completes with expected resource usage'
recordAndAssertResourceUsage("Query for anchors with ${scenario}",
expectedTimeInSeconds, resourceMeter.totalTimeInSeconds,
150, resourceMeter.totalMemoryUsageInMB)
5, resourceMeter.totalMemoryUsageInMB)
where: 'the following parameters are used'
scenario | yangModuleName || expectedTimeInSeconds
'1 KB module' | 'module0' || 3
'1000 KB module' | 'module1' || 3
'1 KB module' | 'module0' || 0.05
'1000 KB module' | 'module1' || 0.05
}
def 'Module query - Clean up test data.'() {
Expand Down

0 comments on commit 2830723

Please sign in to comment.