/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { Comparer, List, Stack } from "./collections";
import { LocalReferencePosition } from "./localReference";
import { CollaborationWindow, IMergeBlock, IncrementalMapState, ISegment, MergeBlock, MergeNode, MergeTreeStats, SegmentActions, SegmentGroup } from "./mergeTreeNodes";
import { IMergeTreeDeltaOpArgs, MergeTreeDeltaCallback, MergeTreeMaintenanceCallback } from "./mergeTreeDeltaCallback";
import { ICombiningOp, IMergeTreeDeltaOp, IRelativePosition, ReferenceType } from "./ops";
import { PropertySet } from "./properties";
import { ReferencePosition, RangeStackMap } from "./referencePositions";
import { PropertiesRollback } from "./segmentPropertiesManager";
/**
 * @deprecated  for internal use only. public export will be removed.
 * @internal
 */
export interface ClientSeq {
    refSeq: number;
    clientId: string;
}
/**
 * @deprecated  for internal use only. public export will be removed.
 * @internal
 */
export declare const clientSeqComparer: Comparer<ClientSeq>;
/**
 * @deprecated  for internal use only. public export will be removed.
 * @internal
 */
export interface LRUSegment {
    segment?: ISegment;
    maxSeq: number;
}
/**
 * @deprecated  for internal use only. public export will be removed.
 * @internal
 */
