"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.propertyCopy = void 0;
/* eslint-disable no-bitwise */
/* eslint-disable @typescript-eslint/no-non-null-assertion */
const node_path_1 = __importDefault(require("node:path"));
const client_utils_1 = require("@fluid-internal/client-utils");
const stochastic_test_utils_1 = require("@fluid-private/stochastic-test-utils");
const ops_js_1 = require("../ops.js");
const properties_js_1 = require("../properties.js");
const dirname_cjs_1 = require("./dirname.cjs");
const testClient_js_1 = require("./testClient.js");
const testUtils_js_1 = require("./testUtils.js");
const clock = () => client_utils_1.Trace.start();
function elapsedMicroseconds(trace) {
    return trace.trace().duration * 1000;
}
function propertyCopy() {
    const propCount = 2000;
    const iterCount = 1000;
    const map = new Map();
    const a = [];
    const v = [];
    for (let i = 0; i < propCount; i++) {
        a[i] = `prop${i}`;
        v[i] = i;
        map.set(a[i], v[i]);
    }
    let clockStart = clock();
    let obj = {};
    for (let j = 0; j < iterCount; j++) {
        obj = (0, properties_js_1.createMap)();
        for (let i = 0; i < propCount; i++) {
            obj[a[i]] = v[i];
        }
    }
    let et = elapsedMicroseconds(clockStart);
    let perIter = (et / iterCount).toFixed(3);
    let perProp = (et / (iterCount * propCount)).toFixed(3);
    console.log(`arr prop init time ${perIter} us per ${propCount} properties; ${perProp} us per property`);
    clockStart = clock();
    for (let j = 0; j < iterCount; j++) {
        const bObj = (0, properties_js_1.createMap)();
        // eslint-disable-next-line no-restricted-syntax
        for (const key in obj) {
            if (key in obj) {
                bObj[key] = obj[key];
            }
        }
    }
    et = elapsedMicroseconds(clockStart);
    perIter = (et / iterCount).toFixed(3);
    perProp = (et / (iterCount * propCount)).toFixed(3);
    console.log(`obj prop init time ${perIter} us per ${propCount} properties; ${perProp} us per property`);
    clockStart = clock();
    for (let j = 0; j < iterCount; j++) {
        const bObj = (0, properties_js_1.createMap)();
        for (const [key, value] of map) {
            bObj[key] = value;
        }
    }
    et = elapsedMicroseconds(clockStart);
    perIter = (et / iterCount).toFixed(3);
    perProp = (et / (iterCount * propCount)).toFixed(2);
    console.log(`map prop init time ${perIter} us per ${propCount} properties; ${perProp} us per property`);
    clockStart = clock();
    for (let j = 0; j < iterCount; j++) {
        const bObj = (0, properties_js_1.createMap)();
        for (const [key, value] of map.entries()) {
            bObj[key] = value;
        }
    }
    et = elapsedMicroseconds(clockStart);
    perIter = (et / iterCount).toFixed(3);
    perProp = (et / (iterCount * propCount)).toFixed(2);
    console.log(`map foreach prop init time ${perIter} us per ${propCount} properties; ${perProp} us per property`);
    clockStart = clock();
    for (let j = 0; j < iterCount; j++) {
        const bmap = new Map();
        for (const [key, value] of map.entries()) {
            bmap.set(key, value);
        }
    }
    et = elapsedMicroseconds(clockStart);
    perIter = (et / iterCount).toFixed(3);
    perProp = (et / (iterCount * propCount)).toFixed(2);
    console.log(`map to map foreach prop init time ${perIter} us per ${propCount} properties; ${perProp} us per property`);
    const diffMap = new Map();
    for (const [key, value] of map.entries()) {
        if (Math.random() < 0.5) {
            diffMap.set(key, value);
        }
        else {
            diffMap.set(key, value * 3);
        }
    }
    clockStart = clock();
    const grayMap = new Map();
    for (let j = 0; j < iterCount; j++) {
        for (const [key, value] of map.entries()) {
            if (diffMap.get(key) !== value) {
                grayMap.set(key, 1);
            }
        }
    }
    perIter = (et / iterCount).toFixed(3);
    perProp = (et / (iterCount * propCount)).toFixed(2);
    console.log(`diff time ${perIter} us per ${propCount} properties; ${perProp} us per property`);
}
exports.propertyCopy = propertyCopy;
function makeBookmarks(client, bookmarkCount) {
    const random = (0, stochastic_test_utils_1.makeRandom)(0xdeadbeef, 0xfeedbed);
    const bookmarks = [];
    const len = client.getLength();
    for (let i = 0; i < bookmarkCount; i++) {
        const pos = random.integer(0, len - 1);
        const segoff = client.getContainingSegment(pos);
        let refType = ops_js_1.ReferenceType.Simple;
        if (i & 1) {
            refType = ops_js_1.ReferenceType.SlideOnRemove;
        }
        const lref = client.mergeTree.createLocalReferencePosition(segoff.segment, segoff.offset, refType, undefined);
        bookmarks.push(lref);
    }
    return bookmarks;
}
function measureFetch(startFile, withBookmarks = false) {
    const bookmarkCount = 20000;
    const client = new testClient_js_1.TestClient();
    (0, testUtils_js_1.loadTextFromFileWithMarkers)(startFile, client.mergeTree);
    if (withBookmarks) {
        makeBookmarks(client, bookmarkCount);
        console.log(`inserting ${bookmarkCount} refs into text`);
    }
    const reps = 20;
    const clockStart = clock();
    let count = 0;
    for (let i = 0; i < reps; i++) {
        for (let pos = 0; pos < client.getLength();) {
            // curPG.pos is ca end
            const curPG = client.searchForMarker(pos, "pg", true);
            const properties = curPG.properties;
            const curSegOff = client.getContainingSegment(pos);
            const curSeg = curSegOff.segment;
            // Combine paragraph and direct properties
            (0, properties_js_1.extend)(properties, curSeg.properties);
            pos += curSeg.cachedLength - curSegOff.offset;
            count++;
        }
    }
    const et = elapsedMicroseconds(clockStart);
    console.log(`fetch of ${count / reps} runs over ${client.getLength()} total chars took ${(et / count).toFixed(1)} microseconds per run`);
}
const baseDir = "../../src/test/literature";
const filename = node_path_1.default.join(dirname_cjs_1._dirname, baseDir, "pp.txt");
const testTimeout = 30000;
describe("Routerlicious", () => {
    describe("merge-tree", () => {
        it("wordUnitTest", () => {
            propertyCopy();
            measureFetch(filename);
            measureFetch(filename, true);
            measureFetch(filename);
            measureFetch(filename, true);
        }).timeout(testTimeout);
    });
});
//# sourceMappingURL=wordUnitTests.spec.js.map