All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.shanqiang.window.InThreadOverWindow Maven / Gradle / Ivy

package io.github.shanqiang.window;

import io.github.shanqiang.function.WindowFunction;
import io.github.shanqiang.table.Row;
import io.github.shanqiang.table.SlideTable;
import io.github.shanqiang.table.Table;
import io.github.shanqiang.table.TableBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

import static io.github.shanqiang.window.TimeWindow.appendRows;

class InThreadOverWindow extends InThreadWindow {
    private static final Logger logger = LoggerFactory.getLogger(InThreadOverWindow.class);

    private long lastDataTime;
    private long lastDataSystemTime;
    private final long windowSize;
    private final WindowFunction windowFunction;
    private final String[] partitionByColumnNames;
    private final String timeColumnName;

    InThreadOverWindow(long windowSize,
                       WindowFunction windowFunction,
                       String[] partitionByColumnNames,
                       String timeColumnName) {
        this.windowSize = windowSize;
        this.windowFunction = windowFunction;
        this.partitionByColumnNames = partitionByColumnNames;
        this.timeColumnName = timeColumnName;
    }

    void triggerAllWindowBySchedule(TableBuilder retTable, long noDataDelay) {
        long now = System.currentTimeMillis();
        if (0 == lastDataTime) {
            return;
        }
        long dataTime = now - lastDataSystemTime + lastDataTime;
        if (dataTime - noDataDelay >= 0) {
            triggerAllWindow(retTable, start(dataTime));
            return;
        }
    }

    private long start(long dataTime) {
        return dataTime - windowSize + 1;
    }

    private void triggerAllWindow(TableBuilder retTable, long start) {
        List> willRemove = new ArrayList<>();
        for (List key : partitionedTables.keySet()) {
            if (trigger(retTable, start, key)) {
                willRemove.add(key);
            }
        }
        for (List key : willRemove) {
            partitionedTables.remove(key);
        }
    }

    private boolean trigger(TableBuilder retTable, long start, List key) {
        SlideTable partitionedTable = partitionedTables.get(key);
        int needCompute = partitionedTable.countLessThan(start);
        if (needCompute > 0) {
            List rows = partitionedTable.rows();
            List comparablesList = windowFunction.transform(key, rows, needCompute);
            TimeWindow.appendRows(retTable, comparablesList);
            partitionedTable.removeLessThan(start);

            if (partitionedTable.size() <= 0) {
                return true;
            }
        }

        return false;
    }

    void trigger(TableBuilder retTable, Table table, StoreType storeType) {
        //time column must be bigint else throw exception to remind the user
        long dataTime = (long) table.getColumn(timeColumnName).get(0);
        lastDataTime = dataTime;
        lastDataSystemTime = System.currentTimeMillis();
        long start = dataTime - windowSize + 1;
        for (int i = 0; i < table.size(); i++) {
            List key = TimeWindow.genPartitionKey(table, i,partitionByColumnNames);
            SlideTable partitionedTable = TimeWindow.getPartitionedSlideTable(key, table, partitionedTables, timeColumnName, storeType);
            if (partitionedTable.size() <= 0) {
                partitionedTable.addRow(table, i);
                continue;
            }

            assert (Long) table.getColumn(timeColumnName).get(i) == dataTime;
            if (trigger(retTable, start, key)) {
                partitionedTables.remove(key);
            }

            partitionedTable.addRow(table, i);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy