package org.openlca.core.database; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * Provides the functionality for loading of data for a given set of IDs with a * minimal amount of queries but with block sizes of ID sets that are not * greater than the allowed maximum list size for queries (see * {@link BaseDao#MAX_LIST_SIZE}). */ public class BlockFetch<T> { private QueryFunction<T> func; public BlockFetch(QueryFunction<T> func) { this.func = func; } /** Creates a new BlockFetch and runs the given query function. */ public static <T> List<T> doFetch(List<Long> ids, QueryFunction<T> function) { BlockFetch<T> fetch = new BlockFetch<>(function); return fetch.doFetch(ids); } /** * Split the given IDs into chunks with a size not greater than * {@link Dao#MAX_LIST_SIZE}, run the queries and return the results. */ public List<T> doFetch(List<Long> ids) { if (ids == null || ids.isEmpty()) return Collections.emptyList(); List<Long> restToLoad = new ArrayList<>(ids); List<T> results = new ArrayList<>(); while (!restToLoad.isEmpty()) { int toPos = restToLoad.size() > BaseDao.MAX_LIST_SIZE ? BaseDao.MAX_LIST_SIZE : restToLoad.size(); List<Long> nextChunk = restToLoad.subList(0, toPos); List<T> chunkResults = func.fetchChunk(nextChunk); results.addAll(chunkResults); nextChunk.clear(); // clears also the elements in rest } return results; } /** * A function that does the query for a chunk of IDs. */ public interface QueryFunction<T> { List<T> fetchChunk(List<Long> ids); } }