
net.sf.jagg.NtileAnalytic Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jagg-core Show documentation
Show all versions of jagg-core Show documentation
jAgg is a Java 5.0 API that supports “group by” operations on Lists of Java objects: aggregate operations such as count, sum, max, min, avg, and many more. It also allows custom aggregate operations.
The newest version!
package net.sf.jagg;
import net.sf.jagg.exception.ExpectedNumberException;
import net.sf.jagg.model.WindowClause;
/**
* A NtileAnalytic
is an
* AbstractDependentAnalyticFunction
that assigns a bucket number
* to each row, from 1
through n
. If the number of
* rows is not a multiple of n
, then the remainder of rows get
* assigned, one each, to buckets 1
through the remainder.
*
* @author Randy Gettman
* @since 0.9.0
*/
public class NtileAnalytic extends AbstractDependentAnalyticFunction
{
private int myN;
/**
* Constructs a NtileAnalytic
, with no property.
*
* @param property Should be convertible to a positive integer.
*/
public NtileAnalytic(String property)
{
setProperty(property);
}
/**
* Expects that the only "property" given is the actual desired number of,
* buckets, convertible to a positive integer.
*
* @param property The property string.
* @throws IllegalArgumentException If the the number of buckets is not a
* positive integer.
* @see Aggregator#getProperty()
*/
@Override
protected void setProperty(String property)
{
super.setProperty(property);
try
{
myN = Integer.parseInt(getProperty());
if (myN <= 0)
{
throw new ExpectedNumberException("The number of buckets must be a positive integer, but got \"" +
getProperty() + "\".");
}
}
catch (NumberFormatException e)
{
throw new ExpectedNumberException("The number of buckets must be a positive integer, but got \"" +
getProperty() + "\".");
}
}
/**
* Returns an uninitialized copy of this Aggregator
object,
* with the same property(ies) to analyze.
* @return An uninitialized copy of this Aggregator
object.
*/
public NtileAnalytic replicate()
{
return new NtileAnalytic(String.valueOf(myN));
}
/**
* This depends on 2 functions.
* @return 2
.
*/
public int getNumDependentFunctions()
{
return 2;
}
/**
* Depends on 2 CountAggregators
.
* @param index A 0-based index, ranging from 0
through
* getNumDependentFunctions() - 1
.
* @return
* 0
=> CountAggregator("*")
* 1
=> CountAggregator("*")
*
*/
public AnalyticFunction getAnalyticFunction(int index)
{
switch(index)
{
case 0:
return new CountAggregator("*");
case 1:
return new CountAggregator("*");
default:
throw new IndexOutOfBoundsException("Invalid index: " + index);
}
}
/**
* WindowClause
0 is rows(, 0)
and
* WindowClause
1 is range()
.
* @param index A 0-based index, ranging from 0
through
* getNumDependentFunctions() - 1
.
* @return
* 0
=> rows(, 0)
* 1
=> range()
*
*/
public WindowClause getWindowClause(int index)
{
switch(index)
{
case 0:
return new WindowClause(WindowClause.Type.ROWS, null, 0);
case 1:
return new WindowClause(WindowClause.Type.RANGE, null, null);
default:
throw new IndexOutOfBoundsException("Invalid index: " + index);
}
}
/**
* Returns the bucket number as a Long
.
* @return The bucket number as a Long
.
*/
public Long terminate()
{
long rownum = (Long) getValue(0);
long count = (Long) getValue(1);
// remainder of items; also number of buckets with one extra item
long y = count % myN;
// items per bucket without remainder
long z = count / myN;
// number of items in buckets with extra items
long x = y * (z + 1);
if (rownum <= x)
{
// z+1 items in the first y buckets.
return (rownum - 1) / (z + 1) + 1;
}
else
{
// z items past the first y buckets.
return y + (rownum - 1 - x) / z + 1;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy