/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import type { IIdCompressor } from "@fluidframework/id-compressor";
import { type FieldKey, type ITreeCursorSynchronous, type TreeFieldStoredSchema, type TreeNodeSchemaIdentifier, type TreeStoredSchemaSubscription, type Value, type TreeChunk, type SchemaAndPolicy, type SchemaPolicy } from "../../core/index.js";
import { BasicChunk } from "./basicChunk.js";
import type { IncrementalEncodingPolicy } from "./codec/index.js";
import { type FieldShape, TreeShape, UniformChunk } from "./uniformChunk.js";
export interface Disposable {
    /**
     * Cleans up resources used by this, such as inbound event registrations.
     */
    dispose(): void;
}
/**
 * Creates a ChunkPolicy which responds to schema changes.
 */
export declare function makeTreeChunker(schema: TreeStoredSchemaSubscription, policy: SchemaPolicy, shouldEncodeIncrementally: IncrementalEncodingPolicy): IChunker;
/**
 * Extends ChunkPolicy to include stateful details required by ChunkedForest.
 *
 * This extra complexity is mostly due to the fact that schema can change over time,
 * and that chunk policy uses caching which thus needs invalidation.
 */
export interface IChunker extends ChunkPolicy, Disposable {
    readonly schema: TreeStoredSchemaSubscription;
    clone(schema: TreeStoredSchemaSubscription): IChunker;
}
/**
 * Indicates that there are multiple possible `TreeShape` trees with a given type can have.
 *
 * @remarks
 * For example, a schema transitively containing a sequence field, optional field, or allowing multiple child types will be Polymorphic.
 * See `tryShapeFromNodeSchema` for how to tell if a type is Polymorphic.
 *
 * TODO: cache some of the possible shapes here.
 */
export declare class Polymorphic {
}
/**
 * See `Polymorphic`.
 * For now Polymorphic is stateless, so just use a singleton.
 */
export declare const polymorphic: Polymorphic;
/**
 * Information about the possible shapes a tree could take based on its type.
 * Note that this information is for a specific version of the schema.
 */
export type ShapeInfo = TreeShape | Polymorphic;
export declare class Chunker implements IChunker {
    readonly schema: TreeStoredSchemaSubscription;
    readonly policy: SchemaPolicy;
    readonly sequenceChunkSplitThreshold: number;
    readonly sequenceChunkInlineThreshold: number;
    readonly uniformChunkNodeCount: number;
    private readonly tryShapeFromNodeSchema;
    /**
     * Cache for information about possible shapes for types.
     * Corresponds to the version of the schema in `schema`.
     * Cleared when `schema` changes.
     */
    private readonly typeShapes;
    private unregisterSchemaCallback;
    constructor(schema: TreeStoredSchemaSubscription, policy: SchemaPolicy, sequenceChunkSplitThreshold: number, sequenceChunkInlineThreshold: number, uniformChunkNodeCount: number, tryShapeFromNodeSchema: (type: TreeNodeSchemaIdentifier, shapes: Map<TreeNodeSchemaIdentifier, ShapeInfo>) => ShapeInfo);
    clone(schema: TreeStoredSchemaSubscription): IChunker;
    shapeFromSchema(schema: TreeNodeSchemaIdentifier): ShapeInfo;
    dispose(): void;
    private schemaChanged;
}
/**
 * Get a TreeChunk for the current node (and its children) of cursor.
 * This will copy if needed, but add refs to existing chunks which hold the data.
 *
 * @param cursor - cursor in nodes mode
 */
export declare function chunkTree(cursor: ITreeCursorSynchronous, policy: ChunkCompressor): TreeChunk;
/**
 * Get a TreeChunk[] for the current field (and its children) of cursor.
 * This will copy if needed, but add refs to existing chunks which hold the data.
 */
