package org.openlca.core.matrix; import java.util.Collections; import java.util.List; import java.util.Map; import org.openlca.core.matrix.cache.MatrixCache; import org.openlca.core.model.AllocationMethod; import org.openlca.core.model.FlowType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Builds a flow index from a product index and exchange table. All flows that * are not contained in the product index will be added to the flow index * (except if they are allocated co-products). */ class FlowIndexBuilder { private Logger log = LoggerFactory.getLogger(getClass()); private final MatrixCache cache; private final TechIndex techIndex; private final AllocationMethod allocationMethod; FlowIndexBuilder(MatrixCache cache, TechIndex techIndex, AllocationMethod allocationMethod) { this.allocationMethod = allocationMethod; this.cache = cache; this.techIndex = techIndex; } FlowIndex build() { FlowIndex index = new FlowIndex(); Map<Long, List<CalcExchange>> map = loadExchanges(); for (Long processId : techIndex.getProcessIds()) { List<CalcExchange> exchanges = map.get(processId); for (CalcExchange e : exchanges) { if (index.contains(e.flowId)) continue; // already indexed as flow if (techIndex.contains(LongPair.of(e.processId, e.flowId))) continue; // the exchange is an output product if (techIndex.isLinked(LongPair.of(e.processId, e.exchangeId))) continue; // the exchange is a linked exchange if (e.input || e.flowType == FlowType.ELEMENTARY_FLOW) indexFlow(e, index); else if (allocationMethod == null || allocationMethod == AllocationMethod.NONE) indexFlow(e, index); // non-allocated co-product -> handle // like elementary flow } } return index; } private Map<Long, List<CalcExchange>> loadExchanges() { try { Map<Long, List<CalcExchange>> map = cache.getExchangeCache() .getAll(techIndex.getProcessIds()); return map; } catch (Exception e) { log.error("failed to load exchanges from cache", e); return Collections.emptyMap(); } } private void indexFlow(CalcExchange e, FlowIndex index) { if (e.input) index.putInputFlow(e.flowId); else index.putOutputFlow(e.flowId); } }