package org.openlca.core.matrix;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* The TechIndex maps the linked product-outputs and waste-inputs (provider-flow
* pairs) of a product system to a matrix index that is used in the calculation
* and results. It also contains the process links of that product system.
*/
public class TechIndex {
/**
* Maps the product-outputs and waste-inputs as (processId, flowId) pairs to
* an ordinal index.
*/
private final HashMap<LongPair, Integer> index = new HashMap<>();
/**
* Contains the product-outputs and waste-inputs in an ordinal list.
*/
private final ArrayList<LongPair> providers = new ArrayList<>();
/**
* Maps linked exchanges (keys) as (processId, exchangeId) pairs to the
* respective provider.
*/
private final HashMap<LongPair, LongPair> links = new HashMap<>();
/**
* Maps the process IDs to the list of product-outputs and waste-inputs
* provided by the respective process.
*/
private final HashMap<Long, List<LongPair>> processProviders = new HashMap<>();
/**
* The demand value of the reference flow of the product system described by
* this index. The value is given in the reference unit and quantity of the
* respective flow.
*/
private double demand = 1d;
/**
* Creates a new technosphere index of a product system.
*
* @param refFlow
* the reference product-output or waste-input as (processId,
* flowId) pair.
*/
public TechIndex(LongPair refFlow) {
put(refFlow);
}
/**
* The demand value. This is the amount of the reference flow given in the
* reference unit and flow property. The default value is 1.0.
*/
public void setDemand(double demand) {
this.demand = demand;
}
/**
* Get the reference product-output or waste-input of the product system
* described by this index.
*/
public LongPair getRefFlow() {
return providers.get(0);
}
/**
* The demand value. This is the amount of the reference flow given in the
* reference unit and flow property. The default value is 1.0.
*/
public double getDemand() {
return demand;
}
/**
* Returns the size of this index which is equal to the number of rows and
* columns in the related technology matrix.
*/
public int size() {
return index.size();
}
/**
* Returns the ordinal index of the given provider (product-output or waste
* input).
*/
public int getIndex(LongPair provider) {
Integer idx = index.get(provider);
if (idx == null)
return -1;
return idx;
}
/**
* Returns true if the given provider (product-output or waste-input) is
* contained in this index.
*/
public boolean contains(LongPair provider) {
return index.containsKey(provider);
}
/**
* Adds the given provider (product-output or waste-input) to this index.
* Does nothing if it is already contained in this index.
*/
public void put(LongPair provider) {
if (contains(provider))
return;
int idx = index.size();
index.put(provider, idx);
long processId = provider.getFirst();
List<LongPair> list = processProviders.get(processId);
if (list == null) {
list = new ArrayList<>();
processProviders.put(processId, list);
}
list.add(provider);
providers.add(provider);
}
/**
* Returns the provider (product-output or waste-input) at the given index.
*/
public LongPair getProviderAt(int index) {
return providers.get(index);
}
/**
* Returns the providers (product-outputs and waste-inputs) for the process
* with the given ID.
*/
public List<LongPair> getProviders(long processId) {
List<LongPair> providers = processProviders.get(processId);
if (providers == null)
return Collections.emptyList();
return new ArrayList<>(providers);
}
/**
* Adds a process link to this index.
*
* @param exchange
* The linked product-input or waste-output as (processId,
* exchangeId) pair.
* @param provider
* The product-output or waste-input (provider) as (processId,
* flowId) pair.
*/
public void putLink(LongPair exchange, LongPair provider) {
if (links.containsKey(exchange))
return;
put(provider);
links.put(exchange, provider);
}
/**
*
* Returns true if the given product-input or waste-output is linked to a
* provider of this index.
*/
public boolean isLinked(LongPair exchange) {
return links.containsKey(exchange);
}
/**
* Returns the linked provider (product-output or waste-input) for the given
* exchange (product-input or waste-output)
*/
public LongPair getLinkedProvider(LongPair exchange) {
return links.get(exchange);
}
/**
* Returns all exchanges (product-inputs and waste-outputs) that are linked
* to provider of this index.
*/
public Set<LongPair> getLinkedExchanges() {
return links.keySet();
}
/**
* Returns the IDs of all processes in this index.
*/
public Set<Long> getProcessIds() {
HashSet<Long> set = new HashSet<>();
for (LongPair product : providers) {
set.add(product.getFirst());
}
return set;
}
}