export declare function chunkField(cursor: ITreeCursorSynchronous, policy: ChunkCompressor): TreeChunk[];
/**
 * Get a TreeChunk for the current field (and its children) of cursor.
 * Like {@link chunkField}, but forces the results into a single TreeChunk.
 */
export declare function chunkFieldSingle(cursor: ITreeCursorSynchronous, policy: ChunkCompressor): TreeChunk;
/**
 * Create a single TreeChunk from an array of TreeChunks.
 * @remarks
 * This takes ownership of the provided TreeChunk references, and returns an owned referenced.
 */
export declare function combineChunks(chunks: TreeChunk[]): TreeChunk;
/**
 * Get a BasicChunk for the current node (and its children) of cursor.
 * This will copy if needed, and add refs to existing chunks which hold the data.
 */
export declare function basicChunkTree(cursor: ITreeCursorSynchronous, policy: ChunkCompressor): BasicChunk;
export declare function makePolicy(policy?: Partial<ChunkPolicy>): ChunkPolicy;
export interface ShapeFromSchemaParameters extends SchemaAndPolicy {
    /**
     * Policy function to determine if a field should be encoded incrementally.
     * Incrementally encoding requires the subtree to not start in the middle of a larger uniform chunk.
     * Thus returning true from this callback indicates that shapes should not be produced which could
     *contain the incremental portion as a part of a larger shape.
     */
    readonly shouldEncodeIncrementally: IncrementalEncodingPolicy;
    /**
     * A cache for shapes which may be read and/or updated.
     * As the shape is a function of the other members of `ShapeFromSchemaParameters`,
     * it must be replaced or cleared if any of the properties other than this cache are modified.
     */
    readonly shapes: Map<TreeNodeSchemaIdentifier, ShapeInfo>;
}
/**
 * A TreeFieldStoredSchema with some additional context about where it is in the tree.
 */
export interface FieldSchemaWithContext {
    /**
     * The identifier of the specific field schema to analyze for shape uniformity.
     */
    readonly fieldSchema: TreeFieldStoredSchema;
    /**
     * The identifier of the parent node schema containing this field.
     * If undefined, this is a root field.
     */
    readonly parentNodeSchema?: TreeNodeSchemaIdentifier;
    /**
     * The field key/name used to identify this field within the parent node.
     */
    readonly key: FieldKey;
}
/**
 * Analyzes a tree node schema to determine if it has a single, uniform shape that can be optimized for chunking.
 * If the schema defines a tree structure with a deterministic, fixed shape (no optional fields, no sequences,
 * single child types), returns a TreeShape that can be used for efficient uniform chunking. Otherwise,
 * returns Polymorphic to indicate the shape varies and should use basic chunking.
 *
 * @param context - {@link ShapeFromSchemaParameters}.
 * @param nodeSchema - The identifier of the specific node schema to analyze for shape uniformity.
 * @returns TreeShape if the schema has a uniform shape, or Polymorphic if shape varies.
 *
 * @remarks
 * The determination here is conservative. `shouldEncodeIncrementally` is used to split up shapes so incrementally
 * encoded schema are not part of larger shapes. It also does not tolerate optional or sequence fields, nor does it
 * optimize for patterns of specific values.
 */
export declare function tryShapeFromNodeSchema(context: ShapeFromSchemaParameters, nodeSchema: TreeNodeSchemaIdentifier): ShapeInfo;
/**
 * Same as {@link tryShapeFromNodeSchema} but for fields with {@link FieldSchemaWithContext} instead of a nodeSchema.
 *
 * @param context - {@link ShapeFromFieldSchemaParameters}.
 * @param fieldSchemaWithContext - {@link FieldSchemaWithContext}.
 * @returns FieldShape if the field has a uniform shape, or undefined if the field is polymorphic.
 */
export declare function tryShapeFromFieldSchema(context: ShapeFromSchemaParameters, fieldSchemaWithContext: FieldSchemaWithContext): FieldShape | undefined;
/**
 * Default settings for use for {@link ChunkPolicy}.
 * Use `makeTreeChunker` to create a policy with the defaults, but leverages to schema.
 */
