/** * Copyright (C) 2009-2013 FoundationDB, LLC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.foundationdb.server.store.statistics; import com.foundationdb.ais.model.Index; /** Index statistics */ public class IndexStatistics { public static enum Validity { VALID, INVALID, OUTDATED }; private final String indexName; // NOTE: There is no backpointer to the Index in this class because of // IndexStatisticsServiceImpl.cache, a WeakHashMap<Index,IndexStatistics>. private long analysisTimestamp, rowCount, sampledCount; private Validity validity; private boolean warned; // Single-column histograms are indexed by column position, starting at 1. // Multi-column histograms are indexed by (number of columns) - 1. // The histogram for the leading column of a multi-column index could be handled as single or multi. It // is handled only as a multi-column histogram for historical reasons, (single-column was added later). // Example: For an index on (a, b, c) we have the following histograms: // singleColumnHistograms[0]: null // singleColumnHistograms[1]: (b) // singleColumnHistograms[2]: (c) // multiColumnHistograms[0]: (a) // multiColumnHistograms[1]: (a, b) // multiColumnHistograms[2]: (a, b, c) private Histogram[] multiColumnHistograms; private Histogram[] singleColumnHistograms; protected IndexStatistics(Index index) { this.indexName = index.getIndexName().getName(); this.validity = Validity.VALID; this.multiColumnHistograms = new Histogram[index.getKeyColumns().size()]; this.singleColumnHistograms = new Histogram[index.getKeyColumns().size()]; } protected IndexStatistics (Index index, long analysisTimeStamp, long rowCount, long sampledCount) { this(index); this.analysisTimestamp = analysisTimeStamp; this.rowCount = rowCount; this.sampledCount = sampledCount; } /** The system time at which the statistics were gathered. */ public long getAnalysisTimestamp() { return analysisTimestamp; } public void setAnalysisTimestamp(long analysisTimestamp) { this.analysisTimestamp = analysisTimestamp; } /** The number of rows in the index when it was analyzed. */ public long getRowCount() { return rowCount; } protected void setRowCount(long rowCount) { this.rowCount = rowCount; } /** The number of rows that were actually sampled. * Right now, always equal to <code>rowCount</code>. */ public long getSampledCount() { return sampledCount; } protected void setSampledCount(long sampledCount) { this.sampledCount = sampledCount; } public Validity getValidity() { return validity; } public void setValidity(Validity validity) { this.validity = validity; } public boolean isValid() { return (validity == Validity.VALID); } public boolean isInvalid() { return (validity == Validity.INVALID); } public boolean isWarned() { return warned; } public void setWarned(boolean warned) { this.warned = warned; } public Histogram getHistogram(int firstColumn, int columnCount) { assert firstColumn == 0 || columnCount == 1; return firstColumn == 0 ? multiColumnHistograms[columnCount - 1] : singleColumnHistograms[firstColumn]; } protected void addHistogram(Histogram histogram) { if (histogram.getFirstColumn() == 0) { assert (multiColumnHistograms[histogram.getColumnCount() - 1] == null); multiColumnHistograms[histogram.getColumnCount() - 1] = histogram; } else { assert (singleColumnHistograms[histogram.getFirstColumn()] == null); singleColumnHistograms[histogram.getFirstColumn()] = histogram; } histogram.setIndexStatistics(this); } @Override public String toString() { return toString(null); } public String toString(Index index) { StringBuilder str = new StringBuilder(super.toString()); if (index != null) str.append(" for ").append(index); for (int i = 0; i < singleColumnHistograms.length; i++) { Histogram h = singleColumnHistograms[i]; if (h == null) continue; str.append("\n"); str.append(h.toString(index)); } for (int i = 0; i < multiColumnHistograms.length; i++) { Histogram h = multiColumnHistograms[i]; if (h == null) continue; str.append("\n"); str.append(h.toString(index)); } return str.toString(); } }