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; } }