net.sf.jasperreports.data.cache.RunLengthStore Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jasperreports Show documentation
Show all versions of jasperreports Show documentation
Free Java Reporting Library
/*
* JasperReports - Free Java Reporting Library.
* Copyright (C) 2001 - 2019 TIBCO Software Inc. All rights reserved.
* http://www.jaspersoft.com
*
* Unless you have purchased a commercial license agreement from Jaspersoft,
* the following license terms apply:
*
* This program is part of JasperReports.
*
* JasperReports is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JasperReports 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JasperReports. If not, see .
*/
package net.sf.jasperreports.data.cache;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author Lucian Chirita ([email protected])
*/
public class RunLengthStore
{
private static final Log log = LogFactory.getLog(RunLengthStore.class);
protected static final int MAX_RUN_LENGTH = Short.MAX_VALUE - Short.MIN_VALUE;
private static final int RUN_LENGTH_PENALTY = 32;// 32 bytes
private final ArrayStore store;
private int runStart;
private int runCount;
private int maxRunLength;
public RunLengthStore(ArrayStore store)
{
this.store = store;
if (log.isDebugEnabled())
{
log.debug("created " + this + " for " + store);
}
}
public void reset()
{
this.runStart = -1;
this.runCount = 0;
this.maxRunLength = 1;
}
public void valueAdded()
{
int count = store.count();
if (runStart >= 0 && store.valuesEqual(runStart, count - 1)
&& (count - runStart) < MAX_RUN_LENGTH)
{
if (count - runStart > maxRunLength)
{
maxRunLength = count - runStart;
}
}
else
{
runStart = count - 1;
++runCount;
}
}
public ColumnValues applyRunLengths(ValueLength valueLength)
{
ValueLength runLength = ValueLength.getNumberLength(maxRunLength - 1);
ColumnValues runLengthValues = null;
int originalCount = store.count();
if (useRunLength(originalCount, valueLength, runLength))
{
if (log.isDebugEnabled())
{
log.debug(this + ": using run lengths count " + runCount
+ ", original count " + originalCount);
}
// go with run lengths
long[] runLengths = new long[runCount];
int runIdx = 0;
runLengths[runIdx] = 0;// we start from 0 because we use 1 as offset
for (int i = 1; i < originalCount; ++i)
{
if (store.valuesEqual(i, runIdx) && runLengths[runIdx] < RunLengthStore.MAX_RUN_LENGTH)
{
++runLengths[runIdx];
}
else
{
++runIdx;
runLengths[runIdx] = 0;
store.copyValue(runIdx, i);
}
}
// update the values count
store.updateCount(runCount);
if (log.isDebugEnabled())
{
log.debug(this + ": creating run lengths of count " + runCount
+ ", value length " + runLength);
}
runLengthValues = NumberValuesUtils.instance().toValues(runCount,
runLengths, runLength, 1, 1);
}
return runLengthValues;
}
protected boolean useRunLength(int count, ValueLength valueLength, ValueLength runLength)
{
return count * valueLength.byteLength() >
runCount * (valueLength.byteLength() + runLength.byteLength()) + RUN_LENGTH_PENALTY;
}
public int getRunStart()
{
return runStart;
}
public int getRunCount()
{
return runCount;
}
public int getMaxRunLength()
{
return maxRunLength;
}
@Override
public String toString()
{
return "RunLengthStore@" + hashCode();
}
}