UNPKG

@jawis/shared-algs

Version:

Data structures for building concurrent programs.

130 lines (129 loc) 3.63 kB
import { TypedArray, TypedArrayContructor } from "^jab"; import { FixedSizeHeap, HeapFactory } from "./internal"; export type SharedChunkHeapDeps = { heapFactory: HeapFactory; pageSize: number; dataSize: number; verifyAfterOperations: boolean; }; /** * A heap of the given chunk size. Created from another heap. * * - A chunk ref includes a random version, which is used to detect invalid references. * - This heap allocates pages on the parent heap, and keeps them in a linked list. * - Operations are constant time. Plus the time used in parent heap. * - But parent pages are only deallocated when they are completely empty. Hence worst * case space use is one parent page per child page. * * notes * - Free seems to be synonymous with non-full. * - Similar implementation/purpose as SharedLeftCompactTree * * impl invariants * - There is at least one node. * - All full nodes are before any non-full nodes in the list. * - Non-full nodes are not in sorted order. * - Free pointer points at the last full or first non-full node. * - If the free pointer is full, then it's the last node in the list. * - not needed for anything, though. * - There's no empty nodes, except if the heap is fully empty. * * page layout * x bytes chunks * y bytes validity vector * * structure of reference (heighest bits first) * 20 bits page ref * 4 bits chunk integrity version * 8 bits chunk index * * todo * - count and freePointer should be in shared array * - pack function. */ export declare class SharedChunkHeap implements FixedSizeHeap { private deps; count: number; private list; private freePointer; readonly dataSize: number; readonly CHUNKS_PER_NODE: number; readonly VALIDITY_VECTOR_BYTES: number; /** * */ constructor(deps: SharedChunkHeapDeps); /** * */ static getMaxChunksPerNode: (blockSize: number, overhead: number, available: number, dataSize: number) => number; pack: () => never; /** * Get a previously allocated memory. * */ get: <T extends TypedArray>(ref: number, TypedArray: TypedArrayContructor<T>) => T; /** * */ allocate: <T extends TypedArray>(TypedArray: TypedArrayContructor<T>, zeroFill?: boolean) => { ref: number; array: T; }; /** * */ deallocate: (ref: number) => void; /** * todo: linked list doesn't deallocate. So must do it here. */ private _deallocate; /** * Given a node, that has become empty. * */ private onNodeBecomesEmpty; /** * Given a node, that has become non-full. * * - The node is moved to the free pointer. If the free pointer is full, * the node is placed after. Otherwise before. * - The node becomes the new free pointer. It will be sorted correctly, * because it has removed only one element, so it's a maximal element. */ private onNodeBecomesNonFull; /** * */ private getNonFullSubArray; /** * */ private getSubArray; /** * */ private getBitVector; /** * */ private encode; /** * */ private decode; /** * */ private _invariant; /** * */ toString: (includeRef?: boolean) => string; /** * Is the good enough? * - maybe it would be better to ensure it uses no space, when empty. But that would not * be possible, because threads need a shared value, even to determine that. */ dispose: () => void; }