/* * StreamCruncher: Copyright (c) 2006-2008, Ashwin Jayaprakash. All Rights Reserved. * Contact: ashwin {dot} jayaprakash {at} gmail {dot} com * Web: http://www.StreamCruncher.com * * This file is part of StreamCruncher. * * StreamCruncher 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. * * StreamCruncher 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 StreamCruncher. If not, see <http://www.gnu.org/licenses/>. */ package streamcruncher.innards.core.partition.function; import java.util.List; import streamcruncher.api.artifact.RowSpec; import streamcruncher.innards.core.QueryContext; import streamcruncher.innards.core.partition.Row; import streamcruncher.util.AtomicX; /* * Author: Ashwin Jayaprakash Date: Feb 18, 2006 Time: 6:53:20 PM */ public class SlidingWindowFunction extends WindowFunction { protected final int windowSize; /** * @param pinned * @param selectedRowSpec * @param newRowSpec * @param rowIdGenerator * @param sourceLocationForTargetCols * @param windowSize */ public SlidingWindowFunction(RowSpec selectedRowSpec, RowSpec newRowSpec, AtomicX rowIdGenerator, int[] sourceLocationForTargetCols, int windowSize) { super(selectedRowSpec, newRowSpec, rowIdGenerator, sourceLocationForTargetCols, windowSize); this.windowSize = windowSize; } /** * @return Returns the windowSize. */ public int getWindowSize() { return windowSize; } // ------------------- @Override /** * @param context */ public void onCalculate(QueryContext context) { free = 0; maxRowsThatCanBeConsumed = 0; /* * Once the Window reaches its full capacity, it can only move 1 Row at * a time, because it's a Sliding Window. If a Row cannot be slid in, * then an old Row cannot be slid out. Also, for each simCycle, only 1 * Row can be slid out/in. */ if (getNumOfIds() == windowSize) { maxRowsThatCanBeConsumed = 1; free = 1; } /* Otherwise, allow the Window to fill up. */ else { maxRowsThatCanBeConsumed = windowSize - getNumOfIds(); } // ------------------- final List<Row> unprocessedRows = unprocessedRowBuffer.getRows(); final int pendingEventsAllowed = context.getPendingEventsAllowed(); final int newEvents = unprocessedRows.size() - pendingEventsAllowed; /** * <pre> * Max-Window-Size | * .................... | * | * .................................|............ * |XXXXXXXXXXXX|YYYYY| |XXXXXXXXXXX| * `..................:.............|...........' * Curr-Window | Allowed-Pending * | * | * </pre> */ if ((getNumOfIds() + newEvents) - windowSize > 1) { free = 0; int idsInWindow = getNumOfIds(); while (idsInWindow > 0 && (idsInWindow + newEvents) > windowSize) { free++; idsInWindow--; } maxRowsThatCanBeConsumed = windowSize - idsInWindow; /* * Drop some rows so that only 'windowSize' number of Rows remain. */ int extraEvents = idsInWindow + newEvents; while (extraEvents > windowSize) { unprocessedRows.remove(0); extraEvents--; } } } }