"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.mergeTupleBTrees = exports.createTupleComparator = exports.newTupleBTree = void 0;
const internal_1 = require("@fluidframework/core-utils/internal");
const sorted_btree_es6_1 = require("@tylerbu/sorted-btree-es6");
// eslint-disable-next-line import-x/no-internal-modules
const union_1 = require("@tylerbu/sorted-btree-es6/extended/union");
const brand_js_1 = require("./brand.js");
/**
 * Create a new {@link TupleBTree}.
 * @param comparator - Either a single {@link TupleComparator | comparator} for all pairs of elements in the tuple or a {@link TupleComparators | tuple of comparators} that compares each pair of corresponding elements individually.
 * @param entries - Optional initial entries for the btree.
 */
function newTupleBTree(comparator, entries) {
    return (0, brand_js_1.brand)(new sorted_btree_es6_1.BTree(entries, comparator));
}
exports.newTupleBTree = newTupleBTree;
/**
 * Compares two tuples (arrays) element by element.
 * @param a - The first tuple to compare.
 * @param b - The second tuple to compare.
 * @returns The comparison of the first pair of elements at the same index that differ, or 0 if all elements are equal.
 * @remarks The tuples must be the same length and have the same type of elements in the same order.
 */
function createTupleComparator(compare = sorted_btree_es6_1.defaultComparator) {
    return (a, b) => {
        (0, internal_1.debugAssert)(() => a.length === b.length || "compareTuples requires arrays of the same length");
        const comparators = typeof compare === "function" ? undefined : compare;
        for (let i = 0; i < a.length; i++) {
            const comparator = comparators?.[i] ?? compare;
            const result = comparator(a[i], b[i]);
            if (result !== 0) {
                return result;
            }
        }
        return 0;
    };
}
exports.createTupleComparator = createTupleComparator;
/**
 * Merge the entries of two {@link TupleBTree}s.
 * @param tree1 - The first btree.
 * @param tree2 - The second btree.
 * This always returns a new btree and does not modify either input.
 * @param preferLeft - If true, colliding keys will use the value from `tree1`, otherwise the value from `tree2` is used.
 */
function mergeTupleBTrees(tree1, tree2, preferLeft = true) {
    if (tree2 === undefined) {
        return (0, brand_js_1.brand)(tree1.clone());
    }
    // Use efficient union operation from sorted-btree 2.x
    const result = (0, union_1.union)(tree1, tree2, (_key, val1, val2) => (preferLeft ? val1 : val2));
    return (0, brand_js_1.brand)(result);
}
exports.mergeTupleBTrees = mergeTupleBTrees;
//# sourceMappingURL=bTreeUtils.js.map