package org.openlca.core.matrix; import java.sql.Connection; import java.sql.ResultSet; import java.util.Collections; import java.util.List; import java.util.Map; import org.openlca.core.matrix.cache.MatrixCache; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.primitives.Longs; class ImpactTableBuilder { private Logger log = LoggerFactory.getLogger(getClass()); private final MatrixCache cache; private final long methodId; private final FlowIndex flowIndex; ImpactTableBuilder(MatrixCache cache, long impactMethodId, FlowIndex flowIndex) { this.cache = cache; this.methodId = impactMethodId; this.flowIndex = flowIndex; } ImpactTable build() { log.trace("Build impact factor matrix for method {}", methodId); LongIndex categoryIndex = buildCategoryIndex(); if (categoryIndex.isEmpty() || flowIndex.isEmpty()) return null; ImpactTable table = new ImpactTable(); table.categoryIndex = categoryIndex; table.flowIndex = flowIndex; ImpactFactorMatrix matrix = new ImpactFactorMatrix( categoryIndex.size(), flowIndex.size()); table.factorMatrix = matrix; fill(matrix, categoryIndex); log.trace("Impact factor matrix ready"); return table; } private LongIndex buildCategoryIndex() { LongIndex index = new LongIndex(); try (Connection con = cache.getDatabase().createConnection()) { String query = "select id from tbl_impact_categories where f_impact_method = " + methodId; ResultSet result = con.createStatement().executeQuery(query); while (result.next()) { long id = result.getLong("id"); index.put(id); } result.close(); } catch (Exception e) { log.error("failed to build impact category index", e); } return index; } private void fill(ImpactFactorMatrix matrix, LongIndex categoryIndex) { Map<Long, List<CalcImpactFactor>> factorMap = loadFactors(categoryIndex); for (int row = 0; row < categoryIndex.size(); row++) { long categoryId = categoryIndex.getKeyAt(row); List<CalcImpactFactor> factors = factorMap.get(categoryId); if (factors == null) continue; for (CalcImpactFactor factor : factors) { long flowId = factor.getFlowId(); int col = flowIndex.getIndex(flowId); if (col < 0) continue; boolean input = flowIndex.isInput(flowId); ImpactFactorCell cell = new ImpactFactorCell(factor, methodId, input); matrix.setEntry(row, col, cell); } } } private Map<Long, List<CalcImpactFactor>> loadFactors( LongIndex categoryIndex) { try { return cache.getImpactCache().getAll( Longs.asList(categoryIndex.getKeys())); } catch (Exception e) { log.error("failed to load impact factors"); return Collections.emptyMap(); } } }