New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@bnaya/objectbuffer

Package Overview
Dependencies
Maintainers
1
Versions
122
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bnaya/objectbuffer - npm Package Compare versions

Comparing version 0.0.0-136a848 to 0.0.0-1ed1bee

dist/internal/arraySaverIterative.d.ts

2

dist/index.d.ts

@@ -9,3 +9,3 @@ /**

*/ /** */
export { createObjectBuffer, resizeObjectBuffer, getUnderlyingArrayBuffer, loadObjectBuffer, replaceUnderlyingArrayBuffer, sizeOf as unreliable_sizeOf, memoryStats, disposeWrapperObject, updateExternalArgs } from "./internal/api";
export { createObjectBuffer, resizeObjectBuffer, getUnderlyingArrayBuffer, loadObjectBuffer, replaceUnderlyingArrayBuffer, sizeOf as unreliable_sizeOf, memoryStats, disposeWrapperObject, updateExternalArgs, } from "./internal/api";
export { acquireLock, acquireLockWait, releaseLock } from "./internal/locks";

@@ -12,0 +12,0 @@ export declare type ExternalArgs = import("./internal/interfaces").ExternalArgsApi;

@@ -11,4 +11,3 @@ /**

/** */
export { createObjectBuffer, resizeObjectBuffer, getUnderlyingArrayBuffer, loadObjectBuffer, replaceUnderlyingArrayBuffer // eslint-disable-next-line @typescript-eslint/camelcase
, sizeOf as unreliable_sizeOf, memoryStats, disposeWrapperObject, updateExternalArgs } from "./internal/api";
export { createObjectBuffer, resizeObjectBuffer, getUnderlyingArrayBuffer, loadObjectBuffer, replaceUnderlyingArrayBuffer, sizeOf as unreliable_sizeOf, memoryStats, disposeWrapperObject, updateExternalArgs } from "./internal/api";
export { acquireLock, acquireLockWait, releaseLock } from "./internal/locks";
import { initializeArrayBuffer } from "./store";
import { objectSaver } from "./objectSaver";
import { createObjectWrapper } from "./objectWrapper";
import { arrayBufferCopyTo, externalArgsApiToExternalArgsApi, getInternalAPI } from "./utils";
import { arrayBufferCopyTo, externalArgsApiToExternalArgsApi, getInternalAPI, isPrimitive } from "./utils";
import { getCacheFor } from "./externalObjectsCache";
import { INITIAL_ENTRY_POINTER_TO_POINTER, MEM_POOL_START } from "./consts";
import { MemPool } from "@thi.ng/malloc";
import { UnsupportedOperationError } from "./exceptions";
import { createHeap } from "../structsGenerator/consts";
import { saveValueIterative } from "./saveValue";
import { allocationsTransaction } from "./allocationsTransaction";

@@ -15,5 +18,10 @@ /**

export function createObjectBuffer(externalArgs, size, initialValue, options = {}) {
if (Array.isArray(initialValue) || initialValue instanceof Date || initialValue instanceof Map || initialValue instanceof Set || isPrimitive(initialValue) || typeof initialValue === "symbol") {
throw new UnsupportedOperationError();
}
const arrayBuffer = new (options.useSharedArrayBuffer ? SharedArrayBuffer : ArrayBuffer)(size);
const dataView = initializeArrayBuffer(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
align: 8,
buf: arrayBuffer,

@@ -23,3 +31,3 @@ start: MEM_POOL_START

const carrier = {
dataView,
// dataView,
allocator,

@@ -30,7 +38,9 @@ uint8: new Uint8Array(arrayBuffer),

float64: new Float64Array(arrayBuffer),
bigUint64: new BigUint64Array(arrayBuffer)
bigUint64: new BigUint64Array(arrayBuffer),
heap: createHeap(arrayBuffer)
};
const start = objectSaver(externalArgsApiToExternalArgsApi(externalArgs), carrier, [], initialValue);
dataView.setUint32(INITIAL_ENTRY_POINTER_TO_POINTER, start);
return createObjectWrapper(externalArgsApiToExternalArgsApi(externalArgs), carrier, start);
allocationsTransaction(() => {
saveValueIterative(externalArgsApiToExternalArgsApi(externalArgs), carrier, [], INITIAL_ENTRY_POINTER_TO_POINTER, initialValue);
}, allocator);
return createObjectWrapper(externalArgsApiToExternalArgsApi(externalArgs), carrier, carrier.heap.Uint32Array[INITIAL_ENTRY_POINTER_TO_POINTER / Uint32Array.BYTES_PER_ELEMENT]);
}

@@ -52,3 +62,3 @@ /**

export function getUnderlyingArrayBuffer(objectBuffer) {
return getInternalAPI(objectBuffer).getCarrier().dataView.buffer;
return getInternalAPI(objectBuffer).getCarrier().uint8.buffer;
}

@@ -66,4 +76,5 @@ /**

export function loadObjectBuffer(externalArgs, arrayBuffer) {
const dataView = new DataView(arrayBuffer);
// const dataView = new DataView(arrayBuffer);
const allocator = new MemPool({
align: 8,
buf: arrayBuffer,

@@ -74,3 +85,3 @@ start: MEM_POOL_START,

const carrier = {
dataView,
// dataView,
allocator,

@@ -81,5 +92,6 @@ uint8: new Uint8Array(arrayBuffer),

float64: new Float64Array(arrayBuffer),
bigUint64: new BigUint64Array(arrayBuffer)
bigUint64: new BigUint64Array(arrayBuffer),
heap: createHeap(arrayBuffer)
};
return createObjectWrapper(externalArgsApiToExternalArgsApi(externalArgs), carrier, dataView.getUint32(INITIAL_ENTRY_POINTER_TO_POINTER));
return createObjectWrapper(externalArgsApiToExternalArgsApi(externalArgs), carrier, carrier.uint32[INITIAL_ENTRY_POINTER_TO_POINTER / Uint32Array.BYTES_PER_ELEMENT]);
}

@@ -108,2 +120,3 @@ /**

const allocator = new MemPool({
align: 8,
buf: newArrayBuffer,

@@ -114,3 +127,3 @@ start: MEM_POOL_START,

const carrier = {
dataView: new DataView(newArrayBuffer),
// dataView: new DataView(newArrayBuffer),
allocator,

@@ -121,5 +134,6 @@ uint8: new Uint8Array(newArrayBuffer),

float64: new Float64Array(newArrayBuffer),
bigUint64: new BigUint64Array(newArrayBuffer)
}; // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
bigUint64: new BigUint64Array(newArrayBuffer),
heap: createHeap(newArrayBuffer)
}; // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error

@@ -137,2 +151,3 @@ allocator.end = newArrayBuffer.byteLength;

const pool = new MemPool({
align: 8,
buf,

@@ -139,0 +154,0 @@ skipInitialization: true,

@@ -1,20 +0,20 @@

import { ArrayEntry, ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces";
export declare function arrayGetMetadata(carrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number): ArrayEntry;
export declare function arrayGetPointersToValueInIndex(carrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number, indexToGet: number): {
import { ExternalArgs, GlobalCarrier } from "./interfaces";
import { Heap } from "../structsGenerator/consts";
export declare function arrayGetPointersToValueInIndex(carrier: GlobalCarrier, pointerToArrayEntry: number, indexToGet: number): {
pointer: number;
pointerToThePointer: number;
} | undefined;
export declare function getFinalValueAtArrayIndex(externalArgs: ExternalArgs, dataViewCarrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number, indexToGet: number): any;
export declare function setValuePointerAtArrayIndex(carrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number, indexToSet: number, pointerToEntry: number): void;
export declare function setValueAtArrayIndex(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number, indexToSet: number, value: any): void;
export declare function getFinalValueAtArrayIndex(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, pointerToArrayEntry: number, indexToGet: number): any;
export declare function setValuePointerAtArrayIndex(carrier: GlobalCarrier, pointerToArrayEntry: number, indexToSet: number, pointerToEntry: number): void;
export declare function setValueAtArrayIndex(externalArgs: ExternalArgs, carrier: GlobalCarrier, pointerToArrayEntry: number, indexToSet: number, value: any): void;
/**
* Will not shrink the array!
*/
export declare function extendArrayIfNeeded(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number, wishedLength: number): void;
export declare function extendArrayIfNeeded(externalArgs: ExternalArgs, carrier: GlobalCarrier, pointerToArrayEntry: number, wishedLength: number): void;
/**
* Will not empty memory or relocate the array!
*/
export declare function shrinkArray(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number, wishedLength: number): void;
export declare function arraySort(externalArgs: ExternalArgs, dataViewCarrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number, sortComparator?: (a: any, b: any) => 1 | -1 | 0): void;
export declare function arrayReverse(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number): void;
export declare function shrinkArray(heap: Heap, pointerToArrayEntry: number, wishedLength: number): void;
export declare function arraySort(externalArgs: ExternalArgs, carrier: GlobalCarrier, pointerToArrayEntry: number, sortComparator?: (a: any, b: any) => 1 | -1 | 0): void;
export declare function arrayReverse(carrier: GlobalCarrier, pointerToArrayEntry: number): void;
//# sourceMappingURL=arrayHelpers.d.ts.map

@@ -1,18 +0,14 @@

import { readEntry, writeEntry, writeValueInPtrToPtrAndHandleMemory } from "./store";
import { writeValueInPtrToPtrAndHandleMemory } from "./store";
import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue";
import { ENTRY_TYPE } from "./entry-types";
import { assertNonNull } from "./assertNonNull";
export function arrayGetMetadata(carrier, pointerToArrayEntry) {
const arrayEntry = readEntry(carrier, pointerToArrayEntry);
return arrayEntry;
}
import { array_length_get, array_dataspacePointer_get, array_allocatedLength_get, array_length_set, array_set_all, array_refsCount_get } from "./generatedStructs";
export function arrayGetPointersToValueInIndex(carrier, pointerToArrayEntry, indexToGet) {
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry); // out of bound
if (indexToGet >= metadata.length) {
// out of bound
if (indexToGet >= array_length_get(carrier.heap, pointerToArrayEntry)) {
return undefined;
}
const pointerToThePointer = metadata.value + indexToGet * Uint32Array.BYTES_PER_ELEMENT;
const pointer = carrier.dataView.getUint32(pointerToThePointer);
const pointerToThePointer = array_dataspacePointer_get(carrier.heap, pointerToArrayEntry) + indexToGet * Uint32Array.BYTES_PER_ELEMENT;
const pointer = carrier.uint32[pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT];
return {

@@ -23,4 +19,4 @@ pointer,

}
export function getFinalValueAtArrayIndex(externalArgs, dataViewCarrier, pointerToArrayEntry, indexToGet) {
const pointers = arrayGetPointersToValueInIndex(dataViewCarrier, pointerToArrayEntry, indexToGet);
export function getFinalValueAtArrayIndex(externalArgs, globalCarrier, pointerToArrayEntry, indexToGet) {
const pointers = arrayGetPointersToValueInIndex(globalCarrier, pointerToArrayEntry, indexToGet);

@@ -31,3 +27,3 @@ if (pointers === undefined) {

return entryToFinalJavaScriptValue(externalArgs, dataViewCarrier, pointers.pointer);
return entryToFinalJavaScriptValue(externalArgs, globalCarrier, pointers.pointer);
}

@@ -37,3 +33,3 @@ export function setValuePointerAtArrayIndex(carrier, pointerToArrayEntry, indexToSet, pointerToEntry) {

assertNonNull(pointers);
carrier.dataView.setUint32(pointers.pointerToThePointer, pointerToEntry);
carrier.uint32[pointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT] = pointerToEntry;
}

@@ -50,16 +46,8 @@ export function setValueAtArrayIndex(externalArgs, carrier, pointerToArrayEntry, indexToSet, value) {

export function extendArrayIfNeeded(externalArgs, carrier, pointerToArrayEntry, wishedLength) {
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry);
if (wishedLength > metadata.length) {
if (wishedLength > metadata.allocatedLength) {
reallocateArray(externalArgs, carrier, pointerToArrayEntry, wishedLength + externalArgs.arrayAdditionalAllocation, wishedLength);
if (wishedLength > array_length_get(carrier.heap, pointerToArrayEntry)) {
if (wishedLength > array_allocatedLength_get(carrier.heap, pointerToArrayEntry)) {
reallocateArray(carrier, pointerToArrayEntry, wishedLength + externalArgs.arrayAdditionalAllocation, wishedLength);
} else {
// no need to re-allocated, just push the length forward
writeEntry(carrier, pointerToArrayEntry, {
type: ENTRY_TYPE.ARRAY,
refsCount: metadata.refsCount,
value: metadata.value,
allocatedLength: metadata.allocatedLength,
length: wishedLength
});
array_length_set(carrier.heap, pointerToArrayEntry, wishedLength);
}

@@ -72,42 +60,16 @@ }

export function shrinkArray(externalArgs, carrier, pointerToArrayEntry, wishedLength) {
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry);
writeEntry(carrier, pointerToArrayEntry, {
type: ENTRY_TYPE.ARRAY,
refsCount: metadata.refsCount,
value: metadata.value,
allocatedLength: metadata.allocatedLength,
length: wishedLength
});
export function shrinkArray(heap, pointerToArrayEntry, wishedLength) {
array_length_set(heap, pointerToArrayEntry, wishedLength);
}
function reallocateArray(externalArgs, carrier, pointerToArrayEntry, newAllocatedLength, newLength) {
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry);
const newArrayValueLocation = carrier.allocator.realloc(metadata.value, newAllocatedLength * Uint32Array.BYTES_PER_ELEMENT); // for (
// let memoryToCopyIndex = 0;
// memoryToCopyIndex < metadata.length;
// memoryToCopyIndex += 1
// ) {
// carrier.dataView.setUint32(
// newArrayValueLocation + memoryToCopyIndex * Uint32Array.BYTES_PER_ELEMENT,
// carrier.dataView.getUint32(
// metadata.value + memoryToCopyIndex * Uint32Array.BYTES_PER_ELEMENT
// )
// );
// }
writeEntry(carrier, pointerToArrayEntry, {
type: ENTRY_TYPE.ARRAY,
refsCount: metadata.refsCount,
value: newArrayValueLocation,
allocatedLength: newAllocatedLength,
length: newLength
});
function reallocateArray(carrier, pointerToArrayEntry, newAllocatedLength, newLength) {
const newArrayValueLocation = carrier.allocator.realloc(array_dataspacePointer_get(carrier.heap, pointerToArrayEntry), newAllocatedLength * Uint32Array.BYTES_PER_ELEMENT);
array_set_all(carrier.heap, pointerToArrayEntry, ENTRY_TYPE.ARRAY, array_refsCount_get(carrier.heap, pointerToArrayEntry), newArrayValueLocation, newLength, newAllocatedLength);
}
export function arraySort(externalArgs, dataViewCarrier, pointerToArrayEntry, sortComparator = defaultCompareFunction) {
const metadata = arrayGetMetadata(dataViewCarrier, pointerToArrayEntry);
const pointersToValues = [...new Array(metadata.length).keys()].map(index => metadata.value + index * Uint32Array.BYTES_PER_ELEMENT).map(pointerToPointer => dataViewCarrier.dataView.getUint32(pointerToPointer));
export function arraySort(externalArgs, carrier, pointerToArrayEntry, sortComparator = defaultCompareFunction) {
const arrayDataSpace = array_dataspacePointer_get(carrier.heap, pointerToArrayEntry);
const pointersToValues = [...new Array(array_length_get(carrier.heap, pointerToArrayEntry)).keys()].map(index => arrayDataSpace + index * Uint32Array.BYTES_PER_ELEMENT).map(pointerToPointer => carrier.heap.Uint32Array[pointerToPointer / Uint32Array.BYTES_PER_ELEMENT]);
const sortMe = pointersToValues.map(pointer => {
return [pointer, entryToFinalJavaScriptValue(externalArgs, dataViewCarrier, pointer)];
return [pointer, entryToFinalJavaScriptValue(externalArgs, carrier, pointer)];
});

@@ -119,3 +81,3 @@ sortMe.sort((a, b) => {

for (let i = 0; i < sortMe.length; i += 1) {
dataViewCarrier.dataView.setUint32(metadata.value + i * Uint32Array.BYTES_PER_ELEMENT, sortMe[i][0]);
carrier.heap.Uint32Array[(arrayDataSpace + i * Uint32Array.BYTES_PER_ELEMENT) / Uint32Array.BYTES_PER_ELEMENT] = sortMe[i][0];
}

@@ -147,8 +109,6 @@ } // https://stackoverflow.com/a/47349064/711152

export function arrayReverse(externalArgs, carrier, pointerToArrayEntry) {
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry);
export function arrayReverse(carrier, pointerToArrayEntry) {
for (let i = 0; i < Math.floor(array_length_get(carrier.heap, pointerToArrayEntry) / 2); i += 1) {
const theOtherIndex = array_length_get(carrier.heap, pointerToArrayEntry) - i - 1; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
for (let i = 0; i < Math.floor(metadata.length / 2); i += 1) {
const theOtherIndex = metadata.length - i - 1; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const a = arrayGetPointersToValueInIndex(carrier, pointerToArrayEntry, i); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion

@@ -155,0 +115,0 @@

@@ -1,3 +0,3 @@

import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces";
export declare function arraySplice(externalArgs: ExternalArgs, dataViewCarrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number, startArg: number, deleteCountArg?: number, ...itemsToAddArg: Array<any>): any[];
import { ExternalArgs, GlobalCarrier } from "./interfaces";
export declare function arraySplice(externalArgs: ExternalArgs, carrier: GlobalCarrier, pointerToArrayEntry: number, startArg: number, deleteCountArg?: number, ...itemsToAddArg: Array<any>): any[];
//# sourceMappingURL=arraySplice.d.ts.map

@@ -1,17 +0,18 @@

import { arrayGetMetadata, getFinalValueAtArrayIndex, shrinkArray, extendArrayIfNeeded, arrayGetPointersToValueInIndex, setValuePointerAtArrayIndex } from "./arrayHelpers";
import { getFinalValueAtArrayIndex, shrinkArray, extendArrayIfNeeded, arrayGetPointersToValueInIndex, setValuePointerAtArrayIndex } from "./arrayHelpers";
import { assertNonNull } from "./assertNonNull";
import { writeValueInPtrToPtr } from "./store"; // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice#Syntax
import { writeValueInPtrToPtr } from "./store";
import { array_length_get } from "./generatedStructs"; // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice#Syntax
export function arraySplice(externalArgs, dataViewCarrier, pointerToArrayEntry, startArg, deleteCountArg, ...itemsToAddArg) {
const metadata = arrayGetMetadata(dataViewCarrier, pointerToArrayEntry);
const calcedStart = calculateSpliceStart(metadata.length, startArg);
const calcedDeleteCount = calculateDeleteCount(metadata.length, calcedStart, deleteCountArg);
const newLength = metadata.length + itemsToAddArg.length - calcedDeleteCount;
extendArrayIfNeeded(externalArgs, dataViewCarrier, pointerToArrayEntry, newLength);
export function arraySplice(externalArgs, carrier, pointerToArrayEntry, startArg, deleteCountArg, ...itemsToAddArg) {
const arrayLength = array_length_get(carrier.heap, pointerToArrayEntry);
const calcedStart = calculateSpliceStart(arrayLength, startArg);
const calcedDeleteCount = calculateDeleteCount(arrayLength, calcedStart, deleteCountArg);
const newLength = arrayLength + itemsToAddArg.length - calcedDeleteCount;
extendArrayIfNeeded(externalArgs, carrier, pointerToArrayEntry, newLength);
const deletedItemsToReturn = []; // can be negative
const itemCountChange = newLength - metadata.length;
const itemCountChange = newLength - arrayLength;
for (let deletedItemIndexToSave = calcedStart; deletedItemIndexToSave < calcedStart + calcedDeleteCount; deletedItemIndexToSave += 1) {
deletedItemsToReturn.push(getFinalValueAtArrayIndex(externalArgs, dataViewCarrier, pointerToArrayEntry, deletedItemIndexToSave));
deletedItemsToReturn.push(getFinalValueAtArrayIndex(externalArgs, carrier, pointerToArrayEntry, deletedItemIndexToSave));
} // copy-up items

@@ -28,6 +29,6 @@

for (let writeValueToIndex = newLength - 1; writeValueToIndex >= calcedStart + itemCountChange; writeValueToIndex -= 1) {
const valueToCopyPointers = arrayGetPointersToValueInIndex(dataViewCarrier, pointerToArrayEntry, writeValueToIndex - itemCountChange);
const valueToCopyPointers = arrayGetPointersToValueInIndex(carrier, pointerToArrayEntry, writeValueToIndex - itemCountChange);
assertNonNull(valueToCopyPointers);
setValuePointerAtArrayIndex(dataViewCarrier, pointerToArrayEntry, writeValueToIndex, valueToCopyPointers.pointer);
dataViewCarrier.dataView.setUint32(valueToCopyPointers.pointerToThePointer, 0);
setValuePointerAtArrayIndex(carrier, pointerToArrayEntry, writeValueToIndex, valueToCopyPointers.pointer);
carrier.heap.Uint32Array[valueToCopyPointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT] = 0;
}

@@ -42,8 +43,10 @@ } // copy-down items

else if (itemCountChange < 0) {
for (let writeValueToIndex = calcedStart + itemsToAddArg.length; writeValueToIndex < metadata.length + itemCountChange; writeValueToIndex += 1) {
const valueToCopyPointers = arrayGetPointersToValueInIndex(dataViewCarrier, pointerToArrayEntry, writeValueToIndex - itemCountChange);
assertNonNull(valueToCopyPointers);
setValuePointerAtArrayIndex(dataViewCarrier, pointerToArrayEntry, writeValueToIndex, valueToCopyPointers.pointer); // empty old array index, its still allocated!
for (let writeValueToIndex = calcedStart + itemsToAddArg.length; writeValueToIndex < arrayLength + itemCountChange; writeValueToIndex += 1) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const valueToCopyPointers = arrayGetPointersToValueInIndex(carrier, pointerToArrayEntry, writeValueToIndex - itemCountChange); // assertNonNull(valueToCopyPointers);
dataViewCarrier.dataView.setUint32(valueToCopyPointers.pointerToThePointer, 0); // using that is wastefull
setValuePointerAtArrayIndex(carrier, pointerToArrayEntry, writeValueToIndex, valueToCopyPointers.pointer); // empty old array index, its still allocated!
// handleArcForDeletedValuePointer(carrier, valueToCopyPointers.pointer);
carrier.heap.Uint32Array[valueToCopyPointers.pointer] = 0; // using that is wastefull
// setValueAtArrayIndex(

@@ -62,9 +65,9 @@ // dataView,

for (let i = 0; i < itemsToAddArg.length; i += 1) {
const valueToSetPointers = arrayGetPointersToValueInIndex(dataViewCarrier, pointerToArrayEntry, calcedStart + i);
const valueToSetPointers = arrayGetPointersToValueInIndex(carrier, pointerToArrayEntry, calcedStart + i);
assertNonNull(valueToSetPointers);
writeValueInPtrToPtr(externalArgs, dataViewCarrier, valueToSetPointers.pointerToThePointer, itemsToAddArg[i]);
writeValueInPtrToPtr(externalArgs, carrier, valueToSetPointers.pointerToThePointer, itemsToAddArg[i]);
}
if (newLength < metadata.length) {
shrinkArray(externalArgs, dataViewCarrier, pointerToArrayEntry, newLength);
if (newLength < arrayLength) {
shrinkArray(carrier.heap, pointerToArrayEntry, newLength);
}

@@ -71,0 +74,0 @@

@@ -1,9 +0,9 @@

import { ExternalArgs, DataViewAndAllocatorCarrier, ArrayEntry } from "./interfaces";
import { ExternalArgs, GlobalCarrier } from "./interfaces";
import { BaseProxyTrap } from "./BaseProxyTrap";
export declare class ArrayWrapper extends BaseProxyTrap<ArrayEntry> implements ProxyHandler<{}> {
get(target: {}, p: PropertyKey): any;
deleteProperty(target: {}, p: PropertyKey): boolean;
export declare class ArrayWrapper extends BaseProxyTrap implements ProxyHandler<Record<string, unknown>> {
get(target: Record<string, unknown>, p: PropertyKey): any;
deleteProperty(target: Record<string, unknown>, p: PropertyKey): boolean;
enumerate(): PropertyKey[];
ownKeys(): PropertyKey[];
getOwnPropertyDescriptor(target: {}, prop: any): {
getOwnPropertyDescriptor(target: Record<string, unknown>, prop: any): {
configurable: boolean;

@@ -17,4 +17,4 @@ enumerable: boolean;

} | undefined;
has(target: {}, p: PropertyKey): boolean;
set(target: {}, accessedProp: PropertyKey, value: any): boolean;
has(target: Record<string, unknown>, p: PropertyKey): boolean;
set(target: Record<string, unknown>, accessedProp: PropertyKey, value: any): boolean;
entries(): Iterable<[number, any]>;

@@ -29,3 +29,2 @@ keys(): Iterable<number>;

unshift(...elements: any): number;
getDataView(): DataView;
getEntryPointer(): number;

@@ -37,3 +36,3 @@ isExtensible(): boolean;

}
export declare function createArrayWrapper(externalArgs: ExternalArgs, dataViewCarrier: DataViewAndAllocatorCarrier, entryPointer: number): Array<any>;
export declare function createArrayWrapper(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, entryPointer: number): Array<any>;
//# sourceMappingURL=arrayWrapper.d.ts.map

@@ -1,2 +0,2 @@

import { getFinalValueAtArrayIndex, arrayGetMetadata, setValueAtArrayIndex, arraySort, extendArrayIfNeeded, arrayReverse } from "./arrayHelpers";
import { getFinalValueAtArrayIndex, setValueAtArrayIndex, arraySort, extendArrayIfNeeded, arrayReverse } from "./arrayHelpers";
import { INTERNAL_API_SYMBOL } from "./symbols";

@@ -7,2 +7,3 @@ import { arraySplice } from "./arraySplice";

import { BaseProxyTrap } from "./BaseProxyTrap";
import { array_length_get } from "./generatedStructs";
export class ArrayWrapper extends BaseProxyTrap {

@@ -15,4 +16,4 @@ get(target, p) {

if (p in this && p !== "constructor") {
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
return this[p];

@@ -22,3 +23,3 @@ }

if (p === "length") {
return arrayGetMetadata(this.carrier, this.entryPointer).length;
return array_length_get(this.carrier.heap, this.entryPointer);
}

@@ -32,4 +33,4 @@

}
} // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
} // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error

@@ -50,3 +51,3 @@

ownKeys() {
const length = arrayGetMetadata(this.carrier, this.entryPointer).length;
const length = array_length_get(this.carrier.heap, this.entryPointer);
return [...new Array(length).keys(), "length"];

@@ -79,3 +80,3 @@ }

const length = arrayGetMetadata(this.carrier, this.entryPointer).length;
const length = array_length_get(this.carrier.heap, this.entryPointer);

@@ -101,3 +102,3 @@ if (typeof p === "number") {

const currentLength = arrayGetMetadata(this.carrier, this.entryPointer).length;
const currentLength = array_length_get(this.carrier.heap, this.entryPointer);

@@ -139,3 +140,3 @@ if (currentLength === value) {

index += 1;
length = arrayGetMetadata(this.carrier, this.entryPointer).length;
length = array_length_get(this.carrier.heap, this.entryPointer);
} while (index < length);

@@ -151,3 +152,3 @@ }

index += 1;
length = arrayGetMetadata(this.carrier, this.entryPointer).length;
length = array_length_get(this.carrier.heap, this.entryPointer);
} while (index < length);

@@ -163,3 +164,3 @@ }

index += 1;
length = arrayGetMetadata(this.carrier, this.entryPointer).length;
length = array_length_get(this.carrier.heap, this.entryPointer);
} while (index < length);

@@ -181,3 +182,3 @@ }

reverse() {
arrayReverse(this.externalArgs, this.carrier, this.entryPointer);
arrayReverse(this.carrier, this.entryPointer);
return this;

@@ -196,8 +197,7 @@ } // no copy inside array is needed, so we can live with the built-in impl

this.splice(0, 0, ...elements);
return arrayGetMetadata(this.carrier, this.entryPointer).length;
}
return array_length_get(this.carrier.heap, this.entryPointer);
} // public getDataView() {
// return this.carrier.dataView;
// }
getDataView() {
return this.carrier.dataView;
}

@@ -233,4 +233,6 @@ getEntryPointer() {

}
export function createArrayWrapper(externalArgs, dataViewCarrier, entryPointer) {
return new Proxy([], new ArrayWrapper(externalArgs, dataViewCarrier, entryPointer));
export function createArrayWrapper(externalArgs, globalCarrier, entryPointer) {
return new Proxy( // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
[], new ArrayWrapper(externalArgs, globalCarrier, entryPointer));
}

@@ -1,10 +0,10 @@

import { ExternalArgs, DataViewAndAllocatorCarrier, InternalAPI, DateEntry, ArrayEntry, ObjectEntry, MapEntry, SetEntry } from "./interfaces";
export declare class BaseProxyTrap<T extends ObjectEntry | DateEntry | ArrayEntry | MapEntry | SetEntry> implements InternalAPI {
import { ExternalArgs, GlobalCarrier, InternalAPI } from "./interfaces";
export declare abstract class BaseProxyTrap implements InternalAPI {
protected externalArgs: ExternalArgs;
protected carrier: DataViewAndAllocatorCarrier;
protected carrier: GlobalCarrier;
protected _entryPointer: number;
constructor(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, _entryPointer: number);
constructor(externalArgs: ExternalArgs, carrier: GlobalCarrier, _entryPointer: number);
destroy(): number;
getCarrier(): DataViewAndAllocatorCarrier;
replaceCarrierContent(newCarrierContent: DataViewAndAllocatorCarrier): void;
getCarrier(): GlobalCarrier;
replaceCarrierContent(newCarrierContent: GlobalCarrier): void;
getEntryPointer(): number;

@@ -15,8 +15,5 @@ getExternalArgs(): Readonly<{

arrayAdditionalAllocation: number;
textDecoder: import("./textEncoderDecoderTypes").TextDecoder;
textEncoder: import("./textEncoderDecoderTypes").TextEncoder;
}>;
protected get entryPointer(): number;
protected get entry(): T;
}
//# sourceMappingURL=BaseProxyTrap.d.ts.map

@@ -1,2 +0,2 @@

import { incrementRefCount, decrementRefCount, readEntry } from "./store";
import { incrementRefCount, decrementRefCount } from "./store";
import { WrapperDestroyed } from "./exceptions";

@@ -8,7 +8,7 @@ export class BaseProxyTrap {

this._entryPointer = _entryPointer;
incrementRefCount(this.externalArgs, this.carrier, this.entryPointer);
incrementRefCount(this.carrier.heap, this.entryPointer);
}
destroy() {
const newRefCount = decrementRefCount(this.externalArgs, this.carrier, this.entryPointer);
const newRefCount = decrementRefCount(this.carrier.heap, this.entryPointer);
this._entryPointer = 0;

@@ -42,6 +42,2 @@ return newRefCount;

get entry() {
return readEntry(this.carrier, this.entryPointer);
}
}

@@ -9,2 +9,3 @@ export declare const LOCK_OFFSET = 0;

export declare const FALSE_KNOWN_ADDRESS = 3;
export declare const MAX_64_BIG_INT: bigint;
//# sourceMappingURL=consts.d.ts.map

@@ -8,2 +8,3 @@ export const LOCK_OFFSET = 0;

export const TRUE_KNOWN_ADDRESS = 2;
export const FALSE_KNOWN_ADDRESS = 3;
export const FALSE_KNOWN_ADDRESS = 3;
export const MAX_64_BIG_INT = BigInt("0xFFFFFFFFFFFFFFFF");

@@ -1,7 +0,7 @@

import { ExternalArgs, DataViewAndAllocatorCarrier, DateEntry } from "./interfaces";
import { ExternalArgs, GlobalCarrier } from "./interfaces";
import { BaseProxyTrap } from "./BaseProxyTrap";
export declare class DateWrapper extends BaseProxyTrap<DateEntry> implements ProxyHandler<Date> {
export declare class DateWrapper extends BaseProxyTrap implements ProxyHandler<Date> {
private dateObjectForReuse;
private useMeToGiveNamesToFunctionsAndCacheThem;
constructor(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, entryPointer: number);
constructor(externalArgs: ExternalArgs, carrier: GlobalCarrier, entryPointer: number);
get(target: Date, p: PropertyKey): any;

@@ -14,3 +14,3 @@ private updateDateObjectForReuse;

}
export declare function createDateWrapper(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, entryPointer: number): Date;
export declare function createDateWrapper(externalArgs: ExternalArgs, carrier: GlobalCarrier, entryPointer: number): Date;
//# sourceMappingURL=dateWrapper.d.ts.map

@@ -1,2 +0,1 @@

import { readEntry, writeEntry } from "./store";
import { ENTRY_TYPE } from "./entry-types";

@@ -6,2 +5,3 @@ import { INTERNAL_API_SYMBOL } from "./symbols";

import { BaseProxyTrap } from "./BaseProxyTrap";
import { date_set_all, date_refsCount_get, date_timestamp_get } from "./generatedStructs";
const getFunctions = ["toString", "toDateString", "toTimeString", "toISOString", "toUTCString", // "toGMTString",

@@ -50,12 +50,8 @@ "getDate", "getDay", "getFullYear", "getHours", "getMilliseconds", "getMinutes", "getMonth", "getSeconds", "getTime", "getTimezoneOffset", "getUTCDate", "getUTCDay", "getUTCFullYear", "getUTCHours", "getUTCMilliseconds", "getUTCMinutes", "getUTCMonth", "getUTCSeconds", // "getYear",

updateDateObjectForReuse() {
const entry = readEntry(this.carrier, this.entryPointer);
this.dateObjectForReuse.setTime(entry.value);
this.dateObjectForReuse.setTime(date_timestamp_get(this.carrier.heap, this.entryPointer));
}
persistDateObject() {
writeEntry(this.carrier, this.entryPointer, {
type: ENTRY_TYPE.DATE,
refsCount: this.entry.refsCount,
value: this.dateObjectForReuse.getTime()
});
date_set_all(this.carrier.heap, this.entryPointer, ENTRY_TYPE.DATE, date_refsCount_get(this.carrier.heap, this.entryPointer), // padding
0, this.dateObjectForReuse.getTime());
}

@@ -62,0 +58,0 @@

@@ -18,9 +18,13 @@ import { getInternalAPI } from "./utils";

const addressesToFree = getAllLinkedAddresses(internalApi.getCarrier(), false, entryPointer);
const {
allocator,
heap
} = internalApi.getCarrier();
for (const address of addressesToFree.leafAddresses) {
internalApi.getCarrier().allocator.free(address);
allocator.free(address);
}
for (const address of addressesToFree.arcAddresses) {
decrementRefCount(internalApi.getExternalArgs(), internalApi.getCarrier(), address);
decrementRefCount(heap, address);
}

@@ -27,0 +31,0 @@

@@ -1,3 +0,3 @@

import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces";
export declare function entryToFinalJavaScriptValue(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, pointerToEntry: number): any;
import { ExternalArgs, GlobalCarrier } from "./interfaces";
export declare function entryToFinalJavaScriptValue(externalArgs: ExternalArgs, carrier: GlobalCarrier, pointerToEntry: number): any;
//# sourceMappingURL=entryToFinalJavaScriptValue.d.ts.map

@@ -1,2 +0,2 @@

import { ENTRY_TYPE, isPrimitiveEntryType } from "./entry-types";
import { ENTRY_TYPE } from "./entry-types";
import { createObjectWrapper } from "./objectWrapper";

@@ -6,9 +6,9 @@ import { createArrayWrapper } from "./arrayWrapper";

import { getCacheFor } from "./externalObjectsCache";
import { decrementRefCount, readEntry } from "./store";
import { decrementRefCount } from "./store";
import { getAllLinkedAddresses } from "./getAllLinkedAddresses";
import { createMapWrapper } from "./mapWrapper";
import { createSetWrapper } from "./setWrapper";
import { UNDEFINED_KNOWN_ADDRESS, NULL_KNOWN_ADDRESS, TRUE_KNOWN_ADDRESS, FALSE_KNOWN_ADDRESS } from "./consts"; // declare const FinalizationGroup: any;
// declare const WeakRef: any;
import { UNDEFINED_KNOWN_ADDRESS, NULL_KNOWN_ADDRESS, TRUE_KNOWN_ADDRESS, FALSE_KNOWN_ADDRESS } from "./consts";
import { typeOnly_type_get, number_value_get, bigint_value_get } from "./generatedStructs";
import { readString } from "./readString";
const TYPE_TO_FACTORY = {

@@ -38,29 +38,44 @@ [ENTRY_TYPE.OBJECT]: createObjectWrapper,

const valueEntry = readEntry(carrier, pointerToEntry);
const entryType = typeOnly_type_get(carrier.heap, pointerToEntry);
if (isPrimitiveEntryType(valueEntry.type)) {
return valueEntry.value;
}
switch (entryType) {
case ENTRY_TYPE.NUMBER:
return number_value_get(carrier.heap, pointerToEntry);
break;
if (valueEntry.type === ENTRY_TYPE.OBJECT || valueEntry.type === ENTRY_TYPE.DATE || valueEntry.type === ENTRY_TYPE.ARRAY || valueEntry.type === ENTRY_TYPE.MAP || valueEntry.type === ENTRY_TYPE.SET) {
const cache = getCacheFor(carrier, key => {
finalizer(key, carrier, externalArgs);
});
let ret = cache.get(pointerToEntry);
case ENTRY_TYPE.STRING:
return readString(carrier.heap, pointerToEntry);
break;
if (!ret) {
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
ret = TYPE_TO_FACTORY[valueEntry.type](externalArgs, carrier, pointerToEntry);
cache.set(pointerToEntry, ret);
}
case ENTRY_TYPE.BIGINT_POSITIVE:
return bigint_value_get(carrier.heap, pointerToEntry);
break;
return ret;
case ENTRY_TYPE.BIGINT_NEGATIVE:
return bigint_value_get(carrier.heap, pointerToEntry) * BigInt("-1");
break;
} // this is an invariant
if (!(entryType === ENTRY_TYPE.OBJECT || entryType === ENTRY_TYPE.DATE || entryType === ENTRY_TYPE.ARRAY || entryType === ENTRY_TYPE.MAP || entryType === ENTRY_TYPE.SET)) {
throw new Error("Nope Nope Nope");
}
throw new Error("unsupported yet");
const cache = getCacheFor(carrier, key => {
finalizer(key, carrier);
});
let ret = cache.get(pointerToEntry);
if (!ret) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
ret = TYPE_TO_FACTORY[entryType](externalArgs, carrier, pointerToEntry);
cache.set(pointerToEntry, ret);
}
return ret;
}
function finalizer(memoryAddress, carrier, externalArgs) {
const newRefsCount = decrementRefCount(externalArgs, carrier, memoryAddress);
function finalizer(memoryAddress, carrier) {
const newRefsCount = decrementRefCount(carrier.heap, memoryAddress);

@@ -75,5 +90,5 @@ if (newRefsCount === 0) {

for (const address of freeUs.arcAddresses) {
decrementRefCount(externalArgs, carrier, address);
decrementRefCount(carrier.heap, address);
}
}
}

@@ -1,4 +0,6 @@

import { WeakValueMap } from "./WeakValueMap";
import { WeakValueMap } from "./WeakValueMap"; // eslint-disable-next-line @typescript-eslint/ban-types
const externalObjectsCache = new WeakMap();
export function getCacheFor(obj, externalFinalizer) {
export function getCacheFor( // eslint-disable-next-line @typescript-eslint/ban-types
obj, externalFinalizer) {
let map = externalObjectsCache.get(obj);

@@ -16,3 +18,3 @@

function supportWeakRef() {
return typeof WeakRef !== "undefined";
return typeof WeakRef !== "undefined" && (typeof FinalizationGroup !== "undefined" || typeof "FinalizationRegistry" !== "undefined");
}

@@ -1,7 +0,7 @@

import { DataViewAndAllocatorCarrier } from "./interfaces";
export declare function getAllLinkedAddresses(carrier: DataViewAndAllocatorCarrier, ignoreRefCount: boolean, entryPointer: number): {
leafAddresses: number[];
arcAddresses: number[];
import { GlobalCarrier } from "./interfaces";
export declare function getAllLinkedAddresses(carrier: GlobalCarrier, ignoreRefCount: boolean, entryPointer: number): {
leafAddresses: Set<number>;
arcAddresses: Set<number>;
};
export declare function getObjectOrMapOrSetAddresses(carrier: DataViewAndAllocatorCarrier, ignoreRefCount: boolean, internalHashmapPointer: number, leafAddresses: number[], arcAddresses: number[]): void;
export declare function getObjectOrMapOrSetAddresses(carrier: GlobalCarrier, internalHashmapPointer: number, leafAddresses: Set<number>, addressesToProcessQueue: number[]): void;
//# sourceMappingURL=getAllLinkedAddresses.d.ts.map

@@ -1,9 +0,21 @@

import { readEntry } from "./store";
import { ENTRY_TYPE } from "./entry-types";
import { hashMapGetPointersToFree } from "./hashmap/hashmap";
import { UNDEFINED_KNOWN_ADDRESS, NULL_KNOWN_ADDRESS, TRUE_KNOWN_ADDRESS, FALSE_KNOWN_ADDRESS } from "./consts";
import { isKnownAddressValuePointer } from "./utils";
import { typeOnly_type_get, string_charsPointer_get, typeAndRc_refsCount_get, object_pointerToHashMap_get, array_dataspacePointer_get, array_length_get } from "./generatedStructs";
export function getAllLinkedAddresses(carrier, ignoreRefCount, entryPointer) {
const leafAddresses = [];
const arcAddresses = [];
getAllLinkedAddressesStep(carrier, ignoreRefCount, entryPointer, leafAddresses, arcAddresses);
const leafAddresses = new Set();
const arcAddresses = new Set();
const addressesToProcessQueue = [entryPointer];
let addressToProcess = undefined; // const diffs = [];
while ((addressToProcess = addressesToProcessQueue.shift()) !== undefined) {
// const before = addressesToProcessQueue.slice();
if (addressToProcess === 0) {
continue;
}
getAllLinkedAddressesStep(carrier, ignoreRefCount, addressToProcess, leafAddresses, arcAddresses, addressesToProcessQueue); // diffs.push(addressesToProcessQueue.filter((p) => !before.includes(p)));
} // console.log(diffs);
return {

@@ -15,25 +27,35 @@ leafAddresses,

function getAllLinkedAddressesStep(carrier, ignoreRefCount, entryPointer, leafAddresses, arcAddresses) {
if (entryPointer === UNDEFINED_KNOWN_ADDRESS || entryPointer === NULL_KNOWN_ADDRESS || entryPointer === TRUE_KNOWN_ADDRESS || entryPointer === FALSE_KNOWN_ADDRESS) {
function getAllLinkedAddressesStep(carrier, ignoreRefCount, entryPointer, leafAddresses, arcAddresses, addressesToProcessQueue) {
const {
heap
} = carrier;
if (isKnownAddressValuePointer(entryPointer) || leafAddresses.has(entryPointer) || arcAddresses.has(entryPointer)) {
return;
}
const entry = readEntry(carrier, entryPointer);
const entryType = typeOnly_type_get(heap, entryPointer); // to be used ONLY if the type has ref counter
switch (entry.type) {
const refsCount = typeAndRc_refsCount_get(heap, entryPointer);
switch (entryType) {
case ENTRY_TYPE.NUMBER:
case ENTRY_TYPE.STRING:
case ENTRY_TYPE.BIGINT_NEGATIVE:
case ENTRY_TYPE.BIGINT_POSITIVE:
leafAddresses.push(entryPointer);
leafAddresses.add(entryPointer);
break;
case ENTRY_TYPE.STRING:
leafAddresses.add(string_charsPointer_get(heap, entryPointer));
leafAddresses.add(entryPointer);
break;
case ENTRY_TYPE.OBJECT:
case ENTRY_TYPE.MAP:
case ENTRY_TYPE.SET:
if (entry.refsCount <= 1 || ignoreRefCount) {
leafAddresses.push(entryPointer);
getObjectOrMapOrSetAddresses(carrier, ignoreRefCount, entry.value, leafAddresses, arcAddresses);
if (refsCount <= 1 || ignoreRefCount) {
leafAddresses.add(entryPointer);
getObjectOrMapOrSetAddresses(carrier, object_pointerToHashMap_get(heap, entryPointer), leafAddresses, addressesToProcessQueue);
} else {
arcAddresses.push(entryPointer);
arcAddresses.add(entryPointer);
}

@@ -44,12 +66,13 @@

case ENTRY_TYPE.ARRAY:
if (entry.refsCount <= 1 || ignoreRefCount) {
leafAddresses.push(entryPointer);
leafAddresses.push(entry.value);
if (refsCount <= 1 || ignoreRefCount) {
leafAddresses.add(entryPointer);
leafAddresses.add(array_dataspacePointer_get(heap, entryPointer));
const arrayLength = array_length_get(heap, entryPointer);
for (let i = 0; i < entry.allocatedLength; i += 1) {
const valuePointer = carrier.dataView.getUint32(entry.value + i * Uint32Array.BYTES_PER_ELEMENT);
getAllLinkedAddressesStep(carrier, ignoreRefCount, valuePointer, leafAddresses, arcAddresses);
for (let i = 0; i < arrayLength; i += 1) {
const valuePointer = carrier.uint32[(array_dataspacePointer_get(heap, entryPointer) + i * Uint32Array.BYTES_PER_ELEMENT) / Uint32Array.BYTES_PER_ELEMENT];
addressesToProcessQueue.push(valuePointer);
}
} else {
arcAddresses.push(entryPointer);
arcAddresses.add(entryPointer);
}

@@ -60,6 +83,6 @@

case ENTRY_TYPE.DATE:
if (entry.refsCount <= 1 || ignoreRefCount) {
leafAddresses.push(entryPointer);
if (refsCount <= 1 || ignoreRefCount) {
leafAddresses.add(entryPointer);
} else {
arcAddresses.push(entryPointer);
arcAddresses.add(entryPointer);
}

@@ -70,18 +93,19 @@

default:
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
throw new Error(ENTRY_TYPE[entry.type] + " Not implemented yet");
throw new Error(ENTRY_TYPE[entryType] + " Not implemented yet");
}
}
export function getObjectOrMapOrSetAddresses(carrier, ignoreRefCount, internalHashmapPointer, leafAddresses, arcAddresses) {
export function getObjectOrMapOrSetAddresses(carrier, internalHashmapPointer, leafAddresses, addressesToProcessQueue) {
const {
pointersToValuePointers,
pointers
} = hashMapGetPointersToFree(carrier.dataView, internalHashmapPointer);
leafAddresses.push(...pointers);
} = hashMapGetPointersToFree(carrier, internalHashmapPointer);
for (const leafPointer of pointers) {
leafAddresses.add(leafPointer);
}
for (const pointer of pointersToValuePointers) {
getAllLinkedAddressesStep(carrier, ignoreRefCount, carrier.dataView.getUint32(pointer), leafAddresses, arcAddresses);
addressesToProcessQueue.push(carrier.uint32[pointer / Uint32Array.BYTES_PER_ELEMENT]);
}
}

@@ -1,3 +0,3 @@

import { DataViewAndAllocatorCarrier, ExternalArgs } from "../interfaces";
export declare function createHashMap(carrier: DataViewAndAllocatorCarrier,
import { GlobalCarrier, ExternalArgs } from "../interfaces";
export declare function createHashMap(carrier: GlobalCarrier,
/**

@@ -10,12 +10,12 @@ * number of buckets

*/
export declare function hashMapInsertUpdate(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, mapPointer: number, externalKeyValue: number | string): number;
export declare function hashMapInsertUpdate(externalArgs: ExternalArgs, carrier: GlobalCarrier, mapPointer: number, externalKeyValue: number | string): number;
/**
* @returns pointer of the pointer to the found node
*/
export declare function hashMapNodeLookup(carrier: DataViewAndAllocatorCarrier, mapPointer: number, externalKeyValue: number | string): number;
export declare function hashMapValueLookup(carrier: DataViewAndAllocatorCarrier, mapPointer: number, externalKeyValue: number | string): number;
export declare function hashMapNodeLookup(carrier: GlobalCarrier, mapPointer: number, externalKeyValue: number | string): number;
export declare function hashMapValueLookup(carrier: GlobalCarrier, mapPointer: number, externalKeyValue: number | string): number;
/**
* @returns the value pointer of the deleted key
*/
export declare function hashMapDelete(carrier: DataViewAndAllocatorCarrier, mapPointer: number, externalKeyValue: number | string): number;
export declare function hashMapDelete(carrier: GlobalCarrier, mapPointer: number, externalKeyValue: number | string): number;
/**

@@ -25,13 +25,13 @@ *

*/
export declare function hashMapLowLevelIterator(dataView: DataView, mapPointer: number, nodePointerIteratorToken: number): number;
export declare function hashMapNodePointerToKeyValue(dataView: DataView, nodePointer: number): {
export declare function hashMapLowLevelIterator(carrier: GlobalCarrier, mapPointer: number, nodePointerIteratorToken: number): number;
export declare function hashMapNodePointerToKeyValue(carrier: GlobalCarrier, nodePointer: number): {
valuePointer: number;
keyPointer: number;
};
export declare function hashMapSize(dataView: DataView, mapPointer: number): number;
export declare function hashMapGetPointersToFree(dataView: DataView, hashmapPointer: number): {
export declare function hashMapSize(carrier: GlobalCarrier, mapPointer: number): number;
export declare function hashMapGetPointersToFree(carrier: GlobalCarrier, hashmapPointer: number): {
pointers: number[];
pointersToValuePointers: number[];
};
export declare function hashmapNodesPointerIterator(dataView: DataView, mapPointer: number): Generator<number, void, unknown>;
export declare function hashmapNodesPointerIterator(carrier: GlobalCarrier, mapPointer: number): Generator<number, void, unknown>;
//# sourceMappingURL=hashmap.d.ts.map
import { MAP_MACHINE, NODE_MACHINE } from "./memoryLayout";
import { hashCodeInPlace, hashCodeExternalValue, getKeyStartLength } from "./hashmapUtils";
import { primitiveValueToEntry } from "../utils";
import { sizeOfEntry, writeEntry, readEntry, compareStringOrNumberEntriesInPlace } from "../store";
import { strByteLength } from "../utils";
import { stringEncodeInto } from "../stringEncodeInto";
import { compareStringOrNumberEntriesInPlace, readNumberOrString } from "../store";
import { ENTRY_TYPE } from "../entry-types";
import { initLinkedList, linkedListItemInsert, linkedListItemRemove, linkedListLowLevelIterator, linkedListGetValue, linkedListGetPointersToFree } from "../linkedList/linkedList";
import { number_size, string_size, number_set_all, string_set_all, number_value_place, number_value_ctor, typeOnly_type_get, string_charsPointer_get } from "../generatedStructs";
export function createHashMap(carrier,

@@ -15,3 +17,3 @@ /**

const linkedListPointer = initLinkedList(carrier);
const mapMachine = MAP_MACHINE.createOperator(carrier.dataView, hashMapMemory);
const mapMachine = MAP_MACHINE.createOperator(carrier, hashMapMemory);
mapMachine.set("ARRAY_POINTER", arrayMemory);

@@ -29,17 +31,31 @@ mapMachine.set("CAPACITY", initialCapacity);

export function hashMapInsertUpdate(externalArgs, carrier, mapPointer, externalKeyValue) {
const mapOperator = MAP_MACHINE.createOperator(carrier.dataView, mapPointer);
const keyEntry = primitiveValueToEntry(externalKeyValue); // allocate all possible needed memory upfront, so we won't oom in the middle of something
const mapOperator = MAP_MACHINE.createOperator(carrier, mapPointer); // const keyEntry = primitiveValueToEntry(externalKeyValue) as
// | NumberEntry
// | StringEntry;
// allocate all possible needed memory upfront, so we won't oom in the middle of something
// in case of overwrite, we will not need this memory
const memoryForNewNode = carrier.allocator.calloc(NODE_MACHINE.map.SIZE_OF);
const memorySizeOfKey = sizeOfEntry(keyEntry);
const keyEntryMemory = carrier.allocator.calloc(memorySizeOfKey);
writeEntry(carrier, keyEntryMemory, keyEntry);
const keyHeaderOverhead = keyEntry.type === ENTRY_TYPE.STRING ? 5 : 1;
const keyHashCode = hashCodeInPlace(carrier.dataView, mapOperator.get("CAPACITY"), // + 1 for the type of key
keyEntryMemory + keyHeaderOverhead, memorySizeOfKey - keyHeaderOverhead);
let keyMemoryEntryPointer;
let keyDataMemoryStart;
let keyDataMemoryLength;
if (typeof externalKeyValue === "number") {
keyMemoryEntryPointer = carrier.allocator.calloc(number_size);
number_set_all(carrier.heap, keyMemoryEntryPointer, ENTRY_TYPE.NUMBER, externalKeyValue);
keyDataMemoryStart = keyMemoryEntryPointer + number_value_place;
keyDataMemoryLength = number_value_ctor.BYTES_PER_ELEMENT;
} else {
keyMemoryEntryPointer = carrier.allocator.calloc(string_size);
keyDataMemoryLength = strByteLength(externalKeyValue);
keyDataMemoryStart = carrier.allocator.calloc(keyDataMemoryLength);
stringEncodeInto(carrier.heap.Uint8Array, keyDataMemoryStart, externalKeyValue);
string_set_all(carrier.heap, keyMemoryEntryPointer, ENTRY_TYPE.STRING, keyDataMemoryLength, keyDataMemoryStart);
}
const keyHashCode = hashCodeInPlace(carrier.uint8, mapOperator.get("CAPACITY"), keyDataMemoryStart, keyDataMemoryLength);
let ptrToPtrToSaveTheNodeTo = mapOperator.get("ARRAY_POINTER") + keyHashCode * Uint32Array.BYTES_PER_ELEMENT;
const commonNodeOperator = NODE_MACHINE.createOperator(carrier.dataView, carrier.dataView.getUint32(ptrToPtrToSaveTheNodeTo)); // todo: share code with hashMapNodeLookup?
const commonNodeOperator = NODE_MACHINE.createOperator(carrier, carrier.uint32[ptrToPtrToSaveTheNodeTo / Uint32Array.BYTES_PER_ELEMENT]); // todo: share code with hashMapNodeLookup?
while (commonNodeOperator.startAddress !== 0 && !compareStringOrNumberEntriesInPlace(carrier.dataView, commonNodeOperator.get("KEY_POINTER"), keyEntryMemory)) {
while (commonNodeOperator.startAddress !== 0 && !compareStringOrNumberEntriesInPlace(carrier.heap, commonNodeOperator.get("KEY_POINTER"), keyMemoryEntryPointer)) {
ptrToPtrToSaveTheNodeTo = commonNodeOperator.pointerTo("NEXT_NODE_POINTER");

@@ -57,3 +73,4 @@ commonNodeOperator.startAddress = commonNodeOperator.get("NEXT_NODE_POINTER");

// we don't need the new memory
carrier.allocator.free(keyEntryMemory);
// @todo Free here also the string data
carrier.allocator.free(keyMemoryEntryPointer);
carrier.allocator.free(memoryForNewNode);

@@ -63,8 +80,8 @@ return commonNodeOperator.pointerTo("VALUE_POINTER");

commonNodeOperator.startAddress = memoryForNewNode;
commonNodeOperator.set("KEY_POINTER", keyEntryMemory);
commonNodeOperator.set("KEY_POINTER", keyMemoryEntryPointer);
commonNodeOperator.set("LINKED_LIST_ITEM_POINTER", linkedListItemInsert(carrier, mapOperator.get("LINKED_LIST_POINTER"), memoryForNewNode));
carrier.dataView.setUint32(ptrToPtrToSaveTheNodeTo, memoryForNewNode);
carrier.uint32[ptrToPtrToSaveTheNodeTo / Uint32Array.BYTES_PER_ELEMENT] = memoryForNewNode;
mapOperator.set("LINKED_LIST_SIZE", mapOperator.get("LINKED_LIST_SIZE") + 1);
if (shouldRehash(mapOperator.get("LINKED_LIST_SIZE"), mapOperator.get("CAPACITY"), mapOperator.get("USED_CAPACITY"), externalArgs.hashMapLoadFactor)) {
if (shouldRehash(mapOperator.get("CAPACITY"), mapOperator.get("USED_CAPACITY"), externalArgs.hashMapLoadFactor)) {
// console.log("rehash", {

@@ -84,11 +101,11 @@ // USED_CAPACITY: mapOperator.get("USED_CAPACITY")

export function hashMapNodeLookup(carrier, mapPointer, externalKeyValue) {
const mapMachine = MAP_MACHINE.createOperator(carrier.dataView, mapPointer);
const mapMachine = MAP_MACHINE.createOperator(carrier, mapPointer);
const keyHashCode = hashCodeExternalValue(mapMachine.get("CAPACITY"), externalKeyValue);
let ptrToPtr = mapMachine.get("ARRAY_POINTER") + keyHashCode * Uint32Array.BYTES_PER_ELEMENT;
const node = NODE_MACHINE.createOperator(carrier.dataView, carrier.dataView.getUint32(ptrToPtr));
const node = NODE_MACHINE.createOperator(carrier, carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT]);
while (node.startAddress !== 0) {
const keyEntry = readEntry(carrier, node.get("KEY_POINTER"));
const keyValue = readNumberOrString(carrier.heap, node.get("KEY_POINTER"));
if (keyEntry.value === externalKeyValue) {
if (keyValue === externalKeyValue) {
return ptrToPtr;

@@ -110,3 +127,3 @@ }

const node = NODE_MACHINE.createOperator(carrier.dataView, carrier.dataView.getUint32(nodePtrToPtr));
const node = NODE_MACHINE.createOperator(carrier, carrier.uint32[nodePtrToPtr / Uint32Array.BYTES_PER_ELEMENT]);
return node.pointerTo("VALUE_POINTER");

@@ -125,11 +142,16 @@ }

const nodeToDeletePointer = carrier.dataView.getUint32(foundNodePtrToPtr);
const nodeOperator = NODE_MACHINE.createOperator(carrier.dataView, nodeToDeletePointer);
const nodeToDeletePointer = carrier.uint32[foundNodePtrToPtr / Uint32Array.BYTES_PER_ELEMENT];
const nodeOperator = NODE_MACHINE.createOperator(carrier, nodeToDeletePointer);
const valuePointer = nodeOperator.pointerTo("VALUE_POINTER");
linkedListItemRemove(carrier, nodeOperator.get("LINKED_LIST_ITEM_POINTER")); // remove node from bucket
carrier.dataView.setUint32(foundNodePtrToPtr, nodeOperator.get("NEXT_NODE_POINTER"));
carrier.uint32[foundNodePtrToPtr / Uint32Array.BYTES_PER_ELEMENT] = nodeOperator.get("NEXT_NODE_POINTER");
if (typeOnly_type_get(carrier.heap, nodeOperator.get("KEY_POINTER")) === ENTRY_TYPE.STRING) {
carrier.allocator.free(string_charsPointer_get(carrier.heap, nodeOperator.get("KEY_POINTER")));
}
carrier.allocator.free(nodeOperator.get("KEY_POINTER"));
carrier.allocator.free(nodeOperator.startAddress);
carrier.dataView.setUint32(mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset, carrier.dataView.getUint32(mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset) - 1);
carrier.uint32[(mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset) / Uint32Array.BYTES_PER_ELEMENT]--;
return valuePointer;

@@ -142,11 +164,11 @@ }

export function hashMapLowLevelIterator(dataView, mapPointer, nodePointerIteratorToken) {
const mapOperator = MAP_MACHINE.createOperator(dataView, mapPointer);
export function hashMapLowLevelIterator(carrier, mapPointer, nodePointerIteratorToken) {
const mapOperator = MAP_MACHINE.createOperator(carrier, mapPointer);
let tokenToUseForLinkedListIterator = 0;
if (nodePointerIteratorToken !== 0) {
tokenToUseForLinkedListIterator = NODE_MACHINE.createOperator(dataView, nodePointerIteratorToken).get("LINKED_LIST_ITEM_POINTER");
tokenToUseForLinkedListIterator = NODE_MACHINE.createOperator(carrier, nodePointerIteratorToken).get("LINKED_LIST_ITEM_POINTER");
}
const pointerToNextLinkedListItem = linkedListLowLevelIterator(dataView, mapOperator.get("LINKED_LIST_POINTER"), tokenToUseForLinkedListIterator);
const pointerToNextLinkedListItem = linkedListLowLevelIterator(carrier, mapOperator.get("LINKED_LIST_POINTER"), tokenToUseForLinkedListIterator);

@@ -157,6 +179,6 @@ if (pointerToNextLinkedListItem === 0) {

return linkedListGetValue(dataView, pointerToNextLinkedListItem);
return linkedListGetValue(carrier, pointerToNextLinkedListItem);
}
export function hashMapNodePointerToKeyValue(dataView, nodePointer) {
const operator = NODE_MACHINE.createOperator(dataView, nodePointer);
export function hashMapNodePointerToKeyValue(carrier, nodePointer) {
const operator = NODE_MACHINE.createOperator(carrier, nodePointer);
return {

@@ -167,12 +189,12 @@ valuePointer: operator.pointerTo("VALUE_POINTER"),

}
export function hashMapSize(dataView, mapPointer) {
return dataView.getUint32(mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset);
export function hashMapSize(carrier, mapPointer) {
return carrier.uint32[(mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset) / Uint32Array.BYTES_PER_ELEMENT];
}
export function hashMapGetPointersToFree(dataView, hashmapPointer) {
const mapOperator = MAP_MACHINE.createOperator(dataView, hashmapPointer);
export function hashMapGetPointersToFree(carrier, hashmapPointer) {
const mapOperator = MAP_MACHINE.createOperator(carrier, hashmapPointer);
const pointers = [hashmapPointer, mapOperator.get("ARRAY_POINTER")];
const pointersToValuePointers = [];
const pointersOfLinkedList = linkedListGetPointersToFree(dataView, mapOperator.get("LINKED_LIST_POINTER"));
const pointersOfLinkedList = linkedListGetPointersToFree(carrier, mapOperator.get("LINKED_LIST_POINTER"));
pointers.push(...pointersOfLinkedList.pointers);
const nodeOperator = NODE_MACHINE.createOperator(dataView, 0);
const nodeOperator = NODE_MACHINE.createOperator(carrier, 0);

@@ -182,2 +204,7 @@ for (const nodePointer of pointersOfLinkedList.valuePointers) {

pointersToValuePointers.push(nodeOperator.pointerTo("VALUE_POINTER"));
if (typeOnly_type_get(carrier.heap, nodeOperator.get("KEY_POINTER")) === ENTRY_TYPE.STRING) {
pointers.push(string_charsPointer_get(carrier.heap, nodeOperator.get("KEY_POINTER")));
}
pointers.push(nodePointer, nodeOperator.get("KEY_POINTER"));

@@ -214,3 +241,3 @@ }

while ((pointerToNode = hashMapLowLevelIterator(carrier.dataView, mapOperator.startAddress, pointerToNode)) !== 0) {
while ((pointerToNode = hashMapLowLevelIterator(carrier, mapOperator.startAddress, pointerToNode)) !== 0) {
hashMapRehashInsert(carrier, biggerArray, newCapacity, pointerToNode);

@@ -221,9 +248,9 @@ }

function hashMapRehashInsert(carrier, bucketsArrayPointer, arraySize, nodePointer) {
const nodeOperator = NODE_MACHINE.createOperator(carrier.dataView, nodePointer);
const keyInfo = getKeyStartLength(carrier.dataView, nodeOperator.get("KEY_POINTER"));
const keyHashCode = hashCodeInPlace(carrier.dataView, arraySize, keyInfo.start, keyInfo.length);
const nodeOperator = NODE_MACHINE.createOperator(carrier, nodePointer);
const keyInfo = getKeyStartLength(carrier, nodeOperator.get("KEY_POINTER"));
const keyHashCode = hashCodeInPlace(carrier.uint8, arraySize, keyInfo.start, keyInfo.length);
const bucket = keyHashCode % arraySize;
const bucketStartPointer = bucketsArrayPointer + bucket * Uint32Array.BYTES_PER_ELEMENT;
const prevFirstNodeInBucket = carrier.dataView.getUint32(bucketStartPointer);
carrier.dataView.setUint32(bucketStartPointer, nodePointer);
const prevFirstNodeInBucket = carrier.uint32[bucketStartPointer / Uint32Array.BYTES_PER_ELEMENT];
carrier.uint32[bucketStartPointer / Uint32Array.BYTES_PER_ELEMENT] = nodePointer;
nodeOperator.set("NEXT_NODE_POINTER", prevFirstNodeInBucket); // // Add is first node in bucket

@@ -241,3 +268,3 @@ // if (nodeOperator.startAddress === 0) {

function shouldRehash(nodesCount, buckets, fullBuckets, loadFactor) {
function shouldRehash(buckets, fullBuckets, loadFactor) {
// add proportion check?

@@ -248,8 +275,8 @@ // nodesCount

export function* hashmapNodesPointerIterator(dataView, mapPointer) {
export function* hashmapNodesPointerIterator(carrier, mapPointer) {
let iteratorToken = 0;
while ((iteratorToken = hashMapLowLevelIterator(dataView, mapPointer, iteratorToken)) !== 0) {
while ((iteratorToken = hashMapLowLevelIterator(carrier, mapPointer, iteratorToken)) !== 0) {
yield iteratorToken;
}
}

@@ -1,5 +0,6 @@

export declare function hashCodeInPlace(dataView: DataView, capacity: number, keyStart: number, keyBytesLength: number): number;
import { GlobalCarrier } from "../interfaces";
export declare function hashCodeInPlace(uint8: Uint8Array, capacity: number, keyStart: number, keyBytesLength: number): number;
export declare function hashCodeExternalValue(capacity: number, value: string | number): number;
export declare function hashCodeEntry(dataView: DataView, capacity: number, pointer: number): number;
export declare function getKeyStartLength(dataView: DataView, keyPointer: number): {
export declare function hashCodeEntry(carrier: GlobalCarrier, capacity: number, pointer: number): number;
export declare function getKeyStartLength(carrier: GlobalCarrier, keyPointer: number): {
start: number;

@@ -6,0 +7,0 @@ length: number;

import { ENTRY_TYPE } from "../entry-types";
import { stringEncodeInto } from "../stringEncodeInto";
export function hashCodeInPlace(dataView, capacity, keyStart, keyBytesLength) {
export function hashCodeInPlace(uint8, capacity, keyStart, keyBytesLength) {
let h = 0 | 0; // const hashed: number[] = [];
for (let i = 0; i < keyBytesLength; i++) {
// hashed.push(dataView.getUint8(i + keyStart));
h = Math.imul(31, h) + dataView.getUint8(i + keyStart) | 0;
h = Math.imul(31, h) + uint8[i + keyStart] | 0;
} // console.log(hashed);

@@ -16,3 +15,3 @@

const ab = new ArrayBuffer(typeof value === "string" ? value.length * 3 : 8);
const dv = new DataView(ab);
const uint8 = new Uint8Array(ab);
let keyBytesLength = ab.byteLength;

@@ -23,18 +22,18 @@

} else {
dv.setFloat64(0, value);
new Float64Array(ab)[0] = value;
}
return hashCodeInPlace(dv, capacity, 0, keyBytesLength);
return hashCodeInPlace(uint8, capacity, 0, keyBytesLength);
}
export function hashCodeEntry(dataView, capacity, pointer) {
const type = dataView.getUint8(pointer);
export function hashCodeEntry(carrier, capacity, pointer) {
const type = carrier.uint8[pointer];
if (type === ENTRY_TYPE.NUMBER) {
return hashCodeInPlace(dataView, capacity, pointer + 1, 8);
return hashCodeInPlace(carrier.uint8, capacity, pointer + 1, 8);
} else {
return hashCodeInPlace(dataView, capacity, pointer + 1 + Uint16Array.BYTES_PER_ELEMENT, dataView.getUint16(pointer + 1));
return hashCodeInPlace(carrier.uint8, capacity, pointer + 1 + Uint16Array.BYTES_PER_ELEMENT, carrier.uint16[(pointer + 1) / Uint16Array.BYTES_PER_ELEMENT]);
}
}
export function getKeyStartLength(dataView, keyPointer) {
if (dataView.getUint32(keyPointer) === ENTRY_TYPE.NUMBER) {
export function getKeyStartLength(carrier, keyPointer) {
if (carrier.uint32[keyPointer / Uint32Array.BYTES_PER_ELEMENT] === ENTRY_TYPE.NUMBER) {
return {

@@ -47,5 +46,5 @@ start: keyPointer + 1,

start: keyPointer + 1 + 2 + 2,
length: dataView.getUint16(keyPointer + 1)
length: carrier.uint16[(keyPointer + 1) / Uint16Array.BYTES_PER_ELEMENT]
};
}
}
export declare const MAP_MACHINE: {
map: import("../memoryMachinery").MemoryMap<"CAPACITY" | "USED_CAPACITY" | "ARRAY_POINTER" | "LINKED_LIST_POINTER" | "LINKED_LIST_SIZE">;
createOperator: (dataView: DataView, address: number) => import("../memoryMachinery").MemoryOperator<"CAPACITY" | "USED_CAPACITY" | "ARRAY_POINTER" | "LINKED_LIST_POINTER" | "LINKED_LIST_SIZE">;
map: import("../memoryMachinery").MemoryMap<"ARRAY_POINTER" | "LINKED_LIST_POINTER" | "LINKED_LIST_SIZE" | "CAPACITY" | "USED_CAPACITY">;
createOperator: (carrier: import("../interfaces").GlobalCarrier, address: number) => import("../memoryMachinery").MemoryOperator<"ARRAY_POINTER" | "LINKED_LIST_POINTER" | "LINKED_LIST_SIZE" | "CAPACITY" | "USED_CAPACITY">;
};
export declare const NODE_MACHINE: {
map: import("../memoryMachinery").MemoryMap<"VALUE_POINTER" | "NEXT_NODE_POINTER" | "KEY_POINTER" | "LINKED_LIST_ITEM_POINTER">;
createOperator: (dataView: DataView, address: number) => import("../memoryMachinery").MemoryOperator<"VALUE_POINTER" | "NEXT_NODE_POINTER" | "KEY_POINTER" | "LINKED_LIST_ITEM_POINTER">;
createOperator: (carrier: import("../interfaces").GlobalCarrier, address: number) => import("../memoryMachinery").MemoryOperator<"VALUE_POINTER" | "NEXT_NODE_POINTER" | "KEY_POINTER" | "LINKED_LIST_ITEM_POINTER">;
};

@@ -9,0 +9,0 @@ export declare type MapMachineType = ReturnType<typeof MAP_MACHINE.createOperator>;

import { createMemoryMachine } from "../memoryMachinery";
export const MAP_MACHINE = createMemoryMachine({
CAPACITY: Uint8Array,
USED_CAPACITY: Uint8Array,
ARRAY_POINTER: Uint32Array,
LINKED_LIST_POINTER: Uint32Array,
// maybe put save this value in the linked list?
LINKED_LIST_SIZE: Uint32Array
LINKED_LIST_SIZE: Uint32Array,
CAPACITY: Uint8Array,
USED_CAPACITY: Uint8Array
});

@@ -10,0 +10,0 @@ export const NODE_MACHINE = createMemoryMachine({

import { ENTRY_TYPE } from "./entry-types";
import { TextDecoder, TextEncoder } from "./textEncoderDecoderTypes";
import { Heap } from "../structsGenerator/consts";
export declare type primitive = string | number | bigint | boolean | undefined | null;

@@ -61,4 +61,3 @@ export declare type Entry = StringEntry | NumberEntry | BigIntPositiveEntry | BigIntNegativeEntry | ObjectEntry | ArrayEntry | DateEntry | MapEntry | SetEntry;

*/
export interface DataViewAndAllocatorCarrier {
dataView: DataView;
export interface GlobalCarrier {
uint8: Uint8Array;

@@ -70,2 +69,3 @@ uint16: Uint16Array;

allocator: import("@thi.ng/malloc").IMemPool;
heap: Heap;
}

@@ -75,5 +75,7 @@ export declare type ExternalArgs = Readonly<{

hashMapMinInitialCapacity: number;
/**
* Allocate additional memory for array pointers,
* will prevent the reallocation and copy when array is getting bigger
*/
arrayAdditionalAllocation: number;
textDecoder: TextDecoder;
textEncoder: TextEncoder;
}>;

@@ -84,9 +86,7 @@ export declare type ExternalArgsApi = Readonly<{

arrayAdditionalAllocation?: number;
textDecoder: TextDecoder;
textEncoder: TextEncoder;
}>;
export interface InternalAPI {
getExternalArgs(): ExternalArgs;
getCarrier(): Readonly<DataViewAndAllocatorCarrier>;
replaceCarrierContent(carrier: DataViewAndAllocatorCarrier): void;
getCarrier(): Readonly<GlobalCarrier>;
replaceCarrierContent(carrier: GlobalCarrier): void;
getEntryPointer(): number;

@@ -93,0 +93,0 @@ destroy(): number;

@@ -1,5 +0,5 @@

import { DataViewAndAllocatorCarrier } from "../interfaces";
import { GlobalCarrier } from "../interfaces";
export declare const LINKED_LIST_ITEM_MACHINE: {
map: import("../memoryMachinery").MemoryMap<"NEXT_POINTER" | "VALUE">;
createOperator: (dataView: DataView, address: number) => import("../memoryMachinery").MemoryOperator<"NEXT_POINTER" | "VALUE">;
createOperator: (carrier: GlobalCarrier, address: number) => import("../memoryMachinery").MemoryOperator<"NEXT_POINTER" | "VALUE">;
};

@@ -9,11 +9,11 @@ export declare type LinkedListItemMachineType = ReturnType<typeof LINKED_LIST_ITEM_MACHINE.createOperator>;

map: import("../memoryMachinery").MemoryMap<"END_POINTER" | "START_POINTER">;
createOperator: (dataView: DataView, address: number) => import("../memoryMachinery").MemoryOperator<"END_POINTER" | "START_POINTER">;
createOperator: (carrier: GlobalCarrier, address: number) => import("../memoryMachinery").MemoryOperator<"END_POINTER" | "START_POINTER">;
};
export declare type LinkedListMachineType = ReturnType<typeof LINKED_LIST_MACHINE.createOperator>;
export declare function initLinkedList({ dataView, allocator }: DataViewAndAllocatorCarrier): number;
export declare function linkedListItemInsert({ dataView, allocator }: DataViewAndAllocatorCarrier, linkedListPointer: number, nodeValuePointer: number): number;
export declare function linkedListItemRemove({ dataView, allocator }: DataViewAndAllocatorCarrier, itemPointer: number): void;
export declare function linkedListLowLevelIterator(dataView: DataView, linkedListPointer: number, itemPointer: number): number;
export declare function linkedListGetValue(dataView: DataView, itemPointer: number): number;
export declare function linkedListGetPointersToFree(dataView: DataView, linkedListPointer: number): {
export declare function initLinkedList(carrier: GlobalCarrier): number;
export declare function linkedListItemInsert(carrier: GlobalCarrier, linkedListPointer: number, nodeValuePointer: number): number;
export declare function linkedListItemRemove(carrier: GlobalCarrier, itemPointer: number): void;
export declare function linkedListLowLevelIterator(carrier: GlobalCarrier, linkedListPointer: number, itemPointer: number): number;
export declare function linkedListGetValue(carrier: GlobalCarrier, itemPointer: number): number;
export declare function linkedListGetPointersToFree(carrier: GlobalCarrier, linkedListPointer: number): {
pointers: number[];

@@ -20,0 +20,0 @@ valuePointers: number[];

@@ -25,9 +25,9 @@ import { createMemoryMachine } from "../memoryMachinery";

});
export function initLinkedList({
dataView,
allocator
}) {
export function initLinkedList(carrier) {
const {
allocator
} = carrier;
const memoryForLinkedList = allocator.calloc(LINKED_LIST_MACHINE.map.SIZE_OF);
const memoryForEndMarkerItem = allocator.calloc(LINKED_LIST_ITEM_MACHINE.map.SIZE_OF);
const linkedListMachine = LINKED_LIST_MACHINE.createOperator(dataView, memoryForLinkedList);
const linkedListMachine = LINKED_LIST_MACHINE.createOperator(carrier, memoryForLinkedList);
linkedListMachine.set("START_POINTER", memoryForEndMarkerItem);

@@ -37,10 +37,7 @@ linkedListMachine.set("END_POINTER", memoryForEndMarkerItem);

}
export function linkedListItemInsert({
dataView,
allocator
}, linkedListPointer, nodeValuePointer) {
const newItemMemory = allocator.calloc(LINKED_LIST_ITEM_MACHINE.map.SIZE_OF);
const linkedListOperator = LINKED_LIST_MACHINE.createOperator(dataView, linkedListPointer);
const wasEndMarkerOperator = LINKED_LIST_ITEM_MACHINE.createOperator(dataView, linkedListOperator.get("END_POINTER"));
const toBeEndMarkerOperator = LINKED_LIST_ITEM_MACHINE.createOperator(dataView, newItemMemory);
export function linkedListItemInsert(carrier, linkedListPointer, nodeValuePointer) {
const newItemMemory = carrier.allocator.calloc(LINKED_LIST_ITEM_MACHINE.map.SIZE_OF);
const linkedListOperator = LINKED_LIST_MACHINE.createOperator(carrier, linkedListPointer);
const wasEndMarkerOperator = LINKED_LIST_ITEM_MACHINE.createOperator(carrier, linkedListOperator.get("END_POINTER"));
const toBeEndMarkerOperator = LINKED_LIST_ITEM_MACHINE.createOperator(carrier, newItemMemory);
toBeEndMarkerOperator.set("VALUE", 0);

@@ -54,18 +51,15 @@ toBeEndMarkerOperator.set("NEXT_POINTER", 0);

}
export function linkedListItemRemove({
dataView,
allocator
}, itemPointer) {
const itemToOverwrite = LINKED_LIST_ITEM_MACHINE.createOperator(dataView, itemPointer);
const itemToOverwriteWith = LINKED_LIST_ITEM_MACHINE.createOperator(dataView, itemToOverwrite.get("NEXT_POINTER"));
export function linkedListItemRemove(carrier, itemPointer) {
const itemToOverwrite = LINKED_LIST_ITEM_MACHINE.createOperator(carrier, itemPointer);
const itemToOverwriteWith = LINKED_LIST_ITEM_MACHINE.createOperator(carrier, itemToOverwrite.get("NEXT_POINTER"));
const memoryToFree = itemToOverwrite.get("NEXT_POINTER");
itemToOverwrite.set("VALUE", itemToOverwriteWith.get("VALUE"));
itemToOverwrite.set("NEXT_POINTER", itemToOverwriteWith.get("NEXT_POINTER"));
allocator.free(memoryToFree);
carrier.allocator.free(memoryToFree);
}
export function linkedListLowLevelIterator(dataView, linkedListPointer, itemPointer) {
const listItem = LINKED_LIST_ITEM_MACHINE.createOperator(dataView, itemPointer);
export function linkedListLowLevelIterator(carrier, linkedListPointer, itemPointer) {
const listItem = LINKED_LIST_ITEM_MACHINE.createOperator(carrier, itemPointer);
if (itemPointer === 0) {
const list = LINKED_LIST_MACHINE.createOperator(dataView, linkedListPointer);
const list = LINKED_LIST_MACHINE.createOperator(carrier, linkedListPointer);
listItem.startAddress = list.get("START_POINTER"); // can be zero if START_POINTER pointes to the end marker

@@ -94,9 +88,9 @@

}
export function linkedListGetValue(dataView, itemPointer) {
return LINKED_LIST_ITEM_MACHINE.createOperator(dataView, itemPointer).get("VALUE");
export function linkedListGetValue(carrier, itemPointer) {
return LINKED_LIST_ITEM_MACHINE.createOperator(carrier, itemPointer).get("VALUE");
}
export function linkedListGetPointersToFree(dataView, linkedListPointer) {
export function linkedListGetPointersToFree(carrier, linkedListPointer) {
const pointers = [linkedListPointer];
const valuePointers = [];
const operator = LINKED_LIST_MACHINE.createOperator(dataView, linkedListPointer);
const operator = LINKED_LIST_MACHINE.createOperator(carrier, linkedListPointer);
const firstItem = operator.get("START_POINTER");

@@ -109,3 +103,3 @@ const lastItem = operator.get("END_POINTER"); // list empty

const linkItemOperator = LINKED_LIST_ITEM_MACHINE.createOperator(dataView, linkedListLowLevelIterator(dataView, linkedListPointer, 0));
const linkItemOperator = LINKED_LIST_ITEM_MACHINE.createOperator(carrier, linkedListLowLevelIterator(carrier, linkedListPointer, 0));

@@ -112,0 +106,0 @@ while (linkItemOperator.startAddress !== 0) {

@@ -0,1 +1,3 @@

/* istanbul ignore file */
// I'm not sure how to test that yet
import { invariant } from "./utils";

@@ -2,0 +4,0 @@ import { getUnderlyingArrayBuffer } from "./api";

@@ -1,5 +0,5 @@

import { ExternalArgs, DataViewAndAllocatorCarrier, MapEntry, InternalAPI } from "./interfaces";
import { ExternalArgs, GlobalCarrier, InternalAPI } from "./interfaces";
import { INTERNAL_API_SYMBOL } from "./symbols";
import { BaseProxyTrap } from "./BaseProxyTrap";
export declare class MapWrapper<K extends string | number, V> extends BaseProxyTrap<MapEntry> implements Map<K, V> {
export declare class MapWrapper<K extends string | number, V> extends BaseProxyTrap implements Map<K, V> {
clear(): void;

@@ -20,3 +20,3 @@ forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;

}
export declare function createMapWrapper<K extends string | number, V>(externalArgs: ExternalArgs, dataViewCarrier: DataViewAndAllocatorCarrier, entryPointer: number): Map<K, V>;
export declare function createMapWrapper<K extends string | number, V>(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, entryPointer: number): Map<K, V>;
//# sourceMappingURL=mapWrapper.d.ts.map

@@ -7,2 +7,3 @@ import { deleteObjectPropertyEntryByKey, objectGet, objectSet, mapOrSetClear } from "./objectWrapperHelpers";

import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue";
import { object_pointerToHashMap_get } from "./generatedStructs";
export class MapWrapper extends BaseProxyTrap {

@@ -20,3 +21,3 @@ clear() {

get size() {
return hashMapSize(this.carrier.dataView, this.entry.value);
return hashMapSize(this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer));
}

@@ -29,8 +30,8 @@

*entries() {
for (const nodePointer of hashmapNodesPointerIterator(this.carrier.dataView, this.entry.value)) {
for (const nodePointer of hashmapNodesPointerIterator(this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer))) {
const {
valuePointer,
keyPointer
} = hashMapNodePointerToKeyValue(this.carrier.dataView, nodePointer);
yield [entryToFinalJavaScriptValue(this.externalArgs, this.carrier, keyPointer), entryToFinalJavaScriptValue(this.externalArgs, this.carrier, this.carrier.dataView.getUint32(valuePointer))];
} = hashMapNodePointerToKeyValue(this.carrier, nodePointer);
yield [entryToFinalJavaScriptValue(this.externalArgs, this.carrier, keyPointer), entryToFinalJavaScriptValue(this.externalArgs, this.carrier, this.carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT])];
}

@@ -40,4 +41,4 @@ }

*keys() {
for (const nodePointer of hashmapNodesPointerIterator(this.carrier.dataView, this.entry.value)) {
const t = hashMapNodePointerToKeyValue(this.carrier.dataView, nodePointer);
for (const nodePointer of hashmapNodesPointerIterator(this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer))) {
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer);
yield entryToFinalJavaScriptValue(this.externalArgs, this.carrier, t.keyPointer);

@@ -48,7 +49,7 @@ }

*values() {
for (const nodePointer of hashmapNodesPointerIterator(this.carrier.dataView, this.entry.value)) {
for (const nodePointer of hashmapNodesPointerIterator(this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer))) {
const {
valuePointer
} = hashMapNodePointerToKeyValue(this.carrier.dataView, nodePointer);
yield entryToFinalJavaScriptValue(this.externalArgs, this.carrier, this.carrier.dataView.getUint32(valuePointer));
} = hashMapNodePointerToKeyValue(this.carrier, nodePointer);
yield entryToFinalJavaScriptValue(this.externalArgs, this.carrier, this.carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT]);
}

@@ -74,3 +75,3 @@ }

return objectGet(this.externalArgs, this.carrier, this.entry.value, p);
return objectGet(this.externalArgs, this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer), p);
}

@@ -83,3 +84,3 @@

return deleteObjectPropertyEntryByKey(this.externalArgs, this.carrier, this.entry.value, p);
return deleteObjectPropertyEntryByKey(this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer), p);
}

@@ -92,3 +93,3 @@

return hashMapNodeLookup(this.carrier, this.entry.value, p) !== 0;
return hashMapNodeLookup(this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer), p) !== 0;
}

@@ -102,3 +103,3 @@

allocationsTransaction(() => {
objectSet(this.externalArgs, this.carrier, this.entry.value, p, value);
objectSet(this.externalArgs, this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer), p, value);
}, this.carrier.allocator);

@@ -109,4 +110,4 @@ return this;

}
export function createMapWrapper(externalArgs, dataViewCarrier, entryPointer) {
return new MapWrapper(externalArgs, dataViewCarrier, entryPointer);
export function createMapWrapper(externalArgs, globalCarrier, entryPointer) {
return new MapWrapper(externalArgs, globalCarrier, entryPointer);
}

@@ -0,1 +1,2 @@

import { GlobalCarrier } from "./interfaces";
declare const ALLOWS_TYPED_ARRAYS_CTORS: readonly [Uint8ArrayConstructor, Uint32ArrayConstructor, Uint16ArrayConstructor];

@@ -19,7 +20,7 @@ declare type TypedArrayCtor = typeof ALLOWS_TYPED_ARRAYS_CTORS[number];

}
export declare function createMemoryOperator<T extends string>(memoryMap: MemoryMap<T>, dataView: DataView, startAddress: number): MemoryOperator<T>;
export declare function createMemoryOperator<T extends string>(memoryMap: MemoryMap<T>, carrier: GlobalCarrier, startAddress: number): MemoryOperator<T>;
export declare function layoutDeclarationToMemoryMap<T extends string>(input: LayoutDeclaration<T>): MemoryMap<T>;
export declare function createMemoryMachine<T extends string>(layoutDeclaration: LayoutDeclaration<T>): {
map: MemoryMap<T>;
createOperator: (dataView: DataView, address: number) => MemoryOperator<T>;
createOperator: (carrier: GlobalCarrier, address: number) => MemoryOperator<T>;
};

@@ -26,0 +27,0 @@ export declare function _buildMemoryLayout<T extends {

const ALLOWS_TYPED_ARRAYS_CTORS = [Uint8Array, Uint32Array, // BigUint64Array,
Uint16Array];
// DataView.prototype is any, ts thing. this is a workaround for better types.
let dataViewInstance = new DataView(new ArrayBuffer(0));
const READ_WRITE_MAPS = [[Uint8Array, dataViewInstance.getUint8, dataViewInstance.setUint8], [Uint32Array, dataViewInstance.getUint32, dataViewInstance.setUint32], // [BigUint64Array, dataViewInstance.getBigUint64, dataViewInstance.setBigUint64],
[Uint16Array, dataViewInstance.getUint16, dataViewInstance.setUint16]]; // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
// let dataViewInstance = new DataView(new ArrayBuffer(0));
// const READ_WRITE_MAPS = [
// [Uint8Array, dataViewInstance.getUint8, dataViewInstance.setUint8],
// [Uint32Array, dataViewInstance.getUint32, dataViewInstance.setUint32],
// // [BigUint64Array, dataViewInstance.getBigUint64, dataViewInstance.setBigUint64],
// [Uint16Array, dataViewInstance.getUint16, dataViewInstance.setUint16]
// ] as const;
const READ_WRITE_MAPS_V2 = [[Uint8Array, "uint8"], [Uint32Array, "uint32"], // [BigUint64Array, dataViewInstance.getBigUint64, dataViewInstance.setBigUint64],
[Uint16Array, "uint16"]]; // dataViewInstance = undefined;
// const READ_MAP = new Map(READ_WRITE_MAPS.map(e => [e[0], e[1]]));
// const WRITE_MAP = new Map(READ_WRITE_MAPS.map(e => [e[0], e[2]]));
dataViewInstance = undefined;
const READ_MAP = new Map(READ_WRITE_MAPS.map(e => [e[0], e[1]]));
const WRITE_MAP = new Map(READ_WRITE_MAPS.map(e => [e[0], e[2]]));
export function createMemoryOperator(memoryMap, dataView, startAddress) {
const READ_WRITE_MAP_V2 = new Map(READ_WRITE_MAPS_V2.map(e => [e[0], e[1]]));
export function createMemoryOperator(memoryMap, carrier, startAddress) {
return {
set(key, value) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const func = WRITE_MAP.get(memoryMap[key].type);
return func.call(dataView, startAddress + memoryMap[key].bytesOffset, value);
const func = READ_WRITE_MAP_V2.get(memoryMap[key].type);
return carrier[func][(startAddress + memoryMap[key].bytesOffset) / memoryMap[key].type.BYTES_PER_ELEMENT] = value;
},

@@ -22,4 +27,4 @@

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const func = READ_MAP.get(memoryMap[key].type);
return func.call(dataView, startAddress + memoryMap[key].bytesOffset);
const func = READ_WRITE_MAP_V2.get(memoryMap[key].type);
return carrier[func][(startAddress + memoryMap[key].bytesOffset) / memoryMap[key].type.BYTES_PER_ELEMENT];
},

@@ -82,6 +87,6 @@

newObjectEntries.push(["TOTAL_SIZE", newObjectEntries[newObjectEntries.length - 1][1] + oldEntries[newObjectEntries.length - 1][1]]); // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
newObjectEntries.push(["TOTAL_SIZE", newObjectEntries[newObjectEntries.length - 1][1] + oldEntries[newObjectEntries.length - 1][1]]); // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
return Object.fromEntries(newObjectEntries);
}

@@ -1,14 +0,14 @@

import { ObjectEntry, ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces";
import { ExternalArgs, GlobalCarrier } from "./interfaces";
import { BaseProxyTrap } from "./BaseProxyTrap";
export declare class ObjectWrapper extends BaseProxyTrap<ObjectEntry> implements ProxyHandler<{}> {
get(target: {}, p: PropertyKey): any;
deleteProperty(target: {}, p: PropertyKey): boolean;
export declare class ObjectWrapper extends BaseProxyTrap implements ProxyHandler<Record<string, unknown>> {
get(target: Record<string, unknown>, p: PropertyKey): any;
deleteProperty(target: Record<string, unknown>, p: PropertyKey): boolean;
enumerate(): PropertyKey[];
ownKeys(): PropertyKey[];
getOwnPropertyDescriptor(target: {}, p: PropertyKey): {
getOwnPropertyDescriptor(target: Record<string, unknown>, p: PropertyKey): {
configurable: boolean;
enumerable: boolean;
} | undefined;
has(target: {}, p: PropertyKey): boolean;
set(target: {}, p: PropertyKey, value: any): boolean;
has(target: Record<string, unknown>, p: PropertyKey): boolean;
set(target: Record<string, unknown>, p: PropertyKey, value: any): boolean;
isExtensible(): boolean;

@@ -19,3 +19,3 @@ preventExtensions(): boolean;

}
export declare function createObjectWrapper<T = any>(externalArgs: ExternalArgs, dataViewCarrier: DataViewAndAllocatorCarrier, entryPointer: number): T;
export declare function createObjectWrapper<T = any>(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, entryPointer: number): T;
//# sourceMappingURL=objectWrapper.d.ts.map

@@ -7,2 +7,3 @@ import { getObjectPropertiesEntries, deleteObjectPropertyEntryByKey, objectGet, objectSet } from "./objectWrapperHelpers";

import { hashMapNodeLookup } from "./hashmap/hashmap";
import { object_pointerToHashMap_get } from "./generatedStructs";
export class ObjectWrapper extends BaseProxyTrap {

@@ -18,3 +19,3 @@ get(target, p) {

return objectGet(this.externalArgs, this.carrier, this.entry.value, p);
return objectGet(this.externalArgs, this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer), p);
}

@@ -27,7 +28,7 @@

return deleteObjectPropertyEntryByKey(this.externalArgs, this.carrier, this.entry.value, p);
return deleteObjectPropertyEntryByKey(this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer), p);
}
enumerate() {
const gotEntries = getObjectPropertiesEntries(this.carrier, this.entry.value);
const gotEntries = getObjectPropertiesEntries(this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer));
return gotEntries.map(e => e.key);

@@ -37,3 +38,3 @@ }

ownKeys() {
const gotEntries = getObjectPropertiesEntries(this.carrier, this.entry.value);
const gotEntries = getObjectPropertiesEntries(this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer));
return gotEntries.map(e => e.key);

@@ -62,3 +63,3 @@ }

return hashMapNodeLookup(this.carrier, this.entry.value, p) !== 0;
return hashMapNodeLookup(this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer), p) !== 0;
}

@@ -72,3 +73,3 @@

allocationsTransaction(() => {
objectSet(this.externalArgs, this.carrier, this.entry.value, p, value);
objectSet(this.externalArgs, this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer), p, value);
}, this.carrier.allocator);

@@ -103,6 +104,6 @@ return true;

}
export function createObjectWrapper(externalArgs, dataViewCarrier, entryPointer) {
export function createObjectWrapper(externalArgs, globalCarrier, entryPointer) {
return new Proxy({
objectBufferWrapper: "objectBufferWrapper"
}, new ObjectWrapper(externalArgs, dataViewCarrier, entryPointer));
}, new ObjectWrapper(externalArgs, globalCarrier, entryPointer));
}

@@ -1,11 +0,10 @@

import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces";
export declare function deleteObjectPropertyEntryByKey(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, hashmapPointer: number, keyToDeleteBy: string | number): boolean;
export declare function getObjectPropertiesEntries(carrier: DataViewAndAllocatorCarrier, hashmapPointer: number): Array<{
import { ExternalArgs, GlobalCarrier } from "./interfaces";
export declare function deleteObjectPropertyEntryByKey(carrier: GlobalCarrier, hashmapPointer: number, keyToDeleteBy: string | number): boolean;
export declare function getObjectPropertiesEntries(carrier: GlobalCarrier, hashmapPointer: number): Array<{
key: string | number;
valuePointer: number;
}>;
export declare function objectSet(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, hashMapPointer: number, p: string | number, value: any): void;
export declare function objectGet(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, entryPointer: number, key: string | number): any;
export declare function hashmapClearFree(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, hashmapPointer: number): void;
export declare function mapOrSetClear(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, mapOrSetPtr: number): void;
export declare function objectSet(externalArgs: ExternalArgs, carrier: GlobalCarrier, hashMapPointer: number, p: string | number, value: unknown): void;
export declare function objectGet(externalArgs: ExternalArgs, carrier: GlobalCarrier, entryPointer: number, key: string | number): any;
export declare function mapOrSetClear(externalArgs: ExternalArgs, carrier: GlobalCarrier, mapOrSetPtr: number): void;
//# sourceMappingURL=objectWrapperHelpers.d.ts.map

@@ -1,6 +0,9 @@

import { readEntry, writeValueInPtrToPtrAndHandleMemory, handleArcForDeletedValuePointer, decrementRefCount, writeEntry } from "./store";
import { writeValueInPtrToPtrAndHandleMemory, handleArcForDeletedValuePointer, decrementRefCount } from "./store";
import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue";
import { hashMapDelete, hashMapLowLevelIterator, hashMapNodePointerToKeyValue, hashMapInsertUpdate, hashMapValueLookup, createHashMap } from "./hashmap/hashmap";
import { getObjectOrMapOrSetAddresses } from "./getAllLinkedAddresses";
export function deleteObjectPropertyEntryByKey(externalArgs, carrier, hashmapPointer, keyToDeleteBy) {
import { getAllLinkedAddresses } from "./getAllLinkedAddresses";
import { typeOnly_type_get, number_value_get, typeAndRc_refsCount_get, typeAndRc_refsCount_set, object_pointerToHashMap_set } from "./generatedStructs";
import { ENTRY_TYPE } from "./entry-types";
import { readString } from "./readString";
export function deleteObjectPropertyEntryByKey(carrier, hashmapPointer, keyToDeleteBy) {
const deletedValuePointerToPointer = hashMapDelete(carrier, hashmapPointer, keyToDeleteBy); // no such key

@@ -12,4 +15,4 @@

const deletedValuePointer = carrier.dataView.getUint32(deletedValuePointerToPointer);
handleArcForDeletedValuePointer(externalArgs, carrier, deletedValuePointer);
const deletedValuePointer = carrier.heap.Uint32Array[deletedValuePointerToPointer / Uint32Array.BYTES_PER_ELEMENT];
handleArcForDeletedValuePointer(carrier, deletedValuePointer);
return true;

@@ -21,11 +24,12 @@ }

while (iterator = hashMapLowLevelIterator(carrier.dataView, hashmapPointer, iterator)) {
while (iterator = hashMapLowLevelIterator(carrier, hashmapPointer, iterator)) {
const {
valuePointer,
keyPointer
} = hashMapNodePointerToKeyValue(carrier.dataView, iterator);
const keyEntry = readEntry(carrier, keyPointer);
} = hashMapNodePointerToKeyValue(carrier, iterator);
const typeOfKeyEntry = typeOnly_type_get(carrier.heap, keyPointer);
const key = typeOfKeyEntry === ENTRY_TYPE.NUMBER ? number_value_get(carrier.heap, keyPointer) : readString(carrier.heap, keyPointer);
foundValues.push({
valuePointer: carrier.dataView.getUint32(valuePointer),
key: keyEntry.value
valuePointer: carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT],
key
});

@@ -42,15 +46,39 @@ }

const valuePointer = hashMapValueLookup(carrier, entryPointer, key);
return entryToFinalJavaScriptValue(externalArgs, carrier, carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT]);
} // export function hashmapClearFree(
// externalArgs: ExternalArgs,
// carrier: GlobalCarrier,
// hashmapPointer: number
// ) {
// const leafAddresses = new Set<number>();
// const addressesToProcessQueue: number[] = [];
// getObjectOrMapOrSetAddresses(
// carrier,
// hashmapPointer,
// leafAddresses,
// addressesToProcessQueue
// );
// for (const address of leafAddresses) {
// carrier.allocator.free(address);
// }
// for (const address of arcAddresses) {
// decrementRefCount(externalArgs, carrier, address);
// }
// }
if (valuePointer === 0) {
return undefined;
}
export function mapOrSetClear(externalArgs, carrier, mapOrSetPtr) {
// we fake the entry refCount as zero so getAllLinkedAddresses will visit what's needed
const prevCount = typeAndRc_refsCount_get(carrier.heap, mapOrSetPtr);
typeAndRc_refsCount_set(carrier.heap, mapOrSetPtr, 0);
const {
leafAddresses,
arcAddresses
} = getAllLinkedAddresses(carrier, false, mapOrSetPtr);
return entryToFinalJavaScriptValue(externalArgs, carrier, carrier.dataView.getUint32(valuePointer));
}
export function hashmapClearFree(externalArgs, carrier, hashmapPointer) {
const leafAddresses = [];
const arcAddresses = [];
getObjectOrMapOrSetAddresses(carrier, false, hashmapPointer, leafAddresses, arcAddresses);
for (const address of leafAddresses) {
// don't dispose the address we need to reuse
if (address === mapOrSetPtr) {
continue;
}
for (const address of leafAddresses) {
carrier.allocator.free(address);

@@ -60,10 +88,13 @@ }

for (const address of arcAddresses) {
decrementRefCount(externalArgs, carrier, address);
}
}
export function mapOrSetClear(externalArgs, carrier, mapOrSetPtr) {
const entry = readEntry(carrier, mapOrSetPtr);
hashmapClearFree(externalArgs, carrier, entry.value);
entry.value = createHashMap(carrier, externalArgs.hashMapMinInitialCapacity);
writeEntry(carrier, mapOrSetPtr, entry);
// don't dispose the address we need to reuse
if (address === mapOrSetPtr) {
continue;
}
decrementRefCount(carrier.heap, address);
} // Restore real ref count
typeAndRc_refsCount_set(carrier.heap, mapOrSetPtr, prevCount);
object_pointerToHashMap_set(carrier.heap, mapOrSetPtr, createHashMap(carrier, externalArgs.hashMapMinInitialCapacity));
}

@@ -1,6 +0,3 @@

import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces";
/**
* Returns pointer for the value
*/
export declare function saveValue(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, referencedPointers: number[], value: any): number;
import { ExternalArgs, GlobalCarrier } from "./interfaces";
export declare function saveValueIterative(externalArgs: ExternalArgs, carrier: GlobalCarrier, referencedExistingPointers: number[], initialValuePtrToPtr: number, initialValue: unknown): void;
//# sourceMappingURL=saveValue.d.ts.map

@@ -1,56 +0,130 @@

import { primitiveValueToEntry, isPrimitive, getOurPointerIfApplicable } from "./utils";
import { appendEntry } from "./store";
import { objectSaver, mapSaver, setSaver } from "./objectSaver";
import { arraySaver } from "./arraySaver";
import { getOurPointerIfApplicable, strByteLength } from "./utils";
import { ENTRY_TYPE } from "./entry-types";
import { UNDEFINED_KNOWN_ADDRESS, NULL_KNOWN_ADDRESS, TRUE_KNOWN_ADDRESS, FALSE_KNOWN_ADDRESS } from "./consts";
/**
* Returns pointer for the value
*/
import { number_size, number_set_all, bigint_size, bigint_set_all, string_size, string_set_all, date_size, date_set_all } from "./generatedStructs";
import { UNDEFINED_KNOWN_ADDRESS, NULL_KNOWN_ADDRESS, TRUE_KNOWN_ADDRESS, FALSE_KNOWN_ADDRESS, MAX_64_BIG_INT } from "./consts";
import { arraySaverIterative } from "./arraySaverIterative";
import { objectSaverIterative, mapSaverIterative, setSaverIterative } from "./objectSaverIterative";
import { stringEncodeInto } from "./stringEncodeInto";
export function saveValueIterative(externalArgs, carrier, referencedExistingPointers, initialValuePtrToPtr, initialValue) {
const valuesToSave = [initialValue];
const pointersToSaveTo = [initialValuePtrToPtr];
const {
heap: {
Uint32Array: uint32
},
allocator,
heap
} = carrier;
export function saveValue(externalArgs, carrier, referencedPointers, value) {
let valuePointer = 0;
let maybeOurPointer;
while (valuesToSave.length !== 0) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const valueToSave = valuesToSave.pop(); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
if (value === undefined) {
return UNDEFINED_KNOWN_ADDRESS;
}
const ptrToPtrToSaveTo = pointersToSaveTo.pop(); // Handler well-known values
if (value === null) {
return NULL_KNOWN_ADDRESS;
}
if (valueToSave === undefined) {
uint32[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT] = UNDEFINED_KNOWN_ADDRESS;
continue;
}
if (value === true) {
return TRUE_KNOWN_ADDRESS;
}
if (valueToSave === null) {
uint32[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT] = NULL_KNOWN_ADDRESS;
continue;
}
if (value === false) {
return FALSE_KNOWN_ADDRESS;
}
if (valueToSave === true) {
uint32[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT] = TRUE_KNOWN_ADDRESS;
continue;
}
if (isPrimitive(value)) {
const entry = primitiveValueToEntry(value);
valuePointer = appendEntry(externalArgs, carrier, entry);
} else if (maybeOurPointer = getOurPointerIfApplicable(value, carrier.dataView)) {
valuePointer = maybeOurPointer;
referencedPointers.push(valuePointer);
} else if (Array.isArray(value)) {
valuePointer = arraySaver(externalArgs, carrier, referencedPointers, value);
} else if (value instanceof Date) {
valuePointer = appendEntry(externalArgs, carrier, {
type: ENTRY_TYPE.DATE,
refsCount: 1,
value: value.getTime()
});
} else if (value instanceof Map) {
valuePointer = mapSaver(externalArgs, carrier, referencedPointers, value);
} else if (value instanceof Set) {
valuePointer = setSaver(externalArgs, carrier, value);
} else if (typeof value === "object") {
valuePointer = objectSaver(externalArgs, carrier, referencedPointers, value);
} else {
throw new Error("unsupported yet");
if (valueToSave === false) {
uint32[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT] = FALSE_KNOWN_ADDRESS;
continue;
}
switch (typeof valueToSave) {
case "number":
uint32[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT] = allocator.calloc(number_size);
number_set_all(heap, uint32[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT], ENTRY_TYPE.NUMBER, valueToSave);
continue;
break;
case "string":
// eslint-disable-next-line no-case-declarations
const stringBytesLength = strByteLength(valueToSave); // eslint-disable-next-line no-case-declarations
const stringDataPointer = allocator.calloc(stringBytesLength);
uint32[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT] = allocator.calloc(string_size);
stringEncodeInto(heap.Uint8Array, stringDataPointer, valueToSave);
string_set_all(heap, uint32[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT], ENTRY_TYPE.STRING, stringBytesLength, stringDataPointer);
continue;
break;
case "bigint":
if (valueToSave > MAX_64_BIG_INT || valueToSave < -MAX_64_BIG_INT) {
uint32[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT] = UNDEFINED_KNOWN_ADDRESS;
continue; // Maybe don't make undefined but throw, or clamp
// throw new Error("MAX_64_BIG_INT");
}
uint32[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT] = allocator.calloc(bigint_size);
bigint_set_all(heap, uint32[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT], valueToSave > 0 ? ENTRY_TYPE.BIGINT_POSITIVE : ENTRY_TYPE.BIGINT_NEGATIVE, valueToSave * (valueToSave > 0 ? BigInt("1") : BigInt("-1")));
continue;
break;
case "function":
// Nope Nope Nope
uint32[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT] = UNDEFINED_KNOWN_ADDRESS;
continue;
break;
case "symbol":
// not supported, write undefined
uint32[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT] = UNDEFINED_KNOWN_ADDRESS;
continue;
break;
// we will never get here
case "undefined":
continue;
break;
// we will never get here
case "boolean":
continue;
break;
}
const maybeOurPointerFromSymbol = getOurPointerIfApplicable(valueToSave, carrier.allocator);
if (maybeOurPointerFromSymbol) {
referencedExistingPointers.push(maybeOurPointerFromSymbol);
heap.Uint32Array[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT] = maybeOurPointerFromSymbol;
continue;
}
if (Array.isArray(valueToSave)) {
heap.Uint32Array[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT] = arraySaverIterative(externalArgs.arrayAdditionalAllocation, carrier, valuesToSave, pointersToSaveTo, valueToSave);
continue;
}
if (valueToSave instanceof Date) {
heap.Uint32Array[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT] = allocator.calloc(date_size);
date_set_all(heap, heap.Uint32Array[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT], ENTRY_TYPE.DATE, 1, 0, valueToSave.getTime());
continue;
}
if (valueToSave instanceof Map) {
heap.Uint32Array[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT] = mapSaverIterative(externalArgs, carrier, valuesToSave, pointersToSaveTo, valueToSave);
continue;
}
if (valueToSave instanceof Set) {
heap.Uint32Array[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT] = setSaverIterative(externalArgs, carrier, valueToSave);
continue;
} // Plain object? I hope so
heap.Uint32Array[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT] = objectSaverIterative(externalArgs, carrier, valuesToSave, pointersToSaveTo, valueToSave);
}
return valuePointer;
}

@@ -1,5 +0,5 @@

import { ExternalArgs, DataViewAndAllocatorCarrier, MapEntry, InternalAPI } from "./interfaces";
import { ExternalArgs, GlobalCarrier, InternalAPI } from "./interfaces";
import { INTERNAL_API_SYMBOL } from "./symbols";
import { BaseProxyTrap } from "./BaseProxyTrap";
export declare class SetWrapper<K extends string | number> extends BaseProxyTrap<MapEntry> implements Set<K> {
export declare class SetWrapper<K extends string | number> extends BaseProxyTrap implements Set<K> {
clear(): void;

@@ -19,3 +19,3 @@ forEach(callbackfn: (key: K, key2: K, map: Set<K>) => void, thisArg?: any): void;

}
export declare function createSetWrapper<K extends string | number>(externalArgs: ExternalArgs, dataViewCarrier: DataViewAndAllocatorCarrier, entryPointer: number): Set<K>;
export declare function createSetWrapper<K extends string | number>(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, entryPointer: number): Set<K>;
//# sourceMappingURL=setWrapper.d.ts.map

@@ -7,2 +7,3 @@ import { deleteObjectPropertyEntryByKey, objectSet, mapOrSetClear } from "./objectWrapperHelpers";

import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue";
import { object_pointerToHashMap_get } from "./generatedStructs";
export class SetWrapper extends BaseProxyTrap {

@@ -20,3 +21,3 @@ clear() {

get size() {
return hashMapSize(this.carrier.dataView, this.entry.value);
return hashMapSize(this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer));
}

@@ -29,4 +30,4 @@

*entries() {
for (const nodePointer of hashmapNodesPointerIterator(this.carrier.dataView, this.entry.value)) {
const t = hashMapNodePointerToKeyValue(this.carrier.dataView, nodePointer);
for (const nodePointer of hashmapNodesPointerIterator(this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer))) {
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer);
const key = entryToFinalJavaScriptValue(this.externalArgs, this.carrier, t.keyPointer);

@@ -38,4 +39,4 @@ yield [key, key];

*keys() {
for (const nodePointer of hashmapNodesPointerIterator(this.carrier.dataView, this.entry.value)) {
const t = hashMapNodePointerToKeyValue(this.carrier.dataView, nodePointer);
for (const nodePointer of hashmapNodesPointerIterator(this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer))) {
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer);
yield entryToFinalJavaScriptValue(this.externalArgs, this.carrier, t.keyPointer);

@@ -46,4 +47,4 @@ }

*values() {
for (const nodePointer of hashmapNodesPointerIterator(this.carrier.dataView, this.entry.value)) {
const t = hashMapNodePointerToKeyValue(this.carrier.dataView, nodePointer);
for (const nodePointer of hashmapNodesPointerIterator(this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer))) {
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer);
yield entryToFinalJavaScriptValue(this.externalArgs, this.carrier, t.keyPointer);

@@ -70,3 +71,3 @@ }

return hashMapNodeLookup(this.carrier, this.entry.value, p) !== 0;
return hashMapNodeLookup(this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer), p) !== 0;
}

@@ -80,3 +81,3 @@

allocationsTransaction(() => {
objectSet(this.externalArgs, this.carrier, this.entry.value, p, undefined);
objectSet(this.externalArgs, this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer), p, undefined);
}, this.carrier.allocator);

@@ -91,8 +92,8 @@ return this;

return deleteObjectPropertyEntryByKey(this.externalArgs, this.carrier, this.entry.value, p);
return deleteObjectPropertyEntryByKey(this.carrier, object_pointerToHashMap_get(this.carrier.heap, this.entryPointer), p);
}
}
export function createSetWrapper(externalArgs, dataViewCarrier, entryPointer) {
return new SetWrapper(externalArgs, dataViewCarrier, entryPointer);
export function createSetWrapper(externalArgs, globalCarrier, entryPointer) {
return new SetWrapper(externalArgs, globalCarrier, entryPointer);
}

@@ -0,1 +1,2 @@

/* istanbul ignore file */
import { externalArgsApiToExternalArgsApi, isPrimitive, primitiveValueToEntry, align } from "./utils";

@@ -2,0 +3,0 @@ import { ENTRY_TYPE } from "./entry-types";

@@ -1,25 +0,16 @@

import { Entry, primitive, DataViewAndAllocatorCarrier } from "./interfaces";
import { Entry, GlobalCarrier } from "./interfaces";
import { ExternalArgs } from "./interfaces";
export declare function initializeArrayBuffer(arrayBuffer: ArrayBuffer): DataView;
import { Heap } from "../structsGenerator/consts";
export declare function initializeArrayBuffer(arrayBuffer: ArrayBuffer): void;
export declare function sizeOfEntry(entry: Entry): number;
export declare function writeEntry({ dataView, uint8 }: DataViewAndAllocatorCarrier, startingCursor: number, entry: Entry): void;
export declare function appendEntry(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, entry: Entry): number;
export declare function readEntry(carrier: DataViewAndAllocatorCarrier, startingCursor: number): Entry;
export declare function canReuseMemoryOfEntry(entryA: Entry, value: primitive): boolean;
export declare function writeValueInPtrToPtr(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, ptrToPtr: number, value: any): {
referencedPointers: number[];
existingEntryPointer: number;
existingValueEntry: Entry;
} | undefined;
export declare function writeValueInPtrToPtrAndHandleMemory(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, ptrToPtr: number, value: any): void;
export declare function handleArcForDeletedValuePointer(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, deletedValuePointer: number): void;
export declare function incrementRefCount(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, entryPointer: number): number;
export declare function decrementRefCount(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, entryPointer: number): number;
export declare function getObjectPropPtrToPtr({ dataView }: DataViewAndAllocatorCarrier, pointerToEntry: number): {
valuePtrToPtr: number;
nextPtrToPtr: number;
};
export declare function writeValueInPtrToPtr(externalArgs: ExternalArgs, carrier: GlobalCarrier, ptrToPtr: number, value: unknown): number[];
export declare function writeValueInPtrToPtrAndHandleMemory(externalArgs: ExternalArgs, carrier: GlobalCarrier, ptrToPtr: number, value: unknown): void;
export declare function handleArcForDeletedValuePointer(carrier: GlobalCarrier, deletedValuePointer: number): void;
export declare function incrementRefCount(heap: Heap, entryPointer: number): number;
export declare function decrementRefCount(heap: Heap, entryPointer: number): number;
export declare function getObjectValuePtrToPtr(pointerToEntry: number): number;
export declare function memComp(dataView: DataView, aStart: number, bStart: number, length: number): boolean;
export declare function compareStringOrNumberEntriesInPlace(dataView: DataView, entryAPointer: number, entryBPointer: number): boolean;
export declare function memComp(uint8: Uint8Array, aStart: number, bStart: number, length: number): boolean;
export declare function compareStringOrNumberEntriesInPlace(heap: Heap, entryAPointer: number, entryBPointer: number): boolean;
export declare function compareStringOrNumberEntriesInPlaceOld(carrier: GlobalCarrier, entryAPointer: number, entryBPointer: number): boolean;
export declare function readNumberOrString(heap: Heap, pointer: number): string | number;
//# sourceMappingURL=store.d.ts.map

@@ -1,22 +0,20 @@

import { ENTRY_TYPE, isPrimitiveEntryType } from "./entry-types";
import { isPrimitive, primitiveValueToEntry, strByteLength } from "./utils";
import { ENTRY_TYPE } from "./entry-types";
import { isKnownAddressValuePointer, isTypeWithRC } from "./utils";
import { BigInt64OverflowError } from "./exceptions";
import { INITIAL_ENTRY_POINTER_TO_POINTER, INITIAL_ENTRY_POINTER_VALUE, UNDEFINED_KNOWN_ADDRESS, NULL_KNOWN_ADDRESS, TRUE_KNOWN_ADDRESS, FALSE_KNOWN_ADDRESS } from "./consts";
import { saveValue } from "./saveValue";
import { INITIAL_ENTRY_POINTER_TO_POINTER, INITIAL_ENTRY_POINTER_VALUE } from "./consts";
import { getAllLinkedAddresses } from "./getAllLinkedAddresses";
import { stringEncodeInto } from "./stringEncodeInto";
import { stringDecode } from "./stringDecode";
import { typeAndRc_refsCount_get, typeAndRc_refsCount_set, typeOnly_type_get, number_value_get, string_bytesLength_get, string_charsPointer_get } from "./generatedStructs";
import { readString } from "./readString";
import { saveValueIterative } from "./saveValue";
const MAX_64_BIG_INT = BigInt("0xFFFFFFFFFFFFFFFF");
export function initializeArrayBuffer(arrayBuffer) {
const dataView = new DataView(arrayBuffer); // global lock
dataView.setInt32(0, 0); // first entry pointer
dataView.setUint32(INITIAL_ENTRY_POINTER_TO_POINTER, INITIAL_ENTRY_POINTER_VALUE);
return dataView;
const uint32 = new Uint32Array(arrayBuffer);
uint32[0] = 0;
uint32[INITIAL_ENTRY_POINTER_TO_POINTER / Uint32Array.BYTES_PER_ELEMENT] = INITIAL_ENTRY_POINTER_VALUE;
}
export function sizeOfEntry(entry) {
let cursor = 0;
cursor += Uint8Array.BYTES_PER_ELEMENT;
let cursor = 0; // type
cursor += Float64Array.BYTES_PER_ELEMENT;
switch (entry.type) {

@@ -28,4 +26,4 @@ case ENTRY_TYPE.NUMBER:

case ENTRY_TYPE.STRING:
cursor += Uint16Array.BYTES_PER_ELEMENT;
cursor += Uint16Array.BYTES_PER_ELEMENT;
// string length
cursor += Uint32Array.BYTES_PER_ELEMENT;
cursor += entry.allocatedBytes; // oh boy. i don't want to change it now, but no choice

@@ -49,3 +47,5 @@ // @todo: this is incorrect? should be Math.max

case ENTRY_TYPE.SET:
cursor += Uint8Array.BYTES_PER_ELEMENT;
// ref count
cursor += Uint32Array.BYTES_PER_ELEMENT; // pointer
cursor += Uint32Array.BYTES_PER_ELEMENT;

@@ -55,326 +55,99 @@ break;

case ENTRY_TYPE.ARRAY:
cursor += Uint32Array.BYTES_PER_ELEMENT;
cursor += Uint32Array.BYTES_PER_ELEMENT;
cursor += Uint32Array.BYTES_PER_ELEMENT;
cursor += Uint8Array.BYTES_PER_ELEMENT;
break;
// refsCount
cursor += Uint32Array.BYTES_PER_ELEMENT; // pointer
case ENTRY_TYPE.DATE:
cursor += Float64Array.BYTES_PER_ELEMENT;
cursor += Uint8Array.BYTES_PER_ELEMENT;
break;
cursor += Uint32Array.BYTES_PER_ELEMENT; // length
default:
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
throw new Error(ENTRY_TYPE[entry.type] + " Not implemented yet");
}
cursor += Uint32Array.BYTES_PER_ELEMENT; // allocated length
return cursor;
}
export function writeEntry({
dataView,
uint8
}, startingCursor, entry) {
let cursor = startingCursor; // let writtenDataSizeInBytes = 0;
// write type
// undo on throw ?
dataView.setUint8(cursor, entry.type);
cursor += Uint8Array.BYTES_PER_ELEMENT;
switch (entry.type) {
case ENTRY_TYPE.NUMBER:
dataView.setFloat64(cursor, entry.value);
cursor += Float64Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.STRING:
dataView.setUint16(cursor, entry.allocatedBytes);
cursor += Uint16Array.BYTES_PER_ELEMENT;
dataView.setUint16(cursor, entry.allocatedBytes);
cursor += Uint16Array.BYTES_PER_ELEMENT; // const arr = new Uint8Array(entry.allocatedBytes);
// const writtenBytes1 = stringEncodeInto(arr, 0, entry.value);
// eslint-disable-next-line no-case-declarations
const writtenBytes = stringEncodeInto(uint8, cursor, entry.value);
if (writtenBytes !== entry.allocatedBytes) {
// eslint-disable-next-line no-undef
console.warn({
value: entry.value,
writtenBytes,
allocatedBytes: entry.allocatedBytes
});
throw new Error("WTF???");
}
cursor += entry.allocatedBytes;
break;
case ENTRY_TYPE.BIGINT_NEGATIVE:
case ENTRY_TYPE.BIGINT_POSITIVE:
if (entry.value > MAX_64_BIG_INT || entry.value < -MAX_64_BIG_INT) {
throw new BigInt64OverflowError();
}
dataView.setBigUint64(cursor, entry.type === ENTRY_TYPE.BIGINT_NEGATIVE ? -entry.value : entry.value);
cursor += BigUint64Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.OBJECT:
case ENTRY_TYPE.SET:
case ENTRY_TYPE.MAP:
dataView.setUint8(cursor, entry.refsCount);
cursor += Uint8Array.BYTES_PER_ELEMENT;
dataView.setUint32(cursor, entry.value);
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.ARRAY:
dataView.setUint8(cursor, entry.refsCount);
cursor += Uint8Array.BYTES_PER_ELEMENT;
dataView.setUint32(cursor, entry.value);
cursor += Uint32Array.BYTES_PER_ELEMENT;
dataView.setUint32(cursor, entry.length);
cursor += Uint32Array.BYTES_PER_ELEMENT;
dataView.setUint32(cursor, entry.allocatedLength);
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.DATE:
dataView.setUint8(cursor, entry.refsCount);
cursor += Uint8Array.BYTES_PER_ELEMENT;
dataView.setFloat64(cursor, entry.value);
cursor += Float64Array.BYTES_PER_ELEMENT;
break;
// timestamp
cursor += Float64Array.BYTES_PER_ELEMENT; // ref count
default:
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
throw new Error(ENTRY_TYPE[entry.type] + " Not implemented yet");
}
}
export function appendEntry(externalArgs, carrier, entry) {
const size = sizeOfEntry(entry);
const memoryAddress = carrier.allocator.calloc(size);
writeEntry(carrier, memoryAddress, entry);
return memoryAddress;
}
export function readEntry(carrier, startingCursor) {
let cursor = startingCursor;
const entryType = carrier.dataView.getUint8(cursor);
cursor += Uint8Array.BYTES_PER_ELEMENT;
const entry = {
type: entryType,
value: undefined
}; // let writtenDataSizeInBytes = 0;
switch (entryType) {
case ENTRY_TYPE.UNDEFINED:
break;
case ENTRY_TYPE.NULL:
break;
case ENTRY_TYPE.BOOLEAN:
entry.value = carrier.dataView.getUint8(cursor) !== 0;
cursor += Uint8Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.NUMBER:
entry.value = carrier.dataView.getFloat64(cursor);
cursor += Float64Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.STRING:
// eslint-disable-next-line no-case-declarations
const stringLength = carrier.dataView.getUint16(cursor);
cursor += Uint16Array.BYTES_PER_ELEMENT;
entry.allocatedBytes = carrier.dataView.getUint16(cursor);
cursor += Uint16Array.BYTES_PER_ELEMENT; // decode fails with zero length array
if (stringLength > 0) {
// this wrapping is needed until:
// https://github.com/whatwg/encoding/issues/172
// eslint-disable-next-line no-case-declarations
// const tempAB = new ArrayBuffer(stringLength);
// arrayBufferCopyTo(dataView.buffer, cursor, stringLength, tempAB, 0);
entry.value = stringDecode(carrier.uint8, cursor, stringLength);
} else {
entry.value = "";
}
cursor += stringLength;
break;
case ENTRY_TYPE.BIGINT_POSITIVE:
entry.value = carrier.dataView.getBigUint64(cursor);
cursor += BigUint64Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.BIGINT_NEGATIVE:
entry.value = -carrier.dataView.getBigUint64(cursor);
cursor += BigUint64Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.OBJECT:
case ENTRY_TYPE.MAP:
case ENTRY_TYPE.SET:
entry.refsCount = carrier.dataView.getUint8(cursor);
cursor += Uint8Array.BYTES_PER_ELEMENT;
entry.value = carrier.dataView.getUint32(cursor);
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.ARRAY:
entry.refsCount = carrier.dataView.getUint8(cursor);
cursor += Uint8Array.BYTES_PER_ELEMENT;
entry.value = carrier.dataView.getUint32(cursor);
cursor += Uint32Array.BYTES_PER_ELEMENT;
entry.length = carrier.dataView.getUint32(cursor);
cursor += Uint32Array.BYTES_PER_ELEMENT;
entry.allocatedLength = carrier.dataView.getUint32(cursor);
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.DATE:
entry.refsCount = carrier.dataView.getUint8(cursor);
cursor += Uint8Array.BYTES_PER_ELEMENT;
entry.value = carrier.dataView.getFloat64(cursor);
cursor += Float64Array.BYTES_PER_ELEMENT;
break;
default:
throw new Error(ENTRY_TYPE[entryType] + " Not implemented yet");
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
throw new Error(ENTRY_TYPE[entry.type] + " Not implemented yet");
}
return entry;
return cursor;
}
export function canReuseMemoryOfEntry(entryA, value) {
const typeofTheValue = typeof value; // number & bigint 64 are the same size
if ((entryA.type === ENTRY_TYPE.BIGINT_NEGATIVE || entryA.type === ENTRY_TYPE.BIGINT_POSITIVE || entryA.type === ENTRY_TYPE.NUMBER) && (typeofTheValue === "bigint" || typeofTheValue === "number")) {
return true;
}
if (entryA.type === ENTRY_TYPE.STRING && typeofTheValue === "string" && entryA.allocatedBytes >= strByteLength(value)) {
return true;
}
return false;
}
export function writeValueInPtrToPtr(externalArgs, carrier, ptrToPtr, value) {
const existingEntryPointer = carrier.dataView.getUint32(ptrToPtr);
const existingValueEntry = readEntry(carrier, existingEntryPointer); // try to re use memory
const referencedPointers = []; // Might oom here
if (isPrimitive(value) && isPrimitiveEntryType(existingValueEntry.type) && canReuseMemoryOfEntry(existingValueEntry, value) && existingEntryPointer !== 0) {
const newEntry = primitiveValueToEntry(value);
writeEntry(carrier, existingEntryPointer, newEntry);
} else {
const referencedPointers = [];
const newEntryPointer = saveValue(externalArgs, carrier, referencedPointers, value);
carrier.dataView.setUint32(ptrToPtr, newEntryPointer);
return {
referencedPointers,
existingEntryPointer,
existingValueEntry
};
}
saveValueIterative(externalArgs, carrier, referencedPointers, ptrToPtr, value);
return referencedPointers;
}
export function writeValueInPtrToPtrAndHandleMemory(externalArgs, carrier, ptrToPtr, value) {
const {
existingValueEntry = false,
existingEntryPointer = 0,
referencedPointers = []
} = writeValueInPtrToPtr(externalArgs, carrier, ptrToPtr, value) || {};
const existingEntryPointer = carrier.heap.Uint32Array[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT]; // Might oom here
const referencedPointers = writeValueInPtrToPtr(externalArgs, carrier, ptrToPtr, value); // -- end of might oom
// commit ref count changes of existing objects
if (referencedPointers.length > 0) {
for (const ptr of referencedPointers) {
incrementRefCount(externalArgs, carrier, ptr);
incrementRefCount(carrier.heap, ptr);
}
}
if (existingValueEntry && "refsCount" in existingValueEntry) {
const newRefCount = decrementRefCount(externalArgs, carrier, existingEntryPointer);
handleArcForDeletedValuePointer(carrier, existingEntryPointer);
}
export function handleArcForDeletedValuePointer(carrier, deletedValuePointer) {
const {
heap,
allocator
} = carrier; // No memory to free/ARC
if (newRefCount === 0) {
const addressesToFree = getAllLinkedAddresses(carrier, false, existingEntryPointer);
for (const address of addressesToFree.leafAddresses) {
carrier.allocator.free(address);
}
for (const address of addressesToFree.arcAddresses) {
decrementRefCount(externalArgs, carrier, address);
}
}
} else {
carrier.allocator.free(existingEntryPointer);
}
}
export function handleArcForDeletedValuePointer(externalArgs, carrier, deletedValuePointer) {
// No memory to free/ARC
if (deletedValuePointer === UNDEFINED_KNOWN_ADDRESS || deletedValuePointer === NULL_KNOWN_ADDRESS || deletedValuePointer === TRUE_KNOWN_ADDRESS || deletedValuePointer === FALSE_KNOWN_ADDRESS) {
if (isKnownAddressValuePointer(deletedValuePointer)) {
return;
}
const existingValueEntry = readEntry(carrier, deletedValuePointer);
const entryType = typeOnly_type_get(heap, deletedValuePointer);
if (existingValueEntry && "refsCount" in existingValueEntry) {
const newRefCount = decrementRefCount(externalArgs, carrier, deletedValuePointer);
if (!isTypeWithRC(entryType)) {
if (entryType === ENTRY_TYPE.STRING) {
allocator.free(string_charsPointer_get(carrier.heap, deletedValuePointer));
}
if (newRefCount === 0) {
const addressesToFree = getAllLinkedAddresses(carrier, false, deletedValuePointer);
for (const address of addressesToFree.leafAddresses) {
carrier.allocator.free(address);
}
for (const address of addressesToFree.arcAddresses) {
decrementRefCount(externalArgs, carrier, address);
}
}
} else {
carrier.allocator.free(deletedValuePointer);
allocator.free(deletedValuePointer);
return;
}
}
export function incrementRefCount(externalArgs, carrier, entryPointer) {
const entry = readEntry(carrier, entryPointer);
if ("refsCount" in entry) {
entry.refsCount += 1;
writeEntry(carrier, entryPointer, entry);
return entry.refsCount;
if (decrementRefCount(heap, deletedValuePointer) > 0) {
allocator.free(deletedValuePointer);
return;
}
throw new Error("unexpected");
}
export function decrementRefCount(externalArgs, carrier, entryPointer) {
const entry = readEntry(carrier, entryPointer);
const {
leafAddresses,
arcAddresses
} = getAllLinkedAddresses(carrier, false, deletedValuePointer);
if ("refsCount" in entry) {
entry.refsCount -= 1;
writeEntry(carrier, entryPointer, entry);
return entry.refsCount;
for (const address of leafAddresses) {
allocator.free(address);
}
throw new Error("unexpected");
for (const address of arcAddresses) {
decrementRefCount(heap, address);
}
}
export function getObjectPropPtrToPtr({
dataView
}, pointerToEntry) {
const keyStringLength = dataView.getUint16(pointerToEntry + 1);
const valuePtrToPtr = Uint16Array.BYTES_PER_ELEMENT + pointerToEntry + 1 + keyStringLength;
const nextPtrToPtr = valuePtrToPtr + Uint32Array.BYTES_PER_ELEMENT;
return {
valuePtrToPtr,
nextPtrToPtr
};
export function incrementRefCount(heap, entryPointer) {
typeAndRc_refsCount_set(heap, entryPointer, typeAndRc_refsCount_get(heap, entryPointer) + 1);
return typeAndRc_refsCount_get(heap, entryPointer);
}
export function decrementRefCount(heap, entryPointer) {
typeAndRc_refsCount_set(heap, entryPointer, typeAndRc_refsCount_get(heap, entryPointer) - 1);
return typeAndRc_refsCount_get(heap, entryPointer);
}
export function getObjectValuePtrToPtr(pointerToEntry) {
return pointerToEntry + 1 + 1;
}
export function memComp(dataView, aStart, bStart, length) {
if (dataView.byteLength < aStart + length || dataView.byteLength < bStart + length) {
export function memComp(uint8, aStart, bStart, length) {
if (uint8.byteLength < aStart + length || uint8.byteLength < bStart + length) {
return false;

@@ -385,3 +158,3 @@ }

// compare 8 using Float64Array?
if (dataView.getUint8(aStart + i) !== dataView.getUint8(bStart + i)) {
if (uint8[aStart + i] !== uint8[bStart + i]) {
return false;

@@ -393,7 +166,30 @@ }

}
export function compareStringOrNumberEntriesInPlace(dataView, entryAPointer, entryBPointer) {
export function compareStringOrNumberEntriesInPlace(heap, entryAPointer, entryBPointer) {
typeOnly_type_get(heap, entryAPointer);
const entryAType = typeOnly_type_get(heap, entryAPointer);
const entryBType = typeOnly_type_get(heap, entryBPointer);
if (entryAType !== entryBType) {
return false;
}
if (entryAType === ENTRY_TYPE.STRING) {
const aLength = string_bytesLength_get(heap, entryAPointer);
const bLength = string_bytesLength_get(heap, entryBPointer);
if (aLength !== bLength) {
return false;
}
return memComp(heap.Uint8Array, string_charsPointer_get(heap, entryAPointer), string_charsPointer_get(heap, entryBPointer), aLength);
} // numbers
return number_value_get(heap, entryAPointer) === number_value_get(heap, entryBPointer);
}
export function compareStringOrNumberEntriesInPlaceOld(carrier, entryAPointer, entryBPointer) {
let cursor = 0;
const entryAType = dataView.getUint8(entryAPointer + cursor);
const entryBType = dataView.getUint8(entryBPointer + cursor);
cursor += 1;
const entryAType = carrier.float64[(entryAPointer + cursor) / Float64Array.BYTES_PER_ELEMENT];
const entryBType = carrier.float64[(entryBPointer + cursor) / Float64Array.BYTES_PER_ELEMENT];
cursor += Float64Array.BYTES_PER_ELEMENT;

@@ -405,4 +201,4 @@ if (entryAType !== entryBType) {

if (entryAType === ENTRY_TYPE.STRING) {
const aLength = dataView.getUint16(entryAPointer + cursor);
const bLength = dataView.getUint16(entryBPointer + cursor);
const aLength = carrier.uint32[(entryAPointer + cursor) / Uint32Array.BYTES_PER_ELEMENT];
const bLength = carrier.uint32[(entryBPointer + cursor) / Uint32Array.BYTES_PER_ELEMENT];

@@ -414,9 +210,16 @@ if (aLength !== bLength) {

cursor += Uint16Array.BYTES_PER_ELEMENT; // allocated length, skip.
cursor += Uint32Array.BYTES_PER_ELEMENT;
return memComp(carrier.uint8, entryAPointer + cursor, entryBPointer + cursor, aLength);
}
cursor += Uint16Array.BYTES_PER_ELEMENT;
return memComp(dataView, entryAPointer + cursor, entryBPointer + cursor, aLength);
return carrier.float64[(entryAPointer + cursor) / Float64Array.BYTES_PER_ELEMENT] === carrier.float64[(entryBPointer + cursor) / Float64Array.BYTES_PER_ELEMENT];
}
export function readNumberOrString(heap, pointer) {
const type = typeOnly_type_get(heap, pointer);
if (type === ENTRY_TYPE.NUMBER) {
return number_value_get(heap, pointer);
} else {
return readString(heap, pointer);
}
return dataView.getFloat64(entryAPointer + cursor) === dataView.getFloat64(entryBPointer + cursor);
}

@@ -16,3 +16,4 @@ export function arrayBuffer2HexArray(buffer, withByteNumber = false) {

import { OutOfMemoryError } from "./exceptions";
import { MEM_POOL_START } from "./consts"; // extend pool and not monkey patch? need to think about it
import { MEM_POOL_START } from "./consts";
import { createHeap } from "../structsGenerator/consts"; // extend pool and not monkey patch? need to think about it

@@ -65,4 +66,4 @@ export function recordAllocations(operation, pool) {

return allocation;
}; // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
}; // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error

@@ -92,3 +93,3 @@

const carrier = {
dataView: new DataView(arrayBuffer),
// dataView: new DataView(arrayBuffer),
allocator,

@@ -99,5 +100,6 @@ uint8: new Uint8Array(arrayBuffer),

float64: new Float64Array(arrayBuffer),
bigUint64: new BigUint64Array(arrayBuffer)
bigUint64: new BigUint64Array(arrayBuffer),
heap: createHeap(arrayBuffer)
};
return carrier;
}
import { primitive, Entry, ExternalArgs, InternalAPI, ExternalArgsApi } from "./interfaces";
import { ENTRY_TYPE } from "./entry-types";
import { IMemPool } from "@thi.ng/malloc";
export declare function isPrimitive(value: unknown): value is primitive;

@@ -7,7 +9,13 @@ export declare function primitiveValueToEntry(value: primitive): Entry;

export declare function arrayBufferCopyTo(origin: ArrayBuffer, startByte: number, length: number, target: ArrayBuffer, toTargetByte: number): void;
export declare function getOurPointerIfApplicable(value: any, ourDateView: DataView): number | undefined;
export declare function getOurPointerIfApplicable(value: any, ourAllocator: IMemPool): number | undefined;
export declare function externalArgsApiToExternalArgsApi(p: ExternalArgsApi): ExternalArgs;
export declare function getInternalAPI(value: any): InternalAPI;
/**
* Incorrect length (too big) for emojis
* @param str
*/
export declare function strByteLength(str: string): number;
export declare function align(value: number, alignTo?: number): number;
export declare function isKnownAddressValuePointer(entryPointer: number): boolean;
export declare function isTypeWithRC(type: ENTRY_TYPE): boolean;
//# sourceMappingURL=utils.d.ts.map
import { ENTRY_TYPE } from "./entry-types";
import { INTERNAL_API_SYMBOL } from "./symbols";
import { UNDEFINED_KNOWN_ADDRESS, NULL_KNOWN_ADDRESS, TRUE_KNOWN_ADDRESS, FALSE_KNOWN_ADDRESS } from "./consts";
const primitives = ["string", "number", "bigint", "boolean", "undefined"];

@@ -53,12 +54,9 @@ export function isPrimitive(value) {

const copyTo = new Uint8Array(target);
for (let i = 0; i < length; i += 1) {
copyTo[toTargetByte + i] = copyFrom[startByte + i];
}
copyTo.set(copyFrom.subarray(startByte, startByte + length), toTargetByte);
}
export function getOurPointerIfApplicable(value, ourDateView) {
export function getOurPointerIfApplicable(value, ourAllocator) {
if (INTERNAL_API_SYMBOL in value) {
const api = getInternalAPI(value);
if (api.getCarrier().dataView === ourDateView) {
if (api.getCarrier().allocator === ourAllocator) {
return api.getEntryPointer();

@@ -82,2 +80,7 @@ }

}
/**
* Incorrect length (too big) for emojis
* @param str
*/
export function strByteLength(str) {

@@ -95,2 +98,8 @@ let s = str.length;

return Math.ceil(value / alignTo) * alignTo;
}
export function isKnownAddressValuePointer(entryPointer) {
return entryPointer === UNDEFINED_KNOWN_ADDRESS || entryPointer === NULL_KNOWN_ADDRESS || entryPointer === TRUE_KNOWN_ADDRESS || entryPointer === FALSE_KNOWN_ADDRESS;
}
export function isTypeWithRC(type) {
return type === ENTRY_TYPE.OBJECT || type === ENTRY_TYPE.ARRAY || type === ENTRY_TYPE.DATE || type === ENTRY_TYPE.MAP || type === ENTRY_TYPE.SET;
}

@@ -0,1 +1,3 @@

/* istanbul ignore file */
// We can't run test with weakrefs yet
const KEYS = 1;

@@ -15,3 +17,4 @@ const VALUES = 2;

this.map = new Map();
this.group = new FinalizationGroup(iterator => {
const FinalizationSomething = typeof FinalizationRegistry !== "undefined" ? FinalizationRegistry : FinalizationGroup;
this.group = new FinalizationSomething(iterator => {
for (const key of iterator) {

@@ -18,0 +21,0 @@ this.map.delete(key);

@@ -9,3 +9,3 @@ /**

*/ /** */
export { createObjectBuffer, resizeObjectBuffer, getUnderlyingArrayBuffer, loadObjectBuffer, replaceUnderlyingArrayBuffer, sizeOf as unreliable_sizeOf, memoryStats, disposeWrapperObject, updateExternalArgs } from "./internal/api";
export { createObjectBuffer, resizeObjectBuffer, getUnderlyingArrayBuffer, loadObjectBuffer, replaceUnderlyingArrayBuffer, sizeOf as unreliable_sizeOf, memoryStats, disposeWrapperObject, updateExternalArgs, } from "./internal/api";
export { acquireLock, acquireLockWait, releaseLock } from "./internal/locks";

@@ -12,0 +12,0 @@ export declare type ExternalArgs = import("./internal/interfaces").ExternalArgsApi;

{
"name": "@bnaya/objectbuffer",
"description": "Object-like api, backed by an array buffer",
"version": "0.0.0-136a848",
"version": "0.0.0-1ed1bee",
"main": "dist/objectbuffer.cjs.js",

@@ -36,39 +36,42 @@ "module": "dist/index.js",

"webpack-playground": "webpack-dev-server --mode=development --config playground/webpack.config.js --open",
"generate-docs": "rimraf -f docs/generated/ && typedoc --out docs/generated/ --includes . --name objectbuffer --readme none --entryPoint \"\\\"index\\\"\" --excludeNotExported --ignoreCompilerErrors --mode modules src/index.ts"
"generate-docs": "rimraf -f docs/generated/ && typedoc --mode library --readme none --out docs/generated/ --excludeNotExported --ignoreCompilerErrors src/index.ts",
"generate-structs": "npx ts-node src/structsGenerator/run.ts"
},
"devDependencies": {
"@babel/cli": "^7.7.5",
"@babel/core": "^7.7.5",
"@babel/preset-env": "^7.7.6",
"@babel/preset-typescript": "^7.7.4",
"@types/benchmark": "^1.0.31",
"@types/jest": "^24.0.24",
"@babel/cli": "^7.8.4",
"@babel/core": "^7.9.6",
"@babel/node": "^7.8.7",
"@babel/preset-env": "^7.9.6",
"@babel/preset-typescript": "^7.9.0",
"@types/benchmark": "^1.0.32",
"@types/jest": "^25.2.2",
"@types/node": "^12.12.21",
"@typescript-eslint/eslint-plugin": "^2.12.0",
"@typescript-eslint/parser": "^2.12.0",
"babel-loader": "^8.0.6",
"@typescript-eslint/eslint-plugin": "^3.0.0-alpha.23",
"@typescript-eslint/parser": "^3.0.0-alpha.23",
"babel-loader": "^8.1.0",
"benchmark": "^2.1.4",
"concurrently": "^5.0.2",
"core-js": "^3.5.0",
"eslint": "^6.7.2",
"eslint-config-prettier": "^6.7.0",
"eslint-plugin-prettier": "^3.1.2",
"gh-pages": "^2.1.1",
"html-webpack-plugin": "^3.2.0",
"husky": "^3.1.0",
"jest": "^24.9.0",
"prettier": "^1.19.1",
"concurrently": "^5.2.0",
"core-js": "^3.6.5",
"eslint": "^7.0.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-prettier": "^3.1.3",
"gh-pages": "^2.2.0",
"html-webpack-plugin": "^4.3.0",
"husky": "^4.2.5",
"jest": "^26.0.1",
"kind-of": "^6.0.3",
"prettier": "^2.0.5",
"prettier-eslint": "^9.0.1",
"rimraf": "^3.0.0",
"rollup": "^1.27.13",
"rollup-plugin-babel": "^4.3.3",
"rimraf": "^3.0.2",
"rollup": "^2.10.0",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-node-resolve": "^5.2.0",
"typedoc": "npm:@gnd/typedoc",
"typedoc-plugin-markdown": "^2.2.14",
"typescript": "^3.7.3",
"webpack": "^4.41.3",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.10.0",
"typedoc": "^0.17.6",
"typedoc-plugin-markdown": "^2.2.17",
"typescript": "^3.9.2",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.11.0",
"worker-loader": "^2.0.0",
"yarn-deduplicate": "^1.1.1"
"yarn-deduplicate": "^2.0.0"
},

@@ -87,8 +90,5 @@ "husky": {

],
"resolutions": {
"typescript": "^3.7.2"
},
"dependencies": {
"@thi.ng/malloc": "^4.1.1"
"@thi.ng/malloc": "^4.1.14"
}
}

@@ -1,2 +0,2 @@

# ObjectBuffer: object-like API, backed by a [shared]arraybuffer
# ObjectBuffer: object-like API, backed by a [shared]arraybuffer 👀

@@ -6,14 +6,17 @@ [![npm version](https://badge.fury.io/js/%40bnaya%2Fobjectbuffer.svg)](https://badge.fury.io/js/%40bnaya%2Fobjectbuffer)

## The readme is for latest release `v0.10.0`.big refactor ongoing (allocator, hashmap)
For Modern browsers and node.
For Modern browsers and node. Zero direct dependencies.
Save, read and update plain javascript objects into `ArrayBuffer` (And not only TypedArrays), using regular javascript object api, without serialization/deserialization, or pre-defined schema.
In other words, It's an implementation of javascript objects in user-land.
Save, read and update plain javascript objects into `ArrayBuffer` (And not only TypedArrays), using regular javascript object api, without serialization/deserialization.
Look at it as a simple implementation of javascript objects in user-land.
That's enables us to `transfer` or share objects in-memory with `WebWorker` without additional memory or serialization
While the library is not `1.0`, it is usable.
The library is still not `1.0`, but already usable, and will never offer full compatibility with plain js (`Symbol` and such)
A core part of the library is an allocator, that allocates & free memory on the `ArrayBuffer` for us!
The allocator in use is [@thi.ng/malloc](https://www.npmjs.com/package/@thi.ng/malloc), part of the amazing [thi.ng/umbrella](https://github.com/thi-ng/umbrella) project
For in-depth overview of how things are implemented, see [implementation details document](docs/implementationDetails.md)
## 🐉🐉🐉 Adventurers Beware 🐉🐉🐉
Using this library, and workers in general, will not necessarily make you code faster.
First be sure where are your bottlenecks and if you don't have a better and more simple workaround.
I personally also really like what's going on around the [main thread scheduling proposal](https://github.com/WICG/main-thread-scheduling) and [react userland scheduler](https://www.npmjs.com/package/scheduler) that powers concurrent react

@@ -30,7 +33,3 @@ ## Quick example

const myObject = createObjectBuffer(
{
// available globally in the browser, or inside `util` in node
textEncoder: new TextEncoder(),
textDecoder: new TextDecoder()
},
{},
// size in bytes

@@ -84,15 +83,18 @@ 1024,

* Date
* Internal references (`foo.bar2 = foo.bar` will not create a copy)
* BigInt
* Internal references (`foo.bar2 = foo.bar` will not create a copy, but a reference)
* Automatic reference counting, to dispose a value you need to use the `disposeWrapperObject` or to have WeakRef support
* Internal equality between objects (`foo.bar === foo.bar` will be true)
* global lock for shared memory using [Atomics](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics) (i hope its really working)
* global lock for shared memory using [Atomics](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics) (I hope its really working)
## Caveats & Limitations
* Need to specify size for the `ArrayBuffer`. When exceed that size, exception will be thrown. (Can be extended with a utility function, but not automatically)
* Not memory re-use. memory allocation is append based, or overwrite when possible [#21](https://github.com/Bnaya/objectbuffer/issues/21)
* Object are implemented using simple linked list [#26](https://github.com/Bnaya/objectbuffer/issues/26)
* Maps & Sets are not supported yet [#15](https://github.com/Bnaya/objectbuffer/issues/15) & [#24](https://github.com/Bnaya/objectbuffer/issues/24)
* No prototype chain. objects props will simply be copied
* Additional props on Array, Date, primitives will not be saved.
* getters, setters, will not work/break the library
* Need to specify size for the `ArrayBuffer`. When exceed that size, exception will be thrown. (Can be extended later with a utility function, but not automatically)
* Size must be multiplication of 8
* Set, Map, Object keys can be only string or numbers. no symbols or other things
* You can't save objects with circularities (But you can create them on objectbuffer)
* No prototype chain. no methods on the objects
* Adding getters, setters, will not work/break the library
* deleting/removing the current key of Map/Set while iteration will make you skip the next key [#60](https://github.com/Bnaya/objectbuffer/issues/60)
* unreliable_sizeOf is unreliable due to hashmap array side depends on actual keys, Also It's an expensive operation

@@ -103,3 +105,3 @@ ### What's not working yet, but can be

### What's probably never going to work (convince me otherwise )
### What's probably never going to work

@@ -112,2 +114,10 @@ * Anything that cannot go into `JSON.stringify`

There's a huge place for optimizations, code hygiene, and features!
Feel free to open issues and maybe implementing missing parts
Feel free to open issues and maybe implementing missing parts.
The code is Written in TypeScript 🦾, but the semantics are more like `C` 🥵
Have a look on the [issues](https://github.com/Bnaya/objectbuffer/issues) and see if you find something interesting
## If you came this far, you better also look at:
* [GoogleChromeLabs/buffer-backed-object](https://github.com/GoogleChromeLabs/buffer-backed-object#readme)
* [FlatBuffers](https://google.github.io/flatbuffers/flatbuffers_guide_use_javascript.html)
/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer } from "../";

@@ -12,5 +10,3 @@ import { memoryStats } from "../internal/api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -40,4 +36,4 @@

expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`624`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`560`);
});
});
/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer } from "../";

@@ -11,5 +9,3 @@ import { memoryStats } from "../internal/api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -20,3 +16,3 @@

// 1/1 2000
myDate: new Date(946684800000)
myDate: new Date(946684800000),
});

@@ -50,4 +46,4 @@

expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`240`);
expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`272`);
});
});
/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer } from "../";

@@ -11,5 +9,3 @@ import { memoryStats } from "../internal/api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -28,2 +24,25 @@

expect(objectBuffer).toMatchInlineSnapshot(`
Object {
"arr": Array [
1,
2,
3,
4,
],
"arr2": Array [
1,
2,
3,
4,
],
"obj": Object {
"a": 1,
},
"obj2": Object {
"a": 1,
},
}
`);
expect(objectBuffer.arr2).toBe(objectBuffer.arr2);

@@ -35,27 +54,4 @@ expect(objectBuffer.arr2).toBe(objectBuffer.arr);

expect(objectBuffer).toMatchInlineSnapshot(`
Object {
"arr": Array [
1,
2,
3,
4,
],
"arr2": Array [
1,
2,
3,
4,
],
"obj": Object {
"a": 1,
},
"obj2": Object {
"a": 1,
},
}
`);
expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`728`);
expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`856`);
});
});
/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer } from "../";

@@ -10,13 +8,10 @@ import { memoryStats } from "../internal/api";

describe("Map", () => {
const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder()
});
const externalArgs = externalArgsApiToExternalArgsApi({});
test("creation", () => {
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`);
objectBuffer.foo = new Map([[1, "a"]]);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`624`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`560`);
expect(objectBuffer.foo).toMatchInlineSnapshot(`

@@ -31,7 +26,7 @@ Map {

const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`);
objectBuffer.foo = new Map([[1, "a"]]);
objectBuffer.foo.set("2", "b");
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`440`);
expect(objectBuffer.foo).toMatchInlineSnapshot(`

@@ -55,11 +50,11 @@ Map {

const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`);
objectBuffer.foo = new Map([[1, "a"]]);
objectBuffer.foo.set("2", "b");
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`440`);
objectBuffer.foo.delete(1);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`632`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`544`);

@@ -75,11 +70,15 @@ expect(objectBuffer.foo).toMatchInlineSnapshot(`

const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`);
objectBuffer.foo = new Map([[1, "a"]]);
objectBuffer.foo = new Map();
const availSizeAfterCreation = memoryStats(objectBuffer).available;
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`664`);
objectBuffer.foo.set(1, "a");
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`560`);
objectBuffer.foo.set("2", "b");
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`440`);
objectBuffer.foo.clear();
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`704`);
expect(memoryStats(objectBuffer).available).toBe(availSizeAfterCreation);

@@ -91,3 +90,3 @@ expect(objectBuffer.foo).toMatchInlineSnapshot(`Map {}`);

const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`);

@@ -97,3 +96,3 @@ objectBuffer.foo = new Map([[1, "a"]]);

expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`440`);

@@ -125,3 +124,3 @@ expect(objectBuffer.foo).toMatchInlineSnapshot(`

[1, "a"],
[2, "b"]
[2, "b"],
]);

@@ -135,4 +134,4 @@ for (const [key] of nativeMap) {

[1, "a"],
[2, "b"]
])
[2, "b"],
]),
});

@@ -148,3 +147,3 @@ for (const [key] of objectBuffer.foo) {

const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`);

@@ -162,3 +161,3 @@ objectBuffer.foo = new Map([[1, "a"]]);

expect(thisArgs.every(v => v === objectBuffer.foo)).toBe(true);
expect(thisArgs.every((v) => v === objectBuffer.foo)).toBe(true);

@@ -165,0 +164,0 @@ expect(dump).toMatchInlineSnapshot(`

/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer } from "../";

@@ -11,5 +9,3 @@ import { resizeObjectBuffer, memoryStats } from "../internal/api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -20,3 +16,3 @@

arr: [1, 2, 3, 4],
obj: { a: 1 }
obj: { a: 1 },
});

@@ -26,4 +22,4 @@

Object {
"available": 424,
"used": 600,
"available": 328,
"used": 696,
}

@@ -36,3 +32,3 @@ `);

arr: [1, 2, 3, 4],
obj: { a: 1 }
obj: { a: 1 },
});

@@ -42,4 +38,4 @@

Object {
"available": 1448,
"used": 600,
"available": 1352,
"used": 696,
}

@@ -51,4 +47,4 @@ `);

Object {
"available": 424,
"used": 600,
"available": 328,
"used": 696,
}

@@ -60,4 +56,4 @@ `);

Object {
"available": 168,
"used": 600,
"available": 72,
"used": 696,
}

@@ -69,4 +65,4 @@ `);

Object {
"available": 1448,
"used": 600,
"available": 1352,
"used": 696,
}

@@ -73,0 +69,0 @@ `);

/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer } from "../";

@@ -10,17 +8,15 @@ import { memoryStats } from "../internal/api";

describe("object tests", () => {
const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder()
});
const externalArgs = externalArgsApiToExternalArgsApi({});
test("delete object prop", () => {
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);
const sizeBeforeSet = memoryStats(objectBuffer).available;
expect(sizeBeforeSet).toMatchInlineSnapshot(`864`);
objectBuffer.foo = "a";
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`800`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`744`);
delete objectBuffer.foo;
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);
expect(memoryStats(objectBuffer).available).toBe(sizeBeforeSet);
expect(objectBuffer).toMatchInlineSnapshot(`Object {}`);

@@ -36,7 +32,7 @@ });

e: undefined,
foo: { a: 1, b: true, c: false, d: null, e: undefined }
foo: { a: 1, b: true, c: false, d: null, e: undefined },
};
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, input);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`96`);
const objectBuffer = createObjectBuffer<any>(externalArgs, 2048, input);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`840`);
expect(input).toEqual(objectBuffer);

@@ -60,2 +56,28 @@ expect(objectBuffer).toMatchInlineSnapshot(`

});
// Not working. will make infinite loop
test.skip("With circular", () => {
const input: any = {
a: 1,
b: true,
c: false,
d: null,
e: undefined,
foo: { a: 1, b: true, c: false, d: null, e: undefined },
};
// Create circularity
input.foo.circular = input.foo;
const objectBuffer = createObjectBuffer<any>(externalArgs, 2048, input);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`1016`);
expect(input).toEqual(objectBuffer);
expect(objectBuffer.foo.circular).toEqual(objectBuffer.foo);
expect(objectBuffer.foo.circular.d).toMatchInlineSnapshot();
objectBuffer.foo.circular = "severe the circularity";
expect(objectBuffer).toMatchInlineSnapshot();
});
});
/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer, resizeObjectBuffer } from "../";

@@ -9,7 +7,7 @@ import {

replaceUnderlyingArrayBuffer,
memoryStats
memoryStats,
} from "../internal/api";
import {
arrayBufferCopyTo,
externalArgsApiToExternalArgsApi
externalArgsApiToExternalArgsApi,
} from "../internal/utils";

@@ -19,5 +17,3 @@

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -27,3 +23,3 @@

const objectBuffer = createObjectBuffer<any>(externalArgs, 512, {
a: 1
a: 1,
});

@@ -42,3 +38,3 @@

expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`792`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`760`);
expect(objectBuffer).toMatchInlineSnapshot(`

@@ -53,3 +49,3 @@ Object {

const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {
obj1: { a: 1 }
obj1: { a: 1 },
});

@@ -56,0 +52,0 @@

/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer } from "../";

@@ -12,5 +10,3 @@ import { memoryStats } from "../internal/api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -25,4 +21,4 @@

test("Fail to set new data when enough memory", () => {
const objectBuffer = createObjectBuffer<any>(externalArgs, 256, {
value: "first value 123"
const objectBuffer = createObjectBuffer<any>(externalArgs, 312, {
value: "first value 123",
});

@@ -36,3 +32,3 @@ const freeSpaceLeft = memoryStats(objectBuffer).available;

expect(memoryStats(objectBuffer).available).toEqual(freeSpaceLeft);
expect(freeSpaceLeft).toMatchInlineSnapshot(`8`);
expect(freeSpaceLeft).toMatchInlineSnapshot(`24`);

@@ -39,0 +35,0 @@ expect(objectBuffer).toMatchInlineSnapshot(`

/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer } from "../";

@@ -10,13 +8,10 @@ import { memoryStats } from "../internal/api";

describe("Set tests", () => {
const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder()
});
const externalArgs = externalArgsApiToExternalArgsApi({});
test("creation", () => {
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`);
objectBuffer.foo = new Set(["a"]);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`648`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`584`);
expect(objectBuffer.foo).toMatchInlineSnapshot(`

@@ -31,7 +26,7 @@ Set {

const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`);
objectBuffer.foo = new Set(["a"]);
objectBuffer.foo.add("b");
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`592`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`504`);
expect(objectBuffer.foo).toMatchInlineSnapshot(`

@@ -55,11 +50,11 @@ Set {

const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`);
objectBuffer.foo = new Set(["a"]);
objectBuffer.foo.add("b");
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`592`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`504`);
objectBuffer.foo.delete(1);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`592`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`504`);

@@ -76,11 +71,11 @@ expect(objectBuffer.foo).toMatchInlineSnapshot(`

const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`);
objectBuffer.foo = new Set(["a"]);
objectBuffer.foo.add("b");
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`592`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`504`);
objectBuffer.foo.clear();
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`704`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`664`);

@@ -92,3 +87,3 @@ expect(objectBuffer.foo).toMatchInlineSnapshot(`Set {}`);

const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`);

@@ -98,3 +93,3 @@ objectBuffer.foo = new Set(["a"]);

expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`592`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`504`);

@@ -130,3 +125,3 @@ expect(objectBuffer.foo).toMatchInlineSnapshot(`

const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {
foo: new Set(["a", "b"])
foo: new Set(["a", "b"]),
});

@@ -142,3 +137,3 @@ for (const [key] of objectBuffer.foo) {

const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`);

@@ -156,3 +151,3 @@ objectBuffer.foo = new Set(["a"]);

expect(thisArgs.every(v => v === objectBuffer.foo)).toBe(true);
expect(thisArgs.every((v) => v === objectBuffer.foo)).toBe(true);

@@ -159,0 +154,0 @@ expect(dump).toMatchInlineSnapshot(`

/* eslint-env jest */
import * as util from "util";
import { createObjectBuffer } from "../";

@@ -12,5 +10,3 @@ import { memoryStats, disposeWrapperObject } from "../internal/api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -26,2 +22,15 @@

// expect(objectBuffer).toMatchInlineSnapshot(`
// Object {
// "arr": Array [
// Object {
// "a": 1,
// },
// ],
// }
// `);
// disposeWrapperObject(objectBuffer.arr[0]);
// disposeWrapperObject(objectBuffer.arr);
objectBuffer.arr = [{ bar: 666 }];

@@ -39,3 +48,9 @@

expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`440`);
expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`528`);
disposeWrapperObject(objectBuffer.arr[0]);
disposeWrapperObject(objectBuffer.arr);
delete objectBuffer.arr;
expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`176`);
});

@@ -89,4 +104,4 @@

expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`608`);
expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`744`);
});
});
/* eslint-disable */
import { ExternalArgs } from "../internal/interfaces";
import * as util from "util";
import { createObjectBuffer } from "..";

@@ -27,6 +27,6 @@ import { memoryStats } from "../internal/api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0,
});

@@ -33,0 +33,0 @@

@@ -1,2 +0,1 @@

import * as util from "util";
import { createObjectBuffer } from "..";

@@ -10,5 +9,3 @@ import { memoryStats } from "../internal/api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -18,3 +15,3 @@

const objectBuffer = createObjectBuffer<any>(externalArgs, 256, {
foo: null
foo: null,
});

@@ -24,3 +21,3 @@

expect(initialFreeSpace).toMatchInlineSnapshot(`48`);
expect(initialFreeSpace).toMatchInlineSnapshot(`16`);

@@ -31,7 +28,7 @@ expect(() => {

more: "than size",
arr: [1, 2, 3]
arr: [1, 2, 3],
};
}).toThrowErrorMatchingInlineSnapshot(`"OutOfMemoryError"`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`48`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`16`);

@@ -38,0 +35,0 @@ expect(objectBuffer).toMatchInlineSnapshot(`

@@ -1,2 +0,1 @@

import * as util from "util";
import { createObjectBuffer } from "..";

@@ -10,5 +9,3 @@ import { memoryStats } from "../internal/api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -18,3 +15,3 @@

const objectBuffer = createObjectBuffer(externalArgs, 128, {
num: 1 as number | bigint
num: 1 as number | bigint,
});

@@ -54,3 +51,3 @@

const objectBuffer = createObjectBuffer(externalArgs, 128, {
nullContainer: null as null | undefined
nullContainer: null as null | undefined,
});

@@ -83,3 +80,3 @@

const objectBuffer = createObjectBuffer(externalArgs, 128, {
booleanContainer: false
booleanContainer: false,
});

@@ -86,0 +83,0 @@

/* eslint-env jest */
import * as util from "util";

@@ -7,3 +6,3 @@ import {

getUnderlyingArrayBuffer,
loadObjectBuffer
loadObjectBuffer,
} from ".";

@@ -15,5 +14,3 @@ import { arrayBuffer2HexArray } from "./internal/testUtils";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -25,3 +22,3 @@

b: null,
c: { t: 5 }
c: { t: 5 },
});

@@ -43,5 +40,3 @@

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -51,3 +46,3 @@ test("getUnderlyingArrayBuffer simple", () => {

b: null,
c: { t: 5 }
c: { t: 5 },
});

@@ -66,5 +61,3 @@

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0
arrayAdditionalAllocation: 0,
});

@@ -76,3 +69,3 @@

b: null,
c: { t: 5 }
c: { t: 5 },
});

@@ -79,0 +72,0 @@

@@ -16,7 +16,6 @@ /**

replaceUnderlyingArrayBuffer,
// eslint-disable-next-line @typescript-eslint/camelcase
sizeOf as unreliable_sizeOf,
memoryStats,
disposeWrapperObject,
updateExternalArgs
updateExternalArgs,
} from "./internal/api";

@@ -23,0 +22,0 @@ export { acquireLock, acquireLockWait, releaseLock } from "./internal/locks";

import { initializeArrayBuffer } from "./store";
import { objectSaver } from "./objectSaver";
import { createObjectWrapper } from "./objectWrapper";
import { ExternalArgsApi, DataViewAndAllocatorCarrier } from "./interfaces";
import { ExternalArgsApi, GlobalCarrier } from "./interfaces";
import {
arrayBufferCopyTo,
externalArgsApiToExternalArgsApi,
getInternalAPI
getInternalAPI,
isPrimitive,
} from "./utils";

@@ -13,2 +13,6 @@ import { getCacheFor } from "./externalObjectsCache";

import { MemPool } from "@thi.ng/malloc";
import { UnsupportedOperationError } from "./exceptions";
import { createHeap } from "../structsGenerator/consts";
import { saveValueIterative } from "./saveValue";
import { allocationsTransaction } from "./allocationsTransaction";

@@ -36,14 +40,26 @@ export interface CreateObjectBufferOptions {

): T {
if (
Array.isArray(initialValue) ||
initialValue instanceof Date ||
initialValue instanceof Map ||
initialValue instanceof Set ||
isPrimitive(initialValue) ||
typeof initialValue === "symbol"
) {
throw new UnsupportedOperationError();
}
const arrayBuffer = new (options.useSharedArrayBuffer
? SharedArrayBuffer
: ArrayBuffer)(size);
const dataView = initializeArrayBuffer(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
align: 8,
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});
const carrier: DataViewAndAllocatorCarrier = {
dataView,
const carrier: GlobalCarrier = {
// dataView,
allocator,

@@ -54,18 +70,22 @@ uint8: new Uint8Array(arrayBuffer),

float64: new Float64Array(arrayBuffer),
bigUint64: new BigUint64Array(arrayBuffer)
bigUint64: new BigUint64Array(arrayBuffer),
heap: createHeap(arrayBuffer),
};
const start = objectSaver(
externalArgsApiToExternalArgsApi(externalArgs),
carrier,
[],
initialValue
);
allocationsTransaction(() => {
saveValueIterative(
externalArgsApiToExternalArgsApi(externalArgs),
carrier,
[],
INITIAL_ENTRY_POINTER_TO_POINTER,
initialValue
);
}, allocator);
dataView.setUint32(INITIAL_ENTRY_POINTER_TO_POINTER, start);
return createObjectWrapper(
externalArgsApiToExternalArgsApi(externalArgs),
carrier,
start
carrier.heap.Uint32Array[
INITIAL_ENTRY_POINTER_TO_POINTER / Uint32Array.BYTES_PER_ELEMENT
]
);

@@ -100,3 +120,3 @@ }

): ArrayBuffer | SharedArrayBuffer {
return getInternalAPI(objectBuffer).getCarrier().dataView.buffer;
return getInternalAPI(objectBuffer).getCarrier().uint8.buffer;
}

@@ -117,11 +137,12 @@

): T {
const dataView = new DataView(arrayBuffer);
// const dataView = new DataView(arrayBuffer);
const allocator = new MemPool({
align: 8,
buf: arrayBuffer,
start: MEM_POOL_START,
skipInitialization: true
skipInitialization: true,
});
const carrier: DataViewAndAllocatorCarrier = {
dataView,
const carrier: GlobalCarrier = {
// dataView,
allocator,

@@ -132,3 +153,4 @@ uint8: new Uint8Array(arrayBuffer),

float64: new Float64Array(arrayBuffer),
bigUint64: new BigUint64Array(arrayBuffer)
bigUint64: new BigUint64Array(arrayBuffer),
heap: createHeap(arrayBuffer),
};

@@ -139,3 +161,5 @@

carrier,
dataView.getUint32(INITIAL_ENTRY_POINTER_TO_POINTER)
carrier.uint32[
INITIAL_ENTRY_POINTER_TO_POINTER / Uint32Array.BYTES_PER_ELEMENT
]
);

@@ -169,9 +193,10 @@ }

const allocator = new MemPool({
align: 8,
buf: newArrayBuffer,
start: MEM_POOL_START,
skipInitialization: true
skipInitialization: true,
});
const carrier: DataViewAndAllocatorCarrier = {
dataView: new DataView(newArrayBuffer),
const carrier: GlobalCarrier = {
// dataView: new DataView(newArrayBuffer),
allocator,

@@ -182,7 +207,8 @@ uint8: new Uint8Array(newArrayBuffer),

float64: new Float64Array(newArrayBuffer),
bigUint64: new BigUint64Array(newArrayBuffer)
bigUint64: new BigUint64Array(newArrayBuffer),
heap: createHeap(newArrayBuffer),
};
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
allocator.end = newArrayBuffer.byteLength;

@@ -202,5 +228,6 @@

const pool = new MemPool({
align: 8,
buf,
skipInitialization: true,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -207,0 +234,0 @@

@@ -1,33 +0,23 @@

import {
readEntry,
writeEntry,
writeValueInPtrToPtrAndHandleMemory
} from "./store";
import {
ArrayEntry,
ExternalArgs,
DataViewAndAllocatorCarrier
} from "./interfaces";
import { writeValueInPtrToPtrAndHandleMemory } from "./store";
import { ExternalArgs, GlobalCarrier } from "./interfaces";
import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue";
import { ENTRY_TYPE } from "./entry-types";
import { assertNonNull } from "./assertNonNull";
import {
array_length_get,
array_dataspacePointer_get,
array_allocatedLength_get,
array_length_set,
array_set_all,
array_refsCount_get,
} from "./generatedStructs";
import { Heap } from "../structsGenerator/consts";
export function arrayGetMetadata(
carrier: DataViewAndAllocatorCarrier,
pointerToArrayEntry: number
) {
const arrayEntry = readEntry(carrier, pointerToArrayEntry) as ArrayEntry;
return arrayEntry;
}
export function arrayGetPointersToValueInIndex(
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
pointerToArrayEntry: number,
indexToGet: number
) {
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry);
// out of bound
if (indexToGet >= metadata.length) {
if (indexToGet >= array_length_get(carrier.heap, pointerToArrayEntry)) {
return undefined;

@@ -37,9 +27,11 @@ }

const pointerToThePointer =
metadata.value + indexToGet * Uint32Array.BYTES_PER_ELEMENT;
array_dataspacePointer_get(carrier.heap, pointerToArrayEntry) +
indexToGet * Uint32Array.BYTES_PER_ELEMENT;
const pointer = carrier.dataView.getUint32(pointerToThePointer);
const pointer =
carrier.uint32[pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT];
return {
pointer,
pointerToThePointer
pointerToThePointer,
};

@@ -50,3 +42,3 @@ }

externalArgs: ExternalArgs,
dataViewCarrier: DataViewAndAllocatorCarrier,
globalCarrier: GlobalCarrier,
pointerToArrayEntry: number,

@@ -56,3 +48,3 @@ indexToGet: number

const pointers = arrayGetPointersToValueInIndex(
dataViewCarrier,
globalCarrier,
pointerToArrayEntry,

@@ -68,3 +60,3 @@ indexToGet

externalArgs,
dataViewCarrier,
globalCarrier,
pointers.pointer

@@ -75,3 +67,3 @@ );

export function setValuePointerAtArrayIndex(
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
pointerToArrayEntry: number,

@@ -88,4 +80,5 @@ indexToSet: number,

assertNonNull(pointers);
carrier.dataView.setUint32(pointers.pointerToThePointer, pointerToEntry);
carrier.uint32[
pointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT
] = pointerToEntry;
}

@@ -95,3 +88,3 @@

externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
pointerToArrayEntry: number,

@@ -121,12 +114,12 @@ indexToSet: number,

externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
pointerToArrayEntry: number,
wishedLength: number
) {
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry);
if (wishedLength > metadata.length) {
if (wishedLength > metadata.allocatedLength) {
if (wishedLength > array_length_get(carrier.heap, pointerToArrayEntry)) {
if (
wishedLength >
array_allocatedLength_get(carrier.heap, pointerToArrayEntry)
) {
reallocateArray(
externalArgs,
carrier,

@@ -139,9 +132,3 @@ pointerToArrayEntry,

// no need to re-allocated, just push the length forward
writeEntry(carrier, pointerToArrayEntry, {
type: ENTRY_TYPE.ARRAY,
refsCount: metadata.refsCount,
value: metadata.value,
allocatedLength: metadata.allocatedLength,
length: wishedLength
});
array_length_set(carrier.heap, pointerToArrayEntry, wishedLength);
}

@@ -155,52 +142,29 @@ }

export function shrinkArray(
externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
heap: Heap,
pointerToArrayEntry: number,
wishedLength: number
) {
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry);
writeEntry(carrier, pointerToArrayEntry, {
type: ENTRY_TYPE.ARRAY,
refsCount: metadata.refsCount,
value: metadata.value,
allocatedLength: metadata.allocatedLength,
length: wishedLength
});
array_length_set(heap, pointerToArrayEntry, wishedLength);
}
function reallocateArray(
externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
pointerToArrayEntry: number,
newAllocatedLength: number,
newLength: number
) {
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry);
): void {
const newArrayValueLocation = carrier.allocator.realloc(
metadata.value,
array_dataspacePointer_get(carrier.heap, pointerToArrayEntry),
newAllocatedLength * Uint32Array.BYTES_PER_ELEMENT
);
// for (
// let memoryToCopyIndex = 0;
// memoryToCopyIndex < metadata.length;
// memoryToCopyIndex += 1
// ) {
// carrier.dataView.setUint32(
// newArrayValueLocation + memoryToCopyIndex * Uint32Array.BYTES_PER_ELEMENT,
// carrier.dataView.getUint32(
// metadata.value + memoryToCopyIndex * Uint32Array.BYTES_PER_ELEMENT
// )
// );
// }
writeEntry(carrier, pointerToArrayEntry, {
type: ENTRY_TYPE.ARRAY,
refsCount: metadata.refsCount,
value: newArrayValueLocation,
allocatedLength: newAllocatedLength,
length: newLength
});
array_set_all(
carrier.heap,
pointerToArrayEntry,
ENTRY_TYPE.ARRAY,
array_refsCount_get(carrier.heap, pointerToArrayEntry),
newArrayValueLocation,
newLength,
newAllocatedLength
);
}

@@ -210,17 +174,25 @@

externalArgs: ExternalArgs,
dataViewCarrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
pointerToArrayEntry: number,
sortComparator: (a: any, b: any) => 1 | -1 | 0 = defaultCompareFunction
) {
const metadata = arrayGetMetadata(dataViewCarrier, pointerToArrayEntry);
const pointersToValues = [...new Array(metadata.length).keys()]
.map(index => metadata.value + index * Uint32Array.BYTES_PER_ELEMENT)
.map(pointerToPointer =>
dataViewCarrier.dataView.getUint32(pointerToPointer)
const arrayDataSpace = array_dataspacePointer_get(
carrier.heap,
pointerToArrayEntry
);
const pointersToValues = [
...new Array(array_length_get(carrier.heap, pointerToArrayEntry)).keys(),
]
.map((index) => arrayDataSpace + index * Uint32Array.BYTES_PER_ELEMENT)
.map(
(pointerToPointer) =>
carrier.heap.Uint32Array[
pointerToPointer / Uint32Array.BYTES_PER_ELEMENT
]
);
const sortMe = pointersToValues.map(pointer => {
const sortMe = pointersToValues.map((pointer) => {
return [
pointer,
entryToFinalJavaScriptValue(externalArgs, dataViewCarrier, pointer)
entryToFinalJavaScriptValue(externalArgs, carrier, pointer),
] as const;

@@ -234,6 +206,6 @@ });

for (let i = 0; i < sortMe.length; i += 1) {
dataViewCarrier.dataView.setUint32(
metadata.value + i * Uint32Array.BYTES_PER_ELEMENT,
sortMe[i][0]
);
carrier.heap.Uint32Array[
(arrayDataSpace + i * Uint32Array.BYTES_PER_ELEMENT) /
Uint32Array.BYTES_PER_ELEMENT
] = sortMe[i][0];
}

@@ -280,11 +252,13 @@ }

export function arrayReverse(
externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
pointerToArrayEntry: number
) {
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry);
for (
let i = 0;
i < Math.floor(array_length_get(carrier.heap, pointerToArrayEntry) / 2);
i += 1
) {
const theOtherIndex =
array_length_get(carrier.heap, pointerToArrayEntry) - i - 1;
for (let i = 0; i < Math.floor(metadata.length / 2); i += 1) {
const theOtherIndex = metadata.length - i - 1;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion

@@ -291,0 +265,0 @@ const a = arrayGetPointersToValueInIndex(carrier, pointerToArrayEntry, i)!;

/* eslint-env jest */
import { initializeArrayBuffer } from "./store";
import * as util from "util";
import { createArrayWrapper } from "./arrayWrapper";
import { arraySaver } from "./arraySaver";
import { MemPool } from "@thi.ng/malloc";
import { MEM_POOL_START } from "./consts";
import { externalArgsApiToExternalArgsApi } from "./utils";
import { makeCarrier } from "./testUtils";
import { createObjectBuffer } from "..";
import { memoryStats } from "./api";
describe("arraySplice tests", () => {
const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
});
test("arrayWrapper splice - add + delete - array stay in same length", () => {
const arrayBuffer = new ArrayBuffer(512);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
const plainJSArray: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const ob = createObjectBuffer({ arrayAdditionalAllocation: 20 }, 1024, {
arr: plainJSArray,
});
const plainJSArray: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const arrayWrapper = ob.arr;
const saverOutput = arraySaver(externalArgs, carrier, [], plainJSArray);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
carrier,
saverOutput
);
const removed = arrayWrapper.splice(2, 3, "a", "b", "c");

@@ -88,25 +65,12 @@ const removedFromPlain = plainJSArray.splice(2, 3, "a", "b", "c");

expect(removedFromPlain).toEqual([...removed]);
expect(allocator.stats().available).toMatchInlineSnapshot(`32`);
});
test("arrayWrapper splice - Just delete items from the middle", () => {
const arrayBuffer = new ArrayBuffer(512);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
const plainJSArray: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const ob = createObjectBuffer({ arrayAdditionalAllocation: 20 }, 1024, {
arr: plainJSArray,
});
const plainJSArray: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const arrayWrapper = ob.arr;
const saverOutput = arraySaver(externalArgs, carrier, [], plainJSArray);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
carrier,
saverOutput
);
arrayWrapper.splice(2, 3);

@@ -139,25 +103,12 @@ plainJSArray.splice(2, 3);

expect(plainJSArray).toEqual([...arrayWrapper]);
expect(allocator.stats().available).toMatchInlineSnapshot(`80`);
});
test("arrayWrapper splice - Just add items in the middle", () => {
const arrayBuffer = new ArrayBuffer(512);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
const plainJSArray: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const ob = createObjectBuffer({ arrayAdditionalAllocation: 20 }, 1024, {
arr: plainJSArray,
});
const plainJSArray: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const arrayWrapper = ob.arr;
const saverOutput = arraySaver(externalArgs, carrier, [], plainJSArray);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
carrier,
saverOutput
);
arrayWrapper.splice(4, 0, "a", "b");

@@ -200,24 +151,12 @@ plainJSArray.splice(4, 0, "a", "b");

expect(plainJSArray).toEqual([...arrayWrapper]);
expect(allocator.stats().available).toMatchInlineSnapshot(`48`);
});
test("arrayWrapper splice - add + delete - array will get longer", () => {
const arrayBuffer = new ArrayBuffer(512);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
const plainJSArray: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const ob = createObjectBuffer({ arrayAdditionalAllocation: 3 }, 1024, {
arr: plainJSArray,
});
const plainJSArray: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const arrayWrapper = ob.arr;
const saverOutput = arraySaver(externalArgs, carrier, [], plainJSArray);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
carrier,
saverOutput
);
const removed = arrayWrapper.splice(2, 2, "a", "b", "c", "d");

@@ -277,25 +216,14 @@ const removedFromPlain = plainJSArray.splice(2, 2, "a", "b", "c", "d");

expect(removedFromPlain).toEqual([...removed]);
expect(allocator.stats().available).toMatchInlineSnapshot(`16`);
});
test("arrayWrapper splice - add + delete - array will get shorter", () => {
const arrayBuffer = new ArrayBuffer(512);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
const plainJSArray: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const ob = createObjectBuffer({ arrayAdditionalAllocation: 20 }, 1024, {
arr: plainJSArray,
});
const plainJSArray: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const availableCheckpoint = memoryStats(ob).available;
const saverOutput = arraySaver(externalArgs, carrier, [], plainJSArray);
const arrayWrapper = ob.arr;
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
carrier,
saverOutput
);
const removed = arrayWrapper.splice(2, 6, "a", "b", "c", "d");

@@ -357,24 +285,15 @@ const removedFromPlain = plainJSArray.splice(2, 6, "a", "b", "c", "d");

expect(allocator.stats().available).toMatchInlineSnapshot(`16`);
expect(
availableCheckpoint - memoryStats(ob).available
).toMatchInlineSnapshot(`96`);
});
test("arrayWrapper splice - start bigger than array", () => {
const arrayBuffer = new ArrayBuffer(512);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
const plainJSArray: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const ob = createObjectBuffer({ arrayAdditionalAllocation: 20 }, 1024, {
arr: plainJSArray,
});
const plainJSArray: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const arrayWrapper = ob.arr;
const saverOutput = arraySaver(externalArgs, carrier, [], plainJSArray);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
carrier,
saverOutput
);
const removed = arrayWrapper.splice(12, 3, "a", "b");

@@ -425,25 +344,12 @@ const removedFromPlain = plainJSArray.splice(12, 3, "a", "b");

expect(removedFromPlain).toEqual([...removed]);
expect(allocator.stats().available).toMatchInlineSnapshot(`48`);
});
test("arrayWrapper splice - delete bigger than array", () => {
const arrayBuffer = new ArrayBuffer(512);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
const plainJSArray: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const ob = createObjectBuffer({ arrayAdditionalAllocation: 20 }, 1024, {
arr: plainJSArray,
});
const plainJSArray: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const arrayWrapper = ob.arr;
const saverOutput = arraySaver(externalArgs, carrier, [], plainJSArray);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
carrier,
saverOutput
);
const removed = arrayWrapper.splice(2, 20, "a", "b");

@@ -500,25 +406,12 @@ const removedFromPlain = plainJSArray.splice(2, 20, "a", "b");

expect(removedFromPlain).toEqual([...removed]);
expect(allocator.stats().available).toMatchInlineSnapshot(`48`);
});
test("arrayWrapper splice - negative start", () => {
const arrayBuffer = new ArrayBuffer(512);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
const plainJSArray: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const ob = createObjectBuffer({ arrayAdditionalAllocation: 20 }, 1024, {
arr: plainJSArray,
});
const plainJSArray: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const arrayWrapper = ob.arr;
const saverOutput = arraySaver(externalArgs, carrier, [], plainJSArray);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
carrier,
saverOutput
);
const removed = arrayWrapper.splice(-4, 1, "a", "b");

@@ -575,25 +468,12 @@ const removedFromPlain = plainJSArray.splice(-4, 1, "a", "b");

expect(removedFromPlain).toEqual([...removed]);
expect(allocator.stats().available).toMatchInlineSnapshot(`48`);
});
test("arrayWrapper splice - negative delete", () => {
const arrayBuffer = new ArrayBuffer(512);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
const plainJSArray: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const ob = createObjectBuffer({ arrayAdditionalAllocation: 3 }, 1024, {
arr: plainJSArray,
});
const plainJSArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const arrayWrapper = ob.arr;
const saverOutput = arraySaver(externalArgs, carrier, [], plainJSArray);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
carrier,
saverOutput
);
const removed = arrayWrapper.splice(4, -1, 50, 51);

@@ -644,5 +524,3 @@ const removedFromPlain = plainJSArray.splice(4, -1, 50, 51);

expect(removedFromPlain).toEqual([...removed]);
expect(allocator.stats().available).toMatchInlineSnapshot(`32`);
});
});
import {
arrayGetMetadata,
getFinalValueAtArrayIndex,

@@ -7,7 +6,8 @@ shrinkArray,

arrayGetPointersToValueInIndex,
setValuePointerAtArrayIndex
setValuePointerAtArrayIndex,
} from "./arrayHelpers";
import { assertNonNull } from "./assertNonNull";
import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces";
import { writeValueInPtrToPtr } from "./store";
import { ExternalArgs, GlobalCarrier } from "./interfaces";
import { writeValueInPtrToPtr, handleArcForDeletedValuePointer } from "./store";
import { array_length_get } from "./generatedStructs";

@@ -17,3 +17,3 @@ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice#Syntax

externalArgs: ExternalArgs,
dataViewCarrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
pointerToArrayEntry: number,

@@ -24,8 +24,8 @@ startArg: number,

) {
const metadata = arrayGetMetadata(dataViewCarrier, pointerToArrayEntry);
const arrayLength = array_length_get(carrier.heap, pointerToArrayEntry);
const calcedStart = calculateSpliceStart(metadata.length, startArg);
const calcedStart = calculateSpliceStart(arrayLength, startArg);
const calcedDeleteCount = calculateDeleteCount(
metadata.length,
arrayLength,
calcedStart,

@@ -35,14 +35,9 @@ deleteCountArg

const newLength = metadata.length + itemsToAddArg.length - calcedDeleteCount;
const newLength = arrayLength + itemsToAddArg.length - calcedDeleteCount;
extendArrayIfNeeded(
externalArgs,
dataViewCarrier,
pointerToArrayEntry,
newLength
);
extendArrayIfNeeded(externalArgs, carrier, pointerToArrayEntry, newLength);
const deletedItemsToReturn = [];
// can be negative
const itemCountChange = newLength - metadata.length;
const itemCountChange = newLength - arrayLength;

@@ -57,3 +52,3 @@ for (

externalArgs,
dataViewCarrier,
carrier,
pointerToArrayEntry,

@@ -78,3 +73,3 @@ deletedItemIndexToSave

const valueToCopyPointers = arrayGetPointersToValueInIndex(
dataViewCarrier,
carrier,
pointerToArrayEntry,

@@ -87,3 +82,3 @@ writeValueToIndex - itemCountChange

setValuePointerAtArrayIndex(
dataViewCarrier,
carrier,
pointerToArrayEntry,

@@ -94,6 +89,5 @@ writeValueToIndex,

dataViewCarrier.dataView.setUint32(
valueToCopyPointers.pointerToThePointer,
0
);
carrier.heap.Uint32Array[
valueToCopyPointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT
] = 0;
}

@@ -110,15 +104,16 @@ }

let writeValueToIndex = calcedStart + itemsToAddArg.length;
writeValueToIndex < metadata.length + itemCountChange;
writeValueToIndex < arrayLength + itemCountChange;
writeValueToIndex += 1
) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const valueToCopyPointers = arrayGetPointersToValueInIndex(
dataViewCarrier,
carrier,
pointerToArrayEntry,
writeValueToIndex - itemCountChange
);
)!;
assertNonNull(valueToCopyPointers);
// assertNonNull(valueToCopyPointers);
setValuePointerAtArrayIndex(
dataViewCarrier,
carrier,
pointerToArrayEntry,

@@ -130,6 +125,4 @@ writeValueToIndex,

// empty old array index, its still allocated!
dataViewCarrier.dataView.setUint32(
valueToCopyPointers.pointerToThePointer,
0
);
// handleArcForDeletedValuePointer(carrier, valueToCopyPointers.pointer);
carrier.heap.Uint32Array[valueToCopyPointers.pointer] = 0;

@@ -151,3 +144,3 @@ // using that is wastefull

const valueToSetPointers = arrayGetPointersToValueInIndex(
dataViewCarrier,
carrier,
pointerToArrayEntry,

@@ -161,3 +154,3 @@ calcedStart + i

externalArgs,
dataViewCarrier,
carrier,
valueToSetPointers.pointerToThePointer,

@@ -168,4 +161,4 @@ itemsToAddArg[i]

if (newLength < metadata.length) {
shrinkArray(externalArgs, dataViewCarrier, pointerToArrayEntry, newLength);
if (newLength < arrayLength) {
shrinkArray(carrier.heap, pointerToArrayEntry, newLength);
}

@@ -172,0 +165,0 @@

/* eslint-env jest */
import { initializeArrayBuffer } from "./store";
import * as util from "util";
import { createArrayWrapper } from "./arrayWrapper";
import { arraySaver } from "./arraySaver";
import { MemPool } from "@thi.ng/malloc";
import { MEM_POOL_START } from "./consts";
import { externalArgsApiToExternalArgsApi } from "./utils";
import { makeCarrier } from "./testUtils";
import { createObjectBuffer, memoryStats } from "./api";
describe("arrayWrapper tests", () => {
const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
});
describe("arrayWrapper - general", () => {
test("arrayWrapper class 1", () => {
const arrayBuffer = new ArrayBuffer(256);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const arrayToSave = ["a", "b", 1];
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper = createObjectBuffer(
{ arrayAdditionalAllocation: 20 },
512,
{ arrayToSave }
).arrayToSave;
const arrayWrapper: any = createArrayWrapper(
externalArgs,
carrier,
saverOutput
);
expect(arrayWrapper).toMatchInlineSnapshot(`

@@ -47,46 +24,28 @@ Array [

expect(allocator.stats().available).toMatchInlineSnapshot(`32`);
expect(memoryStats(arrayWrapper).available).toMatchInlineSnapshot(`24`);
});
test("arrayWrapper array.keys()", () => {
const arrayBuffer = new ArrayBuffer(256);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const arrayToSave = ["a", "b", 1];
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper = createObjectBuffer(
{ arrayAdditionalAllocation: 20 },
512,
{ arrayToSave }
).arrayToSave;
const arrayWrapper = createArrayWrapper(
externalArgs,
carrier,
saverOutput
);
expect([...arrayWrapper.keys()]).toEqual([0, 1, 2]);
expect(allocator.stats().available).toMatchInlineSnapshot(`32`);
expect(memoryStats(arrayWrapper).available).toMatchInlineSnapshot(`24`);
});
test("arrayWrapper array.entries()", () => {
const arrayBuffer = new ArrayBuffer(256);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const arrayToSave = ["a", "b", 1];
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper = createObjectBuffer(
{ arrayAdditionalAllocation: 20 },
512,
{ arrayToSave }
).arrayToSave;
const arrayWrapper = createArrayWrapper(
externalArgs,
carrier,
saverOutput
);
expect([...arrayWrapper.entries()]).toMatchInlineSnapshot(`

@@ -109,23 +68,14 @@ Array [

expect(allocator.stats().available).toMatchInlineSnapshot(`32`);
expect(memoryStats(arrayWrapper).available).toMatchInlineSnapshot(`24`);
});
test("arrayWrapper array.values() & iterator", () => {
const arrayBuffer = new ArrayBuffer(256);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const arrayToSave = ["a", "b", 1];
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper = createObjectBuffer(
{ arrayAdditionalAllocation: 20 },
512,
{ arrayToSave }
).arrayToSave;
const arrayWrapper = createArrayWrapper(
externalArgs,
carrier,
saverOutput
);
expect([...arrayWrapper.values()]).toMatchInlineSnapshot(`

@@ -146,19 +96,14 @@ Array [

expect(allocator.stats().available).toMatchInlineSnapshot(`32`);
expect(memoryStats(arrayWrapper).available).toMatchInlineSnapshot(`24`);
});
test("arrayWrapper set value in bound", () => {
const arrayBuffer = new ArrayBuffer(256);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const arrayToSave = ["a", "b", 1];
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper = createObjectBuffer(
{ arrayAdditionalAllocation: 20 },
1024,
{ arrayToSave }
).arrayToSave;
const arrayWrapper: any = createArrayWrapper(
externalArgs,
carrier,
saverOutput
);
arrayWrapper[1] = "new value";

@@ -176,20 +121,10 @@

test("arrayWrapper set value out of bound, but inside allocated space", () => {
const arrayBuffer = new ArrayBuffer(256);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const arrayToSave = ["a", "b", 1];
const saverOutput = arraySaver(
{ ...externalArgs, arrayAdditionalAllocation: 15 },
carrier,
[],
arrayToSave
);
const arrayWrapper = createObjectBuffer(
{ arrayAdditionalAllocation: 15 },
512,
{ arrayToSave }
).arrayToSave;
const arrayWrapper: any = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 15 },
carrier,
saverOutput
);
arrayWrapper[10] = "new value";

@@ -215,19 +150,10 @@

test("arrayWrapper set value out of bound, but outside allocated space", () => {
const arrayBuffer = new ArrayBuffer(256);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const arrayToSave = ["a", "b", 1];
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper = createObjectBuffer(
{ arrayAdditionalAllocation: 3 },
1024,
{ arrayToSave }
).arrayToSave;
const arrayWrapper: any = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
carrier,
saverOutput
);
arrayWrapper[10] = "new value";

@@ -250,3 +176,3 @@

`);
expect(allocator.stats().available).toMatchInlineSnapshot(`8`);
expect(memoryStats(arrayWrapper).available).toMatchInlineSnapshot(`496`);
});

@@ -256,20 +182,10 @@ });

test("arrayWrapper sort - no comparator", () => {
const arrayBuffer = new ArrayBuffer(512);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const arrayToSave = [2, 1, null, 3, 10, undefined, 6, 77];
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper = createObjectBuffer(
{ arrayAdditionalAllocation: 3 },
512,
{ arrayToSave }
).arrayToSave;
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
carrier,
saverOutput
);
arrayWrapper.sort();

@@ -290,26 +206,16 @@

expect(allocator.stats().available).toMatchInlineSnapshot(`184`);
expect(memoryStats(arrayWrapper).available).toMatchInlineSnapshot(`32`);
});
test("arrayWrapper sort - with comparator", () => {
const arrayBuffer = new ArrayBuffer(2048);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const arrayToSave = [2, 1, 3, 10, 6, 77].map(value => ({
value
const arrayToSave = [2, 1, 3, 10, 6, 77].map((value) => ({
value,
}));
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper = createObjectBuffer(
{ arrayAdditionalAllocation: 3 },
1024 * 2,
{ arrayToSave }
).arrayToSave;
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
carrier,
saverOutput
);
arrayWrapper.sort((a, b) => {

@@ -348,24 +254,14 @@ if (a.value > b.value) {

expect(allocator.stats().available).toMatchInlineSnapshot(`672`);
expect(memoryStats(arrayWrapper).available).toMatchInlineSnapshot(`376`);
});
test("arrayWrapper - reverse", () => {
const arrayBuffer = new ArrayBuffer(512);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const arrayToSave = [1, 2, 3, 4, 5, 6, 7];
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper = createObjectBuffer(
{ arrayAdditionalAllocation: 3 },
512,
{ arrayToSave }
).arrayToSave;
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
carrier,
saverOutput
);
arrayWrapper.reverse();

@@ -389,24 +285,14 @@ arrayWrapper.reverse();

expect(allocator.stats().available).toMatchInlineSnapshot(`160`);
expect(memoryStats(arrayWrapper).available).toMatchInlineSnapshot(`16`);
});
test("arrayWrapper - set length", () => {
const arrayBuffer = new ArrayBuffer(512);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const arrayToSave = [1, 2, 3, 4, 5, 6, 7];
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper = createObjectBuffer(
{ arrayAdditionalAllocation: 3 },
512,
{ arrayToSave }
).arrayToSave;
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
carrier,
saverOutput
);
arrayWrapper.length = 10;

@@ -447,4 +333,4 @@ expect(arrayWrapper).toMatchInlineSnapshot(`

expect(allocator.stats().available).toMatchInlineSnapshot(`160`);
expect(memoryStats(arrayWrapper).available).toMatchInlineSnapshot(`16`);
});
});
import {
getFinalValueAtArrayIndex,
arrayGetMetadata,
setValueAtArrayIndex,
arraySort,
extendArrayIfNeeded,
arrayReverse
arrayReverse,
} from "./arrayHelpers";
import { INTERNAL_API_SYMBOL } from "./symbols";
import { arraySplice } from "./arraySplice";
import { ExternalArgs, GlobalCarrier } from "./interfaces";
import {
ExternalArgs,
DataViewAndAllocatorCarrier,
ArrayEntry
} from "./interfaces";
import {
IllegalArrayIndexError,
UnsupportedOperationError
UnsupportedOperationError,
} from "./exceptions";
import { allocationsTransaction } from "./allocationsTransaction";
import { BaseProxyTrap } from "./BaseProxyTrap";
import { array_length_get } from "./generatedStructs";
export class ArrayWrapper extends BaseProxyTrap<ArrayEntry>
implements ProxyHandler<{}> {
public get(target: {}, p: PropertyKey): any {
export class ArrayWrapper extends BaseProxyTrap
implements ProxyHandler<Record<string, unknown>> {
public get(target: Record<string, unknown>, p: PropertyKey): any {
if (p === INTERNAL_API_SYMBOL) {

@@ -31,4 +27,4 @@ return this;

if (p in this && p !== "constructor") {
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
return this[p];

@@ -38,3 +34,3 @@ }

if (p === "length") {
return arrayGetMetadata(this.carrier, this.entryPointer).length;
return array_length_get(this.carrier.heap, this.entryPointer);
}

@@ -55,8 +51,11 @@

// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
return target[p];
}
public deleteProperty(target: {}, p: PropertyKey): boolean {
public deleteProperty(
target: Record<string, unknown>,
p: PropertyKey
): boolean {
const index = typeof p === "number" ? p : Number.parseInt(p as string, 10);

@@ -72,3 +71,3 @@

public ownKeys(): PropertyKey[] {
const length = arrayGetMetadata(this.carrier, this.entryPointer).length;
const length = array_length_get(this.carrier.heap, this.entryPointer);

@@ -78,3 +77,3 @@ return [...new Array(length).keys(), "length"];

public getOwnPropertyDescriptor(target: {}, prop: any) {
public getOwnPropertyDescriptor(target: Record<string, unknown>, prop: any) {
if (prop === "length") {

@@ -91,3 +90,3 @@ return { configurable: false, enumerable: false, writable: true };

public has(target: {}, p: PropertyKey): boolean {
public has(target: Record<string, unknown>, p: PropertyKey): boolean {
if (p === INTERNAL_API_SYMBOL) {

@@ -97,3 +96,3 @@ return true;

const length = arrayGetMetadata(this.carrier, this.entryPointer).length;
const length = array_length_get(this.carrier.heap, this.entryPointer);

@@ -109,3 +108,7 @@ if (typeof p === "number") {

public set(target: {}, accessedProp: PropertyKey, value: any): boolean {
public set(
target: Record<string, unknown>,
accessedProp: PropertyKey,
value: any
): boolean {
if (typeof accessedProp === "symbol") {

@@ -120,4 +123,6 @@ throw new IllegalArrayIndexError();

const currentLength = arrayGetMetadata(this.carrier, this.entryPointer)
.length;
const currentLength = array_length_get(
this.carrier.heap,
this.entryPointer
);

@@ -184,3 +189,3 @@ if (currentLength === value) {

index
)
),
];

@@ -190,3 +195,3 @@

length = arrayGetMetadata(this.carrier, this.entryPointer).length;
length = array_length_get(this.carrier.heap, this.entryPointer);
} while (index < length);

@@ -204,3 +209,3 @@ }

length = arrayGetMetadata(this.carrier, this.entryPointer).length;
length = array_length_get(this.carrier.heap, this.entryPointer);
} while (index < length);

@@ -223,3 +228,3 @@ }

length = arrayGetMetadata(this.carrier, this.entryPointer).length;
length = array_length_get(this.carrier.heap, this.entryPointer);
} while (index < length);

@@ -248,3 +253,3 @@ }

public reverse() {
arrayReverse(this.externalArgs, this.carrier, this.entryPointer);
arrayReverse(this.carrier, this.entryPointer);
return this;

@@ -266,8 +271,8 @@ }

return arrayGetMetadata(this.carrier, this.entryPointer).length;
return array_length_get(this.carrier.heap, this.entryPointer);
}
public getDataView() {
return this.carrier.dataView;
}
// public getDataView() {
// return this.carrier.dataView;
// }

@@ -290,3 +295,3 @@ public getEntryPointer() {

public defineProperty(): // target: {},
public defineProperty(): // target: Record<string, unknown>,
// p: PropertyKey,

@@ -311,9 +316,11 @@ // attributes: PropertyDescriptor

externalArgs: ExternalArgs,
dataViewCarrier: DataViewAndAllocatorCarrier,
globalCarrier: GlobalCarrier,
entryPointer: number
): Array<any> {
return new Proxy(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
[],
new ArrayWrapper(externalArgs, dataViewCarrier, entryPointer)
new ArrayWrapper(externalArgs, globalCarrier, entryPointer)
) as any;
}

@@ -1,32 +0,16 @@

import {
ExternalArgs,
DataViewAndAllocatorCarrier,
InternalAPI,
DateEntry,
ArrayEntry,
ObjectEntry,
MapEntry,
SetEntry
} from "./interfaces";
import { IMemPool } from "@thi.ng/malloc";
import { incrementRefCount, decrementRefCount, readEntry } from "./store";
import { ExternalArgs, GlobalCarrier, InternalAPI } from "./interfaces";
import { incrementRefCount, decrementRefCount } from "./store";
import { WrapperDestroyed } from "./exceptions";
export class BaseProxyTrap<
T extends ObjectEntry | DateEntry | ArrayEntry | MapEntry | SetEntry
> implements InternalAPI {
export abstract class BaseProxyTrap implements InternalAPI {
constructor(
protected externalArgs: ExternalArgs,
protected carrier: DataViewAndAllocatorCarrier,
protected carrier: GlobalCarrier,
protected _entryPointer: number
) {
incrementRefCount(this.externalArgs, this.carrier, this.entryPointer);
incrementRefCount(this.carrier.heap, this.entryPointer);
}
public destroy() {
const newRefCount = decrementRefCount(
this.externalArgs,
this.carrier,
this.entryPointer
);
const newRefCount = decrementRefCount(this.carrier.heap, this.entryPointer);
this._entryPointer = 0;

@@ -41,3 +25,3 @@

public replaceCarrierContent(newCarrierContent: DataViewAndAllocatorCarrier) {
public replaceCarrierContent(newCarrierContent: GlobalCarrier) {
Object.assign(this.carrier, newCarrierContent);

@@ -61,6 +45,2 @@ }

}
protected get entry(): T {
return readEntry(this.carrier, this.entryPointer) as T;
}
}

@@ -15,1 +15,2 @@ export const LOCK_OFFSET = 0;

export const FALSE_KNOWN_ADDRESS = 3;
export const MAX_64_BIG_INT = BigInt("0xFFFFFFFFFFFFFFFF");

@@ -1,8 +0,3 @@

import {
ExternalArgs,
DataViewAndAllocatorCarrier,
DateEntry
} from "./interfaces";
import { ExternalArgs, GlobalCarrier } from "./interfaces";
import { readEntry, writeEntry } from "./store";
import { ENTRY_TYPE } from "./entry-types";

@@ -12,2 +7,7 @@ import { INTERNAL_API_SYMBOL } from "./symbols";

import { BaseProxyTrap } from "./BaseProxyTrap";
import {
date_set_all,
date_refsCount_get,
date_timestamp_get,
} from "./generatedStructs";

@@ -43,3 +43,3 @@ const getFunctions: Array<keyof Date> = [

"toLocaleDateString",
"toLocaleTimeString"
"toLocaleTimeString",
];

@@ -63,8 +63,7 @@

"setUTCMonth",
"setUTCSeconds"
"setUTCSeconds",
// "setYear"
];
export class DateWrapper extends BaseProxyTrap<DateEntry>
implements ProxyHandler<Date> {
export class DateWrapper extends BaseProxyTrap implements ProxyHandler<Date> {
private dateObjectForReuse: Date;

@@ -75,3 +74,3 @@ private useMeToGiveNamesToFunctionsAndCacheThem: any;

externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
entryPointer: number

@@ -115,13 +114,17 @@ ) {

private updateDateObjectForReuse() {
const entry = readEntry(this.carrier, this.entryPointer) as DateEntry;
this.dateObjectForReuse.setTime(entry.value);
this.dateObjectForReuse.setTime(
date_timestamp_get(this.carrier.heap, this.entryPointer)
);
}
private persistDateObject() {
writeEntry(this.carrier, this.entryPointer, {
type: ENTRY_TYPE.DATE,
refsCount: this.entry.refsCount,
value: this.dateObjectForReuse.getTime()
});
date_set_all(
this.carrier.heap,
this.entryPointer,
ENTRY_TYPE.DATE,
date_refsCount_get(this.carrier.heap, this.entryPointer),
// padding
0,
this.dateObjectForReuse.getTime()
);
}

@@ -144,3 +147,3 @@

externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
entryPointer: number

@@ -147,0 +150,0 @@ ): Date {

@@ -1,2 +0,1 @@

import * as util from "util";
import { createObjectBuffer } from "..";

@@ -9,5 +8,3 @@ import { externalArgsApiToExternalArgsApi } from "./utils";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});

@@ -19,3 +16,3 @@

array: [1],
object: {}
object: {},
});

@@ -35,3 +32,3 @@

Object.defineProperty(objectBuffer.date, "propy", {
enumerable: true
enumerable: true,
});

@@ -59,3 +56,3 @@ }).toThrowErrorMatchingInlineSnapshot(`"UnsupportedOperationError"`);

array: [1],
object: {}
object: {},
});

@@ -92,3 +89,3 @@

array: [1],
object: {}
object: {},
});

@@ -99,3 +96,3 @@

configurable: false,
enumerable: false
enumerable: false,
});

@@ -102,0 +99,0 @@ }).toThrowErrorMatchingInlineSnapshot(`"UnsupportedOperationError"`);

@@ -25,12 +25,10 @@ import { getInternalAPI } from "./utils";

const { allocator, heap } = internalApi.getCarrier();
for (const address of addressesToFree.leafAddresses) {
internalApi.getCarrier().allocator.free(address);
allocator.free(address);
}
for (const address of addressesToFree.arcAddresses) {
decrementRefCount(
internalApi.getExternalArgs(),
internalApi.getCarrier(),
address
);
decrementRefCount(heap, address);
}

@@ -37,0 +35,0 @@

@@ -29,3 +29,3 @@ import { createKnownTypeGuard } from "./utils";

SET,
DATE
DATE,
}

@@ -37,5 +37,5 @@

ENTRY_TYPE.BIGINT_NEGATIVE,
ENTRY_TYPE.STRING
ENTRY_TYPE.STRING,
] as const;
export const isPrimitiveEntryType = createKnownTypeGuard(PRIMITIVE_TYPES);

@@ -1,3 +0,3 @@

import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces";
import { ENTRY_TYPE, isPrimitiveEntryType } from "./entry-types";
import { ExternalArgs, GlobalCarrier } from "./interfaces";
import { ENTRY_TYPE } from "./entry-types";
import { createObjectWrapper } from "./objectWrapper";

@@ -7,3 +7,3 @@ import { createArrayWrapper } from "./arrayWrapper";

import { getCacheFor } from "./externalObjectsCache";
import { decrementRefCount, readEntry } from "./store";
import { decrementRefCount } from "./store";
import { getAllLinkedAddresses } from "./getAllLinkedAddresses";

@@ -16,8 +16,11 @@ import { createMapWrapper } from "./mapWrapper";

TRUE_KNOWN_ADDRESS,
FALSE_KNOWN_ADDRESS
FALSE_KNOWN_ADDRESS,
} from "./consts";
import {
typeOnly_type_get,
number_value_get,
bigint_value_get,
} from "./generatedStructs";
import { readString } from "./readString";
// declare const FinalizationGroup: any;
// declare const WeakRef: any;
const TYPE_TO_FACTORY = {

@@ -28,3 +31,3 @@ [ENTRY_TYPE.OBJECT]: createObjectWrapper,

[ENTRY_TYPE.MAP]: createMapWrapper,
[ENTRY_TYPE.SET]: createSetWrapper
[ENTRY_TYPE.SET]: createSetWrapper,
} as const;

@@ -34,3 +37,3 @@

externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
pointerToEntry: number

@@ -54,44 +57,53 @@ ) {

const valueEntry = readEntry(carrier, pointerToEntry);
const entryType: ENTRY_TYPE = typeOnly_type_get(carrier.heap, pointerToEntry);
if (isPrimitiveEntryType(valueEntry.type)) {
return valueEntry.value;
switch (entryType) {
case ENTRY_TYPE.NUMBER:
return number_value_get(carrier.heap, pointerToEntry);
break;
case ENTRY_TYPE.STRING:
return readString(carrier.heap, pointerToEntry);
break;
case ENTRY_TYPE.BIGINT_POSITIVE:
return bigint_value_get(carrier.heap, pointerToEntry);
break;
case ENTRY_TYPE.BIGINT_NEGATIVE:
return bigint_value_get(carrier.heap, pointerToEntry) * BigInt("-1");
break;
}
// this is an invariant
if (
valueEntry.type === ENTRY_TYPE.OBJECT ||
valueEntry.type === ENTRY_TYPE.DATE ||
valueEntry.type === ENTRY_TYPE.ARRAY ||
valueEntry.type === ENTRY_TYPE.MAP ||
valueEntry.type === ENTRY_TYPE.SET
!(
entryType === ENTRY_TYPE.OBJECT ||
entryType === ENTRY_TYPE.DATE ||
entryType === ENTRY_TYPE.ARRAY ||
entryType === ENTRY_TYPE.MAP ||
entryType === ENTRY_TYPE.SET
)
) {
const cache = getCacheFor(carrier, key => {
finalizer(key, carrier, externalArgs);
});
throw new Error("Nope Nope Nope");
}
let ret = cache.get(pointerToEntry);
const cache = getCacheFor(carrier, (key) => {
finalizer(key, carrier);
});
if (!ret) {
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
ret = TYPE_TO_FACTORY[valueEntry.type](
externalArgs,
carrier,
pointerToEntry
);
cache.set(pointerToEntry, ret);
}
let ret = cache.get(pointerToEntry);
return ret;
if (!ret) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
ret = TYPE_TO_FACTORY[entryType](externalArgs, carrier, pointerToEntry);
cache.set(pointerToEntry, ret);
}
throw new Error("unsupported yet");
return ret;
}
function finalizer(
memoryAddress: number,
carrier: DataViewAndAllocatorCarrier,
externalArgs: ExternalArgs
) {
const newRefsCount = decrementRefCount(externalArgs, carrier, memoryAddress);
function finalizer(memoryAddress: number, carrier: GlobalCarrier) {
const newRefsCount = decrementRefCount(carrier.heap, memoryAddress);

@@ -106,5 +118,5 @@ if (newRefsCount === 0) {

for (const address of freeUs.arcAddresses) {
decrementRefCount(externalArgs, carrier, address);
decrementRefCount(carrier.heap, address);
}
}
}
import { WeakValueMap } from "./WeakValueMap";
// eslint-disable-next-line @typescript-eslint/ban-types
const externalObjectsCache = new WeakMap<object, Map<number, any>>();

@@ -9,2 +10,3 @@

export function getCacheFor(
// eslint-disable-next-line @typescript-eslint/ban-types
obj: object,

@@ -27,3 +29,7 @@ externalFinalizer?: (key: number) => void

function supportWeakRef() {
return typeof WeakRef !== "undefined";
return (
typeof WeakRef !== "undefined" &&
(typeof FinalizationGroup !== "undefined" ||
typeof "FinalizationRegistry" !== "undefined")
);
}
/* eslint-env jest */
import * as util from "util";
import { MemPool } from "@thi.ng/malloc";

@@ -11,9 +10,7 @@ import { createObjectBuffer, memoryStats } from "./api";

const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});
describe("getAllLinkedAddresses no reference counting", () => {
test("getAllLinkedAddresses", () => {
describe("Make sure all allocated are discovered", () => {
test("Small object", () => {
const allocatedAddresses: number[] = [];

@@ -30,12 +27,44 @@ const origMalloc = MemPool.prototype.malloc;

const objectBuffer = createObjectBuffer(externalArgs, 2048, {
nestedObject: { a: 1, b: null, c: "string", bigint: BigInt("100") },
arr: [new Date(0), "somestring", { a: "6", h: null }]
smallObject: [{ a: "6" }],
});
// const a = objectBuffer.nestedObject;
// getInternalAPI(a).destroy();
// // a.toString();
const carrier = getInternalAPI(objectBuffer).getCarrier();
const entryPointer = getInternalAPI(objectBuffer).getEntryPointer();
getInternalAPI(objectBuffer).destroy();
const linkedAddresses = getAllLinkedAddresses(
carrier,
false,
// allocatedAddresses[allocatedAddresses.length - 1]
entryPointer
);
expect([...linkedAddresses.leafAddresses].slice().sort()).toEqual(
allocatedAddresses.slice().sort()
);
});
test("With Map & Set", () => {
const allocatedAddresses: number[] = [];
const origMalloc = MemPool.prototype.malloc;
MemPool.prototype.malloc = function malloc(dataSize: number) {
const address = origMalloc.call(this, dataSize);
allocatedAddresses.push(address);
return address;
};
const objectBuffer = createObjectBuffer(externalArgs, 2048, {
m: new Map([
["a", 1],
["b", 2],
]),
s: new Set(["a", "b", "c"]),
});
const carrier = getInternalAPI(objectBuffer).getCarrier();
const entryPointer = getInternalAPI(objectBuffer).getEntryPointer();
getInternalAPI(objectBuffer).destroy();

@@ -46,61 +75,40 @@

false,
allocatedAddresses[allocatedAddresses.length - 1]
entryPointer
);
expect(linkedAddresses.leafAddresses.slice().sort()).toEqual(
expect([...linkedAddresses.leafAddresses].slice().sort()).toEqual(
allocatedAddresses.slice().sort()
);
});
expect(linkedAddresses.leafAddresses.slice().sort())
.toMatchInlineSnapshot(`
Array [
1008,
1032,
1048,
1064,
1080,
1104,
112,
128,
144,
168,
200,
216,
240,
280,
296,
312,
336,
352,
368,
392,
416,
432,
448,
472,
48,
488,
504,
528,
552,
576,
592,
616,
632,
656,
672,
688,
72,
792,
816,
840,
864,
904,
920,
936,
960,
976,
992,
]
`);
test("object with more stuff", () => {
const allocatedAddresses: number[] = [];
const origMalloc = MemPool.prototype.malloc;
MemPool.prototype.malloc = function malloc(dataSize: number) {
const address = origMalloc.call(this, dataSize);
allocatedAddresses.push(address);
return address;
};
const objectBuffer = createObjectBuffer(externalArgs, 2048, {
nestedObject: { a: 1, b: null, c: "string", bigint: BigInt("100") },
arr: [new Date(0), "somestring", { a: "6", h: null }],
});
const carrier = getInternalAPI(objectBuffer).getCarrier();
const entryPointer = getInternalAPI(objectBuffer).getEntryPointer();
getInternalAPI(objectBuffer).destroy();
const linkedAddresses = getAllLinkedAddresses(
carrier,
false,
entryPointer
);
expect([...linkedAddresses.leafAddresses].slice().sort()).toEqual(
allocatedAddresses.slice().sort()
);
});

@@ -123,3 +131,3 @@

nestedObject: { a: 1, b: null, c: "string", bigint: BigInt("100") },
arr: [new Date(0), "somestring", { a: "6", h: null }]
arr: [new Date(0), "somestring", { a: "6", h: null }],
});

@@ -129,7 +137,8 @@

Object {
"available": 936,
"used": 1112,
"available": 656,
"used": 1392,
}
`);
const entryPointer = getInternalAPI(objectBuffer).getEntryPointer();
const carrier = getInternalAPI(objectBuffer).getCarrier();

@@ -142,6 +151,6 @@

false,
allocatedAddresses[allocatedAddresses.length - 1]
entryPointer
);
linkedAddresses.leafAddresses.forEach(address => {
linkedAddresses.leafAddresses.forEach((address) => {
pool.free(address);

@@ -148,0 +157,0 @@ });

@@ -1,28 +0,48 @@

import { readEntry } from "./store";
import { DataViewAndAllocatorCarrier } from "./interfaces";
import { GlobalCarrier } from "./interfaces";
import { ENTRY_TYPE } from "./entry-types";
import { hashMapGetPointersToFree } from "./hashmap/hashmap";
import { isKnownAddressValuePointer } from "./utils";
import {
UNDEFINED_KNOWN_ADDRESS,
NULL_KNOWN_ADDRESS,
TRUE_KNOWN_ADDRESS,
FALSE_KNOWN_ADDRESS
} from "./consts";
typeOnly_type_get,
string_charsPointer_get,
typeAndRc_refsCount_get,
object_pointerToHashMap_get,
array_dataspacePointer_get,
array_length_get,
} from "./generatedStructs";
export function getAllLinkedAddresses(
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
ignoreRefCount: boolean,
entryPointer: number
) {
const leafAddresses: number[] = [];
const arcAddresses: number[] = [];
const leafAddresses: Set<number> = new Set<number>();
const arcAddresses: Set<number> = new Set<number>();
const addressesToProcessQueue: number[] = [entryPointer];
getAllLinkedAddressesStep(
carrier,
ignoreRefCount,
entryPointer,
leafAddresses,
arcAddresses
);
let addressToProcess: number | undefined = undefined;
// const diffs = [];
while ((addressToProcess = addressesToProcessQueue.shift()) !== undefined) {
// const before = addressesToProcessQueue.slice();
if (addressToProcess === 0) {
continue;
}
getAllLinkedAddressesStep(
carrier,
ignoreRefCount,
addressToProcess,
leafAddresses,
arcAddresses,
addressesToProcessQueue
);
// diffs.push(addressesToProcessQueue.filter((p) => !before.includes(p)));
}
// console.log(diffs);
return { leafAddresses, arcAddresses };

@@ -32,13 +52,14 @@ }

function getAllLinkedAddressesStep(
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
ignoreRefCount: boolean,
entryPointer: number,
leafAddresses: number[],
arcAddresses: number[]
leafAddresses: Set<number>,
arcAddresses: Set<number>,
addressesToProcessQueue: number[]
) {
const { heap } = carrier;
if (
entryPointer === UNDEFINED_KNOWN_ADDRESS ||
entryPointer === NULL_KNOWN_ADDRESS ||
entryPointer === TRUE_KNOWN_ADDRESS ||
entryPointer === FALSE_KNOWN_ADDRESS
isKnownAddressValuePointer(entryPointer) ||
leafAddresses.has(entryPointer) ||
arcAddresses.has(entryPointer)
) {

@@ -48,50 +69,51 @@ return;

const entry = readEntry(carrier, entryPointer);
const entryType = typeOnly_type_get(heap, entryPointer);
// to be used ONLY if the type has ref counter
const refsCount = typeAndRc_refsCount_get(heap, entryPointer);
switch (entry.type) {
switch (entryType) {
case ENTRY_TYPE.NUMBER:
case ENTRY_TYPE.STRING:
case ENTRY_TYPE.BIGINT_NEGATIVE:
case ENTRY_TYPE.BIGINT_POSITIVE:
leafAddresses.push(entryPointer);
leafAddresses.add(entryPointer);
break;
case ENTRY_TYPE.STRING:
leafAddresses.add(string_charsPointer_get(heap, entryPointer));
leafAddresses.add(entryPointer);
break;
case ENTRY_TYPE.OBJECT:
case ENTRY_TYPE.MAP:
case ENTRY_TYPE.SET:
if (entry.refsCount <= 1 || ignoreRefCount) {
leafAddresses.push(entryPointer);
if (refsCount <= 1 || ignoreRefCount) {
leafAddresses.add(entryPointer);
getObjectOrMapOrSetAddresses(
carrier,
ignoreRefCount,
entry.value,
object_pointerToHashMap_get(heap, entryPointer),
leafAddresses,
arcAddresses
addressesToProcessQueue
);
} else {
arcAddresses.push(entryPointer);
arcAddresses.add(entryPointer);
}
break;
case ENTRY_TYPE.ARRAY:
if (entry.refsCount <= 1 || ignoreRefCount) {
leafAddresses.push(entryPointer);
leafAddresses.push(entry.value);
if (refsCount <= 1 || ignoreRefCount) {
leafAddresses.add(entryPointer);
leafAddresses.add(array_dataspacePointer_get(heap, entryPointer));
const arrayLength = array_length_get(heap, entryPointer);
for (let i = 0; i < arrayLength; i += 1) {
const valuePointer =
carrier.uint32[
(array_dataspacePointer_get(heap, entryPointer) +
i * Uint32Array.BYTES_PER_ELEMENT) /
Uint32Array.BYTES_PER_ELEMENT
];
for (let i = 0; i < entry.allocatedLength; i += 1) {
const valuePointer = carrier.dataView.getUint32(
entry.value + i * Uint32Array.BYTES_PER_ELEMENT
);
getAllLinkedAddressesStep(
carrier,
ignoreRefCount,
valuePointer,
leafAddresses,
arcAddresses
);
addressesToProcessQueue.push(valuePointer);
}
} else {
arcAddresses.push(entryPointer);
arcAddresses.add(entryPointer);
}

@@ -101,6 +123,6 @@ break;

case ENTRY_TYPE.DATE:
if (entry.refsCount <= 1 || ignoreRefCount) {
leafAddresses.push(entryPointer);
if (refsCount <= 1 || ignoreRefCount) {
leafAddresses.add(entryPointer);
} else {
arcAddresses.push(entryPointer);
arcAddresses.add(entryPointer);
}

@@ -110,5 +132,3 @@ break;

default:
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
throw new Error(ENTRY_TYPE[entry.type] + " Not implemented yet");
throw new Error(ENTRY_TYPE[entryType] + " Not implemented yet");
}

@@ -118,24 +138,21 @@ }

export function getObjectOrMapOrSetAddresses(
carrier: DataViewAndAllocatorCarrier,
ignoreRefCount: boolean,
carrier: GlobalCarrier,
internalHashmapPointer: number,
leafAddresses: number[],
arcAddresses: number[]
leafAddresses: Set<number>,
addressesToProcessQueue: number[]
) {
const { pointersToValuePointers, pointers } = hashMapGetPointersToFree(
carrier.dataView,
carrier,
internalHashmapPointer
);
leafAddresses.push(...pointers);
for (const leafPointer of pointers) {
leafAddresses.add(leafPointer);
}
for (const pointer of pointersToValuePointers) {
getAllLinkedAddressesStep(
carrier,
ignoreRefCount,
carrier.dataView.getUint32(pointer),
leafAddresses,
arcAddresses
addressesToProcessQueue.push(
carrier.uint32[pointer / Uint32Array.BYTES_PER_ELEMENT]
);
}
}
/* eslint-env jest */
import * as util from "util";
import {
arrayBuffer2HexArray,
recordAllocations,
makeCarrier
makeCarrier,
} from "../testUtils";

@@ -16,17 +16,15 @@ import {

hashMapDelete,
hashMapGetPointersToFree
hashMapGetPointersToFree,
} from "./hashmap";
import { DataViewAndAllocatorCarrier, StringEntry } from "../interfaces";
import { readEntry } from "../store";
import { GlobalCarrier } from "../interfaces";
import { externalArgsApiToExternalArgsApi } from "../utils";
import { readString } from "../readString";
describe("hashmap", () => {
const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});
let ab = new ArrayBuffer(128);
let carrier: DataViewAndAllocatorCarrier = makeCarrier(ab);
let carrier: GlobalCarrier = makeCarrier(ab);

@@ -60,3 +58,3 @@ function setABSize(size: number) {

carrier.dataView.setUint32(valuePointer, 5);
carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT] = 5;

@@ -76,3 +74,3 @@ expect(arrayBuffer2HexArray(ab, true)).toMatchSnapshot("after insert");

carrier.dataView.setUint32(pointer, 6);
carrier.uint32[pointer / Uint32Array.BYTES_PER_ELEMENT] = 6;

@@ -157,3 +155,3 @@ expect(arrayBuffer2HexArray(ab, true)).toMatchSnapshot("after insert");

.map((i): number => i + "a".charCodeAt(0))
.map(n => String.fromCharCode(n));
.map((n) => String.fromCharCode(n));

@@ -166,3 +164,6 @@ const inserts: number[] = [];

);
carrier.dataView.setUint32(inserts[inserts.length - 1], index);
carrier.uint32[
inserts[inserts.length - 1] / Uint32Array.BYTES_PER_ELEMENT
] = index;
}

@@ -178,3 +179,3 @@

(iteratorToken = hashMapLowLevelIterator(
carrier.dataView,
carrier,
mapPointer,

@@ -184,9 +185,6 @@ iteratorToken

) {
values.push(
hashMapNodePointerToKeyValue(carrier.dataView, iteratorToken)
);
values.push(hashMapNodePointerToKeyValue(carrier, iteratorToken));
}
expect(
values.map(v => (readEntry(carrier, v.keyPointer) as StringEntry).value)
).toMatchInlineSnapshot(`
expect(values.map((v) => readString(carrier.heap, v.keyPointer)))
.toMatchInlineSnapshot(`
Array [

@@ -215,6 +213,2 @@ "a",

"v",
"w",
"x",
"y",
"z",
]

@@ -228,5 +222,3 @@ `);

expect(hashMapSize(carrier.dataView, mapPointer)).toMatchInlineSnapshot(
`0`
);
expect(hashMapSize(carrier, mapPointer)).toMatchInlineSnapshot(`0`);
const memAvailableAfterEachStep = [carrier.allocator.stats().available];

@@ -236,9 +228,9 @@

.map((i): number => i + "a".charCodeAt(0))
.map(n => String.fromCharCode(n));
.map((n) => String.fromCharCode(n));
for (const [index, useThatAsKey] of input.entries()) {
carrier.dataView.setUint32(
hashMapInsertUpdate(externalArgs, carrier, mapPointer, useThatAsKey),
index
);
carrier.uint32[
hashMapInsertUpdate(externalArgs, carrier, mapPointer, useThatAsKey) /
Uint32Array.BYTES_PER_ELEMENT
] = index;

@@ -248,5 +240,3 @@ memAvailableAfterEachStep.push(carrier.allocator.stats().available);

expect(hashMapSize(carrier.dataView, mapPointer)).toMatchInlineSnapshot(
`26`
);
expect(hashMapSize(carrier, mapPointer)).toMatchInlineSnapshot(`26`);

@@ -256,5 +246,3 @@ hashMapDelete(carrier, mapPointer, "a");

hashMapDelete(carrier, mapPointer, "c");
expect(hashMapSize(carrier.dataView, mapPointer)).toMatchInlineSnapshot(
`23`
);
expect(hashMapSize(carrier, mapPointer)).toMatchInlineSnapshot(`26`);
memAvailableAfterEachStep.push(carrier.allocator.stats().available);

@@ -265,29 +253,29 @@

1904,
1848,
1792,
1736,
1680,
1624,
1568,
1512,
1416,
1352,
1296,
1240,
1184,
1128,
1072,
1016,
880,
1824,
1744,
1664,
1584,
1504,
1424,
1344,
1224,
1144,
1064,
984,
904,
824,
760,
704,
648,
592,
536,
480,
424,
368,
312,
480,
744,
664,
504,
416,
336,
256,
176,
96,
16,
0,
0,
0,
0,
0,
]

@@ -304,3 +292,3 @@ `);

.map((i): number => i + "a".charCodeAt(0))
.map(n => String.fromCharCode(n));
.map((n) => String.fromCharCode(n));
const inputCopy = input.slice();

@@ -316,10 +304,10 @@

while ((toAdd = inputCopy.pop()) !== undefined) {
carrier.dataView.setUint32(
hashMapInsertUpdate(externalArgs, carrier, hashmapPointer, toAdd),
toAdd.charCodeAt(0)
);
carrier.uint32[
hashMapInsertUpdate(externalArgs, carrier, hashmapPointer, toAdd) /
Uint32Array.BYTES_PER_ELEMENT
] = toAdd.charCodeAt(0);
}
}, carrier.allocator);
const r = hashMapGetPointersToFree(carrier.dataView, hashmapPointer);
const r = hashMapGetPointersToFree(carrier, hashmapPointer);

@@ -330,47 +318,57 @@ expect(r).toMatchInlineSnapshot(`

48,
600,
792,
120,
136,
192,
248,
304,
216,
296,
376,
456,
536,
616,
696,
776,
896,
976,
200,
152,
176,
280,
232,
256,
360,
312,
336,
440,
392,
416,
520,
472,
528,
584,
688,
744,
152,
176,
208,
232,
264,
288,
320,
344,
376,
400,
432,
456,
488,
512,
544,
568,
496,
600,
552,
576,
680,
632,
656,
760,
712,
736,
880,
72,
96,
704,
728,
960,
912,
936,
],
"pointersToValuePointers": Array [
152,
208,
264,
320,
376,
432,
488,
544,
232,
312,
392,
472,
552,
632,
712,
72,
704,
912,
],

@@ -383,3 +381,5 @@ }

r.pointersToValuePointers
.map(v => String.fromCharCode(carrier.dataView.getUint32(v)))
.map((v) =>
String.fromCharCode(carrier.uint32[v / Uint32Array.BYTES_PER_ELEMENT])
)
.sort()

@@ -386,0 +386,0 @@ ).toEqual(input.sort());

import { MAP_MACHINE, NODE_MACHINE } from "./memoryLayout";
import { GlobalCarrier, ExternalArgs } from "../interfaces";
import {
DataViewAndAllocatorCarrier,
ExternalArgs,
NumberEntry,
StringEntry
} from "../interfaces";
import {
hashCodeInPlace,
hashCodeExternalValue,
getKeyStartLength
getKeyStartLength,
} from "./hashmapUtils";
import { primitiveValueToEntry } from "../utils";
import { strByteLength } from "../utils";
import { stringEncodeInto } from "../stringEncodeInto";
import {
sizeOfEntry,
writeEntry,
readEntry,
compareStringOrNumberEntriesInPlace
compareStringOrNumberEntriesInPlace,
readNumberOrString,
} from "../store";

@@ -27,9 +21,19 @@ import { ENTRY_TYPE } from "../entry-types";

linkedListGetValue,
linkedListGetPointersToFree
linkedListGetPointersToFree,
} from "../linkedList/linkedList";
import { MemoryOperator } from "../memoryMachinery";
import {
number_size,
string_size,
number_set_all,
string_set_all,
number_value_place,
number_value_ctor,
typeOnly_type_get,
string_charsPointer_get,
} from "../generatedStructs";
export function createHashMap(
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
/**

@@ -47,6 +51,3 @@ * number of buckets

const mapMachine = MAP_MACHINE.createOperator(
carrier.dataView,
hashMapMemory
);
const mapMachine = MAP_MACHINE.createOperator(carrier, hashMapMemory);

@@ -67,10 +68,10 @@ mapMachine.set("ARRAY_POINTER", arrayMemory);

externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
mapPointer: number,
externalKeyValue: number | string
) {
const mapOperator = MAP_MACHINE.createOperator(carrier.dataView, mapPointer);
const keyEntry = primitiveValueToEntry(externalKeyValue) as
| NumberEntry
| StringEntry;
const mapOperator = MAP_MACHINE.createOperator(carrier, mapPointer);
// const keyEntry = primitiveValueToEntry(externalKeyValue) as
// | NumberEntry
// | StringEntry;

@@ -80,14 +81,41 @@ // allocate all possible needed memory upfront, so we won't oom in the middle of something

const memoryForNewNode = carrier.allocator.calloc(NODE_MACHINE.map.SIZE_OF);
const memorySizeOfKey = sizeOfEntry(keyEntry);
const keyEntryMemory = carrier.allocator.calloc(memorySizeOfKey);
let keyMemoryEntryPointer;
let keyDataMemoryStart: number;
let keyDataMemoryLength: number;
writeEntry(carrier, keyEntryMemory, keyEntry);
if (typeof externalKeyValue === "number") {
keyMemoryEntryPointer = carrier.allocator.calloc(number_size);
number_set_all(
carrier.heap,
keyMemoryEntryPointer,
ENTRY_TYPE.NUMBER,
externalKeyValue
);
const keyHeaderOverhead = keyEntry.type === ENTRY_TYPE.STRING ? 5 : 1;
keyDataMemoryStart = keyMemoryEntryPointer + number_value_place;
keyDataMemoryLength = number_value_ctor.BYTES_PER_ELEMENT;
} else {
keyMemoryEntryPointer = carrier.allocator.calloc(string_size);
keyDataMemoryLength = strByteLength(externalKeyValue);
keyDataMemoryStart = carrier.allocator.calloc(keyDataMemoryLength);
stringEncodeInto(
carrier.heap.Uint8Array,
keyDataMemoryStart,
externalKeyValue
);
string_set_all(
carrier.heap,
keyMemoryEntryPointer,
ENTRY_TYPE.STRING,
keyDataMemoryLength,
keyDataMemoryStart
);
}
const keyHashCode = hashCodeInPlace(
carrier.dataView,
carrier.uint8,
mapOperator.get("CAPACITY"),
// + 1 for the type of key
keyEntryMemory + keyHeaderOverhead,
memorySizeOfKey - keyHeaderOverhead
keyDataMemoryStart,
keyDataMemoryLength
);

@@ -100,4 +128,4 @@

const commonNodeOperator = NODE_MACHINE.createOperator(
carrier.dataView,
carrier.dataView.getUint32(ptrToPtrToSaveTheNodeTo)
carrier,
carrier.uint32[ptrToPtrToSaveTheNodeTo / Uint32Array.BYTES_PER_ELEMENT]
);

@@ -109,5 +137,5 @@

!compareStringOrNumberEntriesInPlace(
carrier.dataView,
carrier.heap,
commonNodeOperator.get("KEY_POINTER"),
keyEntryMemory
keyMemoryEntryPointer
)

@@ -133,3 +161,4 @@ ) {

// we don't need the new memory
carrier.allocator.free(keyEntryMemory);
// @todo Free here also the string data
carrier.allocator.free(keyMemoryEntryPointer);
carrier.allocator.free(memoryForNewNode);

@@ -140,3 +169,3 @@

commonNodeOperator.startAddress = memoryForNewNode;
commonNodeOperator.set("KEY_POINTER", keyEntryMemory);
commonNodeOperator.set("KEY_POINTER", keyMemoryEntryPointer);
commonNodeOperator.set(

@@ -151,3 +180,5 @@ "LINKED_LIST_ITEM_POINTER",

carrier.dataView.setUint32(ptrToPtrToSaveTheNodeTo, memoryForNewNode);
carrier.uint32[
ptrToPtrToSaveTheNodeTo / Uint32Array.BYTES_PER_ELEMENT
] = memoryForNewNode;

@@ -161,3 +192,2 @@ mapOperator.set(

shouldRehash(
mapOperator.get("LINKED_LIST_SIZE"),
mapOperator.get("CAPACITY"),

@@ -182,7 +212,7 @@ mapOperator.get("USED_CAPACITY"),

export function hashMapNodeLookup(
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
mapPointer: number,
externalKeyValue: number | string
) {
const mapMachine = MAP_MACHINE.createOperator(carrier.dataView, mapPointer);
const mapMachine = MAP_MACHINE.createOperator(carrier, mapPointer);

@@ -199,12 +229,10 @@ const keyHashCode = hashCodeExternalValue(

const node = NODE_MACHINE.createOperator(
carrier.dataView,
carrier.dataView.getUint32(ptrToPtr)
carrier,
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT]
);
while (node.startAddress !== 0) {
const keyEntry = readEntry(carrier, node.get("KEY_POINTER")) as
| NumberEntry
| StringEntry;
const keyValue = readNumberOrString(carrier.heap, node.get("KEY_POINTER"));
if (keyEntry.value === externalKeyValue) {
if (keyValue === externalKeyValue) {
return ptrToPtr;

@@ -221,3 +249,3 @@ }

export function hashMapValueLookup(
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
mapPointer: number,

@@ -233,4 +261,4 @@ externalKeyValue: number | string

const node = NODE_MACHINE.createOperator(
carrier.dataView,
carrier.dataView.getUint32(nodePtrToPtr)
carrier,
carrier.uint32[nodePtrToPtr / Uint32Array.BYTES_PER_ELEMENT]
);

@@ -245,3 +273,3 @@

export function hashMapDelete(
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
mapPointer: number,

@@ -260,6 +288,7 @@ externalKeyValue: number | string

const nodeToDeletePointer = carrier.dataView.getUint32(foundNodePtrToPtr);
const nodeToDeletePointer =
carrier.uint32[foundNodePtrToPtr / Uint32Array.BYTES_PER_ELEMENT];
const nodeOperator = NODE_MACHINE.createOperator(
carrier.dataView,
carrier,
nodeToDeletePointer

@@ -273,16 +302,22 @@ );

// remove node from bucket
carrier.dataView.setUint32(
foundNodePtrToPtr,
nodeOperator.get("NEXT_NODE_POINTER")
);
carrier.uint32[
foundNodePtrToPtr / Uint32Array.BYTES_PER_ELEMENT
] = nodeOperator.get("NEXT_NODE_POINTER");
if (
typeOnly_type_get(carrier.heap, nodeOperator.get("KEY_POINTER")) ===
ENTRY_TYPE.STRING
) {
carrier.allocator.free(
string_charsPointer_get(carrier.heap, nodeOperator.get("KEY_POINTER"))
);
}
carrier.allocator.free(nodeOperator.get("KEY_POINTER"));
carrier.allocator.free(nodeOperator.startAddress);
carrier.dataView.setUint32(
mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset,
carrier.dataView.getUint32(
mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset
) - 1
);
carrier.uint32[
(mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset) /
Uint32Array.BYTES_PER_ELEMENT
]--;

@@ -297,7 +332,7 @@ return valuePointer;

export function hashMapLowLevelIterator(
dataView: DataView,
carrier: GlobalCarrier,
mapPointer: number,
nodePointerIteratorToken: number
) {
const mapOperator = MAP_MACHINE.createOperator(dataView, mapPointer);
const mapOperator = MAP_MACHINE.createOperator(carrier, mapPointer);
let tokenToUseForLinkedListIterator = 0;

@@ -307,3 +342,3 @@

tokenToUseForLinkedListIterator = NODE_MACHINE.createOperator(
dataView,
carrier,
nodePointerIteratorToken

@@ -314,3 +349,3 @@ ).get("LINKED_LIST_ITEM_POINTER");

const pointerToNextLinkedListItem = linkedListLowLevelIterator(
dataView,
carrier,
mapOperator.get("LINKED_LIST_POINTER"),

@@ -324,28 +359,29 @@ tokenToUseForLinkedListIterator

return linkedListGetValue(dataView, pointerToNextLinkedListItem);
return linkedListGetValue(carrier, pointerToNextLinkedListItem);
}
export function hashMapNodePointerToKeyValue(
dataView: DataView,
carrier: GlobalCarrier,
nodePointer: number
) {
const operator = NODE_MACHINE.createOperator(dataView, nodePointer);
const operator = NODE_MACHINE.createOperator(carrier, nodePointer);
return {
valuePointer: operator.pointerTo("VALUE_POINTER"),
keyPointer: operator.get("KEY_POINTER")
keyPointer: operator.get("KEY_POINTER"),
};
}
export function hashMapSize(dataView: DataView, mapPointer: number) {
return dataView.getUint32(
mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset
);
export function hashMapSize(carrier: GlobalCarrier, mapPointer: number) {
return carrier.uint32[
(mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset) /
Uint32Array.BYTES_PER_ELEMENT
];
}
export function hashMapGetPointersToFree(
dataView: DataView,
carrier: GlobalCarrier,
hashmapPointer: number
) {
const mapOperator = MAP_MACHINE.createOperator(dataView, hashmapPointer);
const mapOperator = MAP_MACHINE.createOperator(carrier, hashmapPointer);
const pointers: number[] = [hashmapPointer, mapOperator.get("ARRAY_POINTER")];

@@ -355,3 +391,3 @@ const pointersToValuePointers: number[] = [];

const pointersOfLinkedList = linkedListGetPointersToFree(
dataView,
carrier,
mapOperator.get("LINKED_LIST_POINTER")

@@ -361,3 +397,3 @@ );

pointers.push(...pointersOfLinkedList.pointers);
const nodeOperator = NODE_MACHINE.createOperator(dataView, 0);
const nodeOperator = NODE_MACHINE.createOperator(carrier, 0);

@@ -367,2 +403,10 @@ for (const nodePointer of pointersOfLinkedList.valuePointers) {

pointersToValuePointers.push(nodeOperator.pointerTo("VALUE_POINTER"));
if (
typeOnly_type_get(carrier.heap, nodeOperator.get("KEY_POINTER")) ===
ENTRY_TYPE.STRING
) {
pointers.push(
string_charsPointer_get(carrier.heap, nodeOperator.get("KEY_POINTER"))
);
}
pointers.push(nodePointer, nodeOperator.get("KEY_POINTER"));

@@ -373,3 +417,3 @@ }

pointers,
pointersToValuePointers
pointersToValuePointers,
};

@@ -379,3 +423,3 @@ }

function hashMapRehash(
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
mapOperator: MemoryOperator<

@@ -419,3 +463,3 @@ | "CAPACITY"

(pointerToNode = hashMapLowLevelIterator(
carrier.dataView,
carrier,
mapOperator.startAddress,

@@ -430,3 +474,3 @@ pointerToNode

function hashMapRehashInsert(
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
bucketsArrayPointer: number,

@@ -436,13 +480,7 @@ arraySize: number,

) {
const nodeOperator = NODE_MACHINE.createOperator(
carrier.dataView,
nodePointer
);
const keyInfo = getKeyStartLength(
carrier.dataView,
nodeOperator.get("KEY_POINTER")
);
const nodeOperator = NODE_MACHINE.createOperator(carrier, nodePointer);
const keyInfo = getKeyStartLength(carrier, nodeOperator.get("KEY_POINTER"));
const keyHashCode = hashCodeInPlace(
carrier.dataView,
carrier.uint8,
arraySize,

@@ -457,4 +495,9 @@ keyInfo.start,

const prevFirstNodeInBucket = carrier.dataView.getUint32(bucketStartPointer);
carrier.dataView.setUint32(bucketStartPointer, nodePointer);
const prevFirstNodeInBucket =
carrier.uint32[bucketStartPointer / Uint32Array.BYTES_PER_ELEMENT];
carrier.uint32[
bucketStartPointer / Uint32Array.BYTES_PER_ELEMENT
] = nodePointer;
nodeOperator.set("NEXT_NODE_POINTER", prevFirstNodeInBucket);

@@ -477,3 +520,2 @@

function shouldRehash(
nodesCount: number,
buckets: number,

@@ -489,3 +531,3 @@ fullBuckets: number,

export function* hashmapNodesPointerIterator(
dataView: DataView,
carrier: GlobalCarrier,
mapPointer: number

@@ -497,3 +539,3 @@ ) {

(iteratorToken = hashMapLowLevelIterator(
dataView,
carrier,
mapPointer,

@@ -500,0 +542,0 @@ iteratorToken

import { ENTRY_TYPE } from "../entry-types";
import { stringEncodeInto } from "../stringEncodeInto";
import { GlobalCarrier } from "../interfaces";
export function hashCodeInPlace(
dataView: DataView,
uint8: Uint8Array,
capacity: number,

@@ -15,4 +16,3 @@ keyStart: number,

for (let i = 0; i < keyBytesLength; i++) {
// hashed.push(dataView.getUint8(i + keyStart));
h = (Math.imul(31, h) + dataView.getUint8(i + keyStart)) | 0;
h = (Math.imul(31, h) + uint8[i + keyStart]) | 0;
}

@@ -30,3 +30,3 @@

const ab = new ArrayBuffer(typeof value === "string" ? value.length * 3 : 8);
const dv = new DataView(ab);
const uint8 = new Uint8Array(ab);
let keyBytesLength = ab.byteLength;

@@ -37,25 +37,23 @@

} else {
dv.setFloat64(0, value);
new Float64Array(ab)[0] = value;
}
return hashCodeInPlace(dv, capacity, 0, keyBytesLength);
return hashCodeInPlace(uint8, capacity, 0, keyBytesLength);
}
export function hashCodeEntry(
dataView: DataView,
carrier: GlobalCarrier,
capacity: number,
pointer: number
): number {
const type: ENTRY_TYPE.NUMBER | ENTRY_TYPE.STRING = dataView.getUint8(
pointer
);
const type: ENTRY_TYPE.NUMBER | ENTRY_TYPE.STRING = carrier.uint8[pointer];
if (type === ENTRY_TYPE.NUMBER) {
return hashCodeInPlace(dataView, capacity, pointer + 1, 8);
return hashCodeInPlace(carrier.uint8, capacity, pointer + 1, 8);
} else {
return hashCodeInPlace(
dataView,
carrier.uint8,
capacity,
pointer + 1 + Uint16Array.BYTES_PER_ELEMENT,
dataView.getUint16(pointer + 1)
carrier.uint16[(pointer + 1) / Uint16Array.BYTES_PER_ELEMENT]
);

@@ -65,7 +63,10 @@ }

export function getKeyStartLength(dataView: DataView, keyPointer: number) {
if (dataView.getUint32(keyPointer) === ENTRY_TYPE.NUMBER) {
export function getKeyStartLength(carrier: GlobalCarrier, keyPointer: number) {
if (
carrier.uint32[keyPointer / Uint32Array.BYTES_PER_ELEMENT] ===
ENTRY_TYPE.NUMBER
) {
return {
start: keyPointer + 1,
length: Float64Array.BYTES_PER_ELEMENT
length: Float64Array.BYTES_PER_ELEMENT,
};

@@ -75,5 +76,5 @@ } else {

start: keyPointer + 1 + 2 + 2,
length: dataView.getUint16(keyPointer + 1)
length: carrier.uint16[(keyPointer + 1) / Uint16Array.BYTES_PER_ELEMENT],
};
}
}
import { createMemoryMachine } from "../memoryMachinery";
export const MAP_MACHINE = createMemoryMachine({
CAPACITY: Uint8Array,
USED_CAPACITY: Uint8Array,
ARRAY_POINTER: Uint32Array,
LINKED_LIST_POINTER: Uint32Array,
// maybe put save this value in the linked list?
LINKED_LIST_SIZE: Uint32Array
LINKED_LIST_SIZE: Uint32Array,
CAPACITY: Uint8Array,
USED_CAPACITY: Uint8Array,
});

@@ -16,3 +16,3 @@

KEY_POINTER: Uint32Array,
LINKED_LIST_ITEM_POINTER: Uint32Array
LINKED_LIST_ITEM_POINTER: Uint32Array,
});

@@ -19,0 +19,0 @@

import { ENTRY_TYPE } from "./entry-types";
import { TextDecoder, TextEncoder } from "./textEncoderDecoderTypes";
import { IMemPool } from "@thi.ng/malloc";
import { Heap } from "../structsGenerator/consts";

@@ -85,4 +84,4 @@ export type primitive = string | number | bigint | boolean | undefined | null;

*/
export interface DataViewAndAllocatorCarrier {
dataView: DataView;
export interface GlobalCarrier {
// dataView: DataView;
uint8: Uint8Array;

@@ -94,2 +93,3 @@ uint16: Uint16Array;

allocator: import("@thi.ng/malloc").IMemPool;
heap: Heap;
}

@@ -100,5 +100,7 @@

hashMapMinInitialCapacity: number;
/**
* Allocate additional memory for array pointers,
* will prevent the reallocation and copy when array is getting bigger
*/
arrayAdditionalAllocation: number;
textDecoder: TextDecoder;
textEncoder: TextEncoder;
}>;

@@ -110,4 +112,2 @@

arrayAdditionalAllocation?: number;
textDecoder: TextDecoder;
textEncoder: TextEncoder;
}>;

@@ -117,6 +117,6 @@

getExternalArgs(): ExternalArgs;
getCarrier(): Readonly<DataViewAndAllocatorCarrier>;
replaceCarrierContent(carrier: DataViewAndAllocatorCarrier): void;
getCarrier(): Readonly<GlobalCarrier>;
replaceCarrierContent(carrier: GlobalCarrier): void;
getEntryPointer(): number;
destroy(): number;
}

@@ -6,9 +6,5 @@ /* eslint-env jest */

recordAllocations,
makeCarrier
makeCarrier,
} from "../testUtils";
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
// import jestDiff from "jest-diff";
import {

@@ -20,3 +16,3 @@ linkedListItemInsert,

linkedListGetValue,
linkedListGetPointersToFree
linkedListGetPointersToFree,
// LINKED_LIST_ITEM_MACHINE

@@ -104,3 +100,3 @@ } from "./linkedList";

linkedListItemInsert(carrier, linkedListPointer, 5),
linkedListItemInsert(carrier, linkedListPointer, 4)
linkedListItemInsert(carrier, linkedListPointer, 4),
];

@@ -113,3 +109,3 @@

(iteratorPointer = linkedListLowLevelIterator(
carrier.dataView,
carrier,
linkedListPointer,

@@ -119,3 +115,3 @@ iteratorPointer

) {
values.push(linkedListGetValue(carrier.dataView, iteratorPointer));
values.push(linkedListGetValue(carrier, iteratorPointer));
}

@@ -134,3 +130,3 @@

itemsPointers.forEach(p => linkedListItemRemove(carrier, p));
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p));

@@ -150,3 +146,3 @@ expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`);

linkedListItemInsert(carrier, linkedListPointer, 5),
linkedListItemInsert(carrier, linkedListPointer, 4)
linkedListItemInsert(carrier, linkedListPointer, 4),
];

@@ -159,3 +155,3 @@

(iteratorPointer = linkedListLowLevelIterator(
carrier.dataView,
carrier,
linkedListPointer,

@@ -165,3 +161,3 @@ iteratorPointer

) {
values.push(linkedListGetValue(carrier.dataView, iteratorPointer));
values.push(linkedListGetValue(carrier, iteratorPointer));
linkedListItemRemove(carrier, iteratorPointer);

@@ -187,3 +183,3 @@ }

itemsPointers.forEach(p => linkedListItemRemove(carrier, p));
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p));

@@ -204,3 +200,3 @@ expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`);

linkedListItemInsert(carrier, linkedListPointer, 5),
linkedListItemInsert(carrier, linkedListPointer, 4)
linkedListItemInsert(carrier, linkedListPointer, 4),
];

@@ -213,3 +209,3 @@

(iteratorPointer = linkedListLowLevelIterator(
carrier.dataView,
carrier,
linkedListPointer,

@@ -219,5 +215,3 @@ iteratorPointer

) {
linkedLintResults.push(
linkedListGetValue(carrier.dataView, iteratorPointer)
);
linkedLintResults.push(linkedListGetValue(carrier, iteratorPointer));
linkedListItemRemove(carrier, iteratorPointer);

@@ -250,3 +244,3 @@ }

itemsPointers.forEach(p => linkedListItemRemove(carrier, p));
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p));

@@ -264,3 +258,3 @@ expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`);

linkedListItemInsert(carrier, linkedListPointer, 7),
linkedListItemInsert(carrier, linkedListPointer, 6)
linkedListItemInsert(carrier, linkedListPointer, 6),
];

@@ -276,3 +270,3 @@

(iteratorPointer = linkedListLowLevelIterator(
carrier.dataView,
carrier,
linkedListPointer,

@@ -282,3 +276,3 @@ iteratorPointer

) {
values.push(linkedListGetValue(carrier.dataView, iteratorPointer));
values.push(linkedListGetValue(carrier, iteratorPointer));
if (c < toAdd.length) {

@@ -312,3 +306,3 @@ linkedListItemInsert(carrier, linkedListPointer, toAdd[c++]);

itemsPointers.forEach(p => linkedListItemRemove(carrier, p));
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p));

@@ -318,3 +312,3 @@ const iteratorPointerToFree = 0;

(iteratorPointer = linkedListLowLevelIterator(
carrier.dataView,
carrier,
linkedListPointer,

@@ -348,3 +342,3 @@ iteratorPointerToFree

const r = linkedListGetPointersToFree(carrier.dataView, linkedListPointer);
const r = linkedListGetPointersToFree(carrier, linkedListPointer);

@@ -351,0 +345,0 @@ expect(r).toMatchInlineSnapshot(`

import { createMemoryMachine } from "../memoryMachinery";
import { DataViewAndAllocatorCarrier } from "../interfaces";
import { GlobalCarrier } from "../interfaces";

@@ -21,3 +21,3 @@ /*

NEXT_POINTER: Uint32Array,
VALUE: Uint32Array
VALUE: Uint32Array,
});

@@ -31,3 +31,3 @@

END_POINTER: Uint32Array,
START_POINTER: Uint32Array
START_POINTER: Uint32Array,
});

@@ -38,6 +38,4 @@ export type LinkedListMachineType = ReturnType<

export function initLinkedList({
dataView,
allocator
}: DataViewAndAllocatorCarrier) {
export function initLinkedList(carrier: GlobalCarrier) {
const { allocator } = carrier;
const memoryForLinkedList = allocator.calloc(LINKED_LIST_MACHINE.map.SIZE_OF);

@@ -49,3 +47,3 @@ const memoryForEndMarkerItem = allocator.calloc(

const linkedListMachine = LINKED_LIST_MACHINE.createOperator(
dataView,
carrier,
memoryForLinkedList

@@ -61,7 +59,7 @@ );

export function linkedListItemInsert(
{ dataView, allocator }: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
linkedListPointer: number,
nodeValuePointer: number
) {
const newItemMemory: number = allocator.calloc(
const newItemMemory: number = carrier.allocator.calloc(
LINKED_LIST_ITEM_MACHINE.map.SIZE_OF

@@ -71,3 +69,3 @@ );

const linkedListOperator = LINKED_LIST_MACHINE.createOperator(
dataView,
carrier,
linkedListPointer

@@ -77,3 +75,3 @@ );

const wasEndMarkerOperator = LINKED_LIST_ITEM_MACHINE.createOperator(
dataView,
carrier,
linkedListOperator.get("END_POINTER")

@@ -83,3 +81,3 @@ );

const toBeEndMarkerOperator = LINKED_LIST_ITEM_MACHINE.createOperator(
dataView,
carrier,
newItemMemory

@@ -101,7 +99,7 @@ );

export function linkedListItemRemove(
{ dataView, allocator }: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
itemPointer: number
) {
const itemToOverwrite = LINKED_LIST_ITEM_MACHINE.createOperator(
dataView,
carrier,
itemPointer

@@ -111,3 +109,3 @@ );

const itemToOverwriteWith = LINKED_LIST_ITEM_MACHINE.createOperator(
dataView,
carrier,
itemToOverwrite.get("NEXT_POINTER")

@@ -122,7 +120,7 @@ );

allocator.free(memoryToFree);
carrier.allocator.free(memoryToFree);
}
export function linkedListLowLevelIterator(
dataView: DataView,
carrier: GlobalCarrier,
linkedListPointer: number,

@@ -132,3 +130,3 @@ itemPointer: number

const listItem = LINKED_LIST_ITEM_MACHINE.createOperator(
dataView,
carrier,
itemPointer

@@ -138,6 +136,3 @@ );

if (itemPointer === 0) {
const list = LINKED_LIST_MACHINE.createOperator(
dataView,
linkedListPointer
);
const list = LINKED_LIST_MACHINE.createOperator(carrier, linkedListPointer);

@@ -170,4 +165,7 @@ listItem.startAddress = list.get("START_POINTER");

export function linkedListGetValue(dataView: DataView, itemPointer: number) {
return LINKED_LIST_ITEM_MACHINE.createOperator(dataView, itemPointer).get(
export function linkedListGetValue(
carrier: GlobalCarrier,
itemPointer: number
) {
return LINKED_LIST_ITEM_MACHINE.createOperator(carrier, itemPointer).get(
"VALUE"

@@ -178,3 +176,3 @@ );

export function linkedListGetPointersToFree(
dataView: DataView,
carrier: GlobalCarrier,
linkedListPointer: number

@@ -186,3 +184,3 @@ ) {

const operator = LINKED_LIST_MACHINE.createOperator(
dataView,
carrier,
linkedListPointer

@@ -200,4 +198,4 @@ );

const linkItemOperator = LINKED_LIST_ITEM_MACHINE.createOperator(
dataView,
linkedListLowLevelIterator(dataView, linkedListPointer, 0)
carrier,
linkedListLowLevelIterator(carrier, linkedListPointer, 0)
);

@@ -219,4 +217,4 @@

pointers,
valuePointers
valuePointers,
};
}

@@ -0,1 +1,5 @@

/* istanbul ignore file */
// I'm not sure how to test that yet
import { invariant } from "./utils";

@@ -2,0 +6,0 @@ import { getUnderlyingArrayBuffer } from "./api";

@@ -0,12 +1,7 @@

import { ExternalArgs, GlobalCarrier, InternalAPI } from "./interfaces";
import {
ExternalArgs,
DataViewAndAllocatorCarrier,
MapEntry,
InternalAPI
} from "./interfaces";
import {
deleteObjectPropertyEntryByKey,
objectGet,
objectSet,
mapOrSetClear
mapOrSetClear,
} from "./objectWrapperHelpers";

@@ -22,8 +17,8 @@

hashMapNodePointerToKeyValue,
hashmapNodesPointerIterator
hashmapNodesPointerIterator,
} from "./hashmap/hashmap";
import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue";
import { object_pointerToHashMap_get } from "./generatedStructs";
export class MapWrapper<K extends string | number, V>
extends BaseProxyTrap<MapEntry>
export class MapWrapper<K extends string | number, V> extends BaseProxyTrap
implements Map<K, V> {

@@ -44,3 +39,6 @@ clear(): void {

get size(): number {
return hashMapSize(this.carrier.dataView, this.entry.value);
return hashMapSize(
this.carrier,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer)
);
}

@@ -54,7 +52,7 @@

for (const nodePointer of hashmapNodesPointerIterator(
this.carrier.dataView,
this.entry.value
this.carrier,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer)
)) {
const { valuePointer, keyPointer } = hashMapNodePointerToKeyValue(
this.carrier.dataView,
this.carrier,
nodePointer

@@ -72,4 +70,4 @@ );

this.carrier,
this.carrier.dataView.getUint32(valuePointer)
)
this.carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT]
),
];

@@ -81,9 +79,6 @@ }

for (const nodePointer of hashmapNodesPointerIterator(
this.carrier.dataView,
this.entry.value
this.carrier,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer)
)) {
const t = hashMapNodePointerToKeyValue(
this.carrier.dataView,
nodePointer
);
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer);

@@ -100,7 +95,7 @@ yield entryToFinalJavaScriptValue(

for (const nodePointer of hashmapNodesPointerIterator(
this.carrier.dataView,
this.entry.value
this.carrier,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer)
)) {
const { valuePointer } = hashMapNodePointerToKeyValue(
this.carrier.dataView,
this.carrier,
nodePointer

@@ -112,3 +107,3 @@ );

this.carrier,
this.carrier.dataView.getUint32(valuePointer)
this.carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT]
);

@@ -135,3 +130,8 @@ }

return objectGet(this.externalArgs, this.carrier, this.entry.value, p);
return objectGet(
this.externalArgs,
this.carrier,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer),
p
);
}

@@ -145,5 +145,4 @@

return deleteObjectPropertyEntryByKey(
this.externalArgs,
this.carrier,
this.entry.value,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer),
p

@@ -158,3 +157,9 @@ );

return hashMapNodeLookup(this.carrier, this.entry.value, p) !== 0;
return (
hashMapNodeLookup(
this.carrier,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer),
p
) !== 0
);
}

@@ -168,3 +173,9 @@

allocationsTransaction(() => {
objectSet(this.externalArgs, this.carrier, this.entry.value, p, value);
objectSet(
this.externalArgs,
this.carrier,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer),
p,
value
);
}, this.carrier.allocator);

@@ -178,6 +189,6 @@

externalArgs: ExternalArgs,
dataViewCarrier: DataViewAndAllocatorCarrier,
globalCarrier: GlobalCarrier,
entryPointer: number
): Map<K, V> {
return new MapWrapper<K, V>(externalArgs, dataViewCarrier, entryPointer);
return new MapWrapper<K, V>(externalArgs, globalCarrier, entryPointer);
}

@@ -5,5 +5,5 @@ /* eslint-env jest */

createMemoryOperator,
_buildMemoryLayout
_buildMemoryLayout,
} from "./memoryMachinery";
import { arrayBuffer2HexArray } from "./testUtils";
import { arrayBuffer2HexArray, makeCarrier } from "./testUtils";

@@ -15,3 +15,3 @@ describe("memory manifest", () => {

Uint32: Uint32Array,
Uint8: Uint8Array
Uint8: Uint8Array,
};

@@ -41,7 +41,7 @@

.filter(([key]) => key !== "SIZE_OF")
.map(entry => [
.map((entry) => [
entry[0],
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
entry[1].type
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
entry[1].type,
])

@@ -54,9 +54,9 @@ ).toEqual(Object.entries(input));

POINTER_TO_NODE: Uint32Array,
LENGTH_OF_KEY: Uint16Array
LENGTH_OF_KEY: Uint32Array,
});
const ab = new ArrayBuffer(memoryMap.SIZE_OF);
const dataView = new DataView(ab);
const ab = new ArrayBuffer(memoryMap.SIZE_OF + 48);
const carrier = makeCarrier(ab);
const operator = createMemoryOperator(memoryMap, dataView, 0);
const operator = createMemoryOperator(memoryMap, carrier, 0);

@@ -68,15 +68,7 @@ operator.set("POINTER_TO_NODE", 9);

Array [
"0x09",
"0x00",
"0x00",
"0x00",
"0x09",
"0x00",
"0x05",
]
`);
operator.set("POINTER_TO_NODE", 0);
expect(arrayBuffer2HexArray(ab)).toMatchInlineSnapshot(`
Array [
"0x00",

@@ -87,5 +79,113 @@ "0x00",

"0x00",
"0x05",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x28",
"0x00",
"0x00",
"0x00",
"0x38",
"0x00",
"0x00",
"0x00",
"0x08",
"0x00",
"0x00",
"0x00",
"0x03",
"0x00",
"0x00",
"0x00",
"0x10",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
]
`);
operator.set("POINTER_TO_NODE", 0);
expect(arrayBuffer2HexArray(ab)).toMatchInlineSnapshot(`
Array [
"0x00",
"0x00",
"0x00",
"0x00",
"0x05",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x28",
"0x00",
"0x00",
"0x00",
"0x38",
"0x00",
"0x00",
"0x00",
"0x08",
"0x00",
"0x00",
"0x00",
"0x03",
"0x00",
"0x00",
"0x00",
"0x10",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
]
`);
});

@@ -96,9 +196,9 @@

POINTER_TO_NODE: Uint32Array,
LENGTH_OF_KEY: Uint16Array
LENGTH_OF_KEY: Uint32Array,
});
const ab = new ArrayBuffer(memoryMap.SIZE_OF);
const dataView = new DataView(ab);
const ab = new ArrayBuffer(memoryMap.SIZE_OF + 48);
const carrier = makeCarrier(ab);
const operator = createMemoryOperator(memoryMap, dataView, 0);
const operator = createMemoryOperator(memoryMap, carrier, 0);

@@ -117,3 +217,3 @@ operator.set("POINTER_TO_NODE", 9);

NODE_KEY_POINTER: Uint32Array.BYTES_PER_ELEMENT,
NODE_KEY_LENGTH: Uint16Array.BYTES_PER_ELEMENT
NODE_KEY_LENGTH: Uint16Array.BYTES_PER_ELEMENT,
});

@@ -120,0 +220,0 @@

@@ -0,1 +1,3 @@

import { GlobalCarrier } from "./interfaces";
const ALLOWS_TYPED_ARRAYS_CTORS = [

@@ -5,3 +7,3 @@ Uint8Array,

// BigUint64Array,
Uint16Array
Uint16Array,
] as const;

@@ -23,18 +25,25 @@

// DataView.prototype is any, ts thing. this is a workaround for better types.
let dataViewInstance = new DataView(new ArrayBuffer(0));
// let dataViewInstance = new DataView(new ArrayBuffer(0));
const READ_WRITE_MAPS = [
[Uint8Array, dataViewInstance.getUint8, dataViewInstance.setUint8],
[Uint32Array, dataViewInstance.getUint32, dataViewInstance.setUint32],
// const READ_WRITE_MAPS = [
// [Uint8Array, dataViewInstance.getUint8, dataViewInstance.setUint8],
// [Uint32Array, dataViewInstance.getUint32, dataViewInstance.setUint32],
// // [BigUint64Array, dataViewInstance.getBigUint64, dataViewInstance.setBigUint64],
// [Uint16Array, dataViewInstance.getUint16, dataViewInstance.setUint16]
// ] as const;
const READ_WRITE_MAPS_V2 = [
[Uint8Array, "uint8"],
[Uint32Array, "uint32"],
// [BigUint64Array, dataViewInstance.getBigUint64, dataViewInstance.setBigUint64],
[Uint16Array, dataViewInstance.getUint16, dataViewInstance.setUint16]
[Uint16Array, "uint16"],
] as const;
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
dataViewInstance = undefined;
// dataViewInstance = undefined;
const READ_MAP = new Map(READ_WRITE_MAPS.map(e => [e[0], e[1]]));
const WRITE_MAP = new Map(READ_WRITE_MAPS.map(e => [e[0], e[2]]));
// const READ_MAP = new Map(READ_WRITE_MAPS.map(e => [e[0], e[1]]));
// const WRITE_MAP = new Map(READ_WRITE_MAPS.map(e => [e[0], e[2]]));
const READ_WRITE_MAP_V2 = new Map(READ_WRITE_MAPS_V2.map((e) => [e[0], e[1]]));
export interface MemoryOperator<T extends string> {

@@ -50,3 +59,3 @@ set(key: T, value: number): void;

memoryMap: MemoryMap<T>,
dataView: DataView,
carrier: GlobalCarrier,
startAddress: number

@@ -57,15 +66,17 @@ ): MemoryOperator<T> {

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const func = WRITE_MAP.get(memoryMap[key].type)!;
const func = READ_WRITE_MAP_V2.get(memoryMap[key].type)!;
return func.call(
dataView,
startAddress + memoryMap[key].bytesOffset,
value
);
return (carrier[func][
(startAddress + memoryMap[key].bytesOffset) /
memoryMap[key].type.BYTES_PER_ELEMENT
] = value);
},
get(key: T): number {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const func = READ_MAP.get(memoryMap[key].type)!;
const func = READ_WRITE_MAP_V2.get(memoryMap[key].type)!;
return func.call(dataView, startAddress + memoryMap[key].bytesOffset);
return carrier[func][
(startAddress + memoryMap[key].bytesOffset) /
memoryMap[key].type.BYTES_PER_ELEMENT
];
},

@@ -81,3 +92,3 @@ pointerTo(key: T): number {

},
size: memoryMap.SIZE_OF
size: memoryMap.SIZE_OF,
};

@@ -105,4 +116,4 @@ }

(oldEntries[index - 1][1] as any).BYTES_PER_ELEMENT,
type: type as any
}
type: type as any,
},
]);

@@ -116,3 +127,3 @@ }

(oldEntries[newObjectEntries.length - 1][1] as TypedArrayCtor)
.BYTES_PER_ELEMENT
.BYTES_PER_ELEMENT,
]);

@@ -131,5 +142,5 @@

createOperator: createMemoryOperator.bind(null, map) as (
dataView: DataView,
carrier: GlobalCarrier,
address: number
) => MemoryOperator<T>
) => MemoryOperator<T>,
};

@@ -150,3 +161,3 @@ }

key,
newObjectEntries[index - 1][1] + oldEntries[index - 1][1]
newObjectEntries[index - 1][1] + oldEntries[index - 1][1],
]);

@@ -159,8 +170,8 @@ }

newObjectEntries[newObjectEntries.length - 1][1] +
oldEntries[newObjectEntries.length - 1][1]
oldEntries[newObjectEntries.length - 1][1],
]);
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
return Object.fromEntries(newObjectEntries);
}

@@ -0,11 +1,7 @@

import { ExternalArgs, GlobalCarrier } from "./interfaces";
import {
ObjectEntry,
ExternalArgs,
DataViewAndAllocatorCarrier
} from "./interfaces";
import {
getObjectPropertiesEntries,
deleteObjectPropertyEntryByKey,
objectGet,
objectSet
objectSet,
} from "./objectWrapperHelpers";

@@ -16,3 +12,3 @@

IllegalObjectPropConfigError,
UnsupportedOperationError
UnsupportedOperationError,
} from "./exceptions";

@@ -22,6 +18,7 @@ import { allocationsTransaction } from "./allocationsTransaction";

import { hashMapNodeLookup } from "./hashmap/hashmap";
import { object_pointerToHashMap_get } from "./generatedStructs";
export class ObjectWrapper extends BaseProxyTrap<ObjectEntry>
implements ProxyHandler<{}> {
public get(target: {}, p: PropertyKey): any {
export class ObjectWrapper extends BaseProxyTrap
implements ProxyHandler<Record<string, unknown>> {
public get(target: Record<string, unknown>, p: PropertyKey): any {
if (p === INTERNAL_API_SYMBOL) {

@@ -35,6 +32,14 @@ return this;

return objectGet(this.externalArgs, this.carrier, this.entry.value, p);
return objectGet(
this.externalArgs,
this.carrier,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer),
p
);
}
public deleteProperty(target: {}, p: PropertyKey): boolean {
public deleteProperty(
target: Record<string, unknown>,
p: PropertyKey
): boolean {
if (typeof p === "symbol") {

@@ -45,5 +50,4 @@ return false;

return deleteObjectPropertyEntryByKey(
this.externalArgs,
this.carrier,
this.entry.value,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer),
p

@@ -56,6 +60,6 @@ );

this.carrier,
this.entry.value
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer)
);
return gotEntries.map(e => e.key);
return gotEntries.map((e) => e.key);
}

@@ -66,9 +70,12 @@

this.carrier,
this.entry.value
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer)
);
return gotEntries.map(e => e.key);
return gotEntries.map((e) => e.key);
}
public getOwnPropertyDescriptor(target: {}, p: PropertyKey) {
public getOwnPropertyDescriptor(
target: Record<string, unknown>,
p: PropertyKey
) {
if (this.has(target, p)) {

@@ -81,3 +88,3 @@ return { configurable: true, enumerable: true };

public has(target: {}, p: PropertyKey) {
public has(target: Record<string, unknown>, p: PropertyKey) {
if (p === INTERNAL_API_SYMBOL) {

@@ -91,6 +98,16 @@ return true;

return hashMapNodeLookup(this.carrier, this.entry.value, p) !== 0;
return (
hashMapNodeLookup(
this.carrier,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer),
p
) !== 0
);
}
public set(target: {}, p: PropertyKey, value: any): boolean {
public set(
target: Record<string, unknown>,
p: PropertyKey,
value: any
): boolean {
if (typeof p === "symbol") {

@@ -101,3 +118,9 @@ throw new IllegalObjectPropConfigError();

allocationsTransaction(() => {
objectSet(this.externalArgs, this.carrier, this.entry.value, p, value);
objectSet(
this.externalArgs,
this.carrier,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer),
p,
value
);
}, this.carrier.allocator);

@@ -120,3 +143,3 @@

public defineProperty(): // target: {},
public defineProperty(): // target: Record<string, unknown>,
// p: PropertyKey,

@@ -141,3 +164,3 @@ // attributes: PropertyDescriptor

externalArgs: ExternalArgs,
dataViewCarrier: DataViewAndAllocatorCarrier,
globalCarrier: GlobalCarrier,
entryPointer: number

@@ -147,4 +170,4 @@ ): T {

{ objectBufferWrapper: "objectBufferWrapper" },
new ObjectWrapper(externalArgs, dataViewCarrier, entryPointer)
new ObjectWrapper(externalArgs, globalCarrier, entryPointer)
) as any;
}

@@ -0,15 +1,6 @@

import { ExternalArgs, GlobalCarrier } from "./interfaces";
import {
ExternalArgs,
DataViewAndAllocatorCarrier,
StringEntry,
NumberEntry,
MapEntry,
SetEntry
} from "./interfaces";
import {
readEntry,
writeValueInPtrToPtrAndHandleMemory,
handleArcForDeletedValuePointer,
decrementRefCount,
writeEntry
} from "./store";

@@ -23,9 +14,17 @@ import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue";

hashMapValueLookup,
createHashMap
createHashMap,
} from "./hashmap/hashmap";
import { getObjectOrMapOrSetAddresses } from "./getAllLinkedAddresses";
import { getAllLinkedAddresses } from "./getAllLinkedAddresses";
import {
typeOnly_type_get,
number_value_get,
typeAndRc_refsCount_get,
typeAndRc_refsCount_set,
object_pointerToHashMap_set,
} from "./generatedStructs";
import { ENTRY_TYPE } from "./entry-types";
import { readString } from "./readString";
export function deleteObjectPropertyEntryByKey(
externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
hashmapPointer: number,

@@ -45,7 +44,8 @@ keyToDeleteBy: string | number

const deletedValuePointer = carrier.dataView.getUint32(
deletedValuePointerToPointer
);
const deletedValuePointer =
carrier.heap.Uint32Array[
deletedValuePointerToPointer / Uint32Array.BYTES_PER_ELEMENT
];
handleArcForDeletedValuePointer(externalArgs, carrier, deletedValuePointer);
handleArcForDeletedValuePointer(carrier, deletedValuePointer);

@@ -56,3 +56,3 @@ return true;

export function getObjectPropertiesEntries(
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
hashmapPointer: number

@@ -64,20 +64,22 @@ ): Array<{ key: string | number; valuePointer: number }> {

while (
(iterator = hashMapLowLevelIterator(
carrier.dataView,
hashmapPointer,
iterator
))
(iterator = hashMapLowLevelIterator(carrier, hashmapPointer, iterator))
) {
const { valuePointer, keyPointer } = hashMapNodePointerToKeyValue(
carrier.dataView,
carrier,
iterator
);
const keyEntry = readEntry(carrier, keyPointer) as
| StringEntry
| NumberEntry;
const typeOfKeyEntry:
| ENTRY_TYPE.NUMBER
| ENTRY_TYPE.STRING = typeOnly_type_get(carrier.heap, keyPointer);
const key =
typeOfKeyEntry === ENTRY_TYPE.NUMBER
? number_value_get(carrier.heap, keyPointer)
: readString(carrier.heap, keyPointer);
foundValues.push({
valuePointer: carrier.dataView.getUint32(valuePointer),
key: keyEntry.value
valuePointer:
carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT],
key,
});

@@ -91,6 +93,6 @@ }

externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
hashMapPointer: number,
p: string | number,
value: any
value: unknown
) {

@@ -109,3 +111,3 @@ const ptrToPtr = hashMapInsertUpdate(

externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
entryPointer: number,

@@ -116,30 +118,55 @@ key: string | number

if (valuePointer === 0) {
return undefined;
}
return entryToFinalJavaScriptValue(
externalArgs,
carrier,
carrier.dataView.getUint32(valuePointer)
carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT]
);
}
export function hashmapClearFree(
// export function hashmapClearFree(
// externalArgs: ExternalArgs,
// carrier: GlobalCarrier,
// hashmapPointer: number
// ) {
// const leafAddresses = new Set<number>();
// const addressesToProcessQueue: number[] = [];
// getObjectOrMapOrSetAddresses(
// carrier,
// hashmapPointer,
// leafAddresses,
// addressesToProcessQueue
// );
// for (const address of leafAddresses) {
// carrier.allocator.free(address);
// }
// for (const address of arcAddresses) {
// decrementRefCount(externalArgs, carrier, address);
// }
// }
export function mapOrSetClear(
externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
hashmapPointer: number
carrier: GlobalCarrier,
mapOrSetPtr: number
) {
const leafAddresses: number[] = [];
const arcAddresses: number[] = [];
// we fake the entry refCount as zero so getAllLinkedAddresses will visit what's needed
const prevCount = typeAndRc_refsCount_get(carrier.heap, mapOrSetPtr);
typeAndRc_refsCount_set(carrier.heap, mapOrSetPtr, 0);
getObjectOrMapOrSetAddresses(
const { leafAddresses, arcAddresses } = getAllLinkedAddresses(
carrier,
false,
hashmapPointer,
leafAddresses,
arcAddresses
mapOrSetPtr
);
for (const address of leafAddresses) {
// don't dispose the address we need to reuse
if (address === mapOrSetPtr) {
continue;
}
carrier.allocator.free(address);

@@ -149,18 +176,17 @@ }

for (const address of arcAddresses) {
decrementRefCount(externalArgs, carrier, address);
// don't dispose the address we need to reuse
if (address === mapOrSetPtr) {
continue;
}
decrementRefCount(carrier.heap, address);
}
}
export function mapOrSetClear(
externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
mapOrSetPtr: number
) {
const entry = readEntry(carrier, mapOrSetPtr) as MapEntry | SetEntry;
hashmapClearFree(externalArgs, carrier, entry.value);
entry.value = createHashMap(carrier, externalArgs.hashMapMinInitialCapacity);
writeEntry(carrier, mapOrSetPtr, entry);
// Restore real ref count
typeAndRc_refsCount_set(carrier.heap, mapOrSetPtr, prevCount);
object_pointerToHashMap_set(
carrier.heap,
mapOrSetPtr,
createHashMap(carrier, externalArgs.hashMapMinInitialCapacity)
);
}

@@ -0,1 +1,2 @@

/* eslint-disable @typescript-eslint/ban-ts-comment */
// @ts-nocheck

@@ -2,0 +3,0 @@

@@ -1,78 +0,237 @@

import {
primitiveValueToEntry,
isPrimitive,
getOurPointerIfApplicable
} from "./utils";
import { appendEntry } from "./store";
import { objectSaver, mapSaver, setSaver } from "./objectSaver";
import { arraySaver } from "./arraySaver";
import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces";
import { getOurPointerIfApplicable, strByteLength } from "./utils";
import { ExternalArgs, GlobalCarrier } from "./interfaces";
import { ENTRY_TYPE } from "./entry-types";
import {
number_size,
number_set_all,
bigint_size,
bigint_set_all,
string_size,
string_set_all,
date_size,
date_set_all,
} from "./generatedStructs";
import {
UNDEFINED_KNOWN_ADDRESS,
NULL_KNOWN_ADDRESS,
TRUE_KNOWN_ADDRESS,
FALSE_KNOWN_ADDRESS
FALSE_KNOWN_ADDRESS,
MAX_64_BIG_INT,
} from "./consts";
import { arraySaverIterative } from "./arraySaverIterative";
import {
objectSaverIterative,
mapSaverIterative,
setSaverIterative,
} from "./objectSaverIterative";
import { stringEncodeInto } from "./stringEncodeInto";
/**
* Returns pointer for the value
*/
export function saveValue(
export function saveValueIterative(
externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
referencedPointers: number[],
value: any
carrier: GlobalCarrier,
referencedExistingPointers: number[],
initialValuePtrToPtr: number,
initialValue: unknown
) {
let valuePointer = 0;
let maybeOurPointer: number | undefined;
const valuesToSave = [initialValue];
const pointersToSaveTo = [initialValuePtrToPtr];
const {
heap: { Uint32Array: uint32 },
allocator,
heap,
} = carrier;
if (value === undefined) {
return UNDEFINED_KNOWN_ADDRESS;
}
while (valuesToSave.length !== 0) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const valueToSave = valuesToSave.pop()!;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const ptrToPtrToSaveTo = pointersToSaveTo.pop()!;
if (value === null) {
return NULL_KNOWN_ADDRESS;
}
// Handler well-known values
if (valueToSave === undefined) {
uint32[
ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT
] = UNDEFINED_KNOWN_ADDRESS;
continue;
}
if (value === true) {
return TRUE_KNOWN_ADDRESS;
}
if (valueToSave === null) {
uint32[
ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT
] = NULL_KNOWN_ADDRESS;
continue;
}
if (value === false) {
return FALSE_KNOWN_ADDRESS;
}
if (valueToSave === true) {
uint32[
ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT
] = TRUE_KNOWN_ADDRESS;
continue;
}
if (isPrimitive(value)) {
const entry = primitiveValueToEntry(value);
valuePointer = appendEntry(externalArgs, carrier, entry);
} else if (
(maybeOurPointer = getOurPointerIfApplicable(value, carrier.dataView))
) {
valuePointer = maybeOurPointer;
referencedPointers.push(valuePointer);
} else if (Array.isArray(value)) {
valuePointer = arraySaver(externalArgs, carrier, referencedPointers, value);
} else if (value instanceof Date) {
valuePointer = appendEntry(externalArgs, carrier, {
type: ENTRY_TYPE.DATE,
refsCount: 1,
value: value.getTime()
});
} else if (value instanceof Map) {
valuePointer = mapSaver(externalArgs, carrier, referencedPointers, value);
} else if (value instanceof Set) {
valuePointer = setSaver(externalArgs, carrier, value);
} else if (typeof value === "object") {
valuePointer = objectSaver(
if (valueToSave === false) {
uint32[
ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT
] = FALSE_KNOWN_ADDRESS;
continue;
}
switch (typeof valueToSave) {
case "number":
uint32[
ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT
] = allocator.calloc(number_size);
number_set_all(
heap,
uint32[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT],
ENTRY_TYPE.NUMBER,
valueToSave
);
continue;
break;
case "string":
// eslint-disable-next-line no-case-declarations
const stringBytesLength = strByteLength(valueToSave);
// eslint-disable-next-line no-case-declarations
const stringDataPointer = allocator.calloc(stringBytesLength);
uint32[
ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT
] = allocator.calloc(string_size);
stringEncodeInto(heap.Uint8Array, stringDataPointer, valueToSave);
string_set_all(
heap,
uint32[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT],
ENTRY_TYPE.STRING,
stringBytesLength,
stringDataPointer
);
continue;
break;
case "bigint":
if (valueToSave > MAX_64_BIG_INT || valueToSave < -MAX_64_BIG_INT) {
uint32[
ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT
] = UNDEFINED_KNOWN_ADDRESS;
continue;
// Maybe don't make undefined but throw, or clamp
// throw new Error("MAX_64_BIG_INT");
}
uint32[
ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT
] = allocator.calloc(bigint_size);
bigint_set_all(
heap,
uint32[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT],
valueToSave > 0
? ENTRY_TYPE.BIGINT_POSITIVE
: ENTRY_TYPE.BIGINT_NEGATIVE,
valueToSave * (valueToSave > 0 ? BigInt("1") : BigInt("-1"))
);
continue;
break;
case "function":
// Nope Nope Nope
uint32[
ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT
] = UNDEFINED_KNOWN_ADDRESS;
continue;
break;
case "symbol":
// not supported, write undefined
uint32[
ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT
] = UNDEFINED_KNOWN_ADDRESS;
continue;
break;
// we will never get here
case "undefined":
continue;
break;
// we will never get here
case "boolean":
continue;
break;
}
const maybeOurPointerFromSymbol = getOurPointerIfApplicable(
valueToSave,
carrier.allocator
);
if (maybeOurPointerFromSymbol) {
referencedExistingPointers.push(maybeOurPointerFromSymbol);
heap.Uint32Array[
ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT
] = maybeOurPointerFromSymbol;
continue;
}
if (Array.isArray(valueToSave)) {
heap.Uint32Array[
ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT
] = arraySaverIterative(
externalArgs.arrayAdditionalAllocation,
carrier,
valuesToSave,
pointersToSaveTo,
valueToSave
);
continue;
}
if (valueToSave instanceof Date) {
heap.Uint32Array[
ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT
] = allocator.calloc(date_size);
date_set_all(
heap,
heap.Uint32Array[ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT],
ENTRY_TYPE.DATE,
1,
0,
valueToSave.getTime()
);
continue;
}
if (valueToSave instanceof Map) {
heap.Uint32Array[
ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT
] = mapSaverIterative(
externalArgs,
carrier,
valuesToSave,
pointersToSaveTo,
valueToSave
);
continue;
}
if (valueToSave instanceof Set) {
heap.Uint32Array[
ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT
] = setSaverIterative(externalArgs, carrier, valueToSave);
continue;
}
// Plain object? I hope so
heap.Uint32Array[
ptrToPtrToSaveTo / Uint32Array.BYTES_PER_ELEMENT
] = objectSaverIterative(
externalArgs,
carrier,
referencedPointers,
value
valuesToSave,
pointersToSaveTo,
valueToSave
);
} else {
throw new Error("unsupported yet");
}
return valuePointer;
}

@@ -0,11 +1,6 @@

import { ExternalArgs, GlobalCarrier, InternalAPI } from "./interfaces";
import {
ExternalArgs,
DataViewAndAllocatorCarrier,
MapEntry,
InternalAPI
} from "./interfaces";
import {
deleteObjectPropertyEntryByKey,
objectSet,
mapOrSetClear
mapOrSetClear,
} from "./objectWrapperHelpers";

@@ -21,8 +16,8 @@

hashMapNodePointerToKeyValue,
hashmapNodesPointerIterator
hashmapNodesPointerIterator,
} from "./hashmap/hashmap";
import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue";
import { object_pointerToHashMap_get } from "./generatedStructs";
export class SetWrapper<K extends string | number>
extends BaseProxyTrap<MapEntry>
export class SetWrapper<K extends string | number> extends BaseProxyTrap
implements Set<K> {

@@ -43,3 +38,6 @@ clear(): void {

get size(): number {
return hashMapSize(this.carrier.dataView, this.entry.value);
return hashMapSize(
this.carrier,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer)
);
}

@@ -53,9 +51,6 @@

for (const nodePointer of hashmapNodesPointerIterator(
this.carrier.dataView,
this.entry.value
this.carrier,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer)
)) {
const t = hashMapNodePointerToKeyValue(
this.carrier.dataView,
nodePointer
);
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer);

@@ -74,9 +69,6 @@ const key = entryToFinalJavaScriptValue(

for (const nodePointer of hashmapNodesPointerIterator(
this.carrier.dataView,
this.entry.value
this.carrier,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer)
)) {
const t = hashMapNodePointerToKeyValue(
this.carrier.dataView,
nodePointer
);
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer);

@@ -92,9 +84,6 @@ yield entryToFinalJavaScriptValue(

for (const nodePointer of hashmapNodesPointerIterator(
this.carrier.dataView,
this.entry.value
this.carrier,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer)
)) {
const t = hashMapNodePointerToKeyValue(
this.carrier.dataView,
nodePointer
);
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer);

@@ -126,3 +115,9 @@ yield entryToFinalJavaScriptValue(

return hashMapNodeLookup(this.carrier, this.entry.value, p) !== 0;
return (
hashMapNodeLookup(
this.carrier,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer),
p
) !== 0
);
}

@@ -139,3 +134,3 @@

this.carrier,
this.entry.value,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer),
p,

@@ -155,5 +150,4 @@ undefined

return deleteObjectPropertyEntryByKey(
this.externalArgs,
this.carrier,
this.entry.value,
object_pointerToHashMap_get(this.carrier.heap, this.entryPointer),
p

@@ -166,6 +160,6 @@ );

externalArgs: ExternalArgs,
dataViewCarrier: DataViewAndAllocatorCarrier,
globalCarrier: GlobalCarrier,
entryPointer: number
): Set<K> {
return new SetWrapper<K>(externalArgs, dataViewCarrier, entryPointer);
return new SetWrapper<K>(externalArgs, globalCarrier, entryPointer);
}
/* eslint-env jest */
import * as util from "util";
import { sizeOf } from "./sizeOf";

@@ -8,7 +7,5 @@ import { externalArgsApiToExternalArgsApi } from "./utils";

describe("sizeOf tests", () => {
describe.skip("sizeOf tests", () => {
const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});

@@ -28,3 +25,3 @@

calcedSize,
realSize: beforeSave - afterSave
realSize: beforeSave - afterSave,
};

@@ -38,4 +35,4 @@ }

Object {
"calcedSize": 64,
"realSize": 64,
"calcedSize": 72,
"realSize": 104,
}

@@ -52,3 +49,3 @@ `);

test("string", () => {
expect(sizeOf(externalArgs, "סלאם עליכום")).toMatchInlineSnapshot(`40`);
expect(sizeOf(externalArgs, "סלאם עליכום")).toMatchInlineSnapshot(`48`);
});

@@ -67,3 +64,3 @@

sizeOf(externalArgs, ["a", { a: "u" }, null, undefined, 1])
).toMatchInlineSnapshot(`356`);
).toMatchInlineSnapshot(`396`);
});

@@ -74,4 +71,4 @@

sizeOf(externalArgs, { a: 1, b: "some string" })
).toMatchInlineSnapshot(`256`);
).toMatchInlineSnapshot(`296`);
});
});

@@ -0,1 +1,2 @@

/* istanbul ignore file */
import {

@@ -5,3 +6,3 @@ ExternalArgsApi,

ArrayEntry,
ObjectEntry
ObjectEntry,
} from "./interfaces";

@@ -12,3 +13,3 @@ import {

primitiveValueToEntry,
align
align,
} from "./utils";

@@ -18,3 +19,3 @@ import { ENTRY_TYPE } from "./entry-types";

LINKED_LIST_MACHINE,
LINKED_LIST_ITEM_MACHINE
LINKED_LIST_ITEM_MACHINE,
} from "./linkedList/linkedList";

@@ -63,3 +64,3 @@ import { MAP_MACHINE, NODE_MACHINE } from "./hashmap/memoryLayout";

arrayToSave.length + externalArgs.arrayAdditionalAllocation,
length: arrayToSave.length
length: arrayToSave.length,
};

@@ -79,3 +80,3 @@

memoryAllocated,
numberOfAllocations
numberOfAllocations,
};

@@ -110,3 +111,3 @@ }

refsCount: 0,
value: 0
value: 0,
};

@@ -119,3 +120,3 @@

memoryAllocated,
numberOfAllocations
numberOfAllocations,
};

@@ -136,3 +137,3 @@ }

memoryAllocated: 0,
numberOfAllocations: 0
numberOfAllocations: 0,
};

@@ -146,3 +147,3 @@ }

memoryAllocated: align(sizeOfEntry(entry)),
numberOfAllocations: 1
numberOfAllocations: 1,
};

@@ -157,6 +158,6 @@ } else if (Array.isArray(value)) {

refsCount: 0,
value: value.getTime()
value: value.getTime(),
})
),
numberOfAllocations: 1
numberOfAllocations: 1,
};

@@ -197,3 +198,3 @@ } else if (typeof value === "object") {

const hashMapKeysSize = keysArray
.map(k => sizeOfEntry(primitiveValueToEntry(k)))
.map((k) => sizeOfEntry(primitiveValueToEntry(k)))
.reduce((p, c) => {

@@ -215,4 +216,4 @@ return p + align(c);

hashMapNodesAllocationsSize +
hashMapKeysSize
hashMapKeysSize,
};
}
/* eslint-env jest */
import {
writeEntry,
initializeArrayBuffer,
readEntry,
appendEntry
} from "./store";
import { ENTRY_TYPE } from "./entry-types";
import * as util from "util";
import { arrayBuffer2HexArray, makeCarrier } from "./testUtils";
import { ObjectEntry } from "./interfaces";
import { externalArgsApiToExternalArgsApi } from "./utils";
import { initializeArrayBuffer } from "./store";
import { arrayBuffer2HexArray } from "./testUtils";
describe("Store tests - Misc", () => {

@@ -27,6 +19,6 @@ test("initializeArrayBuffer", () => {

"3:0x00",
"4:0x00",
"4:0x08",
"5:0x00",
"6:0x00",
"7:0x08",
"7:0x00",
"8:0x00",

@@ -48,500 +40,1 @@ "9:0x00",

});
describe("Store tests writeEntry", () => {
test("writeEntry max number", () => {
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
writeEntry(carrier, 8, {
type: ENTRY_TYPE.NUMBER,
value: Number.MAX_VALUE
});
expect(arrayBuffer2HexArray(arrayBuffer.slice(0, 17)))
.toMatchInlineSnapshot(`
Array [
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x02",
"0x7f",
"0xef",
"0xff",
"0xff",
"0xff",
"0xff",
"0xff",
"0xff",
]
`);
});
test("writeEntry min number", () => {
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
writeEntry(carrier, 8, {
type: ENTRY_TYPE.NUMBER,
value: Number.MIN_VALUE
});
expect(arrayBuffer2HexArray(arrayBuffer.slice(0, 17)))
.toMatchInlineSnapshot(`
Array [
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x02",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x01",
]
`);
});
test("writeEntry string", () => {
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
writeEntry(carrier, 8, {
type: ENTRY_TYPE.STRING,
value: "aא弟",
allocatedBytes: 6
});
expect(arrayBuffer2HexArray(arrayBuffer.slice(0, 19)))
.toMatchInlineSnapshot(`
Array [
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x05",
"0x00",
"0x06",
"0x00",
"0x06",
"0x61",
"0xd7",
"0x90",
"0xe5",
"0xbc",
"0x9f",
]
`);
});
});
describe("Store tests readEntry", () => {
const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
});
test("readEntry max number", () => {
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
writeEntry(carrier, 8, {
type: ENTRY_TYPE.NUMBER,
value: Number.MAX_VALUE
});
const redEntry = readEntry(carrier, 8);
// expect(redBytesLength).toBe(writtenLength);
expect(redEntry).toMatchInlineSnapshot(`
Object {
"type": 2,
"value": 1.7976931348623157e+308,
}
`);
});
test("readEntry min number", () => {
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
writeEntry(carrier, 8, {
type: ENTRY_TYPE.NUMBER,
value: Number.MIN_VALUE
});
const redEntry = readEntry(carrier, 8);
expect(redEntry).toMatchInlineSnapshot(`
Object {
"type": 2,
"value": 5e-324,
}
`);
});
test("readEntry string", () => {
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
writeEntry(carrier, 0, {
type: ENTRY_TYPE.STRING,
value: "aא弟",
allocatedBytes: 6
});
const entry = readEntry(carrier, 0);
expect(entry).toMatchInlineSnapshot(`
Object {
"allocatedBytes": 6,
"type": 5,
"value": "aא弟",
}
`);
});
test("readEntry BigInt", () => {
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
writeEntry(carrier, 0, {
type: ENTRY_TYPE.BIGINT_POSITIVE,
value: BigInt("0b0" + "1".repeat(63))
});
const entry = readEntry(carrier, 0);
expect(entry).toMatchInlineSnapshot(`
Object {
"type": 3,
"value": 9223372036854775807n,
}
`);
});
test("readEntry UBigInt", () => {
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
writeEntry(carrier, 0, {
type: ENTRY_TYPE.BIGINT_POSITIVE,
value: BigInt("0b" + "1".repeat(64))
});
const entry = readEntry(carrier, 0);
expect(entry).toMatchInlineSnapshot(`
Object {
"type": 3,
"value": 18446744073709551615n,
}
`);
});
test("ENTRY_TYPE.BIGINT_POSITIVE max value", () => {
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
writeEntry(carrier, 0, {
type: ENTRY_TYPE.BIGINT_POSITIVE,
value: BigInt("0b" + "1".repeat(64))
});
expect(readEntry(carrier, 0)).toMatchInlineSnapshot(`
Object {
"type": 3,
"value": 18446744073709551615n,
}
`);
});
test("ENTRY_TYPE.BIGINT_NEGATIVE min value", () => {
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
writeEntry(carrier, 0, {
type: ENTRY_TYPE.BIGINT_NEGATIVE,
value: -BigInt("0b" + "1".repeat(64))
});
expect(readEntry(carrier, 0)).toMatchInlineSnapshot(`
Object {
"type": 4,
"value": -18446744073709551615n,
}
`);
});
test("BigInt64 overflow error", () => {
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
expect(() => {
writeEntry(carrier, 0, {
type: ENTRY_TYPE.BIGINT_POSITIVE,
value: BigInt("0b" + "1".repeat(65))
});
}).toThrowErrorMatchingInlineSnapshot(`"BigInt64OverflowError"`);
});
describe("Store tests write/read entry", () => {
test("object entry", () => {
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
const entryToWrite: ObjectEntry = {
type: ENTRY_TYPE.OBJECT,
refsCount: 0,
value: 10
};
writeEntry(carrier, 0, entryToWrite);
const entry = readEntry(carrier, 0);
expect(entry).toMatchInlineSnapshot(`
Object {
"refsCount": 0,
"type": 7,
"value": 10,
}
`);
});
});
describe("appendEntry - general", () => {
test("appendEntry", () => {
const arrayBuffer = new ArrayBuffer(96);
initializeArrayBuffer(arrayBuffer);
const carrier = makeCarrier(arrayBuffer);
const r1 = appendEntry(externalArgs, carrier, {
type: ENTRY_TYPE.STRING,
value: "im a string",
allocatedBytes: 11
});
expect(r1).toMatchInlineSnapshot(`48`);
expect(arrayBuffer2HexArray(arrayBuffer, true)).toMatchInlineSnapshot(`
Array [
"0:0x00",
"1:0x00",
"2:0x00",
"3:0x00",
"4:0x00",
"5:0x00",
"6:0x00",
"7:0x08",
"8:0x00",
"9:0x00",
"10:0x00",
"11:0x00",
"12:0x00",
"13:0x00",
"14:0x00",
"15:0x00",
"16:0x28",
"17:0x00",
"18:0x00",
"19:0x00",
"20:0x40",
"21:0x00",
"22:0x00",
"23:0x00",
"24:0x60",
"25:0x00",
"26:0x00",
"27:0x00",
"28:0x08",
"29:0x00",
"30:0x00",
"31:0x00",
"32:0x03",
"33:0x00",
"34:0x00",
"35:0x00",
"36:0x10",
"37:0x00",
"38:0x00",
"39:0x00",
"40:0x18",
"41:0x00",
"42:0x00",
"43:0x00",
"44:0x00",
"45:0x00",
"46:0x00",
"47:0x00",
"48:0x05",
"49:0x00",
"50:0x0b",
"51:0x00",
"52:0x0b",
"53:0x69",
"54:0x6d",
"55:0x20",
"56:0x61",
"57:0x20",
"58:0x73",
"59:0x74",
"60:0x72",
"61:0x69",
"62:0x6e",
"63:0x67",
"64:0x00",
"65:0x00",
"66:0x00",
"67:0x00",
"68:0x00",
"69:0x00",
"70:0x00",
"71:0x00",
"72:0x00",
"73:0x00",
"74:0x00",
"75:0x00",
"76:0x00",
"77:0x00",
"78:0x00",
"79:0x00",
"80:0x00",
"81:0x00",
"82:0x00",
"83:0x00",
"84:0x00",
"85:0x00",
"86:0x00",
"87:0x00",
"88:0x00",
"89:0x00",
"90:0x00",
"91:0x00",
"92:0x00",
"93:0x00",
"94:0x00",
"95:0x00",
]
`);
expect(arrayBuffer2HexArray(arrayBuffer, true)).toMatchInlineSnapshot(`
Array [
"0:0x00",
"1:0x00",
"2:0x00",
"3:0x00",
"4:0x00",
"5:0x00",
"6:0x00",
"7:0x08",
"8:0x00",
"9:0x00",
"10:0x00",
"11:0x00",
"12:0x00",
"13:0x00",
"14:0x00",
"15:0x00",
"16:0x28",
"17:0x00",
"18:0x00",
"19:0x00",
"20:0x40",
"21:0x00",
"22:0x00",
"23:0x00",
"24:0x60",
"25:0x00",
"26:0x00",
"27:0x00",
"28:0x08",
"29:0x00",
"30:0x00",
"31:0x00",
"32:0x03",
"33:0x00",
"34:0x00",
"35:0x00",
"36:0x10",
"37:0x00",
"38:0x00",
"39:0x00",
"40:0x18",
"41:0x00",
"42:0x00",
"43:0x00",
"44:0x00",
"45:0x00",
"46:0x00",
"47:0x00",
"48:0x05",
"49:0x00",
"50:0x0b",
"51:0x00",
"52:0x0b",
"53:0x69",
"54:0x6d",
"55:0x20",
"56:0x61",
"57:0x20",
"58:0x73",
"59:0x74",
"60:0x72",
"61:0x69",
"62:0x6e",
"63:0x67",
"64:0x00",
"65:0x00",
"66:0x00",
"67:0x00",
"68:0x00",
"69:0x00",
"70:0x00",
"71:0x00",
"72:0x00",
"73:0x00",
"74:0x00",
"75:0x00",
"76:0x00",
"77:0x00",
"78:0x00",
"79:0x00",
"80:0x00",
"81:0x00",
"82:0x00",
"83:0x00",
"84:0x00",
"85:0x00",
"86:0x00",
"87:0x00",
"88:0x00",
"89:0x00",
"90:0x00",
"91:0x00",
"92:0x00",
"93:0x00",
"94:0x00",
"95:0x00",
]
`);
});
});
});

@@ -1,4 +0,4 @@

import { ENTRY_TYPE, isPrimitiveEntryType } from "./entry-types";
import { Entry, primitive, DataViewAndAllocatorCarrier } from "./interfaces";
import { isPrimitive, primitiveValueToEntry, strByteLength } from "./utils";
import { ENTRY_TYPE } from "./entry-types";
import { Entry, GlobalCarrier } from "./interfaces";
import { isKnownAddressValuePointer, isTypeWithRC } from "./utils";
import { ExternalArgs } from "./interfaces";

@@ -9,11 +9,15 @@ import { BigInt64OverflowError } from "./exceptions";

INITIAL_ENTRY_POINTER_VALUE,
UNDEFINED_KNOWN_ADDRESS,
NULL_KNOWN_ADDRESS,
TRUE_KNOWN_ADDRESS,
FALSE_KNOWN_ADDRESS
} from "./consts";
import { saveValue } from "./saveValue";
import { getAllLinkedAddresses } from "./getAllLinkedAddresses";
import { stringEncodeInto } from "./stringEncodeInto";
import { stringDecode } from "./stringDecode";
import {
typeAndRc_refsCount_get,
typeAndRc_refsCount_set,
typeOnly_type_get,
number_value_get,
string_bytesLength_get,
string_charsPointer_get,
} from "./generatedStructs";
import { Heap } from "../structsGenerator/consts";
import { readString } from "./readString";
import { saveValueIterative } from "./saveValue";

@@ -23,14 +27,8 @@ const MAX_64_BIG_INT = BigInt("0xFFFFFFFFFFFFFFFF");

export function initializeArrayBuffer(arrayBuffer: ArrayBuffer) {
const dataView = new DataView(arrayBuffer);
const uint32 = new Uint32Array(arrayBuffer);
// global lock
dataView.setInt32(0, 0);
// first entry pointer
dataView.setUint32(
INITIAL_ENTRY_POINTER_TO_POINTER,
INITIAL_ENTRY_POINTER_VALUE
);
return dataView;
uint32[0] = 0;
uint32[
INITIAL_ENTRY_POINTER_TO_POINTER / Uint32Array.BYTES_PER_ELEMENT
] = INITIAL_ENTRY_POINTER_VALUE;
}

@@ -41,3 +39,4 @@

cursor += Uint8Array.BYTES_PER_ELEMENT;
// type
cursor += Float64Array.BYTES_PER_ELEMENT;

@@ -50,6 +49,5 @@ switch (entry.type) {

case ENTRY_TYPE.STRING:
cursor += Uint16Array.BYTES_PER_ELEMENT;
// string length
cursor += Uint32Array.BYTES_PER_ELEMENT;
cursor += Uint16Array.BYTES_PER_ELEMENT;
cursor += entry.allocatedBytes;

@@ -75,21 +73,29 @@

case ENTRY_TYPE.SET:
cursor += Uint8Array.BYTES_PER_ELEMENT;
// ref count
cursor += Uint32Array.BYTES_PER_ELEMENT;
// pointer
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.ARRAY:
// refsCount
cursor += Uint32Array.BYTES_PER_ELEMENT;
// pointer
cursor += Uint32Array.BYTES_PER_ELEMENT;
// length
cursor += Uint32Array.BYTES_PER_ELEMENT;
cursor += Uint8Array.BYTES_PER_ELEMENT;
// allocated length
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.DATE:
// timestamp
cursor += Float64Array.BYTES_PER_ELEMENT;
cursor += Uint8Array.BYTES_PER_ELEMENT;
// ref count
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;
default:
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
throw new Error(ENTRY_TYPE[entry.type] + " Not implemented yet");

@@ -101,270 +107,19 @@ }

export function writeEntry(
{ dataView, uint8 }: DataViewAndAllocatorCarrier,
startingCursor: number,
entry: Entry
) {
let cursor = startingCursor;
// let writtenDataSizeInBytes = 0;
// write type
// undo on throw ?
dataView.setUint8(cursor, entry.type);
cursor += Uint8Array.BYTES_PER_ELEMENT;
switch (entry.type) {
case ENTRY_TYPE.NUMBER:
dataView.setFloat64(cursor, entry.value);
cursor += Float64Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.STRING:
dataView.setUint16(cursor, entry.allocatedBytes);
cursor += Uint16Array.BYTES_PER_ELEMENT;
dataView.setUint16(cursor, entry.allocatedBytes);
cursor += Uint16Array.BYTES_PER_ELEMENT;
// const arr = new Uint8Array(entry.allocatedBytes);
// const writtenBytes1 = stringEncodeInto(arr, 0, entry.value);
// eslint-disable-next-line no-case-declarations
const writtenBytes = stringEncodeInto(uint8, cursor, entry.value);
if (writtenBytes !== entry.allocatedBytes) {
// eslint-disable-next-line no-undef
console.warn({
value: entry.value,
writtenBytes,
allocatedBytes: entry.allocatedBytes
});
throw new Error("WTF???");
}
cursor += entry.allocatedBytes;
break;
case ENTRY_TYPE.BIGINT_NEGATIVE:
case ENTRY_TYPE.BIGINT_POSITIVE:
if (entry.value > MAX_64_BIG_INT || entry.value < -MAX_64_BIG_INT) {
throw new BigInt64OverflowError();
}
dataView.setBigUint64(
cursor,
entry.type === ENTRY_TYPE.BIGINT_NEGATIVE ? -entry.value : entry.value
);
cursor += BigUint64Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.OBJECT:
case ENTRY_TYPE.SET:
case ENTRY_TYPE.MAP:
dataView.setUint8(cursor, entry.refsCount);
cursor += Uint8Array.BYTES_PER_ELEMENT;
dataView.setUint32(cursor, entry.value);
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.ARRAY:
dataView.setUint8(cursor, entry.refsCount);
cursor += Uint8Array.BYTES_PER_ELEMENT;
dataView.setUint32(cursor, entry.value);
cursor += Uint32Array.BYTES_PER_ELEMENT;
dataView.setUint32(cursor, entry.length);
cursor += Uint32Array.BYTES_PER_ELEMENT;
dataView.setUint32(cursor, entry.allocatedLength);
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.DATE:
dataView.setUint8(cursor, entry.refsCount);
cursor += Uint8Array.BYTES_PER_ELEMENT;
dataView.setFloat64(cursor, entry.value);
cursor += Float64Array.BYTES_PER_ELEMENT;
break;
default:
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
throw new Error(ENTRY_TYPE[entry.type] + " Not implemented yet");
}
}
export function appendEntry(
externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
entry: Entry
) {
const size = sizeOfEntry(entry);
const memoryAddress = carrier.allocator.calloc(size);
writeEntry(carrier, memoryAddress, entry);
return memoryAddress;
}
export function readEntry(
carrier: DataViewAndAllocatorCarrier,
startingCursor: number
): Entry {
let cursor = startingCursor;
const entryType: ENTRY_TYPE = carrier.dataView.getUint8(cursor);
cursor += Uint8Array.BYTES_PER_ELEMENT;
const entry: any = {
type: entryType,
value: undefined as any
};
// let writtenDataSizeInBytes = 0;
switch (entryType) {
case ENTRY_TYPE.UNDEFINED:
break;
case ENTRY_TYPE.NULL:
break;
case ENTRY_TYPE.BOOLEAN:
entry.value = carrier.dataView.getUint8(cursor) !== 0;
cursor += Uint8Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.NUMBER:
entry.value = carrier.dataView.getFloat64(cursor);
cursor += Float64Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.STRING:
// eslint-disable-next-line no-case-declarations
const stringLength = carrier.dataView.getUint16(cursor);
cursor += Uint16Array.BYTES_PER_ELEMENT;
entry.allocatedBytes = carrier.dataView.getUint16(cursor);
cursor += Uint16Array.BYTES_PER_ELEMENT;
// decode fails with zero length array
if (stringLength > 0) {
// this wrapping is needed until:
// https://github.com/whatwg/encoding/issues/172
// eslint-disable-next-line no-case-declarations
// const tempAB = new ArrayBuffer(stringLength);
// arrayBufferCopyTo(dataView.buffer, cursor, stringLength, tempAB, 0);
entry.value = stringDecode(carrier.uint8, cursor, stringLength);
} else {
entry.value = "";
}
cursor += stringLength;
break;
case ENTRY_TYPE.BIGINT_POSITIVE:
entry.value = carrier.dataView.getBigUint64(cursor);
cursor += BigUint64Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.BIGINT_NEGATIVE:
entry.value = -carrier.dataView.getBigUint64(cursor);
cursor += BigUint64Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.OBJECT:
case ENTRY_TYPE.MAP:
case ENTRY_TYPE.SET:
entry.refsCount = carrier.dataView.getUint8(cursor);
cursor += Uint8Array.BYTES_PER_ELEMENT;
entry.value = carrier.dataView.getUint32(cursor);
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.ARRAY:
entry.refsCount = carrier.dataView.getUint8(cursor);
cursor += Uint8Array.BYTES_PER_ELEMENT;
entry.value = carrier.dataView.getUint32(cursor);
cursor += Uint32Array.BYTES_PER_ELEMENT;
entry.length = carrier.dataView.getUint32(cursor);
cursor += Uint32Array.BYTES_PER_ELEMENT;
entry.allocatedLength = carrier.dataView.getUint32(cursor);
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.DATE:
entry.refsCount = carrier.dataView.getUint8(cursor);
cursor += Uint8Array.BYTES_PER_ELEMENT;
entry.value = carrier.dataView.getFloat64(cursor);
cursor += Float64Array.BYTES_PER_ELEMENT;
break;
default:
throw new Error(ENTRY_TYPE[entryType] + " Not implemented yet");
}
return entry;
}
export function canReuseMemoryOfEntry(entryA: Entry, value: primitive) {
const typeofTheValue = typeof value;
// number & bigint 64 are the same size
if (
(entryA.type === ENTRY_TYPE.BIGINT_NEGATIVE ||
entryA.type === ENTRY_TYPE.BIGINT_POSITIVE ||
entryA.type === ENTRY_TYPE.NUMBER) &&
(typeofTheValue === "bigint" || typeofTheValue === "number")
) {
return true;
}
if (
entryA.type === ENTRY_TYPE.STRING &&
typeofTheValue === "string" &&
entryA.allocatedBytes >= strByteLength(value as string)
) {
return true;
}
return false;
}
export function writeValueInPtrToPtr(
externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
ptrToPtr: number,
value: any
value: unknown
) {
const existingEntryPointer = carrier.dataView.getUint32(ptrToPtr);
const existingValueEntry = readEntry(carrier, existingEntryPointer);
const referencedPointers: number[] = [];
// Might oom here
saveValueIterative(
externalArgs,
carrier,
referencedPointers,
ptrToPtr,
value
);
// try to re use memory
if (
isPrimitive(value) &&
isPrimitiveEntryType(existingValueEntry.type) &&
canReuseMemoryOfEntry(existingValueEntry, value) &&
existingEntryPointer !== 0
) {
const newEntry = primitiveValueToEntry(value);
writeEntry(carrier, existingEntryPointer, newEntry);
} else {
const referencedPointers: number[] = [];
const newEntryPointer = saveValue(
externalArgs,
carrier,
referencedPointers,
value
);
carrier.dataView.setUint32(ptrToPtr, newEntryPointer);
return {
referencedPointers,
existingEntryPointer,
existingValueEntry
};
}
return referencedPointers;
}

@@ -374,135 +129,86 @@

externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
ptrToPtr: number,
value: any
value: unknown
) {
const {
existingValueEntry = false,
existingEntryPointer = 0,
referencedPointers = []
} = writeValueInPtrToPtr(externalArgs, carrier, ptrToPtr, value) || {};
const existingEntryPointer =
carrier.heap.Uint32Array[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT];
// Might oom here
const referencedPointers = writeValueInPtrToPtr(
externalArgs,
carrier,
ptrToPtr,
value
);
// -- end of might oom
// commit ref count changes of existing objects
if (referencedPointers.length > 0) {
for (const ptr of referencedPointers) {
incrementRefCount(externalArgs, carrier, ptr);
incrementRefCount(carrier.heap, ptr);
}
}
if (existingValueEntry && "refsCount" in existingValueEntry) {
const newRefCount = decrementRefCount(
externalArgs,
carrier,
existingEntryPointer
);
if (newRefCount === 0) {
const addressesToFree = getAllLinkedAddresses(
carrier,
false,
existingEntryPointer
);
for (const address of addressesToFree.leafAddresses) {
carrier.allocator.free(address);
}
for (const address of addressesToFree.arcAddresses) {
decrementRefCount(externalArgs, carrier, address);
}
}
} else {
carrier.allocator.free(existingEntryPointer);
}
handleArcForDeletedValuePointer(carrier, existingEntryPointer);
}
export function handleArcForDeletedValuePointer(
externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
deletedValuePointer: number
): void {
const { heap, allocator } = carrier;
// No memory to free/ARC
if (
deletedValuePointer === UNDEFINED_KNOWN_ADDRESS ||
deletedValuePointer === NULL_KNOWN_ADDRESS ||
deletedValuePointer === TRUE_KNOWN_ADDRESS ||
deletedValuePointer === FALSE_KNOWN_ADDRESS
) {
if (isKnownAddressValuePointer(deletedValuePointer)) {
return;
}
const existingValueEntry = readEntry(carrier, deletedValuePointer);
if (existingValueEntry && "refsCount" in existingValueEntry) {
const newRefCount = decrementRefCount(
externalArgs,
carrier,
deletedValuePointer
);
if (newRefCount === 0) {
const addressesToFree = getAllLinkedAddresses(
carrier,
false,
deletedValuePointer
const entryType = typeOnly_type_get(heap, deletedValuePointer);
if (!isTypeWithRC(entryType)) {
if (entryType === ENTRY_TYPE.STRING) {
allocator.free(
string_charsPointer_get(carrier.heap, deletedValuePointer)
);
for (const address of addressesToFree.leafAddresses) {
carrier.allocator.free(address);
}
for (const address of addressesToFree.arcAddresses) {
decrementRefCount(externalArgs, carrier, address);
}
}
} else {
carrier.allocator.free(deletedValuePointer);
allocator.free(deletedValuePointer);
return;
}
}
export function incrementRefCount(
externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
entryPointer: number
) {
const entry = readEntry(carrier, entryPointer);
if (decrementRefCount(heap, deletedValuePointer) > 0) {
allocator.free(deletedValuePointer);
return;
}
if ("refsCount" in entry) {
entry.refsCount += 1;
writeEntry(carrier, entryPointer, entry);
const { leafAddresses, arcAddresses } = getAllLinkedAddresses(
carrier,
false,
deletedValuePointer
);
return entry.refsCount;
for (const address of leafAddresses) {
allocator.free(address);
}
throw new Error("unexpected");
for (const address of arcAddresses) {
decrementRefCount(heap, address);
}
}
export function decrementRefCount(
externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
entryPointer: number
) {
const entry = readEntry(carrier, entryPointer);
export function incrementRefCount(heap: Heap, entryPointer: number) {
typeAndRc_refsCount_set(
heap,
entryPointer,
typeAndRc_refsCount_get(heap, entryPointer) + 1
);
if ("refsCount" in entry) {
entry.refsCount -= 1;
writeEntry(carrier, entryPointer, entry);
return entry.refsCount;
}
throw new Error("unexpected");
return typeAndRc_refsCount_get(heap, entryPointer);
}
export function getObjectPropPtrToPtr(
{ dataView }: DataViewAndAllocatorCarrier,
pointerToEntry: number
) {
const keyStringLength = dataView.getUint16(pointerToEntry + 1);
const valuePtrToPtr =
Uint16Array.BYTES_PER_ELEMENT + pointerToEntry + 1 + keyStringLength;
const nextPtrToPtr = valuePtrToPtr + Uint32Array.BYTES_PER_ELEMENT;
export function decrementRefCount(heap: Heap, entryPointer: number) {
typeAndRc_refsCount_set(
heap,
entryPointer,
typeAndRc_refsCount_get(heap, entryPointer) - 1
);
return {
valuePtrToPtr,
nextPtrToPtr
};
return typeAndRc_refsCount_get(heap, entryPointer);
}

@@ -515,3 +221,3 @@

export function memComp(
dataView: DataView,
uint8: Uint8Array,
aStart: number,

@@ -522,4 +228,4 @@ bStart: number,

if (
dataView.byteLength < aStart + length ||
dataView.byteLength < bStart + length
uint8.byteLength < aStart + length ||
uint8.byteLength < bStart + length
) {

@@ -530,3 +236,3 @@ return false;

// compare 8 using Float64Array?
if (dataView.getUint8(aStart + i) !== dataView.getUint8(bStart + i)) {
if (uint8[aStart + i] !== uint8[bStart + i]) {
return false;

@@ -540,10 +246,55 @@ }

export function compareStringOrNumberEntriesInPlace(
dataView: DataView,
heap: Heap,
entryAPointer: number,
entryBPointer: number
) {
typeOnly_type_get(heap, entryAPointer);
const entryAType: ENTRY_TYPE.STRING | ENTRY_TYPE.NUMBER = typeOnly_type_get(
heap,
entryAPointer
);
const entryBType: ENTRY_TYPE.STRING | ENTRY_TYPE.NUMBER = typeOnly_type_get(
heap,
entryBPointer
);
if (entryAType !== entryBType) {
return false;
}
if (entryAType === ENTRY_TYPE.STRING) {
const aLength = string_bytesLength_get(heap, entryAPointer);
const bLength = string_bytesLength_get(heap, entryBPointer);
if (aLength !== bLength) {
return false;
}
return memComp(
heap.Uint8Array,
string_charsPointer_get(heap, entryAPointer),
string_charsPointer_get(heap, entryBPointer),
aLength
);
}
// numbers
return (
number_value_get(heap, entryAPointer) ===
number_value_get(heap, entryBPointer)
);
}
export function compareStringOrNumberEntriesInPlaceOld(
carrier: GlobalCarrier,
entryAPointer: number,
entryBPointer: number
) {
let cursor = 0;
const entryAType: ENTRY_TYPE = dataView.getUint8(entryAPointer + cursor);
const entryBType: ENTRY_TYPE = dataView.getUint8(entryBPointer + cursor);
cursor += 1;
const entryAType: ENTRY_TYPE =
carrier.float64[(entryAPointer + cursor) / Float64Array.BYTES_PER_ELEMENT];
const entryBType: ENTRY_TYPE =
carrier.float64[(entryBPointer + cursor) / Float64Array.BYTES_PER_ELEMENT];
cursor += Float64Array.BYTES_PER_ELEMENT;

@@ -555,4 +306,6 @@ if (entryAType !== entryBType) {

if (entryAType === ENTRY_TYPE.STRING) {
const aLength = dataView.getUint16(entryAPointer + cursor);
const bLength = dataView.getUint16(entryBPointer + cursor);
const aLength =
carrier.uint32[(entryAPointer + cursor) / Uint32Array.BYTES_PER_ELEMENT];
const bLength =
carrier.uint32[(entryBPointer + cursor) / Uint32Array.BYTES_PER_ELEMENT];

@@ -564,8 +317,6 @@ if (aLength !== bLength) {

// string length
cursor += Uint16Array.BYTES_PER_ELEMENT;
// allocated length, skip.
cursor += Uint16Array.BYTES_PER_ELEMENT;
cursor += Uint32Array.BYTES_PER_ELEMENT;
return memComp(
dataView,
carrier.uint8,
entryAPointer + cursor,

@@ -578,5 +329,20 @@ entryBPointer + cursor,

return (
dataView.getFloat64(entryAPointer + cursor) ===
dataView.getFloat64(entryBPointer + cursor)
carrier.float64[
(entryAPointer + cursor) / Float64Array.BYTES_PER_ELEMENT
] ===
carrier.float64[(entryBPointer + cursor) / Float64Array.BYTES_PER_ELEMENT]
);
}
export function readNumberOrString(heap: Heap, pointer: number) {
const type: ENTRY_TYPE.NUMBER | ENTRY_TYPE.STRING = typeOnly_type_get(
heap,
pointer
);
if (type === ENTRY_TYPE.NUMBER) {
return number_value_get(heap, pointer);
} else {
return readString(heap, pointer);
}
}

@@ -19,4 +19,4 @@ /* eslint-env jest */

`請教「署」在文中的含義。 文句中「署」是什么意思?「使直言署」,及下文的「署帛宛然」a`,
125
]
125,
],
];

@@ -23,0 +23,0 @@

@@ -21,4 +21,4 @@ /* eslint-env jest */

`請教「署」在文中的含義。 文句中「署」是什么意思?「使直言署」,及下文的「署帛宛然」`,
124
]
124,
],
];

@@ -25,0 +25,0 @@

@@ -17,3 +17,3 @@ export function arrayBuffer2HexArray(

export function wait(time: number) {
return new Promise(res => {
return new Promise((res) => {
// eslint-disable-next-line no-undef

@@ -26,4 +26,5 @@ setTimeout(res, time);

import { OutOfMemoryError } from "./exceptions";
import { DataViewAndAllocatorCarrier } from "./interfaces";
import { GlobalCarrier } from "./interfaces";
import { MEM_POOL_START } from "./consts";
import { createHeap } from "../structsGenerator/consts";

@@ -82,4 +83,4 @@ // extend pool and not monkey patch? need to think about it

// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
pool.free = function free(ptr: number) {

@@ -104,7 +105,7 @@ deallocations.add(ptr);

buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});
const carrier: DataViewAndAllocatorCarrier = {
dataView: new DataView(arrayBuffer),
const carrier: GlobalCarrier = {
// dataView: new DataView(arrayBuffer),
allocator,

@@ -115,3 +116,4 @@ uint8: new Uint8Array(arrayBuffer),

float64: new Float64Array(arrayBuffer),
bigUint64: new BigUint64Array(arrayBuffer)
bigUint64: new BigUint64Array(arrayBuffer),
heap: createHeap(arrayBuffer),
};

@@ -118,0 +120,0 @@

@@ -6,6 +6,13 @@ import {

InternalAPI,
ExternalArgsApi
ExternalArgsApi,
} from "./interfaces";
import { ENTRY_TYPE } from "./entry-types";
import { INTERNAL_API_SYMBOL } from "./symbols";
import {
UNDEFINED_KNOWN_ADDRESS,
NULL_KNOWN_ADDRESS,
TRUE_KNOWN_ADDRESS,
FALSE_KNOWN_ADDRESS,
} from "./consts";
import { IMemPool } from "@thi.ng/malloc";

@@ -17,3 +24,3 @@ const primitives = [

"boolean",
"undefined"
"undefined",
] as const;

@@ -38,3 +45,3 @@

value,
allocatedBytes: strByteLength(value)
allocatedBytes: strByteLength(value),
};

@@ -46,3 +53,3 @@ }

type: ENTRY_TYPE.NUMBER,
value
value,
};

@@ -57,3 +64,3 @@ }

: ENTRY_TYPE.BIGINT_NEGATIVE,
value
value,
};

@@ -87,11 +94,9 @@ }

for (let i = 0; i < length; i += 1) {
copyTo[toTargetByte + i] = copyFrom[startByte + i];
}
copyTo.set(copyFrom.subarray(startByte, startByte + length), toTargetByte);
}
export function getOurPointerIfApplicable(value: any, ourDateView: DataView) {
export function getOurPointerIfApplicable(value: any, ourAllocator: IMemPool) {
if (INTERNAL_API_SYMBOL in value) {
const api = getInternalAPI(value);
if (api.getCarrier().dataView === ourDateView) {
if (api.getCarrier().allocator === ourAllocator) {
return api.getEntryPointer();

@@ -113,3 +118,3 @@ }

? p.arrayAdditionalAllocation
: 0
: 0,
};

@@ -126,2 +131,6 @@ }

/**
* Incorrect length (too big) for emojis
* @param str
*/
export function strByteLength(str: string) {

@@ -141,1 +150,20 @@ let s = str.length;

}
export function isKnownAddressValuePointer(entryPointer: number) {
return (
entryPointer === UNDEFINED_KNOWN_ADDRESS ||
entryPointer === NULL_KNOWN_ADDRESS ||
entryPointer === TRUE_KNOWN_ADDRESS ||
entryPointer === FALSE_KNOWN_ADDRESS
);
}
export function isTypeWithRC(type: ENTRY_TYPE) {
return (
type === ENTRY_TYPE.OBJECT ||
type === ENTRY_TYPE.ARRAY ||
type === ENTRY_TYPE.DATE ||
type === ENTRY_TYPE.MAP ||
type === ENTRY_TYPE.SET
);
}

@@ -0,1 +1,5 @@

/* istanbul ignore file */
// We can't run test with weakrefs yet
const KEYS = 1;

@@ -6,2 +10,3 @@ const VALUES = 2;

declare const FinalizationGroup: any;
declare const FinalizationRegistry: any;
declare const WeakRef: any;

@@ -25,3 +30,8 @@

this.group = new FinalizationGroup((iterator: Iterable<any>) => {
const FinalizationSomething =
typeof FinalizationRegistry !== "undefined"
? FinalizationRegistry
: FinalizationGroup;
this.group = new FinalizationSomething((iterator: Iterable<any>) => {
for (const key of iterator) {

@@ -28,0 +38,0 @@ this.map.delete(key);

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc