http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/750996a0/geode-core/src/main/java/com/gemstone/gemfire/internal/StatArchiveReader.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/StatArchiveReader.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/StatArchiveReader.java deleted file mode 100644 index 0947b0d..0000000 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/StatArchiveReader.java +++ /dev/null @@ -1,3338 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gemstone.gemfire.internal; - -import com.gemstone.gemfire.GemFireIOException; -import com.gemstone.gemfire.InternalGemFireException; -import com.gemstone.gemfire.internal.i18n.LocalizedStrings; -import com.gemstone.gemfire.internal.logging.DateFormatter; - -import java.io.BufferedInputStream; -import java.io.DataInputStream; -import java.io.EOFException; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.text.DateFormat; -import java.text.NumberFormat; -import java.text.SimpleDateFormat; -import java.util.AbstractList; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SimpleTimeZone; -import java.util.TimeZone; -import java.util.zip.GZIPInputStream; - -/** - * StatArchiveReader provides APIs to read statistic snapshots from an archive - * file. - */ -public class StatArchiveReader implements StatArchiveFormat { - - protected static final NumberFormat nf = NumberFormat.getNumberInstance(); - static { - nf.setMaximumFractionDigits(2); - nf.setGroupingUsed(false); - } - - private final StatArchiveFile[] archives; - private boolean dump; - private boolean closed = false; - - /** - * Creates a StatArchiveReader that will read the named archive file. - * @param autoClose if its <code>true</code> then the reader will close - * input files as soon as it finds their end. - * @throws IOException if <code>archiveName</code> could not be opened - * read, or closed. - */ - public StatArchiveReader(File[] archiveNames, ValueFilter[] filters, boolean autoClose) - throws IOException - { - this.archives = new StatArchiveFile[archiveNames.length]; - this.dump = Boolean.getBoolean("StatArchiveReader.dumpall"); - for (int i=0; i < archiveNames.length; i++) { - this.archives[i] = new StatArchiveFile(this, archiveNames[i], dump, filters); - } - - update(false, autoClose); - - if (this.dump || Boolean.getBoolean("StatArchiveReader.dump")) { - this.dump(new PrintWriter(System.out)); - } - } - - /** - * Creates a StatArchiveReader that will read the named archive file. - * @throws IOException if <code>archiveName</code> could not be opened - * read, or closed. - */ - public StatArchiveReader(String archiveName) throws IOException { - this(new File[]{new File(archiveName)}, null, false); - } - - /** - * Returns an array of stat values that match the specified spec. - * If nothing matches then an empty array is returned. - */ - public StatValue[] matchSpec(StatSpec spec) { - if (spec.getCombineType() == StatSpec.GLOBAL) { - StatValue[] allValues = matchSpec(new RawStatSpec(spec)); - if (allValues.length == 0) { - return allValues; - } else { - ComboValue cv = new ComboValue(allValues); - // need to save this in reader's combo value list - return new StatValue[]{cv}; - } - } else { - List l = new ArrayList(); - StatArchiveReader.StatArchiveFile[] archives = getArchives(); - for (int i=0; i < archives.length; i++) { - StatArchiveFile f = archives[i]; - if (spec.archiveMatches(f.getFile())) { - f.matchSpec(spec, l); - } - } - StatValue[] result = new StatValue[l.size()]; - return (StatValue[])l.toArray(result); - } - } - - /** - * Checks to see if any archives have changed since the StatArchiverReader - * instance was created or last updated. If an archive has additional - * samples then those are read the resource instances maintained by the - * reader are updated. - * <p>Once closed a reader can no longer be updated. - * @return true if update read some new data. - * @throws IOException if an archive could not be opened - * read, or closed. - */ - public boolean update() throws IOException { - return update(true, false); - } - private boolean update(boolean doReset, boolean autoClose) throws IOException { - if (this.closed) { - return false; - } - boolean result = false; - StatArchiveReader.StatArchiveFile[] archives = getArchives(); - for (int i=0; i < archives.length; i++) { - StatArchiveFile f = archives[i]; - if (f.update(doReset)) { - result = true; - } - if (autoClose) { - f.close(); - } - } - return result; - } - - /** - * Returns an unmodifiable list of all the {@link ResourceInst} - * this reader contains. - */ - public List getResourceInstList() { - return new ResourceInstList(); - } - - public StatArchiveFile[] getArchives() { - return this.archives; - } - - /** - * Closes all archives. - */ - public void close() throws IOException { - if (!this.closed) { - StatArchiveReader.StatArchiveFile[] archives = getArchives(); - for (int i=0; i < archives.length; i++) { - StatArchiveFile f = archives[i]; - f.close(); - } - this.closed = true; - } - } - - private int getMemoryUsed() { - int result = 0; - StatArchiveReader.StatArchiveFile[] archives = getArchives(); - for (int i=0; i < archives.length; i++) { - StatArchiveFile f = archives[i]; - result += f.getMemoryUsed(); - } - return result; - } - - private void dump(PrintWriter stream) { - StatArchiveReader.StatArchiveFile[] archives = getArchives(); - for (int i=0; i < archives.length; i++) { - StatArchiveFile f = archives[i]; - f.dump(stream); - } - } - - protected static double bitsToDouble(int type, long bits) { - switch (type) { - case BOOLEAN_CODE: - case BYTE_CODE: - case CHAR_CODE: - case WCHAR_CODE: - case SHORT_CODE: - case INT_CODE: - case LONG_CODE: - return bits; - case FLOAT_CODE: - return Float.intBitsToFloat((int)bits); - case DOUBLE_CODE: - return Double.longBitsToDouble(bits); - default: - throw new InternalGemFireException(LocalizedStrings.StatArchiveReader_UNEXPECTED_TYPECODE_0.toLocalizedString(Integer.valueOf(type))); - } - } - - /** - * Simple utility to read and dump statistic archive. - */ - public static void main(String args[]) throws IOException { - String archiveName = null; - if (args.length > 1) { - System.err.println("Usage: [archiveName]"); - System.exit(1); - } else if (args.length == 1) { - archiveName = args[0]; - } else { - archiveName = "statArchive.gfs"; - } - StatArchiveReader reader = new StatArchiveReader(archiveName); - System.out.println("DEBUG: memory used = " + reader.getMemoryUsed()); - reader.close(); - } - - /** - * Wraps an instance of StatSpec but alwasy returns a combine type of NONE. - */ - private static class RawStatSpec implements StatSpec { - private final StatSpec spec; - RawStatSpec(StatSpec wrappedSpec) { - this.spec = wrappedSpec; - } - public int getCombineType() { - return StatSpec.NONE; - } - public boolean typeMatches(String typeName) { - return spec.typeMatches(typeName); - } - public boolean statMatches(String statName) { - return spec.statMatches(statName); - } - public boolean instanceMatches(String textId, long numericId) { - return spec.instanceMatches(textId, numericId); - } - public boolean archiveMatches(File archive) { - return spec.archiveMatches(archive); - } - } - - private class ResourceInstList extends AbstractList { - protected ResourceInstList() { - // nothing needed. - } - @Override - public Object get(int idx) { - int archiveIdx = 0; - StatArchiveReader.StatArchiveFile[] archives = getArchives(); - for (int i=0; i < archives.length; i++) { - StatArchiveFile f = archives[i]; - if (idx < (archiveIdx + f.resourceInstSize)) { - return f.resourceInstTable[idx - archiveIdx]; - } - archiveIdx += f.resourceInstSize; - } - return null; - } - @Override - public int size() { - int result = 0; - StatArchiveReader.StatArchiveFile[] archives = getArchives(); - for (int i=0; i < archives.length; i++) { - result += archives[i].resourceInstSize; - } - return result; - } - } - - /** - * Describes a single statistic. - */ - public static class StatDescriptor { - private boolean loaded; - private String name; - private final int offset; - private final boolean isCounter; - private final boolean largerBetter; - private final byte typeCode; - private String units; - private String desc; - - protected void dump(PrintWriter stream) { - stream.println(" " + name + ": type=" + typeCode + " offset=" + offset - + (isCounter? " counter" : "") - + " units=" + units - + " largerBetter=" + largerBetter - + " desc=" + desc); - } - - protected StatDescriptor(String name, int offset, boolean isCounter, - boolean largerBetter, - byte typeCode, String units, String desc) { - this.loaded = true; - this.name = name; - this.offset = offset; - this.isCounter = isCounter; - this.largerBetter = largerBetter; - this.typeCode = typeCode; - this.units = units; - this.desc = desc; - } - public boolean isLoaded() { - return this.loaded; - } - void unload() { - this.loaded = false; - this.name = null; - this.units = null; - this.desc = null; - } - /** - * Returns the type code of this statistic. - * It will be one of the following values: - * <ul> - * <li> {@link #BOOLEAN_CODE} - * <li> {@link #WCHAR_CODE} - * <li> {@link #CHAR_CODE} - * <li> {@link #BYTE_CODE} - * <li> {@link #SHORT_CODE} - * <li> {@link #INT_CODE} - * <li> {@link #LONG_CODE} - * <li> {@link #FLOAT_CODE} - * <li> {@link #DOUBLE_CODE} - * </ul> - */ - public byte getTypeCode() { - return this.typeCode; - } - /** - * Returns the name of this statistic. - */ - public String getName() { - return this.name; - } - /** - * Returns true if this statistic's value will always increase. - */ - public boolean isCounter() { - return this.isCounter; - } - /** - * Returns true if larger values indicate better performance. - */ - public boolean isLargerBetter() { - return this.largerBetter; - } - /** - * Returns a string that describes the units this statistic measures. - */ - public String getUnits() { - return this.units; - } - /** - * Returns a textual description of this statistic. - */ - public String getDescription() { - return this.desc; - } - /** - * Returns the offset of this stat in its type. - */ - public int getOffset() { - return this.offset; - } - } - - public static interface StatValue { - /** - * {@link StatArchiveReader.StatValue} filter that causes the - * statistic values to be unfiltered. This causes the raw values - * written to the archive to be used. - * <p>This is the default filter for non-counter statistics. - * To determine if a statistic is not a counter use {@link StatArchiveReader.StatDescriptor#isCounter}. */ - public static final int FILTER_NONE = 0; - /** - * {@link StatArchiveReader.StatValue} filter that causes the - * statistic values to be filtered to reflect how often they - * change per second. Since the difference between two samples is - * used to calculate the value this causes the {@link StatArchiveReader.StatValue} - * to have one less sample than {@link #FILTER_NONE}. The instance - * time stamp that does not have a per second value is the - * instance's first time stamp {@link - * StatArchiveReader.ResourceInst#getFirstTimeMillis}. - * <p>This is the default filter for counter statistics. - * To determine if a statistic is a counter use {@link StatArchiveReader.StatDescriptor#isCounter}. */ - public static final int FILTER_PERSEC = 1; - /** - * {@link StatArchiveReader.StatValue} filter that causes the - * statistic values to be filtered to reflect how much they - * changed between sample periods. Since the difference between - * two samples is used to calculate the value this causes the - * {@link StatArchiveReader.StatValue} to have one less sample than {@link - * #FILTER_NONE}. The instance time stamp that does not have a per - * second value is the instance's first time stamp {@link - * StatArchiveReader.ResourceInst#getFirstTimeMillis}. - */ - public static final int FILTER_PERSAMPLE = 2; - /** - * Creates and returns a trimmed version of this stat value. - * Any samples taken before <code>startTime</code> and after - * <code>endTime</code> are discarded from the resulting value. - * Set a time parameter to <code>-1</code> to not trim that side. - */ - public StatValue createTrimmed(long startTime, long endTime); - /** - * Returns true if value has data that has been trimmed off it - * by a start timestamp. - */ - public boolean isTrimmedLeft(); - /** - * Gets the {@link StatArchiveReader.ResourceType type} of the - * resources that this value belongs to. - */ - public ResourceType getType(); - /** - * Gets the {@link StatArchiveReader.ResourceInst resources} that this value - * belongs to. - */ - public ResourceInst[] getResources(); - /** - * Returns an array of timestamps for each unfiltered snapshot in this value. - * Each returned time stamp is the number of millis since - * midnight, Jan 1, 1970 UTC. - */ - public long[] getRawAbsoluteTimeStamps(); - /** - * Returns an array of timestamps for each unfiltered snapshot in this value. - * Each returned time stamp is the number of millis since - * midnight, Jan 1, 1970 UTC. - * The resolution is seconds. - */ - public long[] getRawAbsoluteTimeStampsWithSecondRes(); - /** - * Returns an array of doubles containing the unfiltered value of this - * statistic for each point in time that it was sampled. - */ - public double[] getRawSnapshots(); - /** - * Returns an array of doubles containing the filtered value of this - * statistic for each point in time that it was sampled. - */ - public double[] getSnapshots(); - /** - * Returns the number of samples taken of this statistic's value. - */ - public int getSnapshotsSize(); - /** - * Returns the smallest of all the samples taken of this statistic's value. - */ - public double getSnapshotsMinimum(); - /** - * Returns the largest of all the samples taken of this statistic's value. - */ - public double getSnapshotsMaximum(); - /** - * Returns the average of all the samples taken of this statistic's value. - */ - public double getSnapshotsAverage(); - /** - * Returns the standard deviation of all the samples taken of this statistic's value. - */ - public double getSnapshotsStandardDeviation(); - /** - * Returns the most recent value of all the samples taken of this statistic's value. - */ - public double getSnapshotsMostRecent(); - /** - * Returns true if sample whose value was different from previous values - * has been added to this StatValue since the last time this method was - * called. - */ - public boolean hasValueChanged(); - /** - * Returns the current filter used to calculate this statistic's values. - * It will be one of these values: - * <ul> - * <li> {@link #FILTER_NONE} - * <li> {@link #FILTER_PERSAMPLE} - * <li> {@link #FILTER_PERSEC} - * </ul> - */ - public int getFilter(); - /** - * Sets the current filter used to calculate this statistic's values. - * The default filter is {@link #FILTER_NONE} unless the statistic - * is a counter, {@link StatArchiveReader.StatDescriptor#isCounter}, - * in which case its {@link #FILTER_PERSEC}. - * @param filter It must be one of these values: - * <ul> - * <li> {@link #FILTER_NONE} - * <li> {@link #FILTER_PERSAMPLE} - * <li> {@link #FILTER_PERSEC} - * </ul> - * @throws IllegalArgumentException if <code>filter</code> is not a valid filter constant. - */ - public void setFilter(int filter); - /** - * Returns a description of this statistic. - */ - public StatDescriptor getDescriptor(); - } - - protected static abstract class AbstractValue implements StatValue { - protected StatDescriptor descriptor; - protected int filter; - - protected long startTime = -1; - protected long endTime = -1; - - protected boolean statsValid = false; - protected int size; - protected double min; - protected double max; - protected double avg; - protected double stddev; - protected double mostRecent; - - public void calcStats() { - if (!statsValid) { - getSnapshots(); - } - } - - public int getSnapshotsSize() { - calcStats(); - return this.size; - } - public double getSnapshotsMinimum() { - calcStats(); - return this.min; - } - public double getSnapshotsMaximum() { - calcStats(); - return this.max; - } - public double getSnapshotsAverage() { - calcStats(); - return this.avg; - } - public double getSnapshotsStandardDeviation() { - calcStats(); - return this.stddev; - } - public double getSnapshotsMostRecent() { - calcStats(); - return this.mostRecent; - } - public StatDescriptor getDescriptor() { - return this.descriptor; - } - public int getFilter() { - return this.filter; - } - - public void setFilter(int filter) { - if (filter != this.filter) { - if (filter != FILTER_NONE - && filter != FILTER_PERSEC - && filter != FILTER_PERSAMPLE) { - throw new IllegalArgumentException(LocalizedStrings.StatArchiveReader_FILTER_VALUE_0_MUST_BE_1_2_OR_3 - .toLocalizedString( - new Object[] { - Integer.valueOf(filter), - Integer.valueOf(FILTER_NONE), - Integer.valueOf(FILTER_PERSEC), - Integer.valueOf(FILTER_PERSAMPLE)})); - } - this.filter = filter; - this.statsValid = false; - } - } - - /** - * Calculates each stat given the result of calling getSnapshots - */ - protected void calcStats(double[] values) { - if (statsValid) { - return; - } - size = values.length; - if (size == 0) { - min = 0.0; - max = 0.0; - avg = 0.0; - stddev = 0.0; - mostRecent = 0.0; - } else { - min = values[0]; - max = values[0]; - mostRecent = values[values.length-1]; - double total = values[0]; - for (int i=1; i < size; i++) { - total += values[i]; - if (values[i] < min) { - min = values[i]; - } else if (values[i] > max) { - max = values[i]; - } - } - avg = total / size; - stddev = 0.0; - if (size > 1) { - for (int i=0; i < size; i++) { - double dv = values[i] - avg; - stddev += (dv*dv); - } - stddev /= (size - 1); - stddev = Math.sqrt(stddev); - } - } - statsValid = true; - } - - /** - * Returns a string representation of this object. - */ - @Override - public String toString() { - calcStats(); - StringBuffer result = new StringBuffer(); - result.append(getDescriptor().getName()); - String units = getDescriptor().getUnits(); - if (units != null && units.length() > 0) { - result.append(' ').append(units); - } - if (filter == FILTER_PERSEC) { - result.append("/sec"); - } else if (filter == FILTER_PERSAMPLE) { - result.append("/sample"); - } - result.append(": samples=") - .append(getSnapshotsSize()); - if (startTime != -1) { - result.append(" startTime=\"") - .append(new Date(startTime)) - .append("\""); - } - if (endTime != -1) { - result.append(" endTime=\"") - .append(new Date(endTime)) - .append("\""); - } - result.append(" min=") - .append(nf.format(min)); - result.append(" max=") - .append(nf.format(max)); - result.append(" average=") - .append(nf.format(avg)); - result.append(" stddev=") - .append(nf.format(stddev)); - result.append(" last=") // for bug 42532 - .append(nf.format(mostRecent)); - return result.toString(); - } - } - - /** - * A ComboValue is a value that is the logical combination of - * a set of other stat values. - * <p> For now ComboValue has a simple implementation that does not - * suppport updates. - */ - private static class ComboValue extends AbstractValue { - private final ResourceType type; - private final StatValue[] values; - /** - * Creates a ComboValue by adding all the specified values together. - */ - ComboValue(List valueList) { - this((StatValue[])valueList.toArray(new StatValue[valueList.size()])); - } - /** - * Creates a ComboValue by adding all the specified values together. - */ - ComboValue(StatValue[] values) { - this.values = values; - this.filter = this.values[0].getFilter(); - String typeName = this.values[0].getType().getName(); - String statName = this.values[0].getDescriptor().getName(); - int bestTypeIdx = 0; - for (int i=1; i < this.values.length; i++) { - if (this.filter != this.values[i].getFilter()) { - /* I'm not sure why this would happen. - * If it really can happen then this code should change - * the filter since a client has no way to select values - * based on the filter. - */ - throw new IllegalArgumentException(LocalizedStrings.StatArchiveReader_CANT_COMBINE_VALUES_WITH_DIFFERENT_FILTERS.toLocalizedString()); - } - if (!typeName.equals(this.values[i].getType().getName())) { - throw new IllegalArgumentException(LocalizedStrings.StatArchiveReader_CANT_COMBINE_VALUES_WITH_DIFFERENT_TYPES.toLocalizedString()); - } - if (!statName.equals(this.values[i].getDescriptor().getName())) { - throw new IllegalArgumentException(LocalizedStrings.StatArchiveReader_CANT_COMBINE_DIFFERENT_STATS.toLocalizedString()); - } - if (this.values[i].getDescriptor().isCounter()) { - // its a counter which is not the default - if (!this.values[i].getDescriptor().isLargerBetter()) { - // this guy has non-defaults for both use him - bestTypeIdx = i; - } else if (this.values[bestTypeIdx].getDescriptor().isCounter() - == this.values[bestTypeIdx].getDescriptor().isLargerBetter()) { - // as long as we haven't already found a guy with defaults - // make this guy the best type - bestTypeIdx = i; - } - } else { - // its a gauge, see if it has a non-default largerBetter - if (this.values[i].getDescriptor().isLargerBetter()) { - // as long as we haven't already found a guy with defaults - if (this.values[bestTypeIdx].getDescriptor().isCounter() - == this.values[bestTypeIdx].getDescriptor().isLargerBetter()) { - // make this guy the best type - bestTypeIdx = i; - } - } - } - } - this.type = this.values[bestTypeIdx].getType(); - this.descriptor = this.values[bestTypeIdx].getDescriptor(); - } - private ComboValue(ComboValue original, long startTime, long endTime) { - this.startTime = startTime; - this.endTime = endTime; - this.type = original.getType(); - this.descriptor = original.getDescriptor(); - this.filter = original.getFilter(); - this.values = new StatValue[original.values.length]; - for (int i=0; i < this.values.length; i++) { - this.values[i] = original.values[i].createTrimmed(startTime, endTime); - } - } - public StatValue createTrimmed(long startTime, long endTime) { - if (startTime == this.startTime && endTime == this.endTime) { - return this; - } else { - return new ComboValue(this, startTime, endTime); - } - } - public ResourceType getType() { - return this.type; - } - public ResourceInst[] getResources() { - Set set = new HashSet(); - for (int i=0; i < values.length; i++) { - set.addAll(Arrays.asList(values[i].getResources())); - } - ResourceInst[] result = new ResourceInst[set.size()]; - return (ResourceInst[])set.toArray(result); - } - public boolean hasValueChanged() { - return true; - } - - public static boolean closeEnough(long v1, long v2, long delta) { - return (v1 == v2) || ((Math.abs(v1-v2)/2) <= delta); - } - /** - * Return true if v is closer to prev. - * Return false if v is closer to next. - * Return true if v is the same distance from both. - */ - public static boolean closer(long v, long prev, long next) { - return Math.abs(v-prev) <= Math.abs(v-next); - } - - - /** - * Return true if the current ts must be inserted instead of - * being mapped to the tsAtInsertPoint - */ - private static boolean mustInsert(int nextIdx, long[] valueTimeStamps, long tsAtInsertPoint) { - return (nextIdx < valueTimeStamps.length) - && (valueTimeStamps[nextIdx] <= tsAtInsertPoint); - } - - public long[] getRawAbsoluteTimeStampsWithSecondRes() { - return getRawAbsoluteTimeStamps(); - } - - public long[] getRawAbsoluteTimeStamps() { - if (values.length == 0) { - return new long[0]; - } -// for (int i=0; i < values.length; i++) { -// System.out.println("DEBUG: inst# " + i + " has " -// + values[i].getRawAbsoluteTimeStamps().length -// + " timestamps"); -// } - long[] valueTimeStamps = values[0].getRawAbsoluteTimeStamps(); - int tsCount = valueTimeStamps.length + 1; - long[] ourTimeStamps = new long[(tsCount*2) + 1]; - System.arraycopy(valueTimeStamps, 0, ourTimeStamps, 0, valueTimeStamps.length); - // Note we add a MAX sample to make the insert logic simple - ourTimeStamps[valueTimeStamps.length] = Long.MAX_VALUE; - for (int i=1; i < values.length; i++) { - valueTimeStamps = values[i].getRawAbsoluteTimeStamps(); - if (valueTimeStamps.length == 0) { - continue; - } - int ourIdx = 0; - int j=0; - long tsToInsert = valueTimeStamps[0] - 1000; // default to 1 second - if (valueTimeStamps.length > 1) { - tsToInsert = valueTimeStamps[0] - (valueTimeStamps[1] - valueTimeStamps[0]); - } - // tsToInsert is now initialized to a value that we can pretend - // was the previous timestamp inserted. - while (j < valueTimeStamps.length) { - long timeDelta = (valueTimeStamps[j] - tsToInsert) / 2; - tsToInsert = valueTimeStamps[j]; - long tsAtInsertPoint = ourTimeStamps[ourIdx]; - while (tsToInsert > tsAtInsertPoint - && !closeEnough(tsToInsert, tsAtInsertPoint, timeDelta)) { -// System.out.println("DEBUG: skipping " + ourIdx + " because it was not closeEnough"); - ourIdx++; - tsAtInsertPoint = ourTimeStamps[ourIdx]; - } - if (closeEnough(tsToInsert, tsAtInsertPoint, timeDelta) - && !mustInsert(j+1, valueTimeStamps, tsAtInsertPoint)) { - // It was already in our list so just go to the next one - j++; - ourIdx++; // never put the next timestamp at this index - while (!closer(tsToInsert, ourTimeStamps[ourIdx-1], ourTimeStamps[ourIdx]) - && !mustInsert(j, valueTimeStamps, ourTimeStamps[ourIdx])) { -// System.out.println("DEBUG: skipping mergeTs[" + (ourIdx-1) + "]=" -// + tsAtInsertPoint + " because it was closer to the next one"); - ourIdx++; // it is closer to the next one so skip forward on more - } - } else { - // its not in our list so add it - int endRunIdx=j+1; - while (endRunIdx < valueTimeStamps.length - && valueTimeStamps[endRunIdx] < tsAtInsertPoint - && !closeEnough(valueTimeStamps[endRunIdx], tsAtInsertPoint, timeDelta)) { - endRunIdx++; - } - int numToCopy = endRunIdx - j; -// System.out.println("DEBUG: tsToInsert=" + tsToInsert -// + " tsAtInsertPoint=" + tsAtInsertPoint -// + " timeDelta=" + timeDelta -// + " vDelta=" + (Math.abs(tsToInsert-tsAtInsertPoint)/2) -// + " numToCopy=" + numToCopy); -// if (j > 0) { -// System.out.println("DEBUG: prevTsToInsert=" + valueTimeStamps[j-1]); -// } -// if (ourIdx > 0) { -// System.out.println("DEBUG ourTimeStamps[" + (ourIdx-1) + "]=" + ourTimeStamps[ourIdx-1]); -// } - -// if (numToCopy > 1) { -// System.out.println("DEBUG: endRunTs=" + valueTimeStamps[endRunIdx-1]); -// } - if (tsCount+numToCopy > ourTimeStamps.length) { - // grow our timestamp array - long[] tmp = new long[(tsCount+numToCopy)*2]; - System.arraycopy(ourTimeStamps, 0, tmp, 0, tsCount); - ourTimeStamps = tmp; - } - // make room for insert - System.arraycopy(ourTimeStamps, ourIdx, - ourTimeStamps, ourIdx+numToCopy, - tsCount-ourIdx); - // insert the elements - if (numToCopy == 1) { - ourTimeStamps[ourIdx] = valueTimeStamps[j]; - } else { - System.arraycopy(valueTimeStamps, j, - ourTimeStamps, ourIdx, - numToCopy); - } - ourIdx += numToCopy; - tsCount += numToCopy; - // skip over all inserted elements - j += numToCopy; - } -// System.out.println("DEBUG: inst #" + i -// + " valueTs[" + (j-1) + "]=" + tsToInsert -// + " found/inserted at" -// + " mergeTs[" + (ourIdx-1) + "]=" + ourTimeStamps[ourIdx-1]); - } - } -// for (int i=0; i < tsCount; i++) { -// System.out.println("DEBUG: mergedTs[" + i + "]=" + ourTimeStamps[i]); -// if (i > 0 && ourTimeStamps[i] <= ourTimeStamps[i-1]) { -// System.out.println("DEBUG: ERROR ts was not greater than previous"); -// } -// } - // Now make one more pass over all the timestamps and make sure they - // will all fit into the current merged timestamps in ourTimeStamps -// boolean changed; -// do { -// changed = false; -// for (int i=0; i < values.length; i++) { -// valueTimeStamps = values[i].getRawAbsoluteTimeStamps(); -// if (valueTimeStamps.length == 0) { -// continue; -// } -// int ourIdx = 0; -// for (int j=0; j < valueTimeStamps.length; j++) { -// while ((ourIdx < (tsCount-1)) -// && !isClosest(valueTimeStamps[j], ourTimeStamps, ourIdx)) { -// ourIdx++; -// } -// if (ourIdx == (tsCount-1)) { -// // we are at the end so we need to append all our remaining stamps [j..valueTimeStamps.length-1] -// // and then reappend the Long.MAX_VALUE that -// // is currently at tsCount-1 -// int numToCopy = valueTimeStamps.length - j; -// if (tsCount+numToCopy > ourTimeStamps.length) { -// // grow our timestamp array -// long[] tmp = new long[tsCount+numToCopy+1]; -// System.arraycopy(ourTimeStamps, 0, tmp, 0, tsCount); -// ourTimeStamps = tmp; -// } -// System.arraycopy(valueTimeStamps, j, -// ourTimeStamps, ourIdx, -// numToCopy); -// tsCount += numToCopy; -// ourTimeStamps[tsCount-1] = Long.MAX_VALUE; -// //changed = true; -// System.out.println("DEBUG: had to add " + numToCopy -// + " timestamps for inst#" + i + " starting at index " + j + " starting with ts=" + valueTimeStamps[j]); -// break; // our of the for j loop since we just finished off this guy -// } else { -// ourIdx++; -// } -// } -// } -// } while (changed); - // remove the max ts we added - tsCount--; - { - int startIdx = 0; - int endIdx = tsCount-1; - if (startTime != -1) { -// for (int i=0; i < tsCount; i++) { -// if (ourTimeStamps[i] >= startTime) { -// break; -// } -// startIdx++; -// } - Assert.assertTrue(ourTimeStamps[startIdx] >= startTime); - } - if (endTime != -1) { -// endIdx = startIdx-1; -// for (int i=startIdx; i < tsCount; i++) { -// if (ourTimeStamps[i] >= endTime) { -// break; -// } -// endIdx++; -// } - Assert.assertTrue(endIdx == startIdx-1 || ourTimeStamps[endIdx] < endTime); - } - tsCount = (endIdx-startIdx) + 1; - - // shrink and trim our timestamp array - long[] tmp = new long[tsCount]; - System.arraycopy(ourTimeStamps, startIdx, tmp, 0, tsCount); - ourTimeStamps = tmp; - } - return ourTimeStamps; - } - public double[] getRawSnapshots() { - return getRawSnapshots(getRawAbsoluteTimeStamps()); - } - /** - * Returns true if the timeStamp at curIdx is the one that ts is - * the closest to. - * We know that timeStamps[curIdx-1], if it exists, was not the closest. - */ - private static boolean isClosest(long ts, long[] timeStamps, int curIdx) { - if (curIdx >= (timeStamps.length - 1)) { - // curIdx is the last one so it must be the closest - return true; - } - if (ts == timeStamps[curIdx]) { - return true; - } - return closer(ts, timeStamps[curIdx], timeStamps[curIdx+1]); - } - - public boolean isTrimmedLeft() { - for (int i=0; i < this.values.length; i++) { - if (this.values[i].isTrimmedLeft()) { - return true; - } - } - return false; - } - - private double[] getRawSnapshots(long[] ourTimeStamps) { - double[] result = new double[ourTimeStamps.length]; -// System.out.println("DEBUG: producing " + result.length + " values"); - if (result.length > 0) { - for (int i=0; i < values.length; i++) { - long[] valueTimeStamps = values[i].getRawAbsoluteTimeStamps(); - double[] valueSnapshots = values[i].getRawSnapshots(); - double currentValue = 0.0; - int curIdx = 0; - if (values[i].isTrimmedLeft() && valueSnapshots.length > 0) { - currentValue = valueSnapshots[0]; - } -// System.out.println("DEBUG: inst#" + i + " has " + valueSnapshots.length + " values"); - for (int j=0; j < valueSnapshots.length; j++) { -// System.out.println("DEBUG: Doing v with" -// + " vTs[" + j + "]=" + valueTimeStamps[j] -// + " at mergeTs[" + curIdx + "]=" + ourTimeStamps[curIdx]); - while (!isClosest(valueTimeStamps[j], ourTimeStamps, curIdx)) { - if (descriptor.isCounter()) { - result[curIdx] += currentValue; - } -// System.out.println("DEBUG: skipping curIdx=" + curIdx -// + " valueTimeStamps[" + j + "]=" + valueTimeStamps[j] -// + " ourTimeStamps[" + curIdx + "]=" + ourTimeStamps[curIdx] -// + " ourTimeStamps[" + (curIdx+1) + "]=" + ourTimeStamps[curIdx+1]); - - curIdx++; - } - if (curIdx >= result.length) { - // Add this to workaround bug 30288 - int samplesSkipped = valueSnapshots.length - j; - StringBuffer msg = new StringBuffer(100); - msg.append("WARNING: dropping last "); - if (samplesSkipped == 1) { - msg.append("sample because it"); - } else { - msg.append(samplesSkipped).append(" samples because they"); - } - msg.append(" could not fit in the merged result."); - System.out.println(msg.toString()); - break; - } - currentValue = valueSnapshots[j]; - result[curIdx] += currentValue; - curIdx++; - } - if (descriptor.isCounter()) { - for (int j=curIdx; j < result.length; j++) { - result[j] += currentValue; - } - } - } - } - return result; - } - public double[] getSnapshots() { - double[] result; - if (filter != FILTER_NONE) { - long[] timestamps = getRawAbsoluteTimeStamps(); - double[] snapshots = getRawSnapshots(timestamps); - if (snapshots.length <= 1) { - return new double[0]; - } - result = new double[snapshots.length - 1]; - for (int i=0; i < result.length; i++) { - double valueDelta = snapshots[i+1] - snapshots[i]; - if (filter == FILTER_PERSEC) { - long timeDelta = timestamps[i+1] - timestamps[i]; - result[i] = valueDelta / (timeDelta / 1000.0); -// if (result[i] > valueDelta) { -// System.out.println("DEBUG: timeDelta was " + timeDelta + " ms."); -// System.out.println("DEBUG: valueDelta was " + valueDelta); -// System.out.println("DEBUG: valueDelta/sec was " + result[i]); -// } - } else { - result[i] = valueDelta; - } - } - } else { - result = getRawSnapshots(); - } - calcStats(result); - return result; - } - } - - /** - * Provides the value series related to a single statistics. - */ - private static class SimpleValue extends AbstractValue { - private final ResourceInst resource; - - private boolean useNextBits = false; - private long nextBits; - private final BitSeries series; - private boolean valueChangeNoticed = false; - - - public StatValue createTrimmed(long startTime, long endTime) { - if (startTime == this.startTime && endTime == this.endTime) { - return this; - } else { - return new SimpleValue(this, startTime, endTime); - } - } - - protected SimpleValue(ResourceInst resource, StatDescriptor sd) { - this.resource = resource; - if (sd.isCounter()) { - this.filter = FILTER_PERSEC; - } else { - this.filter = FILTER_NONE; - } - this.descriptor = sd; - this.series = new BitSeries(); - this.statsValid = false; - } - - private SimpleValue(SimpleValue in, long startTime, long endTime) { - this.startTime = startTime; - this.endTime = endTime; - this.useNextBits = in.useNextBits; - this.nextBits = in.nextBits; - this.resource = in.resource; - this.series = in.series; - this.descriptor = in.descriptor; - this.filter = in.filter; - this.statsValid = false; - this.valueChangeNoticed = true; - } - - public ResourceType getType() { - return this.resource.getType(); - } - - public ResourceInst[] getResources() { - return new ResourceInst[] {this.resource}; - } - - public boolean isTrimmedLeft() { - return getStartIdx() != 0; - } - - private int getStartIdx() { - int startIdx = 0; - if (startTime != -1) { - long startTimeStamp = startTime - resource.getTimeBase(); - long[] timestamps = resource.getAllRawTimeStamps(); - for (int i=resource.getFirstTimeStampIdx(); - i < resource.getFirstTimeStampIdx() + series.getSize(); - i++) { - if (timestamps[i] >= startTimeStamp) { - break; - } - startIdx++; - } - } - return startIdx; - } - private int getEndIdx(int startIdx) { - int endIdx = series.getSize()-1; - if (endTime != -1) { - long endTimeStamp = endTime - resource.getTimeBase(); - long[] timestamps = resource.getAllRawTimeStamps(); - endIdx = startIdx-1; - for (int i=resource.getFirstTimeStampIdx()+startIdx; - i < resource.getFirstTimeStampIdx() + series.getSize(); - i++) { - if (timestamps[i] >= endTimeStamp) { - break; - } - endIdx++; - } - Assert.assertTrue(endIdx == startIdx-1 || timestamps[endIdx] < endTimeStamp); - } - return endIdx; - } - public double[] getSnapshots() { - double[] result; - int startIdx = getStartIdx(); - int endIdx = getEndIdx(startIdx); - int resultSize=(endIdx-startIdx) + 1; - - if (filter != FILTER_NONE && resultSize > 1) { - long[] timestamps = null; - if (filter == FILTER_PERSEC) { - timestamps = resource.getAllRawTimeStamps(); - } - result = new double[resultSize-1]; - int tsIdx = resource.getFirstTimeStampIdx()+startIdx; - double[] values = series.getValuesEx(descriptor.getTypeCode(), startIdx, resultSize); - for (int i=0; i < result.length; i++) { - double valueDelta = values[i+1] - values[i]; - if (filter == FILTER_PERSEC) { - double timeDelta = (timestamps[tsIdx+i+1] - timestamps[tsIdx+i]); // millis - valueDelta /= (timeDelta / 1000); // per second - } - result[i] = valueDelta; - } - } else { - result = series.getValuesEx(descriptor.getTypeCode(), startIdx, resultSize); - } - calcStats(result); - return result; - } - - public double[] getRawSnapshots() { - int startIdx = getStartIdx(); - int endIdx = getEndIdx(startIdx); - int resultSize=(endIdx-startIdx) + 1; - return series.getValuesEx(descriptor.getTypeCode(), startIdx, resultSize); - } - - public long[] getRawAbsoluteTimeStampsWithSecondRes() { - long[] result = getRawAbsoluteTimeStamps(); - for (int i=0; i < result.length; i++) { - result[i] += 500; - result[i] /= 1000; - result[i] *= 1000; - } - return result; - } - - public long[] getRawAbsoluteTimeStamps() { - int startIdx = getStartIdx(); - int endIdx = getEndIdx(startIdx); - int resultSize=(endIdx-startIdx) + 1; - if (resultSize <= 0) { - return new long[0]; - } else { - long[] result = new long[resultSize]; - long[] timestamps = resource.getAllRawTimeStamps(); - int tsIdx = resource.getFirstTimeStampIdx()+startIdx; - long base = resource.getTimeBase(); - for (int i=0; i < resultSize; i++) { - result[i] = base + timestamps[tsIdx+i]; - } - return result; - } - } - - public boolean hasValueChanged() { - if (valueChangeNoticed) { - valueChangeNoticed = false; - return true; - } else { - return false; - } - } - protected int getMemoryUsed() { - int result = 0; - if (series != null) { - result += series.getMemoryUsed(); - } - return result; - } - - protected void dump(PrintWriter stream) { - calcStats(); - stream.print(" " + descriptor.getName() + "="); - stream.print("[size=" + getSnapshotsSize() - + " min=" + nf.format(min) - + " max=" + nf.format(max) - + " avg=" + nf.format(avg) - + " stddev=" + nf.format(stddev) + "]"); - if (Boolean.getBoolean("StatArchiveReader.dumpall")) { - series.dump(stream); - } else { - stream.println(); - } - } - - protected void shrink() { - this.series.shrink(); - } - - protected void initialValue(long v) { - this.series.initialBits(v); - } - protected void prepareNextBits(long bits) { - useNextBits = true; - nextBits = bits; - } - protected void addSample() { - statsValid = false; - if (useNextBits) { - useNextBits = false; - series.addBits(nextBits); - valueChangeNoticed = true; - } else { - series.addBits(0); - } - } - } - - private static abstract class BitInterval { - /** Returns number of items added to values */ - abstract int fill(double[] values, int valueOffset, int typeCode, int skipCount); - abstract void dump(PrintWriter stream); - abstract boolean attemptAdd(long addBits, long addInterval, int addCount); - int getMemoryUsed() { - return 0; - } - - protected int count; - - public final int getSampleCount() { - return this.count; - } - - static BitInterval create(long bits, long interval, int count) { - if (interval == 0) { - if (bits <= Integer.MAX_VALUE && bits >= Integer.MIN_VALUE) { - return new BitZeroIntInterval((int)bits, count); - } else { - return new BitZeroLongInterval(bits, count); - } - } else if (count <= 3) { - if (interval <= Byte.MAX_VALUE && interval >= Byte.MIN_VALUE) { - return new BitExplicitByteInterval(bits, interval, count); - } else if (interval <= Short.MAX_VALUE && interval >= Short.MIN_VALUE) { - return new BitExplicitShortInterval(bits, interval, count); - } else if (interval <= Integer.MAX_VALUE && interval >= Integer.MIN_VALUE) { - return new BitExplicitIntInterval(bits, interval, count); - } else { - return new BitExplicitLongInterval(bits, interval, count); - } - } else { - boolean smallBits = false; - boolean smallInterval = false; - if (bits <= Integer.MAX_VALUE && bits >= Integer.MIN_VALUE) { - smallBits = true; - } - if (interval <= Integer.MAX_VALUE && interval >= Integer.MIN_VALUE) { - smallInterval = true; - } - if (smallBits) { - if (smallInterval) { - return new BitNonZeroIntIntInterval((int)bits, (int)interval, count); - } else { - return new BitNonZeroIntLongInterval((int)bits, interval, count); - } - } else { - if (smallInterval) { - return new BitNonZeroLongIntInterval(bits, (int)interval, count); - } else { - return new BitNonZeroLongLongInterval(bits, interval, count); - } - } - } - } - } - - private static abstract class BitNonZeroInterval extends BitInterval { - @Override - int getMemoryUsed() { - return super.getMemoryUsed() + 4; - } - abstract long getBits(); - abstract long getInterval(); - - @Override - int fill(double[] values, int valueOffset, int typeCode, int skipCount) { - int fillcount = values.length - valueOffset; // space left in values - int maxCount = count - skipCount; // maximum values this interval can produce - if (fillcount > maxCount) { - fillcount = maxCount; - } - long base = getBits(); - long interval = getInterval(); - base += skipCount * interval; - for (int i=0; i < fillcount; i++) { - values[valueOffset+i] = bitsToDouble(typeCode, base); - base += interval; - } - return fillcount; - } - - @Override - void dump(PrintWriter stream) { - stream.print(getBits()); - if (count > 1) { - long interval = getInterval(); - if (interval != 0) { - stream.print("+=" + interval); - } - stream.print("r" + count); - } - } - BitNonZeroInterval(int count) { - this.count = count; - } - @Override - boolean attemptAdd(long addBits, long addInterval, int addCount) { - // addCount >= 2; count >= 2 - if (addInterval == getInterval()) { - if (addBits == (getBits() + (addInterval * (count-1)))) { - count += addCount; - return true; - } - } - return false; - } - } - - private static class BitNonZeroIntIntInterval extends BitNonZeroInterval { - int bits; - int interval; - - @Override - int getMemoryUsed() { - return super.getMemoryUsed() + 8; - } - @Override - long getBits() { - return this.bits; - } - @Override - long getInterval() { - return this.interval; - } - - BitNonZeroIntIntInterval(int bits, int interval, int count) { - super(count); - this.bits = bits; - this.interval = interval; - } - } - - private static class BitNonZeroIntLongInterval extends BitNonZeroInterval { - int bits; - long interval; - - @Override - int getMemoryUsed() { - return super.getMemoryUsed() + 12; - } - @Override - long getBits() { - return this.bits; - } - @Override - long getInterval() { - return this.interval; - } - - BitNonZeroIntLongInterval(int bits, long interval, int count) { - super(count); - this.bits = bits; - this.interval = interval; - } - } - - private static class BitNonZeroLongIntInterval extends BitNonZeroInterval { - long bits; - int interval; - - @Override - int getMemoryUsed() { - return super.getMemoryUsed() + 12; - } - @Override - long getBits() { - return this.bits; - } - @Override - long getInterval() { - return this.interval; - } - - BitNonZeroLongIntInterval(long bits, int interval, int count) { - super(count); - this.bits = bits; - this.interval = interval; - } - } - - private static class BitNonZeroLongLongInterval extends BitNonZeroInterval { - long bits; - long interval; - - @Override - int getMemoryUsed() { - return super.getMemoryUsed() + 16; - } - @Override - long getBits() { - return this.bits; - } - @Override - long getInterval() { - return this.interval; - } - - BitNonZeroLongLongInterval(long bits, long interval, int count) { - super(count); - this.bits = bits; - this.interval = interval; - } - } - - private static abstract class BitZeroInterval extends BitInterval { - @Override - int getMemoryUsed() { - return super.getMemoryUsed() + 4; - } - abstract long getBits(); - - @Override - int fill(double[] values, int valueOffset, int typeCode, int skipCount) { - int fillcount = values.length - valueOffset; // space left in values - int maxCount = count - skipCount; // maximum values this interval can produce - if (fillcount > maxCount) { - fillcount = maxCount; - } - double value = bitsToDouble(typeCode, getBits()); - for (int i=0; i < fillcount; i++) { - values[valueOffset+i] = value; - } - return fillcount; - } - - @Override - void dump(PrintWriter stream) { - stream.print(getBits()); - if (count > 1) { - stream.print("r" + count); - } - } - BitZeroInterval(int count) { - this.count = count; - } - @Override - boolean attemptAdd(long addBits, long addInterval, int addCount) { - // addCount >= 2; count >= 2 - if (addInterval == 0 && addBits == getBits()) { - count += addCount; - return true; - } - return false; - } - } - - private static class BitZeroIntInterval extends BitZeroInterval { - int bits; - - @Override - int getMemoryUsed() { - return super.getMemoryUsed() + 4; - } - @Override - long getBits() { - return bits; - } - BitZeroIntInterval(int bits, int count) { - super(count); - this.bits = bits; - } - } - - private static class BitZeroLongInterval extends BitZeroInterval { - long bits; - - @Override - int getMemoryUsed() { - return super.getMemoryUsed() + 8; - } - @Override - long getBits() { - return bits; - } - BitZeroLongInterval(long bits, int count) { - super(count); - this.bits = bits; - } - } - - private static class BitExplicitByteInterval extends BitInterval { - long firstValue; - long lastValue; - byte[] bitIntervals = null; - - @Override - int getMemoryUsed() { - int result = super.getMemoryUsed() + 4 + 8 + 8 + 4; - if (bitIntervals != null) { - result += bitIntervals.length; - } - return result; - } - @Override - int fill(double[] values, int valueOffset, int typeCode, int skipCount) { - int fillcount = values.length - valueOffset; // space left in values - int maxCount = count - skipCount; // maximum values this interval can produce - if (fillcount > maxCount) { - fillcount = maxCount; - } - long bitValue = firstValue; - for (int i=0; i < skipCount; i++) { - bitValue += bitIntervals[i]; - } - for (int i=0; i < fillcount; i++) { - bitValue += bitIntervals[skipCount+i]; - values[valueOffset+i] = bitsToDouble(typeCode, bitValue); - } - return fillcount; - } - - @Override - void dump(PrintWriter stream) { - stream.print("(byteIntervalCount=" + count + " start=" + firstValue); - for (int i=0; i < count; i++) { - if (i != 0) { - stream.print(", "); - } - stream.print(bitIntervals[i]); - } - stream.print(")"); - } - BitExplicitByteInterval(long bits, long interval, int addCount) { - count = addCount; - firstValue = bits; - lastValue = bits + (interval * (addCount-1)); - bitIntervals = new byte[count*2]; - bitIntervals[0] = 0; - for (int i=1; i < count; i++) { - bitIntervals[i] = (byte)interval; - } - } - @Override - boolean attemptAdd(long addBits, long addInterval, int addCount) { - // addCount >= 2; count >= 2 - if (addCount <= 11) { - if (addInterval <= Byte.MAX_VALUE && addInterval >= Byte.MIN_VALUE) { - long firstInterval = addBits - lastValue; - if (firstInterval <= Byte.MAX_VALUE && firstInterval >= Byte.MIN_VALUE) { - lastValue = addBits + (addInterval * (addCount-1)); - if ((count + addCount) >= bitIntervals.length) { - byte[] tmp = new byte[(count+addCount)*2]; - System.arraycopy(bitIntervals, 0, tmp, 0, bitIntervals.length); - bitIntervals = tmp; - } - bitIntervals[count++] = (byte)firstInterval; - for (int i=1; i < addCount; i++) { - bitIntervals[count++] = (byte)addInterval; - } - return true; - } - } - } - return false; - } - } - - private static class BitExplicitShortInterval extends BitInterval { - long firstValue; - long lastValue; - short[] bitIntervals = null; - - @Override - int getMemoryUsed() { - int result = super.getMemoryUsed() + 4 + 8 + 8 + 4; - if (bitIntervals != null) { - result += bitIntervals.length * 2; - } - return result; - } - - @Override - int fill(double[] values, int valueOffset, int typeCode, int skipCount) { - int fillcount = values.length - valueOffset; // space left in values - int maxCount = count - skipCount; // maximum values this interval can produce - if (fillcount > maxCount) { - fillcount = maxCount; - } - long bitValue = firstValue; - for (int i=0; i < skipCount; i++) { - bitValue += bitIntervals[i]; - } - for (int i=0; i < fillcount; i++) { - bitValue += bitIntervals[skipCount+i]; - values[valueOffset+i] = bitsToDouble(typeCode, bitValue); - } - return fillcount; - } - - @Override - void dump(PrintWriter stream) { - stream.print("(shortIntervalCount=" + count + " start=" + firstValue); - for (int i=0; i < count; i++) { - if (i != 0) { - stream.print(", "); - } - stream.print(bitIntervals[i]); - } - stream.print(")"); - } - BitExplicitShortInterval(long bits, long interval, int addCount) { - count = addCount; - firstValue = bits; - lastValue = bits + (interval * (addCount-1)); - bitIntervals = new short[count*2]; - bitIntervals[0] = 0; - for (int i=1; i < count; i++) { - bitIntervals[i] = (short)interval; - } - } - @Override - boolean attemptAdd(long addBits, long addInterval, int addCount) { - // addCount >= 2; count >= 2 - if (addCount <= 6) { - if (addInterval <= Short.MAX_VALUE && addInterval >= Short.MIN_VALUE) { - long firstInterval = addBits - lastValue; - if (firstInterval <= Short.MAX_VALUE && firstInterval >= Short.MIN_VALUE) { - lastValue = addBits + (addInterval * (addCount-1)); - if ((count + addCount) >= bitIntervals.length) { - short[] tmp = new short[(count+addCount)*2]; - System.arraycopy(bitIntervals, 0, tmp, 0, bitIntervals.length); - bitIntervals = tmp; - } - bitIntervals[count++] = (short)firstInterval; - for (int i=1; i < addCount; i++) { - bitIntervals[count++] = (short)addInterval; - } - return true; - } - } - } - return false; - } - } - - private static class BitExplicitIntInterval extends BitInterval { - long firstValue; - long lastValue; - int[] bitIntervals = null; - - @Override - int getMemoryUsed() { - int result = super.getMemoryUsed() + 4 + 8 + 8 + 4; - if (bitIntervals != null) { - result += bitIntervals.length * 4; - } - return result; - } - - @Override - int fill(double[] values, int valueOffset, int typeCode, int skipCount) { - int fillcount = values.length - valueOffset; // space left in values - int maxCount = count - skipCount; // maximum values this interval can produce - if (fillcount > maxCount) { - fillcount = maxCount; - } - long bitValue = firstValue; - for (int i=0; i < skipCount; i++) { - bitValue += bitIntervals[i]; - } - for (int i=0; i < fillcount; i++) { - bitValue += bitIntervals[skipCount+i]; - values[valueOffset+i] = bitsToDouble(typeCode, bitValue); - } - return fillcount; - } - - @Override - void dump(PrintWriter stream) { - stream.print("(intIntervalCount=" + count + " start=" + firstValue); - for (int i=0; i < count; i++) { - if (i != 0) { - stream.print(", "); - } - stream.print(bitIntervals[i]); - } - stream.print(")"); - } - BitExplicitIntInterval(long bits, long interval, int addCount) { - count = addCount; - firstValue = bits; - lastValue = bits + (interval * (addCount-1)); - bitIntervals = new int[count*2]; - bitIntervals[0] = 0; - for (int i=1; i < count; i++) { - bitIntervals[i] = (int)interval; - } - } - @Override - boolean attemptAdd(long addBits, long addInterval, int addCount) { - // addCount >= 2; count >= 2 - if (addCount <= 4) { - if (addInterval <= Integer.MAX_VALUE && addInterval >= Integer.MIN_VALUE) { - long firstInterval = addBits - lastValue; - if (firstInterval <= Integer.MAX_VALUE && firstInterval >= Integer.MIN_VALUE) { - lastValue = addBits + (addInterval * (addCount-1)); - if ((count + addCount) >= bitIntervals.length) { - int[] tmp = new int[(count+addCount)*2]; - System.arraycopy(bitIntervals, 0, tmp, 0, bitIntervals.length); - bitIntervals = tmp; - } - bitIntervals[count++] = (int)firstInterval; - for (int i=1; i < addCount; i++) { - bitIntervals[count++] = (int)addInterval; - } - return true; - } - } - } - return false; - } - } - - private static class BitExplicitLongInterval extends BitInterval { - long[] bitArray = null; - - @Override - int getMemoryUsed() { - int result = super.getMemoryUsed() + 4 + 4; - if (bitArray != null) { - result += bitArray.length * 8; - } - return result; - } - - @Override - int fill(double[] values, int valueOffset, int typeCode, int skipCount) { - int fillcount = values.length - valueOffset; // space left in values - int maxCount = count - skipCount; // maximum values this interval can produce - if (fillcount > maxCount) { - fillcount = maxCount; - } - for (int i=0; i < fillcount; i++) { - values[valueOffset+i] = bitsToDouble(typeCode, bitArray[skipCount+i]); - } - return fillcount; - } - - @Override - void dump(PrintWriter stream) { - stream.print("(count=" + count + " "); - for (int i=0; i < count; i++) { - if (i != 0) { - stream.print(", "); - } - stream.print(bitArray[i]); - } - stream.print(")"); - } - BitExplicitLongInterval(long bits, long interval, int addCount) { - count = addCount; - bitArray = new long[count*2]; - for (int i=0; i < count; i++) { - bitArray[i] = bits; - bits += interval; - } - } - @Override - boolean attemptAdd(long addBits, long addInterval, int addCount) { - // addCount >= 2; count >= 2 - if (addCount <= 3) { - if ((count + addCount) >= bitArray.length) { - long[] tmp = new long[(count+addCount)*2]; - System.arraycopy(bitArray, 0, tmp, 0, bitArray.length); - bitArray = tmp; - } - for (int i=0; i < addCount; i++) { - bitArray[count++] = addBits; - addBits += addInterval; - } - return true; - } - return false; - } - } - - private static class BitSeries { - int count; // number of items in this series - long currentStartBits; - long currentEndBits; - long currentInterval; - int currentCount; - int intervalIdx; // index of most recent BitInterval - BitInterval intervals[]; - - /** - * Returns the amount of memory used to implement this series. - */ - protected int getMemoryUsed() { - int result = 4 + 8 + 8 + 8 + 4 + 4 + 4; - if (intervals != null) { - result += 4 * intervals.length; - for (int i=0; i <= intervalIdx; i++) { - result += intervals[i].getMemoryUsed(); - } - } - return result; - } - - public double[] getValues(int typeCode) { - return getValuesEx(typeCode, 0, getSize()); - } - /** - * Gets the first "resultSize" values of this series - * skipping over the first "samplesToSkip" ones. - * The first value in a series is at index 0. - * The maximum result size can be obtained by calling "getSize()". - */ - public double[] getValuesEx(int typeCode, int samplesToSkip, int resultSize) { - double[] result = new double[resultSize]; - int firstInterval = 0; - int idx = 0; - while (samplesToSkip > 0 - && firstInterval <= intervalIdx - && intervals[firstInterval].getSampleCount() <= samplesToSkip) { - samplesToSkip -= intervals[firstInterval].getSampleCount(); - firstInterval++; - } - for (int i=firstInterval; i <= intervalIdx; i++) { - idx += intervals[i].fill(result, idx, typeCode, samplesToSkip); - samplesToSkip = 0; - } - if (currentCount != 0) { - idx += BitInterval.create(currentStartBits, currentInterval, currentCount).fill(result, idx, typeCode, samplesToSkip); - } - // assert - if (idx != resultSize) { - throw new InternalGemFireException(LocalizedStrings.StatArchiveReader_GETVALUESEX_DIDNT_FILL_THE_LAST_0_ENTRIES_OF_ITS_RESULT.toLocalizedString(Integer.valueOf(resultSize-idx))); - } - return result; - } - - void dump(PrintWriter stream) { - stream.print("[size=" + count + " intervals=" + (intervalIdx+1) - + " memused=" + getMemoryUsed() + " "); - for (int i=0; i <= intervalIdx; i++) { - if (i != 0) { - stream.print(", "); - } - intervals[i].dump(stream); - } - if (currentCount != 0) { - if (intervalIdx != -1) { - stream.print(", "); - } - BitInterval.create(currentStartBits, currentInterval, currentCount).dump(stream); - } - stream.println("]"); - } - - BitSeries() { - count = 0; - currentStartBits = 0; - currentEndBits = 0; - currentInterval = 0; - currentCount = 0; - intervalIdx = -1; - intervals = null; - } - - void initialBits(long bits) { - this.currentEndBits = bits; - } - - int getSize() { - return this.count; - } - - void addBits(long deltaBits) { - long bits = currentEndBits + deltaBits; - if (currentCount == 0) { - currentStartBits = bits; - currentCount = 1; - } else if (currentCount == 1) { - currentInterval = deltaBits; - currentCount++; - } else if (deltaBits == currentInterval) { - currentCount++; - } else { - // we need to move currentBits into a BitInterval - if (intervalIdx == -1) { - intervals = new BitInterval[2]; - intervalIdx = 0; - intervals[0] = BitInterval.create(currentStartBits, currentInterval, currentCount); - } else { - if (!intervals[intervalIdx].attemptAdd(currentStartBits, currentInterval, currentCount)) { - // wouldn't fit in current bit interval so add a new one - intervalIdx++; - if (intervalIdx >= intervals.length) { - BitInterval[] tmp = new BitInterval[intervals.length * 2]; - System.arraycopy(intervals, 0, tmp, 0, intervals.length); - intervals = tmp; - } - intervals[intervalIdx] = BitInterval.create(currentStartBits, currentInterval, currentCount); - } - } - // now start a new currentBits - currentStartBits = bits; - currentCount = 1; - } - currentEndBits = bits; - count++; - } - /** - * Free up any unused memory - */ - void shrink() { - if (intervals != null) { - int currentSize = intervalIdx+1; - if (currentSize < intervals.length) { - BitInterval[] tmp = new BitInterval[currentSize]; - System.arraycopy(intervals, 0, tmp, 0, currentSize); - intervals = tmp; - } - } - } - } - - private static class TimeStampSeries { - static private final int GROW_SIZE = 256; - int count; // number of items in this series - long base; // millis since midnight, Jan 1, 1970 UTC. - long[] timeStamps = new long[GROW_SIZE]; // elapsed millis from base - - void dump(PrintWriter stream) { - stream.print("[size=" + count); - for (int i=0; i < count; i++) { - if (i != 0) { - stream.print(", "); - stream.print(timeStamps[i]-timeStamps[i-1]); - } else { - stream.print(" " + timeStamps[i]); - } - } - stream.println("]"); - } - - void shrink() { - if (count < timeStamps.length) { - long[] tmp = new long[count]; - System.arraycopy(timeStamps, 0, tmp, 0, count); - timeStamps = tmp; - } - } - - TimeStampSeries() { - count = 0; - base = 0; - } - - void setBase(long base) { - this.base = base; - } - - int getSize() { - return this.count; - } - - void addTimeStamp(int ts) { - if (count >= timeStamps.length) { - long[] tmp = new long[timeStamps.length + GROW_SIZE]; - System.arraycopy(timeStamps, 0, tmp, 0, timeStamps.length); - timeStamps = tmp; - } - if (count != 0) { - timeStamps[count] = timeStamps[count-1] + ts; - } else { - timeStamps[count] = ts; - } - count++; - } - - long getBase() { - return this.base; - } - /** Provides direct access to underlying data. - * Do not modify contents and use getSize() to keep from reading - * past end of array. - */ - long[] getRawTimeStamps() { - return this.timeStamps; - } - long getMilliTimeStamp(int idx) { - return this.base + this.timeStamps[idx]; - } - /** - * Returns an array of time stamp values the first of which - * has the specified index. - * Each returned time stamp is the number of millis since - * midnight, Jan 1, 1970 UTC. - */ - double[] getTimeValuesSinceIdx(int idx) { - int resultSize = this.count - idx; - double[] result = new double[resultSize]; - for (int i=0; i < resultSize; i++) { - result[i] = getMilliTimeStamp(idx+i); - } - return result; - } - } - - /** - * Defines a statistic resource type. Each resource instance must be - * of a single type. The type defines what statistics each instance - * of it will support. The type also has a description of itself. - */ - public static class ResourceType { - private boolean loaded; -// private final int id; - private final String name; - private String desc; - private final StatDescriptor[] stats; - private Map descriptorMap; - - public void dump(PrintWriter stream) { - if (loaded) { - stream.println(name + ": " + desc); - for (int i=0; i < stats.length; i++) { - stats[i].dump(stream); - } - } - } - - protected ResourceType(int id, String name, int statCount) { - this.loaded = false; -// this.id = id; - this.name = name; - this.desc = null; - this.stats = new StatDescriptor[statCount]; - this.descriptorMap = null; - } - - protected ResourceType(int id, String name, String desc, int statCount) { - this.loaded = true; -// this.id = id; - this.name = name; - this.desc = desc; - this.stats = new StatDescriptor[statCount]; - this.descriptorMap = new HashMap(); - } - public boolean isLoaded() { - return this.loaded; - } - /** - * Frees up any resources no longer needed after the archive file is closed. - * Returns true if this guy is no longer needed. - */ - protected boolean close() { - if (isLoaded()) { - for (int i=0; i < stats.length; i++) { - if (stats[i] != null) { - if (!stats[i].isLoaded()) { - stats[i] = null; - } - } - } - return false; - } else { - return true; - } - } - - void unload() { - this.loaded = false; - this.desc = null; - for (int i=0; i < this.stats.length; i++) { - this.stats[i].unload(); - } - this.descriptorMap.clear(); - this.descriptorMap = null; - } - - protected void addStatDescriptor(StatArchiveFile archive, int offset, String name, boolean isCounter, - boolean largerBetter, - byte typeCode, String units, String desc) { - StatDescriptor descriptor = new StatDescriptor(name, offset, isCounter, largerBetter, typeCode, units, desc); - this.stats[offset] = descriptor; - if (archive.loadStatDescriptor(descriptor, this)) { - descriptorMap.put(name, descriptor); - } - } - -// private int getId() { -// return this.id; -// } - /** - * Returns the name of this resource type. - */ - public String getName() { - return this.name; - } - /** - * Returns an array of descriptors for each statistic this resource - * type supports. - */ - public StatDescriptor[] getStats() { - return this.stats; - } - /** - * Gets a stat descriptor contained in this type given the stats name. - * @param name the name of the stat to find in the current type - * @return the descriptor that matches the name or null if the type - * does not have a stat of the given name - */ - public StatDescriptor getStat(String name) { - return (StatDescriptor)descriptorMap.get(name); - } - /** - * Returns a description of this resource type. - */ - public String getDescription() { - return this.desc; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.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; - ResourceType other = (ResourceType) obj; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - return true; - } - } - - /** - * Describes some global information about the archive. - */ - public static class ArchiveInfo { - private final StatArchiveFile archive; - private final byte archiveVersion; - private final long startTimeStamp; // in milliseconds - private final long systemStartTimeStamp; // in milliseconds - private final int timeZoneOffset; - private final String timeZoneName; - private final String systemDirectory; - private final long systemId; - private final String productVersion; - private final String os; - private final String machine; - - public ArchiveInfo(StatArchiveFile archive, byte archiveVersion, - long startTimeStamp, long systemStartTimeStamp, - int timeZoneOffset,String timeZoneName, - String systemDirectory, long systemId, - String productVersion, String os, String machine) { - this.archive = archive; - this.archiveVersion = archiveVersion; - this.startTimeStamp = startTimeStamp; - this.systemStartTimeStamp = systemStartTimeStamp; - this.timeZoneOffset = timeZoneOffset; - this.timeZoneName = timeZoneName; - this.systemDirectory = systemDirectory; - this.systemId = systemId; - this.productVersion = productVersion; - this.os = os; - this.machine = machine; - archive.setTimeZone(getTimeZone()); - } - - /** - * Returns the difference, measured in milliseconds, between the time - * the archive file was create and midnight, January 1, 1970 UTC. - */ - public long getStartTimeMillis() { - return this.startTimeStamp; - } - /** - * Returns the difference, measured in milliseconds, between the time - * the archived system was started and midnight, January 1, 1970 UTC. - */ - public long getSystemStartTimeMillis() { - return this.systemStartTimeStamp; - } - /** - * Returns a numeric id of the archived system. It can be used in - * conjunction with the {@link #getSystemStartTimeMillis} to - * uniquely identify an archived system. - */ - public long getSystemId() { - return this.systemId; - } - /** - * Returns a string describing the operating system the archive was - * written on. - */ - public String getOs() { - return this.os; - } - /** - * Returns a string describing the machine the archive was - * written on. - */ - public String getMachine() { - return this.machine; - } - /** - * Returns the time zone used when the archive was created. - * This can be used to print timestamps in the same time zone - * that was in effect when the archive was created. - */ - public TimeZone getTimeZone() { - TimeZone result = TimeZone.getTimeZone(this.timeZoneName); - if (result.getRawOffset() != this.timeZoneOffset) { - result = new SimpleTimeZone(this.timeZoneOffset, this.timeZoneName); - } - return result; - } - /** - * Returns a string containing the version of the product that wrote - * this archive. - */ - public String getProductVersion() { - return this.productVersion; - } - /** - * Returns a numeric code that represents the format version used to - * encode the archive as a stream of bytes. - */ - public int getArchiveFormatVersion() { - return this.archiveVersion; - } - /** - * Returns a string describing the system that this archive recorded. - */ - public String getSystem() { - return this.systemDirectory; - } - /** - * Return the name of the file this archive was stored in or - * an empty string if the archive was not stored in a file. - */ - public String getArchiveFileName() { - if (this.archive != null) { - return this.archive.getFile().getPath(); - } else { - return ""; - } - } - - /** - * Returns a string representation of this object. - */ - @Override - public String toString() { - StringWriter sw = new StringWriter(); - this.dump(new PrintWriter(sw)); - return sw.toString(); - } - - protected void dump(PrintWriter stream) { - if (archive != null) { - stream.println("archive=" + archive.getFile()); - } - stream.println("archiveVersion=" + archiveVersion); - if (archive != null) { - stream.println("startDate=" + archive.formatTimeMillis(startTimeStamp)); - } - // stream.println("startTimeStamp=" + startTimeStamp +" tz=" + timeZoneName + " tzOffset=" + timeZoneOffset); - // stream.println("timeZone=" + getTimeZone().getDisplayName()); - stream.println("systemDirectory=" + systemDirectory); - if (archive != null) { - stream.println("systemStartDate=" + archive.formatTimeMillis(systemStartTimeStamp)); - } - stream.println("systemId=" + systemId); - stream.println("productVersion=" + productVersion); - stream.println("osInfo=" + os); - stream.println("machineInfo=" + machine); - } - } - - /** - * Defines a single instance of a resource type. - */ - public static class ResourceInst { - private final boolean loaded; - private final StatArchiveFile archive; -// private final int uniqueId; - private final ResourceType type; - private final String name; - private final long id; - private boolean active = true; - private final SimpleValue[] values; - private int firstTSidx = -1; - private int lastTSidx = -1; - - /** - * Returns the approximate amount of memory used to implement this object. - */ - protected int getMemoryUsed() { - int result = 0; - if (values != null) { - for (int i=0; i < values.length; i++) { - result += this.values[i].getMemoryUsed(); - } - } - return result; - } - - public StatArchiveReader getReader() { - return archive.getReader(); - } - /** - * Returns a string representation of this object. - */ - @Override - public String toString() { - StringBuffer result = new StringBuffer(); - result.append(name) - .append(", ") - .append(id) - .append(", ") - .append(type.getName()) - .append(": \"") - .append(archive.formatTimeMillis(getFirstTimeMillis())) - .append('\"'); - if (!active) { - result.append(" inactive"); - } - result.append(" samples="+ getSampleCount()); - return result.toString(); - } - /** - * Returns the number of times this resource instance has been sampled. - */ - public int getSampleCount() { - if (active) { - return archive.getTimeStamps().getSize() - firstTSidx; - } else { - return (lastTSidx+1) - firstTSidx; - } - } - - public StatArchiveFile getArchive() { - return this.archive; - } - - protected void dump(PrintWriter stream) { - stream.println(name + ":" - + " file=" + getArchive().getFile() - + " id=" + id - + (active? "" : " deleted") - + " start=" + archive.formatTimeMillis(getFirstTimeMillis())); - for (int i=0; i < values.length; i++) { - values[i].dump(stream); - } - } - - protected ResourceInst(StatArchiveFile archive, int uniqueId, String name, long id, ResourceType type, boolean loaded) { - this.loaded = loaded; - this.archive = archive; -// this.uniqueId = uniqueId; - this.name = name; - this.id = id; - Assert.assertTrue(type != null); - this.type = type; - if (loaded) { - StatDescriptor[] stats = type.getStats(); - this.values = new SimpleValue[stats.length]; - for (int i=0; i < stats.length; i++) { - if (archive.loadStat(stats[i], this)) { - this.values[i] = new SimpleValue(this, stats[i]); - } else { - this.values[i] = null; - } - } - } else { - this.values = null; - } - } - - void matchSpec(StatSpec spec, List matchedValues) { - if (spec.typeMatches(this.type.getName())) { - if (spec.instanceMatches(this.getName(), this.getId())) { - for (int statIdx=0; statIdx < values.length; statIdx++) { - if (values[statIdx] != null) { - if (spec.statMatches(values[statIdx].getDescriptor().getName())) { - matchedValues.add(values[statIdx]); - } - } - } - } - } - } - - protected void initialValue(int statOffset, long v) { - if (this.values != null && this.values[statOffset] != null) { - this.values[statOffset].initialValue(v); - } - } - /** - * Returns true if sample was added. - */ - protected boolean addValueSample(int statOffset, long statDeltaBits) { - if (this.values != null && this.values[statOffset] != null) { - this.values[statOffset].prepareNextBits(statDeltaBits); - return true; - } else { - return false; - } - } - - public boolean isLoaded() { - return this.loaded; - } - - /** - * Frees up any resources no longer needed after the archive file is closed. - * Returns true if this guy is no longer needed. - */ - protected boolean close() { - if (isLoaded()) { - for (int i=0; i < values.length; i++) { - if (values[i] != null) { - values[i].shrink(); - } - } - return false; - } else { - return true; - } - } - - protected int getFirstTimeStampIdx() { - return this.firstTSidx; - } - protected long[] getAllRawTimeStamps() { - return archive.getTimeStamps().getRawTimeStamps(); - } - protected long getTimeBase() { - return archive.getTimeStamps().getBase(); - } - /** - * Returns an array of doubles containing the timestamps at which - * this instances samples where taken. Each of these timestamps - * is the difference, measured in milliseconds, between the sample - * time and midnight, January 1, 1970 UTC. - * Although these values are double they can safely be converted - * to <code>long</code> with no loss of information. - */ - public double[] getSnapshotTimesMillis() { - return archive.getTimeStamps().getTimeValuesSinceIdx(firstTSidx); - } - /** - * Returns an array of statistic value descriptors. Each element - * of the array describes the corresponding statistic this instance - * supports. The <code>StatValue</code> instances can be used to - * obtain the actual sampled values of the instances statistics. - */ - public StatValue[] getStatValues() { - return this.values; - } - /** - * Gets the value of the stat in the current instance given the stat name. - * @param name the name of the stat to find in the current instance - * @return the value that matches the name or null if the instance - * does not have a stat of the given name - * - */ - public StatValue getStatValue(String name) { - StatValue result = null; - StatDescriptor desc = getType().getStat(name); - if (desc != null) { - result = values[desc.getOffset()]; - } - return result; - } - - /** - * Returns the name of this instance. - */ - public String getName() { - return this.name; - } - /** - * Returns the id of this instance. - */ - public long getId() { - return this.id; - } - /** - * Returns the difference, measured in milliseconds, between the time - * of the instance's first sample and midnight, January 1, 1970 UTC. - */ - public long getFirstTimeMillis() { - return archive.getTimeStamps().getMilliTimeStamp(firstTSidx); - } - /** - * Returns resource type of this instance. - */ - public ResourceType getType() { - return this.type; - } - protected void makeInactive() { - this.active = false; - lastTSidx = archive.getTimeStamps().getSize() - 1; - close(); // this frees up unused memory now that no more samples - } - /** - * Returns true if archive might still have future samples for this instance. - */ - public boolean isActive() { - return this.active; - } - protected void addTimeStamp() { - if (this.loaded) { - if (firstTSidx == -1) { - firstTSidx = archive.getTimeStamps().getSize() - 1; - } - for (int i=0; i < values.length; i++) { - if (values[i] != null) { - values[i].addSample(); - } - } - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + (int) (id ^ (id >>> 32)); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((type == null) ? 0 : type.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getCl
<TRUNCATED>
