/**
* Copyright (C) 2009-2015 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.IndexColumn;
import com.foundationdb.server.service.tree.KeyCreator;
import com.foundationdb.server.store.statistics.histograms.Sampler;
import com.persistit.Key;
import java.util.Map;
import java.util.TreeMap;
public class MemorySingleColumnIndexStatisticsVisitor extends IndexStatisticsGenerator<Key,byte[]>
{
private final Key extractKey = new Key(null, Key.MAX_KEY_LENGTH);
private final Map<Key,int[]> countMap = new TreeMap<>(); // Is ordered required?
private final int field;
public MemorySingleColumnIndexStatisticsVisitor(KeyCreator keyCreator, IndexColumn indexColumn)
{
super(new PersistitKeyFlywheel(keyCreator), indexColumn.getIndex(), 1, indexColumn.getPosition());
this.field = indexColumn.getPosition();
}
@Override
public void init(int bucketCount, long expectedRowCount) {
// Does not do generator init until finish because just
// buffering counts in this pass.
}
@Override
public void finish(int bucketCount) {
// Now init the generator and replay the accumulated counts.
super.init(bucketCount, rowCount);
try {
for(Map.Entry<Key,int[]> entry : countMap.entrySet()) {
int keyCount = entry.getValue()[0];
for(int i = 0; i < keyCount; ++i) {
loadKey(entry.getKey());
}
}
} finally {
super.finish(bucketCount);
}
}
@Override
public void visit(Key key, byte[] value) {
key.indexTo(field);
extractKey.clear().appendKeySegment(key);
int[] curCount = countMap.get(extractKey);
if(curCount == null) {
Key storedKey = new Key(extractKey);
curCount = new int[1];
countMap.put(storedKey, curCount);
}
curCount[0] += 1;
rowCount++;
}
@Override
public Sampler<Key> createKeySampler(int bucketCount, long distinctCount) {
return new Sampler<>(
new PersistitKeySplitter(columnCount(), getKeysFlywheel()),
bucketCount,
distinctCount,
getKeysFlywheel()
);
}
@Override
protected byte[] copyOfKeyBytes(Key key) {
byte[] copy = new byte[key.getEncodedSize()];
System.arraycopy(key.getEncodedBytes(), 0, copy, 0, copy.length);
return copy;
}
}