export declare const defaultChunkPolicy: ChunkPolicy;
export declare const basicOnlyChunkPolicy: ChunkPolicy;
/**
 * Policy for how to chunk a tree.
 */
export interface ChunkPolicy {
    /**
     * Group sequences longer than this into into sequence chunks of this length or less.
     *
     * Must be at least 2.
     * Can be set to `Number.POSITIVE_INFINITY` to never introduce extra sequence chunks.
     */
    readonly sequenceChunkSplitThreshold: number;
    /**
     * SequenceChunks this long or shorter may get inlined into their parent chunk.
     */
    readonly sequenceChunkInlineThreshold: number;
    /**
     * Maximum total nodes to put in a UniformChunk.
     */
    readonly uniformChunkNodeCount: number;
    /**
     * Returns information about the shapes trees of type `schema` can take.
     */
    shapeFromSchema(schema: TreeNodeSchemaIdentifier): ShapeInfo;
}
export interface ChunkCompressor {
    readonly policy: ChunkPolicy;
    /**
     * If the idCompressor is provided, {@link UniformChunk}s with identifiers will be encoded for its in-memory representation.
     * @remarks
     * This compression applies to {@link UniformChunk}s when {@link TreeShape.mayContainCompressedIds} is set.
     * If the `policy` does not use UniformChunks or does not set `mayContainCompressedIds`, then no compression will be applied even when providing `idCompressor`.
     */
    readonly idCompressor: IIdCompressor | undefined;
}
/**
 * Chunk a portion of a field.
 *
 * @param cursor - cursor at the starting node in the field.
 * @param policy - heuristics to impact chunking
 * @param length - how many nodes to process (at the top level). When 0, the cursor is not moved, and may be at the end of the field (and thus in Fields mode)
 * @param skipLastNavigation - if true, leaves the cursor at the last node instead of moving off of it. Invalid if length is 0.
 */
export declare function chunkRange(cursor: ITreeCursorSynchronous, chunkCompressor: ChunkCompressor, length: number, skipLastNavigation: boolean): TreeChunk[];
/**
 * Extracts values from the current cursor position according to the provided tree shape.
 *
 * Walks through the tree structure defined by the shape, extracting values from leaf nodes
 * and recursively processing child fields. If an ID compressor is provided, compressible
 * string values (stable node identifiers) will be recompressed for optimal storage.
 *
 * @param cursor - Tree cursor positioned at the node to extract values from
 * @param shape - The tree shape defining the structure to extract
 * @param values - Array to append the extracted values to
 * @param idCompressor - Optional compressor used to encode string values that are compressible by the idCompressor for in-memory representation.
 * If the idCompressor is not provided, the values will be the original uncompressed values.
 */
export declare function insertValues(cursor: ITreeCursorSynchronous, shape: TreeShape, values: Value[], idCompressor?: IIdCompressor): void;
/**
 * Read up to `maxTopLevelLength` nodes from `cursor`, stopping when limit is hit or type of node changes.
 *
 * This requires that the all trees with matching type match the provided shape.
 * This cannot be used if other shapes are possible for this type.
 *
 * If this stops early due to the type changing, `skipLastNavigation` is not involved:
 * `skipLastNavigation` only determines if the cursor will be left on the node after the last one (possibly exiting the field)
 * if the full length is used.
 *
 * @param idCompressor - compressor used to encoded string values that are compressible by the idCompressor for in-memory representation.
 * If the idCompressor is not provided, the values will be the original uncompressed values.
 */
export declare function uniformChunkFromCursor(cursor: ITreeCursorSynchronous, shape: TreeShape, maxTopLevelLength: number, skipLastNavigation: boolean, idCompressor?: IIdCompressor): UniformChunk;
//# sourceMappingURL=chunkTree.d.ts.map