package gipad.plan.choco.actionmodel.slice;
import java.util.Arrays;
import solver.Cause;
import solver.constraints.ICF;
import solver.variables.IntVar;
import solver.variables.Task;
import gipad.plan.Plan;
import gipad.plan.choco.ReconfigurationProblem;
/**
* Model a period where a managed element is consuming CPU and memory and bandwidth resources during
* a bounded amount of time on a node.
*
*@author Thomas Pocreau
*/
public class Slice {
private Task task;
/**
* Indicates the identifier of slice hoster.
*/
private IntVar<?> hoster;
/**
* The CPU height of the slice.
*/
private int[] cpuHeight;
/**
* The memory height of the slice.
*/
private int memHeight;
/**
* The output bandwidth of the slice
*/
private IntVar<?> bwOutput;
/**
* The input bandwith of the slice
*/
private IntVar<?> bwInput;
/**
* name of the slice
*/
private String name;
/**
* Make a new slice.
*
* @param name the name of the slice
* @param h the hoster of the slice (its identifier)
* @param t The associated task variable
* @param cpuHeight the CPU height of the slice
* @param memHeight the memory height of the slice
*/
public Slice(String name,
IntVar<?> h,
Task t,
int[] cpuHeight,
int memHeight,
IntVar<?> bwOutput,
IntVar<?> bwInput) {
this.name = name;
task = t;
hoster = h;
this.cpuHeight = cpuHeight;
this.memHeight = memHeight;
this.bwOutput = bwOutput;
this.bwInput = bwInput;
}
/**
* Get the CPU consumption of the slice during its activity.
*
* @return a positive integer
*/
public int[] getCPUheight() {
return this.cpuHeight;
}
/**
* Get the output bandwith consumption of the slice during its activity
*
* @return a positive integer
*/
public IntVar<?> getBwOutput() {
return bwOutput;
}
/**
* Get the input bandwith consumption of the slice during its activity
*
* @return a positive integer
*/
public IntVar<?> getBwInput() {
return bwInput;
}
/**
* Get the memory consumption of the slice during its activity.
*
* @return a positive integer
*/
public int getMemoryheight() {
return this.memHeight;
}
/**
* Get the node that host the slice.
*
* @return the index of the node.
*/
public IntVar<?> hoster() {
return hoster;
}
/**
* @return <code>this.pretty()</code>
*/
@Override
public String toString() {
return this.pretty();
}
/**
* Nice print of the slice.
*
* @return a formatted String
*/
public String pretty() {
StringBuilder builder = new StringBuilder();
builder.append(getName()).append("{[").append(getStart().getLB()).append(",");
if (getStart().getUB() == ReconfigurationProblem.MAX_TIME) {
builder.append("MAX");
} else {
builder.append(getStart().getUB());
}
builder.append("] + [")
.append(duration().getLB()).append(",");
if (duration().getUB() == ReconfigurationProblem.MAX_TIME) {
builder.append("MAX");
} else {
builder.append(duration().getUB());
}
builder.append("] = [")
.append(getEnd().getLB()).append(",");
if (getEnd().getLB() == ReconfigurationProblem.MAX_TIME) {
builder.append("MAX");
} else {
builder.append(getEnd().getUB());
}
builder.append("] on [")
.append(hoster().getLB()).append(",").append(hoster().getUB()).append("]}");
return builder.toString();
}
public static int improvable = 0;
public static int nonImpr = 0;
/**
* Add the slice to the model.The following are added:
* <ul>
* <li>A constraint to enforce all the variables to be inferior or equals to <code>model.getEnd()</code></li>
* </ul>
*
* @param core the current model of the reconfiguration problem
*/
public void addToModel(ReconfigurationProblem core) {
core.getSolver().post(ICF.arithm(this.getEnd(), "<=", core.getEnd()));
}
/**
* Get the moment the slice starts.
*
* @return a positive moment
*/
public IntVar<?> getStart() {
return task.getStart();
}
public void setStart(IntVar start){
task.setStart(start);
}
public void setEnd(IntVar end){
task.setEnd(end);
}
/**
* Get the duration of the slice.
*
* @return a positive moment
*/
public IntVar<?> duration() {
return task.getDuration();
}
public void setDuration(IntVar dur){
task.setDuration(dur);
}
public void setHoster(IntVar hoster) {
this.hoster = hoster;
}
public void setBwOutput(IntVar bwOutput) {
this.bwOutput = bwOutput;
}
public void setBwInput(IntVar bwInput) {
this.bwInput = bwInput;
}
/**
* Get the moment the slice ends.
*
* @return a positive moment
*/
public IntVar<?> getEnd() {
return task.getEnd();
}
/**
* Get the name of the slice.
*
* @return a String
*/
public String getName() {
return name;
}
/**
* Set the duration of the slice as a constant.
*
* @param d a positive duration
*/
public void fixDuration(int d) {
try {
this.duration().instantiateTo(d, Cause.Null);
} catch (Exception e) {
Plan.logger.error(e.getMessage(), e);
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + bwInput.hashCode();
result = prime * result + bwOutput.hashCode();
result = prime * result + Arrays.hashCode(cpuHeight);
result = prime * result + ((hoster == null) ? 0 : hoster.hashCode());
result = prime * result + memHeight;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((task == null) ? 0 : task.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Slice other = (Slice) obj;
if (bwInput != other.bwInput)
return false;
if (bwOutput != other.bwOutput)
return false;
if (!Arrays.equals(cpuHeight, other.cpuHeight))
return false;
if (hoster == null) {
if (other.hoster != null)
return false;
} else if (!hoster.equals(other.hoster))
return false;
if (memHeight != other.memHeight)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (task == null) {
if (other.task != null)
return false;
} else if (!task.equals(other.task))
return false;
return true;
}
}