@jawis/shared-algs
Version:
Data structures for building concurrent programs.
130 lines (129 loc) • 3.63 kB
TypeScript
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;
}