Skip to end of metadata
Go to start of metadata

You are viewing an old version of this content. View the current version.

Compare with Current View Version History

Version 1 Next »

Background

Repository queries taking collection parameters are limited to 32K collection items. (This is caused by Hibernate PostgreSQL driver having limit of 32767 bind variables per statement.)
For example, org.onap.cps.spi.repository.FragmentRepository#deleteByAnchorIn:

    Collection<AnchorEntity> findAllByDataspaceAndNameIn(DataspaceEntity dataspaceEntity, Collection<String> anchorNames);

 This would throw an exception if supplied with a collection of 32,768 items.

CPS-1574 is to remove those limits (and write tests to verify).

Proposal #1: List partitioning

This solution partitions the input collection into lists of 32,000 and calls the original repository method, collecting the results:

    Collection<AnchorEntity> findAllByDataspaceAndNameIn(DataspaceEntity dataspaceEntity, Collection<String> anchorNames); 

    default Collection<AnchorEntity> findAllByDataspaceAndNameInBatch(final DataspaceEntity dataspaceEntity,
                                                                      final List<String> anchorNames) {
        Collection<AnchorEntity> results = new ArrayList<>(anchorNames.size());
        for (final Collection<String> anchorNamesBatch : Lists.partition(anchorNames, 32000)) {
            results.addAll(findAllByDataspaceAndNameIn(dataspaceEntity, anchorNamesBatch));
        }
        return results;
    }

In addition, if we wish to avoid the overhead of adding the results to a collection when not needed, we may directly call the original when the collection size is less than 32,000:

    Collection<AnchorEntity> findAllByDataspaceAndNameIn(DataspaceEntity dataspaceEntity, Collection<String> anchorNames); 

    default Collection<AnchorEntity> findAllByDataspaceAndNameInBatch(final DataspaceEntity dataspaceEntity,
                                                                      final List<String> anchorNames) {
        if (anchorNames.size() < 32000) {
            return findAllByDataspaceAndNameIn(dataspaceEntity, anchorNames);
        }
        Collection<AnchorEntity> results = new ArrayList<>(anchorNames.size());
        for (final Collection<String> anchorNamesBatch : Lists.partition(anchorNames, 32000)) {
            results.addAll(findAllByDataspaceAndNameIn(dataspaceEntity, anchorNamesBatch));
        }
        return results;
    }

Proposal #2: PostGres arrays


Comparison


  • No labels