export declare class MergeTree {
    options?: PropertySet | undefined;
    private static readonly zamboniSegmentsMaxCount;
    static readonly options: {
        incrementalUpdate: boolean;
        insertAfterRemovedSegs: boolean;
        zamboniSegments: boolean;
    };
    private static readonly initBlockUpdateActions;
    private static readonly theUnfinishedNode;
    root: IMergeBlock;
    private readonly blockUpdateActions;
    readonly collabWindow: CollaborationWindow;
    /**
     * @deprecated  for internal use only. public export will be removed.
     * @internal
     */
    pendingSegments: List<SegmentGroup> | undefined;
    private segmentsToScour;
    /**
     * Whether or not all blocks in the mergeTree currently have information about local partial lengths computed.
     * This information is only necessary on reconnect, and otherwise costly to bookkeep.
     * This field enables tracking whether partials need to be recomputed using localSeq information.
     */
    private localPartialsComputed;
    private readonly idToSegment;
    private minSeqListeners;
    mergeTreeDeltaCallback?: MergeTreeDeltaCallback;
    mergeTreeMaintenanceCallback?: MergeTreeMaintenanceCallback;
    constructor(options?: PropertySet | undefined);
    private makeBlock;
    clone(): void;
    blockClone(block: IMergeBlock, segments?: ISegment[]): MergeBlock;
    private segmentClone;
    /**
     * Compute the net length of this segment from a local perspective.
     * @param segment - Segment whose length to find
     * @param localSeq - localSeq at which to find the length of this segment. If not provided,
     *     default is to consider the local client's current perspective. Only local sequence
     *     numbers corresponding to un-acked operations give valid results.
     */
    localNetLength(segment: ISegment, refSeq?: number, localSeq?: number): number;
    mapIdToSegment(id: string, segment: ISegment): void;
    private addNode;
    reloadFromSegments(segments: ISegment[]): void;
    startCollaboration(localClientId: number, minSeq: number, currentSeq: number): void;
    private addToLRUSet;
    private underflow;
    private scourNode;
    private packParent;
    private zamboniSegments;
    getCollabWindow(): CollaborationWindow;
    getStats(): MergeTreeStats;
    getLength(refSeq: number, clientId: number): number;
    /**
     * Returns the current length of the MergeTree for the local client.
     */
    get length(): number;
    getPosition(node: MergeNode, refSeq: number, clientId: number, localSeq?: number): number;
    getContainingSegment<T extends ISegment>(pos: number, refSeq: number, clientId: number, localSeq?: number): {
        segment: T | undefined;
        offset: number | undefined;
    };
    /**
     * @internal must only be used by client
     * @param segment - The segment to slide from
     * @returns The segment to
     */
    _getSlideToSegment(segment: ISegment | undefined): ISegment | undefined;
    /**
     * This method should only be called when the current client sequence number is
     * max(remove segment sequence number, add reference sequence number).
     * Otherwise eventual consistency is not guaranteed.
     * See `packages\dds\merge-tree\REFERENCEPOSITIONS.md`
     */
    private slideReferences;
    private updateSegmentRefsAfterMarkRemoved;
    private blockLength;
    private nodeLength;
    addMinSeqListener(minRequired: number, onMinGE: (minSeq: number) => void): void;
    private notifyMinSeqListeners;
    setMinSeq(minSeq: number): void;
    referencePositionToLocalPosition(refPos: ReferencePosition, refSeq?: number, clientId?: number): number;
    /**
     * @deprecated  for internal use only. public export will be removed.
     * @internal
     */
    getStackContext(startPos: number, clientId: number, rangeLabels: string[]): RangeStackMap;
    /**
     * Finds the nearest reference with ReferenceType.Tile to `startPos` in the direction dictated by `tilePrecedesPos`.

     * @param startPos - Position at which to start the search
     * @param clientId - clientId dictating the perspective to search from
     * @param tileLabel - Label of the tile to search for
     * @param tilePrecedesPos - Whether the desired tile comes before (true) or after (false) `startPos`
     * @returns
     */
    findTile(startPos: number, clientId: number, tileLabel: string, tilePrecedesPos?: boolean): {
        tile: ReferencePosition;
        pos: number;
    } | undefined;
    private search;
    private searchBlock;
    private backwardSearch;
    private backwardSearchBlock;
    private updateRoot;
    /**
     * Assign sequence number to existing segment; update partial lengths to reflect the change
     * @param seq - sequence number given by server to pending segment
     */
    ackPendingSegment(opArgs: IMergeTreeDeltaOpArgs): void;
    private addToPendingList;
    getMarkerFromId(id: string): ISegment | undefined;
    /**
     * Given a position specified relative to a marker id, lookup the marker
     * and convert the position to a character position.
     * @param relativePos - Id of marker (may be indirect) and whether position is before or after marker.
     * @param refseq - The reference sequence number at which to compute the position.
     * @param clientId - The client id with which to compute the position.
     */
    posFromRelativePos(relativePos: IRelativePosition, refseq?: number, clientId?: number): number;
    insertSegments(pos: number, segments: ISegment[], refSeq: number, clientId: number, seq: number, opArgs: IMergeTreeDeltaOpArgs | undefined): void;
    insertAtReferencePosition(referencePosition: ReferencePosition, insertSegment: ISegment, opArgs: IMergeTreeDeltaOpArgs): void;
    /**
     * Resolves a remote client's position against the local sequence
     * and returns the remote client's position relative to the local
     * sequence. The client ref seq must be above the minimum sequence number
     * or the return value will be undefined.
     * Generally this method is used in conjunction with signals which provide
     * point in time values for the below parameters, and is useful for things
     * like displaying user position. It should not be used with persisted values
     * as persisted values will quickly become invalid as the remoteClientRefSeq
     * moves below the minimum sequence number
     * @param remoteClientPosition - The remote client's position to resolve
     * @param remoteClientRefSeq - The reference sequence number of the remote client
     * @param remoteClientId - The client id of the remote client
     */
    resolveRemoteClientPosition(remoteClientPosition: number, remoteClientRefSeq: number, remoteClientId: number): number | undefined;
    private insertChildNode;
    private blockInsert;
    private readonly splitLeafSegment;
    private ensureIntervalBoundary;
    private breakTie;
    private leftExcursion;
    /**
     * Visit segments starting from node's right siblings, then up to node's parent.
     * All segments past `node` are visited, regardless of their visibility.
     */
    private rightExcursion;
    private insertingWalk;
    private split;
    private nodeUpdateOrdinals;
    /**
     * Annotate a range with properties
     * @param start - The inclusive start position of the range to annotate
     * @param end - The exclusive end position of the range to annotate
     * @param props - The properties to annotate the range with
     * @param combiningOp - Optional. Specifies how to combine values for the property, such as "incr" for increment.
     * @param refSeq - The reference sequence number to use to apply the annotate
     * @param clientId - The id of the client making the annotate
     * @param seq - The sequence number of the annotate operation
     * @param opArgs - The op args for the annotate op. this is passed to the merge tree callback if there is one
     * @param rollback - Whether this is for a local rollback and what kind
     */
    annotateRange(start: number, end: number, props: PropertySet, combiningOp: ICombiningOp | undefined, refSeq: number, clientId: number, seq: number, opArgs: IMergeTreeDeltaOpArgs, rollback?: PropertiesRollback): void;
    markRangeRemoved(start: number, end: number, refSeq: number, clientId: number, seq: number, overwrite: boolean | undefined, opArgs: IMergeTreeDeltaOpArgs): void;
    /**
     * Revert an unacked local op
     */
    rollback(op: IMergeTreeDeltaOp, localOpMetadata: SegmentGroup): void;
    /**
     *  Walk the segments up to the current segment and calculate its position
     */
    private findRollbackPosition;
    private nodeUpdateLengthNewStructure;
    removeLocalReferencePosition(lref: LocalReferencePosition): LocalReferencePosition | undefined;
    createLocalReferencePosition(segment: ISegment, offset: number, refType: ReferenceType, properties: PropertySet | undefined): LocalReferencePosition;
    private blockUpdate;
    private blockUpdatePathLengths;
    private blockUpdateLength;
    map<TClientData>(actions: SegmentActions<TClientData>, refSeq: number, clientId: number, accum: TClientData): void;
    mapRange<TClientData>(actions: SegmentActions<TClientData>, refSeq: number, clientId: number, accum: TClientData, start?: number, end?: number, splitRange?: boolean): void;
    /**
     * @deprecated  for internal use only. public export will be removed.
     * @internal
     */
    incrementalBlockMap<TContext>(stateStack: Stack<IncrementalMapState<TContext>>): void;
    private nodeMap;
    walkAllSegments<TClientData>(block: IMergeBlock, action: (segment: ISegment, accum?: TClientData) => boolean, accum?: TClientData): boolean;
    private nodeMapReverse;
}
//# sourceMappingURL=mergeTree.d.ts.map