import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.teradata.fnc.Context;
import com.teradata.fnc.Phase;
import com.ncr.teradata.fnc.*;
import java.io.Serializable;
class Element
{
public int v;
}
class AGR_Storage implements Serializable
{
public long current_value; // Current moving sum total
public int next; // Location to store next detail row
public int tptr; // Trailing buffer pointer
public int count; // Number of detail rows processed
public long window_size; // Moving window size
public List<Element> data;
public int heap; // Heap area to store window rows
public AGR_Storage(int a, int b, int c, int d, long e, int f)
{
current_value = a;
next = b;
tptr = c;
count = d;
window_size = e;
data = new ArrayList<Element>(100);
heap = f;
}
}
public class MySumClass
{
final private static boolean debug = true;
public static int MySum(Phase phase, Context context[], int x)
{
int result = 0;
try
{
AGR_Storage s1 = null;
AGR_Storage s2 = null;
int i, t_x;
if (phase.getPhase() != Phase.AGR_INIT && phase.getPhase()!= Phase.AGR_NODATA)
s1 = (AGR_Storage) context[0].getObject(1);
switch (phase.getPhase())
{
case Phase.AGR_INIT:
if (debug)
{
System.err.println("Phase: AGR_INIT");
}
s1 = new AGR_Storage(0,0,0,0,0,0);
context[0].initCtx(s1);
s1.window_size = context[0].getWindowSize();
if(s1.window_size > 0)
{
for (i=0; i < s1.window_size; i++) //initialize heap
{
s1.data.get(i).v = 0;
}
}
// fall through
case Phase.AGR_DETAIL:
t_x = x;
if (s1.window_size < 0) // non moving case
{
s1.current_value += t_x;
}
else // Moving
{
s1.count++;
if (s1.count > s1.window_size) // Remove value row from window
{
s1.current_value -= s1.data.get(s1.tptr).v;
s1.tptr = (int)inc(s1.tptr, (int) s1.window_size);
}
s1.current_value += t_x; // Add row to window
s1.data.get(s1.next).v = t_x;
s1.next = (int) inc(s1.next, (int) s1.window_size);
}
break;
case Phase.AGR_COMBINE:
case Phase.AGR_FINAL:
result = (int) s1.current_value;
return result;
case Phase.AGR_MOVINGTRAIL:
s1.current_value -= s1.data.get(s1.tptr).v;
s1.tptr = (int) inc(s1.tptr,(int)s1.window_size);
break;
case Phase.AGR_NODATA:
if (debug)
System.err.println("Phase: AGR_NODATA");
return 0;
default:
throw new SQLException("Invalid Phase", "U0005");
}
context[0].setObject(1, s1);
}
catch (Exception e)
{
e.printStackTrace();
}
return result;
}
private static long inc(int next, int size)
{
return (next + 1) % size;
}
}