/*
 * 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 org.apache.geode.internal.statistics;

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;

import org.apache.geode.GemFireIOException;
import org.apache.geode.InternalGemFireException;
import org.apache.geode.internal.Assert;
import org.apache.geode.internal.ExitCode;
import org.apache.geode.internal.logging.DateFormatter;

/**
 * StatArchiveReader provides APIs to read statistic snapshots from an archive file.
 */
public class StatArchiveReader implements StatArchiveFormat, AutoCloseable {

  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.
   */
  @Override
  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(String.format("Unexpected typecode %s",
            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]");
      ExitCode.FATAL.doSystemExit();
    } 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;
    }

    @Override
    public int getCombineType() {
      return StatSpec.NONE;
    }

    @Override
    public boolean typeMatches(String typeName) {
      return spec.typeMatches(typeName);
    }

    @Override
    public boolean statMatches(String statName) {
      return spec.statMatches(statName);
    }

    @Override
    public boolean instanceMatches(String textId, long numericId) {
      return spec.instanceMatches(textId, numericId);
    }

    @Override
    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 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}.
     */
    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}.
     */
    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}.
     */
    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.
     */
    StatValue createTrimmed(long startTime, long endTime);

    /**
     * Returns true if value has data that has been trimmed off it by a start timestamp.
     */
    boolean isTrimmedLeft();

    /**
     * Gets the {@link StatArchiveReader.ResourceType type} of the resources that this value belongs
     * to.
     */
    ResourceType getType();

    /**
     * Gets the {@link StatArchiveReader.ResourceInst resources} that this value belongs to.
     */
    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.
     */
    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.
     */
    long[] getRawAbsoluteTimeStampsWithSecondRes();

    /**
     * Returns an array of doubles containing the unfiltered value of this statistic for each point
     * in time that it was sampled.
     */
    double[] getRawSnapshots();

    /**
     * Returns an array of doubles containing the filtered value of this statistic for each point in
     * time that it was sampled.
     */
    double[] getSnapshots();

    /**
     * Returns the number of samples taken of this statistic's value.
     */
    int getSnapshotsSize();

    /**
     * Returns the smallest of all the samples taken of this statistic's value.
     */
    double getSnapshotsMinimum();

    /**
     * Returns the largest of all the samples taken of this statistic's value.
     */
    double getSnapshotsMaximum();

    /**
     * Returns the average of all the samples taken of this statistic's value.
     */
    double getSnapshotsAverage();

    /**
     * Returns the standard deviation of all the samples taken of this statistic's value.
     */
    double getSnapshotsStandardDeviation();

    /**
     * Returns the most recent value of all the samples taken of this statistic's value.
     */
    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.
     */
    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>
     */
    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.
     */
    void setFilter(int filter);

    /**
     * Returns a description of this statistic.
     */
    StatDescriptor getDescriptor();
  }

  protected abstract static 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();
      }
    }

    @Override
    public int getSnapshotsSize() {
      calcStats();
      return this.size;
    }

    @Override
    public double getSnapshotsMinimum() {
      calcStats();
      return this.min;
    }

    @Override
    public double getSnapshotsMaximum() {
      calcStats();
      return this.max;
    }

    @Override
    public double getSnapshotsAverage() {
      calcStats();
      return this.avg;
    }

    @Override
    public double getSnapshotsStandardDeviation() {
      calcStats();
      return this.stddev;
    }

    @Override
    public double getSnapshotsMostRecent() {
      calcStats();
      return this.mostRecent;
    }

    @Override
    public StatDescriptor getDescriptor() {
      return this.descriptor;
    }

    @Override
    public int getFilter() {
      return this.filter;
    }

    @Override
    public void setFilter(int filter) {
      if (filter != this.filter) {
        if (filter != FILTER_NONE && filter != FILTER_PERSEC && filter != FILTER_PERSAMPLE) {
          throw new IllegalArgumentException(
              String.format("Filter value %s must be %s, %s, or %s.",
                  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("\"");
      }

      NumberFormat nf = getNumberFormat();
      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(
              "Cannot combine values with different filters.");
        }
        if (!typeName.equals(this.values[i].getType().getName())) {
          throw new IllegalArgumentException(
              "Cannot combine values with different types.");
        }
        if (!statName.equals(this.values[i].getDescriptor().getName())) {
          throw new IllegalArgumentException(
              "Cannot combine different stats.");
        }
        if (this.values[i].getDescriptor().isCounter()) {
          // it is a counter which is not the default
          if (!this.values[i].getDescriptor().isLargerBetter()) {
            // this value has non-defaults for both, use it
            bestTypeIdx = i;
          } else if (this.values[bestTypeIdx].getDescriptor()
              .isCounter() == this.values[bestTypeIdx].getDescriptor().isLargerBetter()) {
            // as long as we haven't already found a value with defaults
            // make this value 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 value with defaults
            if (this.values[bestTypeIdx].getDescriptor().isCounter() == this.values[bestTypeIdx]
                .getDescriptor().isLargerBetter()) {
              // make this value 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);
      }
    }

    @Override
    public StatValue createTrimmed(long startTime, long endTime) {
      if (startTime == this.startTime && endTime == this.endTime) {
        return this;
      } else {
        return new ComboValue(this, startTime, endTime);
      }
    }

    @Override
    public ResourceType getType() {
      return this.type;
    }

    @Override
    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);
    }

    @Override
    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);
    }

    @Override
    public long[] getRawAbsoluteTimeStampsWithSecondRes() {
      return getRawAbsoluteTimeStamps();
    }

    @Override
    public long[] getRawAbsoluteTimeStamps() {
      if (values.length == 0) {
        return new long[0];
      }
      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])) {
              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;
            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;
          }
        }
      }
      tsCount--;
      {
        int startIdx = 0;
        int endIdx = tsCount - 1;
        if (startTime != -1) {
          Assert.assertTrue(ourTimeStamps[startIdx] >= startTime);
        }
        if (endTime != -1) {
          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;
    }

    @Override
    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]);
    }

    @Override
    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];
      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];
          }
          for (int j = 0; j < valueSnapshots.length; j++) {
            while (!isClosest(valueTimeStamps[j], ourTimeStamps, curIdx)) {
              if (descriptor.isCounter()) {
                result[curIdx] += currentValue;
              }

              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;
    }

    @Override
    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);
          } 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;


    @Override
    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;
    }

    @Override
    public ResourceType getType() {
      return this.resource.getType();
    }

    @Override
    public ResourceInst[] getResources() {
      return new ResourceInst[] {this.resource};
    }

    @Override
    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;
    }

    @Override
    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;
    }

    @Override
    public double[] getRawSnapshots() {
      int startIdx = getStartIdx();
      int endIdx = getEndIdx(startIdx);
      int resultSize = (endIdx - startIdx) + 1;
      return series.getValuesEx(descriptor.getTypeCode(), startIdx, resultSize);
    }

    @Override
    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;
    }

    @Override
    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;
      }
    }

    @Override
    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() + "=");
      NumberFormat nf = getNumberFormat();
      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 abstract static 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 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 abstract static 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 abstract static 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(
            String.format("getValuesEx did not fill the last %s entries of its result.",
                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 {
    private static 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 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.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.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 resource 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);
      }
    }

    /**
     * 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 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.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
     * these stats are 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.getClass())
        return false;
      ResourceInst other = (ResourceInst) obj;
      if (id != other.id)
        return false;
      if (name == null) {
        if (other.name != null)
          return false;
      } else if (!name.equals(other.name))
        return false;
      if (type == null) {
        if (other.type != null)
          return false;
      } else if (!type.equals(other.type))
        return false;
      if (this.firstTSidx != other.firstTSidx) {
        return false;
      }
      return true;
    }
  }

  public interface StatSpec extends ValueFilter {
    /**
     * Causes all stats that matches this spec, in all archive files, to be combined into a single
     * global stat value.
     */
    int GLOBAL = 2;
    /**
     * Causes all stats that matches this spec, in each archive file, to be combined into a single
     * stat value for each file.
     */
    int FILE = 1;
    /**
     * No combination is done.
     */
    int NONE = 0;

    /**
     * Returns one of the following values: {@link #GLOBAL}, {@link #FILE}, {@link #NONE}.
     */
    int getCombineType();
  }

  /**
   * Specifies what data from a statistic archive will be of interest to the reader. This is used
   * when loading a statistic archive file to reduce the memory footprint. Only statistic data that
   * matches all four will be selected for loading.
   */
  public interface ValueFilter {
    /**
     * Returns true if the specified archive file matches this spec. Any archives whose name does
     * not match this spec will not be selected for loading by this spec.
     */
    boolean archiveMatches(File archive);

    /**
     * Returns true if the specified type name matches this spec. Any types whose name does not
     * match this spec will not be selected for loading by this spec.
     */
    boolean typeMatches(String typeName);

    /**
     * Returns true if the specified statistic name matches this spec. Any stats whose name does not
     * match this spec will not be selected for loading by this spec.
     */
    boolean statMatches(String statName);

    /**
     * Returns true if the specified instance matches this spec. Any instance whose text id and
     * numeric id do not match this spec will not be selected for loading by this spec.
     */
    boolean instanceMatches(String textId, long numericId);
  }

  public static class StatArchiveFile {
    private final StatArchiveReader reader;
    private InputStream is;
    private DataInputStream dataIn;
    private ValueFilter[] filters;
    private final File archiveName;
    private /* final */ int archiveVersion;
    private /* final */ ArchiveInfo info;
    private final boolean compressed;
    private boolean updateOK;
    private final boolean dump;
    private boolean closed = false;
    protected int resourceInstSize = 0;
    protected ResourceInst[] resourceInstTable = null;
    private ResourceType[] resourceTypeTable = null;
    private final TimeStampSeries timeSeries = new TimeStampSeries();
    private final DateFormat timeFormatter = new SimpleDateFormat(DateFormatter.FORMAT_STRING);
    private static final int BUFFER_SIZE = 1024 * 1024;
    private final ArrayList fileComboValues = new ArrayList();


    public StatArchiveFile(StatArchiveReader reader, File archiveName, boolean dump,
        ValueFilter[] filters) throws IOException {
      this.reader = reader;
      this.archiveName = archiveName;
      this.dump = dump;
      this.compressed = archiveName.getPath().endsWith(".gz");
      this.is = new FileInputStream(this.archiveName);
      if (this.compressed) {
        this.dataIn = new DataInputStream(
            new BufferedInputStream(new GZIPInputStream(this.is, BUFFER_SIZE), BUFFER_SIZE));
      } else {
        this.dataIn = new DataInputStream(new BufferedInputStream(this.is, BUFFER_SIZE));
      }
      this.updateOK = this.dataIn.markSupported();
      this.filters = createFilters(filters);
    }

    private ValueFilter[] createFilters(ValueFilter[] allFilters) {
      if (allFilters == null) {
        return new ValueFilter[0];
      }
      ArrayList l = new ArrayList();
      for (int i = 0; i < allFilters.length; i++) {
        if (allFilters[i].archiveMatches(this.getFile())) {
          l.add(allFilters[i]);
        }
      }
      if (l.size() == allFilters.length) {
        return allFilters;
      } else {
        ValueFilter[] result = new ValueFilter[l.size()];
        return (ValueFilter[]) l.toArray(result);
      }
    }

    StatArchiveReader getReader() {
      return this.reader;
    }

    void matchSpec(StatSpec spec, List matchedValues) {
      if (spec.getCombineType() == StatSpec.FILE) {
        // search for previous ComboValue
        Iterator it = this.fileComboValues.iterator();
        while (it.hasNext()) {
          ComboValue v = (ComboValue) it.next();
          if (!spec.statMatches(v.getDescriptor().getName())) {
            continue;
          }
          if (!spec.typeMatches(v.getType().getName())) {
            continue;
          }
          ResourceInst[] resources = v.getResources();
          for (int i = 0; i < resources.length; i++) {
            if (!spec.instanceMatches(resources[i].getName(), resources[i].getId())) {
              continue;
            }
            // note: we already know the archive file matches
          }
          matchedValues.add(v);
          return;
        }
        ArrayList l = new ArrayList();
        matchSpec(new RawStatSpec(spec), l);
        if (l.size() != 0) {
          ComboValue cv = new ComboValue(l);
          // save this in file's combo value list
          this.fileComboValues.add(cv);
          matchedValues.add(cv);
        }
      } else {
        for (int instIdx = 0; instIdx < resourceInstSize; instIdx++) {
          resourceInstTable[instIdx].matchSpec(spec, matchedValues);
        }
      }
    }

    /**
     * Formats an archive timestamp in way consistent with GemFire log dates. It will also be
     * formatted to reflect the time zone the archive was created in.
     *
     * @param ts The difference, measured in milliseconds, between the time marked by this time
     *        stamp and midnight, January 1, 1970 UTC.
     */
    public String formatTimeMillis(long ts) {
      synchronized (timeFormatter) {
        return timeFormatter.format(new Date(ts));
      }
    }

    /**
     * sets the time zone this archive was written in.
     */
    void setTimeZone(TimeZone z) {
      timeFormatter.setTimeZone(z);
    }

    /**
     * Returns the time series for this archive.
     */
    TimeStampSeries getTimeStamps() {
      return timeSeries;
    }

    /**
     * Checks to see if the archive has changed since the StatArchiverReader instance was created or
     * last updated. If the 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 <code>archiveName</code> could not be opened read, or closed.
     */
    public boolean update(boolean doReset) throws IOException {
      if (this.closed) {
        return false;
      }
      if (!this.updateOK) {
        throw new InternalGemFireException(
            "update of this type of file is not supported.");
      }

      if (doReset) {
        this.dataIn.reset();
      }

      int updateTokenCount = 0;
      while (this.readToken()) {
        updateTokenCount++;
      }
      return updateTokenCount != 0;
    }

    public void dump(PrintWriter stream) {
      stream.print("archive=" + archiveName);
      if (info != null) {
        info.dump(stream);
      }
      for (int i = 0; i < resourceTypeTable.length; i++) {
        if (resourceTypeTable[i] != null) {
          resourceTypeTable[i].dump(stream);
        }
      }
      stream.print("time=");
      timeSeries.dump(stream);
      for (int i = 0; i < resourceInstTable.length; i++) {
        if (resourceInstTable[i] != null) {
          resourceInstTable[i].dump(stream);
        }
      }
    }

    public File getFile() {
      return this.archiveName;
    }

    /**
     * Closes the archive.
     */
    public void close() throws IOException {
      if (!this.closed) {
        this.closed = true;
        this.is.close();
        this.dataIn.close();
        this.is = null;
        this.dataIn = null;
        int typeCount = 0;
        if (this.resourceTypeTable != null) { // fix for bug 32320
          for (int i = 0; i < this.resourceTypeTable.length; i++) {
            if (this.resourceTypeTable[i] != null) {
              if (this.resourceTypeTable[i].close()) {
                this.resourceTypeTable[i] = null;
              } else {
                typeCount++;
              }
            }
          }
          ResourceType[] newTypeTable = new ResourceType[typeCount];
          typeCount = 0;
          for (int i = 0; i < this.resourceTypeTable.length; i++) {
            if (this.resourceTypeTable[i] != null) {
              newTypeTable[typeCount] = this.resourceTypeTable[i];
              typeCount++;
            }
          }
          this.resourceTypeTable = newTypeTable;
        }

        if (this.resourceInstTable != null) { // fix for bug 32320
          int instCount = 0;
          for (int i = 0; i < this.resourceInstTable.length; i++) {
            if (this.resourceInstTable[i] != null) {
              if (this.resourceInstTable[i].close()) {
                this.resourceInstTable[i] = null;
              } else {
                instCount++;
              }
            }
          }
          ResourceInst[] newInstTable = new ResourceInst[instCount];
          instCount = 0;
          for (int i = 0; i < this.resourceInstTable.length; i++) {
            if (this.resourceInstTable[i] != null) {
              newInstTable[instCount] = this.resourceInstTable[i];
              instCount++;
            }
          }
          this.resourceInstTable = newInstTable;
          this.resourceInstSize = instCount;
        }
        // optimize memory usage of timeSeries now that no more samples
        this.timeSeries.shrink();
        // filters are no longer needed since file will not be read from
        this.filters = null;
      }
    }

    /**
     * Returns global information about the read archive. Returns null if no information is
     * available.
     */
    public ArchiveInfo getArchiveInfo() {
      return this.info;
    }

    private void readHeaderToken() throws IOException {
      byte archiveVersion = dataIn.readByte();
      long startTimeStamp = dataIn.readLong();
      long systemId = dataIn.readLong();
      long systemStartTimeStamp = dataIn.readLong();
      int timeZoneOffset = dataIn.readInt();
      String timeZoneName = dataIn.readUTF();
      String systemDirectory = dataIn.readUTF();
      String productVersion = dataIn.readUTF();
      String os = dataIn.readUTF();
      String machine = dataIn.readUTF();
      if (archiveVersion <= 1) {
        throw new GemFireIOException(
            String.format("Archive version: %s is no longer supported.",
                Byte.valueOf(archiveVersion)),
            null);
      }
      if (archiveVersion > ARCHIVE_VERSION) {
        throw new GemFireIOException(
            String.format("Unsupported archive version: %s .  The supported version is: %s .",

                new Object[] {Byte.valueOf(archiveVersion), Byte.valueOf(ARCHIVE_VERSION)}),
            null);
      }
      this.archiveVersion = archiveVersion;
      this.info = new ArchiveInfo(this, archiveVersion, startTimeStamp, systemStartTimeStamp,
          timeZoneOffset, timeZoneName, systemDirectory, systemId, productVersion, os, machine);
      // Clear all previously read types and instances
      this.resourceInstSize = 0;
      this.resourceInstTable = new ResourceInst[1024];
      this.resourceTypeTable = new ResourceType[256];
      timeSeries.setBase(startTimeStamp);
      if (dump) {
        info.dump(new PrintWriter(System.out));
      }
    }

    boolean loadType(String typeName) {
      // note we don't have instance data or descriptor data yet
      if (filters == null || filters.length == 0) {
        return true;
      } else {
        for (int i = 0; i < filters.length; i++) {
          if (filters[i].typeMatches(typeName)) {
            return true;
          }
        }
        return false;
      }
    }

    boolean loadStatDescriptor(StatDescriptor stat, ResourceType type) {
      // note we don't have instance data yet
      if (!type.isLoaded()) {
        return false;
      }
      if (filters == null || filters.length == 0) {
        return true;
      } else {
        for (int i = 0; i < filters.length; i++) {
          if (filters[i].statMatches(stat.getName()) && filters[i].typeMatches(type.getName())) {
            return true;
          }
        }
        stat.unload();
        return false;
      }
    }

    boolean loadInstance(String textId, long numericId, ResourceType type) {
      if (!type.isLoaded()) {
        return false;
      }
      if (filters == null || filters.length == 0) {
        return true;
      } else {
        for (int i = 0; i < filters.length; i++) {
          if (filters[i].typeMatches(type.getName())) {
            if (filters[i].instanceMatches(textId, numericId)) {
              StatDescriptor[] stats = type.getStats();
              for (int j = 0; j < stats.length; j++) {
                if (stats[j].isLoaded()) {
                  if (filters[i].statMatches(stats[j].getName())) {
                    return true;
                  }
                }
              }
            }
          }
        }
        return false;
      }
    }

    boolean loadStat(StatDescriptor stat, ResourceInst resource) {
      ResourceType type = resource.getType();
      if (!resource.isLoaded() || !type.isLoaded() || !stat.isLoaded()) {
        return false;
      }
      if (filters == null || filters.length == 0) {
        return true;
      } else {
        String textId = resource.getName();
        long numericId = resource.getId();
        for (int i = 0; i < filters.length; i++) {
          if (filters[i].statMatches(stat.getName()) && filters[i].typeMatches(type.getName())
              && filters[i].instanceMatches(textId, numericId)) {
            return true;
          }
        }
        return false;
      }
    }

    private void readResourceTypeToken() throws IOException {
      int resourceTypeId = dataIn.readInt();
      String resourceTypeName = dataIn.readUTF();
      String resourceTypeDesc = dataIn.readUTF();
      int statCount = dataIn.readUnsignedShort();
      while (resourceTypeId >= resourceTypeTable.length) {
        ResourceType[] tmp = new ResourceType[resourceTypeTable.length + 128];
        System.arraycopy(resourceTypeTable, 0, tmp, 0, resourceTypeTable.length);
        resourceTypeTable = tmp;
      }
      Assert.assertTrue(resourceTypeTable[resourceTypeId] == null);

      ResourceType rt;
      if (loadType(resourceTypeName)) {
        rt = new ResourceType(resourceTypeId, resourceTypeName, resourceTypeDesc, statCount);
        if (dump) {
          System.out.println("ResourceType id=" + resourceTypeId + " name=" + resourceTypeName
              + " statCount=" + statCount + " desc=" + resourceTypeDesc);
        }
      } else {
        rt = new ResourceType(resourceTypeId, resourceTypeName, statCount);
        if (dump) {
          System.out.println(
              "Not loading ResourceType id=" + resourceTypeId + " name=" + resourceTypeName);
        }
      }
      resourceTypeTable[resourceTypeId] = rt;
      for (int i = 0; i < statCount; i++) {
        String statName = dataIn.readUTF();
        byte typeCode = dataIn.readByte();
        boolean isCounter = dataIn.readBoolean();
        boolean largerBetter = isCounter; // default
        if (this.archiveVersion >= 4) {
          largerBetter = dataIn.readBoolean();
        }
        String units = dataIn.readUTF();
        String desc = dataIn.readUTF();
        rt.addStatDescriptor(this, i, statName, isCounter, largerBetter, typeCode, units, desc);
        if (dump) {
          System.out.println("  " + i + "=" + statName + " isCtr=" + isCounter + " largerBetter="
              + largerBetter + " typeCode=" + typeCode + " units=" + units + " desc=" + desc);
        }
      }
    }

    private void readResourceInstanceCreateToken(boolean initialize) throws IOException {
      int resourceInstId = dataIn.readInt();
      String name = dataIn.readUTF();
      long id = dataIn.readLong();
      int resourceTypeId = dataIn.readInt();
      while (resourceInstId >= resourceInstTable.length) {
        ResourceInst[] tmp = new ResourceInst[resourceInstTable.length + 128];
        System.arraycopy(resourceInstTable, 0, tmp, 0, resourceInstTable.length);
        resourceInstTable = tmp;
      }
      Assert.assertTrue(resourceInstTable[resourceInstId] == null);
      if ((resourceInstId + 1) > this.resourceInstSize) {
        this.resourceInstSize = resourceInstId + 1;
      }
      ResourceType type = resourceTypeTable[resourceTypeId];
      if (type == null) {
        throw new IllegalStateException("ResourceType is missing for resourceTypeId "
            + resourceTypeId + ", resourceName " + name);
      }
      boolean loadInstance = loadInstance(name, id, resourceTypeTable[resourceTypeId]);
      resourceInstTable[resourceInstId] = new ResourceInst(this, resourceInstId, name, id,
          resourceTypeTable[resourceTypeId], loadInstance);
      if (dump) {
        System.out.println(
            (loadInstance ? "Loaded" : "Did not load") + " resource instance " + resourceInstId);
        System.out.println("  name=" + name + " id=" + id + " typeId=" + resourceTypeId);
      }
      if (initialize) {
        StatDescriptor[] stats = resourceInstTable[resourceInstId].getType().getStats();
        for (int i = 0; i < stats.length; i++) {
          long v;
          switch (stats[i].getTypeCode()) {
            case BOOLEAN_CODE:
              v = dataIn.readByte();
              break;
            case BYTE_CODE:
            case CHAR_CODE:
              v = dataIn.readByte();
              break;
            case WCHAR_CODE:
              v = dataIn.readUnsignedShort();
              break;
            case SHORT_CODE:
              v = dataIn.readShort();
              break;
            case INT_CODE:
            case FLOAT_CODE:
            case LONG_CODE:
            case DOUBLE_CODE:
              v = readCompactValue();
              break;
            default:
              throw new IOException(String.format("unexpected typeCode value %s",
                  Byte.valueOf(stats[i].getTypeCode())));
          }
          resourceInstTable[resourceInstId].initialValue(i, v);
        }
      }
    }

    private void readResourceInstanceDeleteToken() throws IOException {
      int resourceInstId = dataIn.readInt();
      Assert.assertTrue(resourceInstTable[resourceInstId] != null);
      resourceInstTable[resourceInstId].makeInactive();
      if (dump) {
        System.out.println("Delete resource instance " + resourceInstId);
      }
    }

    private int readResourceInstId() throws IOException {
      int token = dataIn.readUnsignedByte();
      if (token <= MAX_BYTE_RESOURCE_INST_ID) {
        return token;
      } else if (token == ILLEGAL_RESOURCE_INST_ID_TOKEN) {
        return ILLEGAL_RESOURCE_INST_ID;
      } else if (token == SHORT_RESOURCE_INST_ID_TOKEN) {
        return dataIn.readUnsignedShort();
      } else { /* token == INT_RESOURCE_INST_ID_TOKEN */
        return dataIn.readInt();
      }
    }

    private int readTimeDelta() throws IOException {
      int result = dataIn.readUnsignedShort();
      if (result == INT_TIMESTAMP_TOKEN) {
        result = dataIn.readInt();
      }
      return result;
    }

    private long readCompactValue() throws IOException {
      return StatArchiveWriter.readCompactValue(this.dataIn);
    }

    private void readSampleToken() throws IOException {
      int millisSinceLastSample = readTimeDelta();
      if (dump) {
        System.out.println("ts=" + millisSinceLastSample);
      }
      int resourceInstId = readResourceInstId();
      while (resourceInstId != ILLEGAL_RESOURCE_INST_ID) {
        if (dump) {
          System.out.print("  instId=" + resourceInstId);
        }
        StatDescriptor[] stats = resourceInstTable[resourceInstId].getType().getStats();
        int statOffset = dataIn.readUnsignedByte();
        while (statOffset != ILLEGAL_STAT_OFFSET) {
          long statDeltaBits;
          switch (stats[statOffset].getTypeCode()) {
            case BOOLEAN_CODE:
              statDeltaBits = dataIn.readByte();
              break;
            case BYTE_CODE:
            case CHAR_CODE:
              statDeltaBits = dataIn.readByte();
              break;
            case WCHAR_CODE:
              statDeltaBits = dataIn.readUnsignedShort();
              break;
            case SHORT_CODE:
              statDeltaBits = dataIn.readShort();
              break;
            case INT_CODE:
            case FLOAT_CODE:
            case LONG_CODE:
            case DOUBLE_CODE:
              statDeltaBits = readCompactValue();
              break;
            default:
              throw new IOException(String.format("unexpected typeCode value %s",
                  Byte.valueOf(stats[statOffset].getTypeCode())));
          }
          if (resourceInstTable[resourceInstId].addValueSample(statOffset, statDeltaBits)) {
            if (dump) {
              System.out.print(" [" + statOffset + "]=" + statDeltaBits);
            }
          }
          statOffset = dataIn.readUnsignedByte();
        }
        if (dump) {
          System.out.println();
        }
        resourceInstId = readResourceInstId();
      }
      timeSeries.addTimeStamp(millisSinceLastSample);
      for (int i = 0; i < resourceInstTable.length; i++) {
        ResourceInst inst = resourceInstTable[i];
        if (inst != null && inst.isActive()) {
          inst.addTimeStamp();
        }
      }
    }

    /**
     * Returns true if token read, false if eof.
     */
    private boolean readToken() throws IOException {
      byte token;
      try {
        if (this.updateOK) {
          this.dataIn.mark(BUFFER_SIZE);
        }
        token = this.dataIn.readByte();
        switch (token) {
          case HEADER_TOKEN:
            readHeaderToken();
            break;
          case RESOURCE_TYPE_TOKEN:
            readResourceTypeToken();
            break;
          case RESOURCE_INSTANCE_CREATE_TOKEN:
            readResourceInstanceCreateToken(false);
            break;
          case RESOURCE_INSTANCE_INITIALIZE_TOKEN:
            readResourceInstanceCreateToken(true);
            break;
          case RESOURCE_INSTANCE_DELETE_TOKEN:
            readResourceInstanceDeleteToken();
            break;
          case SAMPLE_TOKEN:
            readSampleToken();
            break;
          default:
            throw new IOException(String.format("Unexpected token byte value: %s",
                Byte.valueOf(token)));
        }
        return true;
      } catch (EOFException ignore) {
        return false;
      }
    }

    /**
     * Returns the approximate amount of memory used to implement this object.
     */
    protected int getMemoryUsed() {
      int result = 0;
      for (int i = 0; i < resourceInstTable.length; i++) {
        if (resourceInstTable[i] != null) {
          result += resourceInstTable[i].getMemoryUsed();
        }
      }
      return result;
    }
  }

  private static NumberFormat getNumberFormat() {
    NumberFormat nf = NumberFormat.getNumberInstance();
    nf.setMaximumFractionDigits(2);
    nf.setGroupingUsed(false);
    return nf;
  }

}
