import { compileCriteriaMatcher } from '@bilig/formula';
const INDEXED_PREDICATE_AGGREGATE_MAX_ANCHOR_DENSITY = 0.75;
export function getOrBuildIndexedPredicateAggregateFromColumnViews(args) {
    const { request } = args;
    const { criteriaPairs } = request;
    if (criteriaPairs.length === 0) {
        return undefined;
    }
    const expectedLength = criteriaPairs[0].range.length;
    if (criteriaPairs.some((pair) => pair.range.length !== expectedLength)) {
        return undefined;
    }
    if (request.aggregateKind !== 'count' && request.aggregateRange === undefined) {
        return undefined;
    }
    if (request.aggregateRange !== undefined && request.aggregateRange.length !== expectedLength) {
        return undefined;
    }
    const predicates = criteriaPairs.map((pair) => args.buildSlicePredicate(compileCriteriaMatcher(pair.criteria)));
    const resolvedPairs = criteriaPairs.map((pair, index) => ({
        view: args.getColumnView(pair.range),
        predicate: predicates[index],
    }));
    let limitingPairIndex;
    let limitingRows;
    for (let pairIndex = 0; pairIndex < resolvedPairs.length; pairIndex += 1) {
        const pair = resolvedPairs[pairIndex];
        const rowset = args.readIndexedEqualityRows(pair.view, pair.predicate, args.runtimeColumnStore);
        if (rowset === undefined) {
            continue;
        }
        if (limitingRows === undefined || rowset.cardinality < limitingRows.cardinality) {
            limitingPairIndex = pairIndex;
            limitingRows = rowset;
        }
    }
    if (limitingRows === undefined || limitingPairIndex === undefined) {
        return undefined;
    }
    if (expectedLength > 0 && limitingRows.cardinality / expectedLength > INDEXED_PREDICATE_AGGREGATE_MAX_ANCHOR_DENSITY) {
        return undefined;
    }
    const aggregateView = request.aggregateRange === undefined ? undefined : args.getColumnView(request.aggregateRange);
    const bucket = args.createExactAggregateBucket();
    limitingRows.forEachOffset((rowOffset) => {
        for (let pairIndex = 0; pairIndex < resolvedPairs.length; pairIndex += 1) {
            if (pairIndex === limitingPairIndex) {
                continue;
            }
            const pair = resolvedPairs[pairIndex];
            if (!args.slicePredicateMatches(pair.predicate, pair.view, rowOffset, args.runtimeColumnStore)) {
                return;
            }
        }
        args.addExactAggregateMatch(bucket, aggregateView, rowOffset);
    });
    return args.exactAggregateValueFromBucket(bucket.count === 0 ? undefined : bucket, request.aggregateKind);
}
//# sourceMappingURL=criterion-range-indexed-predicate-aggregate.js.map