/*
* Copyright (c) 2010-2012 Grid Dynamics Consulting Services, Inc, All Rights Reserved
* http://www.griddynamics.com
*
* This library is free software; you can redistribute it and/or modify it under the terms of
* the Apache License; either
* version 2.0 of the License, or any later version.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.griddynamics.jagger.engine.e1.scenario;
import com.google.common.collect.*;
import com.griddynamics.jagger.util.Pair;
import java.math.BigDecimal;
import java.util.Map;
import java.util.Queue;
public class NodeTpsRecorder implements NodeTpsStatistics {
private final Map<Long, Pair<WorkloadConfiguration, BigDecimal>> tpsTimeHistory = Maps.newTreeMap();
private final Table<Integer, Integer, Pair<Long, BigDecimal>> tpsTable;
private BigDecimal currentTps = BigDecimal.ZERO;
private WorkloadConfiguration currentConfiguration = WorkloadConfiguration.zero();
private Long lastRecordedTime;
private Long currentSamples = 0l;
private final int limit;
private Queue<WorkloadConfiguration> queue = Lists.newLinkedList();
public NodeTpsRecorder(int limit) {
tpsTable = HashBasedTable.create();
this.limit = limit;
}
public void recordStatus(int threads, int delay, long samples, long pollTime) {
currentTps = calculateTps(samples, pollTime);
currentConfiguration = WorkloadConfiguration.with(threads, delay);
lastRecordedTime = pollTime;
currentSamples = samples;
tpsTimeHistory.put(pollTime, Pair.of(currentConfiguration, currentTps));
if (threads != 0 && delay != 0) {
queue.add(currentConfiguration);
}
if (queue.size() >= limit) {
WorkloadConfiguration outdatedConfiguration = queue.peek();
tpsTable.remove(outdatedConfiguration.getThreads(), outdatedConfiguration.getDelay());
}
tpsTable.put(threads, delay, Pair.of(pollTime, currentTps));
}
private BigDecimal calculateTps(long samples, long pollTime) {
BigDecimal tps = BigDecimal.ZERO;
if (lastRecordedTime != null) {
long interval = pollTime - lastRecordedTime;
tps = new BigDecimal(samples - currentSamples).divide(new BigDecimal(interval), 6, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(1000));
}
return tps;
}
@Override
public WorkloadConfiguration getCurrentWorkloadConfiguration() {
return currentConfiguration;
}
@Override
public BigDecimal getCurrentTps() {
return currentTps;
}
@Override
public Long getCurrentSamples() {
return currentSamples;
}
@Override
public Long getLastRecordedTime() {
return lastRecordedTime;
}
@Override
public Map<Long, Pair<WorkloadConfiguration, BigDecimal>> getTpsHistory() {
return ImmutableMap.copyOf(tpsTimeHistory);
}
@Override
public Table<Integer, Integer, Pair<Long, BigDecimal>> getThreadDelayStats() {
return tpsTable;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
NodeTpsRecorder that = (NodeTpsRecorder) o;
if (currentConfiguration != null ? !currentConfiguration.equals(that.currentConfiguration) : that.currentConfiguration != null)
return false;
if (currentSamples != null ? !currentSamples.equals(that.currentSamples) : that.currentSamples != null)
return false;
if (currentTps != null ? !currentTps.equals(that.currentTps) : that.currentTps != null) return false;
if (lastRecordedTime != null ? !lastRecordedTime.equals(that.lastRecordedTime) : that.lastRecordedTime != null)
return false;
if (tpsTable != null ? !tpsTable.equals(that.tpsTable) : that.tpsTable != null) return false;
if (tpsTimeHistory != null ? !tpsTimeHistory.equals(that.tpsTimeHistory) : that.tpsTimeHistory != null)
return false;
return true;
}
@Override
public int hashCode() {
int result = tpsTimeHistory != null ? tpsTimeHistory.hashCode() : 0;
result = 31 * result + (tpsTable != null ? tpsTable.hashCode() : 0);
result = 31 * result + (currentTps != null ? currentTps.hashCode() : 0);
result = 31 * result + (currentConfiguration != null ? currentConfiguration.hashCode() : 0);
result = 31 * result + (lastRecordedTime != null ? lastRecordedTime.hashCode() : 0);
result = 31 * result + (currentSamples != null ? currentSamples.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "NodeTpsRecorder" +
"\n{" +
"\n\t tpsTimeHistory=" + tpsTimeHistory +
"\n\t tpsTable=" + tpsTable +
"\n\t currentTps=" + currentTps +
"\n\t currentConfiguration=" + currentConfiguration +
"\n\t lastRecordedTime=" + lastRecordedTime +
"\n\t currentSamples=" + currentSamples +
"\n\t queue=" + queue +
"\n\t limit=" + limit +
"\n}";
}
}