/**
* Helios, OpenSource Monitoring
* Brought to you by the Helios Development Group
*
* Copyright 2007, Helios Development Group and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*
*/
package org.helios.apmrouter.tsmodel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
/**
* <p>Title: TimeSeriesModel</p>
* <p>Description: Container and parser for the timeseries core structure and tier model.</p>
* <p>Company: Helios Development Group LLC</p>
* @author Whitehead (nwhitehead AT heliosdev DOT org)
* <p><code>org.helios.apmrouter.tsmodel.TimeSeriesModel</code></p>
*/
public class TimeSeriesModel {
/** The initial model definition */
protected final String model;
/** The timeseries tiers */
protected final LinkedHashSet<Tier> tiers = new LinkedHashSet<Tier>();
/**
* Creates a new TimeSeriesModel
* @param modelDef The model definition
*/
private TimeSeriesModel(String modelDef) {
if(modelDef==null || modelDef.trim().isEmpty()) throw new IllegalArgumentException("The passed model was null or empty", new Throwable());
this.model = modelDef.trim().toLowerCase().replace(" ", "");
String[] frags = model.split("\\|");
Tier previousTier = null;
for(int i = 0; i < frags.length; i++) {
Tier tier = new Tier(frags[i], i);
if(! tiers.add(tier)) {
throw new InvalidTierModelException("Duplicate Tier [" + frags[i] + "] in tier model [" + model + "]");
}
if(previousTier!=null) {
if(tier.periodDuration.seconds%previousTier.periodDuration.seconds!=0) {
throw new InvalidTierModelException("The period duration of tier [" + tier.name + "] is not an even multiple of the prior tier [" + previousTier.name + "]");
}
}
previousTier = tier;
}
}
/**
* Returns the model definition this model was built with
* @return the model definition this model was built with
*/
public String getModelDef() {
return model;
}
/**
* Returns the number of tiers
* @return the number of tiers
*/
public int getTierCount() {
return tiers.size();
}
/**
* Returns a copy of the tier collection for this model
* @return a copy of the tier collection for this model
*/
public List<Tier> getModelTiers() {
return new ArrayList<Tier>(tiers);
}
/**
* Returns a list of tier pairs where the second tier is the parent of the first, or null if the first has no parent
* @return a list of child/parent tier pairs
*/
public List<Tier[]> getModelTierPairs() {
ArrayList<Tier[]> pairs = new ArrayList<Tier[]>();
Tier[] _tiers = tiers.toArray(new Tier[tiers.size()]);
for(int i = 0; i < _tiers.length; i++) {
Tier[] childParent = new Tier[2];
childParent[0] = _tiers[i];
childParent[1] = i==_tiers.length-1 ? null : _tiers[i+1];
pairs.add(childParent);
}
return pairs;
}
/**
* Returns a two dimensional matrix of all the tiers in the model with values expressed in seconds.
* @return a two dimensional matrix of all the tiers in the model with values expressed in seconds.
*/
public long[][] getModelMatrix() {
long[][] matrix = new long[tiers.size()][];
int i = 0;
for(Tier tier: tiers) {
matrix[i] = new long[]{ tier.periodDuration.seconds, tier.tierDuration.seconds, tier.periodCount };
i++;
}
return matrix;
}
/**
* Creates a new TimeSeriesModel from the passed stringified model
* @param model The string representation of the model
* @return a new TimeSeriesModel
*/
public static TimeSeriesModel create(String model) {
return new TimeSeriesModel(model);
}
public static void main(String[] args) {
// log("Test TimeSeriesModel");
// String config = "p=15s,t=7d | p=60s,t=23d | p=15m,t=355d";
// TimeSeriesModel model1 = TimeSeriesModel.create(config);
// log(model1);
// TimeSeriesModel model2 = TimeSeriesModel.create(config);
// log("Model1 equals Model2:" + model1.equals(model2));
// log("Model2 equals Model1:" + model2.equals(model1));
// config = "p=15s,t=7d | p=60s,t=28d | p=15m,t=355d";
// model2 = TimeSeriesModel.create(config);
// log("Model1 equals Model2:" + model1.equals(model2));
// for(long[] t : model2.getModelMatrix()) {
// log(Arrays.toString(t));
// }
log("Test TimeSeriesModel");
//Logger.getLogger(Tier.class).setLevel(Level.DEBUG);
String config = "p=5s,t=1m | p=1m,t=2m | p=5m,t=15m";
TimeSeriesModel model1 = TimeSeriesModel.create(config);
log(model1);
for(Tier[] t: model1.getModelTierPairs()) {
log(Arrays.toString(t));
}
}
public static void log(Object msg) {
System.out.println(msg);
}
/**
* {@inheritDoc}
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuilder b = new StringBuilder("Tier Model [");
for(Tier tier: tiers) {
b.append("\n\tLevel ").append(tier.level).append(":").append(tier);
}
b.append("\n]");
return b.toString();
}
/**
* {@inheritDoc}
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((tiers == null) ? 0 : tiers.hashCode());
return result;
}
/**
* {@inheritDoc}
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
TimeSeriesModel other = (TimeSeriesModel) obj;
if (tiers == null) {
if (other.tiers != null) {
return false;
}
} else if (!tiers.equals(other.tiers)) {
return false;
}
return true;
}
}