/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { FieldKey } from "../tree";
import { UpPath } from "./pathTree";
/**
 * Sparse Tree of nodes.
 *
 * Contains both child and parent pointers, which are kept in sync.
 *
 * Each node is equivalent to a path through the tree.
 * This tree structure stores a collection of these paths, but deduplicating the common prefixes of the tree
 * prefix-tree style.
 */
export declare class SparseNode<TData> implements UpPath {
    parentField: FieldKey;
    parentIndex: number;
    /**
     * The parent of this `SparseNode` (an up pointer in the `SparseNode` tree).
     * If the status of this node is `Alive`, then there must be a corresponding down pointer from the
     * `parentPath` node to this node.
     * When undefined, this node is the root and thus has no parent.
     *
     * When updating the tree, it is valid to transiently leave the up and down pointers inconsistent
     * (updating down pointers first), but they must be consistent when the update is completed.
     */
    parentPath: SparseNode<TData> | undefined;
    data: TData;
    /**
     * SparseNode arrays are kept sorted the SparseNode's parentIndex for efficient search.
     * Users of this field must take care to maintain invariants (correct parent pointers, not empty child arrays etc.)
     *
     * Performance Note:
     * Large child lists could be updated more efficiently here using a data-structure optimized
     * for efficient prefix sum updates, such as a Fenwick tree or Finger tree.
     * This would be complicated by the need for parent pointers (including indexes),
     * but is possible to do.
     */
    readonly children: Map<FieldKey, SparseNode<TData>[]>;
    constructor(parentField: FieldKey, parentIndex: number, 
    /**
     * The parent of this `SparseNode` (an up pointer in the `SparseNode` tree).
     * If the status of this node is `Alive`, then there must be a corresponding down pointer from the
     * `parentPath` node to this node.
     * When undefined, this node is the root and thus has no parent.
     *
     * When updating the tree, it is valid to transiently leave the up and down pointers inconsistent
     * (updating down pointers first), but they must be consistent when the update is completed.
     */
    parentPath: SparseNode<TData> | undefined, data: TData);
    /**
     * @returns true iff this SparseNode is the special root node that sits above all the detached fields.
     * In this case, the fields are detached sequences.
     * Note that the special root node should never appear in an UpPath
     * since UpPaths represent this root as `undefined`.
     */
    private isRoot;
    get parent(): SparseNode<TData> | undefined;
    /**
     * Gets a child, adding a ref to it.
     * Creates child (with 1 ref) if needed.
     */
    getOrCreateChild(key: FieldKey, index: number, data: () => TData): SparseNode<TData>;
    /**
     * Gets a child if it exists.
     * Does NOT add a ref.
     */
    tryGetChild(key: FieldKey, index: number): SparseNode<TData> | undefined;
    /**
     * Removes reference from this to `child`.
     * Since PathNodes are doubly linked,
     * the caller must ensure that the reference from child to parent is also removed (or the child is no longer used).
     */
    removeChild(child: SparseNode<TData>): void;
    /**
     * Call this after directly editing the child array for a field to be empty.
     * Handles cleaning up unneeded data
     * (like the field in the map, and possibly this entire SparseNode and its parents if they are no longer needed.)
     */
    afterEmptyField(key: FieldKey): void;
    /**
     * Removes this from parent if alive, and sets this to disposed.
     * Must only be called when this node is no longer needed (has no references and no children).
     *
     * Allowed when dangling (but not when disposed).
     */
    private disposeThis;
}
export declare function getDescendant<TData>(ancestor: SparseNode<TData>, path: UpPath | undefined): SparseNode<TData>;
//# sourceMappingURL=sparseTree.d.ts.map