/**
* Copyright (C) 2010 BonitaSoft S.A.
* BonitaSoft, 31 rue Gustave Eiffel - 38000 Grenoble
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2.0 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.bonitasoft.simulation.engine;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import org.bonitasoft.simulation.model.Period;
import org.bonitasoft.simulation.model.instance.ResourceInstance;
import org.bonitasoft.simulation.model.resource.Resource;
/**
* @author Romain Bioteau
*
*/
public class RuntimeResource {
protected Resource resource;
protected List<ResourceInstance> instances ;
protected SortedMap<Long,Integer> occupiedInstances ;
protected SortedMap<Long,Integer> minimumWorkingInstance ;
protected SortedMap<Long,Integer> maximumWorkingInstance ;
protected SortedMap<Long,Integer> medianWorkingInstance ;
protected SortedMap<Long,Float> averageWorkingInstance ;
protected Map<String,SortedMap<Long,Long>> waitingFor ;
protected Map<String,Long> intermediateWaitingFor ;
protected HashMap<String, Long> processInstanceWaiting ;
protected long procWaiting ;
protected SortedMap<Long,Long> processWaitingFor ;
public RuntimeResource(Resource resource,List<ResourceInstance> instances, long startTime, long timespan){
this.resource = resource;
this.instances =instances ;
this.occupiedInstances = new TreeMap<Long, Integer>();
this.minimumWorkingInstance = new TreeMap<Long, Integer>();
this.maximumWorkingInstance = new TreeMap<Long, Integer>();
this.averageWorkingInstance = new TreeMap<Long, Float>();
this.intermediateWaitingFor = new HashMap<String, Long>();
this.waitingFor = new HashMap<String, SortedMap<Long,Long>>() ;
this.processInstanceWaiting = new HashMap<String, Long>() ;
this.processWaitingFor = new TreeMap<Long, Long>() ;
}
public List<ResourceInstance> getInstances() {
return Collections.unmodifiableList(instances);
}
public Resource getResource() {
return resource;
}
/**
* @return the availableInstances
*/
public SortedMap<Long, Integer> getOccupiedInstances() {
return occupiedInstances;
}
public void updateInstancesCount(long startDate,long endDate) throws Exception {
int occupiedBefore = 0;
int occupiedAfter = 0;
for(ResourceInstance instance : instances){
for(Period wp : instance.getPlanning().getWorkingPeriods()){
if(wp.contains(startDate)){
occupiedBefore++ ;
}
if(wp.contains(endDate)){
occupiedAfter++ ;
}
}
}
if(getResource().getMaximumQuantity() >=0){
if(occupiedBefore > getResource().getMaximumQuantity() || occupiedAfter > getResource().getMaximumQuantity() ){
throw new Exception("Too Many Resources Ocuppied"); //$NON-NLS-1$
}
}
occupiedInstances.put(startDate,occupiedBefore);
occupiedInstances.put(endDate,occupiedAfter);
}
public void setMinimumWorkingInstance(SortedMap<Long,Integer> minimumWorkingInstance) {
this.minimumWorkingInstance = minimumWorkingInstance;
}
public SortedMap<Long,Integer> getMinimumWorkingInstance() {
return minimumWorkingInstance;
}
public void setMaximumWorkingInstance(SortedMap<Long,Integer> maximumWorkingInstance) {
this.maximumWorkingInstance = maximumWorkingInstance;
}
public SortedMap<Long,Integer> getMaximumWorkingInstance() {
return Collections.unmodifiableSortedMap(maximumWorkingInstance);
}
public SortedMap<Long,Integer> getMedianWorkingInstance() {
return Collections.unmodifiableSortedMap(medianWorkingInstance);
}
public SortedMap<Long,Float> getAverageWorkingInstance() {
return Collections.unmodifiableSortedMap(averageWorkingInstance);
}
public void updateInstancesCount(long interval) {
List<Integer> workingResource = new ArrayList<Integer>();
List<Long> keys = new ArrayList<Long>();
for(Long key : occupiedInstances.keySet()){
if(key <= SimulationEngine.currentTime){
keys.add(key) ;
workingResource.add(occupiedInstances.get(key)) ;
}
}
if(workingResource.isEmpty()){
minimumWorkingInstance.put(interval, 0);
maximumWorkingInstance.put(interval, 0);
averageWorkingInstance.put(interval, 0f);
}else{
minimumWorkingInstance.put(interval, Collections.min(workingResource));
maximumWorkingInstance.put(interval, Collections.max(workingResource));
int total = 0 ;
for(Integer i : workingResource){
total = total + i ;
}
float avg = (float) ((float)total/ (float)workingResource.size()) ;
averageWorkingInstance.put(interval, avg);
}
for(Long key : keys){
occupiedInstances.remove(key) ;
}
}
public void updateWaitingFor(String activityName, long waitingTime) {
if(intermediateWaitingFor.get(activityName) != null){
intermediateWaitingFor.put(activityName, intermediateWaitingFor.get(activityName) + waitingTime) ;
}else{
intermediateWaitingFor.put(activityName, waitingTime) ;
}
}
public void updateWaitingFor(long interval) {
for(String activityName : intermediateWaitingFor.keySet()){
SortedMap<Long, Long> time = null ;
if(waitingFor.get(activityName)!= null){
time = waitingFor.get(activityName) ;
time.put(interval, intermediateWaitingFor.get(activityName));
waitingFor.put(activityName, time) ;
}else{
time = new TreeMap<Long,Long>() ;
time.put(interval, intermediateWaitingFor.get(activityName)) ;
waitingFor.put(activityName, time) ;
}
}
intermediateWaitingFor.clear() ;
}
public Map<String, SortedMap<Long,Long>> getWaitingFor(){
return Collections.unmodifiableMap(waitingFor) ;
}
public SortedMap<Long,Long> getProcessWaitingFor(){
return Collections.unmodifiableSortedMap(processWaitingFor) ;
}
public void updateProcessInstanceWaitingFor(String processInstanceUUID, long waitingTime) {
if(processInstanceWaiting.get(processInstanceUUID) != null){
processInstanceWaiting.put(processInstanceUUID, processInstanceWaiting.get(processInstanceUUID) + waitingTime) ;
}else{
processInstanceWaiting.put(processInstanceUUID, waitingTime) ;
}
}
public void updateProcessInstanceWaitingFor(String processInstanceUUID) {
if(processInstanceWaiting.get(processInstanceUUID) != null){
procWaiting = procWaiting + processInstanceWaiting.get(processInstanceUUID) ;
}
processInstanceWaiting.remove(processInstanceUUID) ;
}
public void updateProcessInstanceWaitingFor(long interval) {
processWaitingFor.put(interval,procWaiting) ;
procWaiting = 0 ;
}
}