export const enum Handle { /** Minimum valid handle. */ valid = 1 , /** Sentinel representing an unallocated Handle. */ unallocated = - 0x80000000 } export const isHandleValid = ( handle ) => handle >= Handle . valid ; /**
 * A handle table provides a fast mapping from an integer `handle` to a value `T`.
 */ export class HandleTable < T > { public constructor ( private readonly handles = [ 1 ] ) { } public clear ( ) { this . handles . splice ( 0 , this . handles . length , 1 ) ; } /**
     * Allocates and returns the next available handle.  Note that freed handles are recycled.
     */ public allocate ( ) { const free = this . next ; this . next = ( this . handles [ free ] as Handle ) ?? ( free + 1 ) ; this . handles [ free ] = 0 ; return free ; } /**
     * Allocates and returns the next available `count` handles.
     */ public allocateMany ( count ) { const handles = new Uint32Array ( count ) ; for ( let i = 0 ; i < count ; i ++ ) { handles [ i ] = this . allocate ( ) ; } return handles ; } /**
     * Returns the given handle to the free list.
     */ public free ( handle ) { this . handles [ handle ] = this . next ; this . next = handle ; } /**
     * Get the value `T` associated with the given handle, if any.
     */ public get ( handle ) { return this . handles [ handle ] as T ; } /**
     * Set the value `T` associated with the given handle.
     */ public set ( handle , value ) { this . handles [ handle ] = value ; } private get next ( ) { return this . handles [ 0 ] as Handle ; } private set next ( handle ) { this . handles [ 0 ] = handle ; } public getSummaryContent ( ) { return this . handles ; } public static load < T > ( data ) { return new HandleTable < T > ( data ) ; } }