Huge News!Announcing our $40M Series B led by Abstract Ventures.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-4b90e23 to 0.0.0-547d018

dist/internal/assertNonNull.js

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;

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";

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

export function createObjectBuffer(externalArgs, size, initialValue, options = {}) {
if (Array.isArray(initialValue) || initialValue instanceof Date || initialValue instanceof Map || initialValue instanceof Set || isPrimitive(initialValue)) {
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,7 +29,12 @@ start: MEM_POOL_START

const carrier = {
dataView,
allocator
// dataView,
allocator,
uint8: new Uint8Array(arrayBuffer),
uint16: new Uint16Array(arrayBuffer),
uint32: new Uint32Array(arrayBuffer),
float64: new Float64Array(arrayBuffer),
bigUint64: new BigUint64Array(arrayBuffer)
};
const start = objectSaver(externalArgsApiToExternalArgsApi(externalArgs), carrier, [], initialValue);
dataView.setUint32(INITIAL_ENTRY_POINTER_TO_POINTER, start);
carrier.uint32[INITIAL_ENTRY_POINTER_TO_POINTER / Uint32Array.BYTES_PER_ELEMENT] = start;
return createObjectWrapper(externalArgsApiToExternalArgsApi(externalArgs), carrier, start);

@@ -46,3 +57,3 @@ }

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

@@ -60,4 +71,5 @@ /**

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

@@ -67,6 +79,12 @@ start: MEM_POOL_START,

});
return createObjectWrapper(externalArgsApiToExternalArgsApi(externalArgs), {
dataView,
allocator
}, dataView.getUint32(INITIAL_ENTRY_POINTER_TO_POINTER));
const carrier = {
// dataView,
allocator,
uint8: new Uint8Array(arrayBuffer),
uint16: new Uint16Array(arrayBuffer),
uint32: new Uint32Array(arrayBuffer),
float64: new Float64Array(arrayBuffer),
bigUint64: new BigUint64Array(arrayBuffer)
};
return createObjectWrapper(externalArgsApiToExternalArgsApi(externalArgs), carrier, carrier.uint32[INITIAL_ENTRY_POINTER_TO_POINTER / Uint32Array.BYTES_PER_ELEMENT]);
}

@@ -95,10 +113,20 @@ /**

const allocator = new MemPool({
align: 8,
buf: newArrayBuffer,
start: MEM_POOL_START,
skipInitialization: true
}); // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
});
const carrier = {
// dataView: new DataView(newArrayBuffer),
allocator,
uint8: new Uint8Array(newArrayBuffer),
uint16: new Uint16Array(newArrayBuffer),
uint32: new Uint32Array(newArrayBuffer),
float64: new Float64Array(newArrayBuffer),
bigUint64: new BigUint64Array(newArrayBuffer)
}; // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
allocator.end = newArrayBuffer.byteLength;
getInternalAPI(objectBuffer).replaceCarrierContent(new DataView(newArrayBuffer), allocator);
getInternalAPI(objectBuffer).replaceCarrierContent(carrier);
}

@@ -113,2 +141,3 @@ export { sizeOf } from "./sizeOf";

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

@@ -115,0 +144,0 @@ skipInitialization: true,

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

import { ArrayEntry, ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces";
export declare function arrayGetMetadata(externalArgs: ExternalArgs, dataView: DataView, pointerToArrayEntry: number): ArrayEntry;
export declare function arrayGetPointersToValueInIndex(externalArgs: ExternalArgs, dataView: DataView, pointerToArrayEntry: number, indexToGet: number): {
import { ArrayEntry, ExternalArgs, GlobalCarrier } from "./interfaces";
export declare function arrayGetMetadata(carrier: GlobalCarrier, pointerToArrayEntry: number): ArrayEntry;
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(externalArgs: ExternalArgs, dataView: DataView, 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, dataView: DataView, 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, dataView: DataView, pointerToArrayEntry: number): void;
export declare function shrinkArray(externalArgs: ExternalArgs, carrier: GlobalCarrier, pointerToArrayEntry: number, wishedLength: number): void;
export declare function arraySort(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, pointerToArrayEntry: number, sortComparator?: (a: any, b: any) => 1 | -1 | 0): void;
export declare function arrayReverse(externalArgs: ExternalArgs, carrier: GlobalCarrier, pointerToArrayEntry: number): void;
//# sourceMappingURL=arrayHelpers.d.ts.map

@@ -5,8 +5,8 @@ import { readEntry, writeEntry, writeValueInPtrToPtrAndHandleMemory } from "./store";

import { assertNonNull } from "./assertNonNull";
export function arrayGetMetadata(externalArgs, dataView, pointerToArrayEntry) {
const arrayEntry = readEntry(externalArgs, dataView, pointerToArrayEntry);
export function arrayGetMetadata(carrier, pointerToArrayEntry) {
const arrayEntry = readEntry(carrier, pointerToArrayEntry);
return arrayEntry;
}
export function arrayGetPointersToValueInIndex(externalArgs, dataView, pointerToArrayEntry, indexToGet) {
const metadata = arrayGetMetadata(externalArgs, dataView, pointerToArrayEntry); // out of bound
export function arrayGetPointersToValueInIndex(carrier, pointerToArrayEntry, indexToGet) {
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry); // out of bound

@@ -18,3 +18,3 @@ if (indexToGet >= metadata.length) {

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

@@ -25,4 +25,4 @@ pointer,

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

@@ -33,12 +33,12 @@ if (pointers === undefined) {

return entryToFinalJavaScriptValue(externalArgs, dataViewCarrier, pointers.pointer);
return entryToFinalJavaScriptValue(externalArgs, globalCarrier, pointers.pointer);
}
export function setValuePointerAtArrayIndex(externalArgs, dataView, pointerToArrayEntry, indexToSet, pointerToEntry) {
const pointers = arrayGetPointersToValueInIndex(externalArgs, dataView, pointerToArrayEntry, indexToSet);
export function setValuePointerAtArrayIndex(carrier, pointerToArrayEntry, indexToSet, pointerToEntry) {
const pointers = arrayGetPointersToValueInIndex(carrier, pointerToArrayEntry, indexToSet);
assertNonNull(pointers);
dataView.setUint32(pointers.pointerToThePointer, pointerToEntry);
carrier.uint32[pointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT] = pointerToEntry;
}
export function setValueAtArrayIndex(externalArgs, carrier, pointerToArrayEntry, indexToSet, value) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const pointers = arrayGetPointersToValueInIndex(externalArgs, carrier.dataView, pointerToArrayEntry, indexToSet);
const pointers = arrayGetPointersToValueInIndex(carrier, pointerToArrayEntry, indexToSet);
writeValueInPtrToPtrAndHandleMemory(externalArgs, carrier, pointers.pointerToThePointer, value);

@@ -51,3 +51,3 @@ }

export function extendArrayIfNeeded(externalArgs, carrier, pointerToArrayEntry, wishedLength) {
const metadata = arrayGetMetadata(externalArgs, carrier.dataView, pointerToArrayEntry);
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry);

@@ -59,3 +59,3 @@ if (wishedLength > metadata.length) {

// no need to re-allocated, just push the length forward
writeEntry(externalArgs, carrier.dataView, pointerToArrayEntry, {
writeEntry(carrier, pointerToArrayEntry, {
type: ENTRY_TYPE.ARRAY,

@@ -74,5 +74,5 @@ refsCount: metadata.refsCount,

export function shrinkArray(externalArgs, dataView, pointerToArrayEntry, wishedLength) {
const metadata = arrayGetMetadata(externalArgs, dataView, pointerToArrayEntry);
writeEntry(externalArgs, dataView, pointerToArrayEntry, {
export function shrinkArray(externalArgs, carrier, pointerToArrayEntry, wishedLength) {
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry);
writeEntry(carrier, pointerToArrayEntry, {
type: ENTRY_TYPE.ARRAY,

@@ -87,3 +87,3 @@ refsCount: metadata.refsCount,

function reallocateArray(externalArgs, carrier, pointerToArrayEntry, newAllocatedLength, newLength) {
const metadata = arrayGetMetadata(externalArgs, carrier.dataView, pointerToArrayEntry);
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry);
const newArrayValueLocation = carrier.allocator.realloc(metadata.value, newAllocatedLength * Uint32Array.BYTES_PER_ELEMENT); // for (

@@ -102,3 +102,3 @@ // let memoryToCopyIndex = 0;

writeEntry(externalArgs, carrier.dataView, pointerToArrayEntry, {
writeEntry(carrier, pointerToArrayEntry, {
type: ENTRY_TYPE.ARRAY,

@@ -112,7 +112,7 @@ refsCount: metadata.refsCount,

export function arraySort(externalArgs, dataViewCarrier, pointerToArrayEntry, sortComparator = defaultCompareFunction) {
const metadata = arrayGetMetadata(externalArgs, dataViewCarrier.dataView, 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, globalCarrier, pointerToArrayEntry, sortComparator = defaultCompareFunction) {
const metadata = arrayGetMetadata(globalCarrier, pointerToArrayEntry);
const pointersToValues = [...new Array(metadata.length).keys()].map(index => metadata.value + index * Uint32Array.BYTES_PER_ELEMENT).map(pointerToPointer => globalCarrier.uint32[pointerToPointer / Uint32Array.BYTES_PER_ELEMENT]);
const sortMe = pointersToValues.map(pointer => {
return [pointer, entryToFinalJavaScriptValue(externalArgs, dataViewCarrier, pointer)];
return [pointer, entryToFinalJavaScriptValue(externalArgs, globalCarrier, pointer)];
});

@@ -124,3 +124,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]);
globalCarrier.uint32[(metadata.value + i * Uint32Array.BYTES_PER_ELEMENT) / Uint32Array.BYTES_PER_ELEMENT] = sortMe[i][0];
}

@@ -152,4 +152,4 @@ } // https://stackoverflow.com/a/47349064/711152

export function arrayReverse(externalArgs, dataView, pointerToArrayEntry) {
const metadata = arrayGetMetadata(externalArgs, dataView, pointerToArrayEntry);
export function arrayReverse(externalArgs, carrier, pointerToArrayEntry) {
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry);

@@ -159,8 +159,8 @@ for (let i = 0; i < Math.floor(metadata.length / 2); i += 1) {

const a = arrayGetPointersToValueInIndex(externalArgs, dataView, pointerToArrayEntry, i); // 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
const b = arrayGetPointersToValueInIndex(externalArgs, dataView, pointerToArrayEntry, theOtherIndex);
setValuePointerAtArrayIndex(externalArgs, dataView, pointerToArrayEntry, i, b.pointer);
setValuePointerAtArrayIndex(externalArgs, dataView, pointerToArrayEntry, theOtherIndex, a.pointer);
const b = arrayGetPointersToValueInIndex(carrier, pointerToArrayEntry, theOtherIndex);
setValuePointerAtArrayIndex(carrier, pointerToArrayEntry, i, b.pointer);
setValuePointerAtArrayIndex(carrier, pointerToArrayEntry, theOtherIndex, a.pointer);
}
}

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

import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces";
export declare function arraySaver(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, referencedPointers: number[], arrayToSave: Array<any>): number;
import { ExternalArgs, GlobalCarrier } from "./interfaces";
export declare function arraySaver(externalArgs: ExternalArgs, carrier: GlobalCarrier, referencedPointers: number[], arrayToSave: Array<any>): number;
//# sourceMappingURL=arraySaver.d.ts.map

@@ -16,3 +16,3 @@ import { appendEntry } from "./store";

const rOfValue = saveValue(externalArgs, carrier, referencedPointers, item);
carrier.dataView.setUint32(memoryForPointersCursor, rOfValue);
carrier.uint32[memoryForPointersCursor / Uint32Array.BYTES_PER_ELEMENT] = rOfValue;
memoryForPointersCursor += Uint32Array.BYTES_PER_ELEMENT;

@@ -19,0 +19,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, globalCarrier: GlobalCarrier, pointerToArrayEntry: number, startArg: number, deleteCountArg?: number, ...itemsToAddArg: Array<any>): any[];
//# sourceMappingURL=arraySplice.d.ts.map

@@ -5,8 +5,8 @@ import { arrayGetMetadata, getFinalValueAtArrayIndex, shrinkArray, extendArrayIfNeeded, arrayGetPointersToValueInIndex, setValuePointerAtArrayIndex } from "./arrayHelpers";

export function arraySplice(externalArgs, dataViewCarrier, pointerToArrayEntry, startArg, deleteCountArg, ...itemsToAddArg) {
const metadata = arrayGetMetadata(externalArgs, dataViewCarrier.dataView, pointerToArrayEntry);
export function arraySplice(externalArgs, globalCarrier, pointerToArrayEntry, startArg, deleteCountArg, ...itemsToAddArg) {
const metadata = arrayGetMetadata(globalCarrier, 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);
extendArrayIfNeeded(externalArgs, globalCarrier, pointerToArrayEntry, newLength);
const deletedItemsToReturn = []; // can be negative

@@ -17,3 +17,3 @@

for (let deletedItemIndexToSave = calcedStart; deletedItemIndexToSave < calcedStart + calcedDeleteCount; deletedItemIndexToSave += 1) {
deletedItemsToReturn.push(getFinalValueAtArrayIndex(externalArgs, dataViewCarrier, pointerToArrayEntry, deletedItemIndexToSave));
deletedItemsToReturn.push(getFinalValueAtArrayIndex(externalArgs, globalCarrier, pointerToArrayEntry, deletedItemIndexToSave));
} // copy-up items

@@ -30,6 +30,6 @@

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

@@ -45,7 +45,7 @@ } // copy-down items

for (let writeValueToIndex = calcedStart + itemsToAddArg.length; writeValueToIndex < metadata.length + itemCountChange; writeValueToIndex += 1) {
const valueToCopyPointers = arrayGetPointersToValueInIndex(externalArgs, dataViewCarrier.dataView, pointerToArrayEntry, writeValueToIndex - itemCountChange);
const valueToCopyPointers = arrayGetPointersToValueInIndex(globalCarrier, pointerToArrayEntry, writeValueToIndex - itemCountChange);
assertNonNull(valueToCopyPointers);
setValuePointerAtArrayIndex(externalArgs, dataViewCarrier.dataView, pointerToArrayEntry, writeValueToIndex, valueToCopyPointers.pointer); // empty old array index, its still allocated!
setValuePointerAtArrayIndex(globalCarrier, pointerToArrayEntry, writeValueToIndex, valueToCopyPointers.pointer); // empty old array index, its still allocated!
dataViewCarrier.dataView.setUint32(valueToCopyPointers.pointerToThePointer, 0); // using that is wastefull
globalCarrier.uint32[valueToCopyPointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT] = 0; // using that is wastefull
// setValueAtArrayIndex(

@@ -64,9 +64,9 @@ // dataView,

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

@@ -73,0 +73,0 @@

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

import { ExternalArgs, DataViewAndAllocatorCarrier, ArrayEntry } from "./interfaces";
import { ExternalArgs, GlobalCarrier, ArrayEntry } from "./interfaces";
import { BaseProxyTrap } from "./BaseProxyTrap";

@@ -28,3 +28,2 @@ export declare class ArrayWrapper extends BaseProxyTrap<ArrayEntry> implements ProxyHandler<{}> {

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

@@ -36,3 +35,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

@@ -20,3 +20,3 @@ import { getFinalValueAtArrayIndex, arrayGetMetadata, setValueAtArrayIndex, arraySort, extendArrayIfNeeded, arrayReverse } from "./arrayHelpers";

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

@@ -47,3 +47,3 @@

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

@@ -76,3 +76,3 @@ }

const length = arrayGetMetadata(this.externalArgs, this.carrier.dataView, this.entryPointer).length;
const length = arrayGetMetadata(this.carrier, this.entryPointer).length;

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

const currentLength = arrayGetMetadata(this.externalArgs, this.carrier.dataView, this.entryPointer).length;
const currentLength = arrayGetMetadata(this.carrier, this.entryPointer).length;

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

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

@@ -148,3 +148,3 @@ }

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

@@ -160,3 +160,3 @@ }

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

@@ -178,3 +178,3 @@ }

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

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

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

@@ -230,4 +229,4 @@ getEntryPointer() {

}
export function createArrayWrapper(externalArgs, dataViewCarrier, entryPointer) {
return new Proxy([], new ArrayWrapper(externalArgs, dataViewCarrier, entryPointer));
export function createArrayWrapper(externalArgs, globalCarrier, entryPointer) {
return new Proxy([], new ArrayWrapper(externalArgs, globalCarrier, entryPointer));
}

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

/**
* @template T
* @param {T} v
* @return {asserts v is NonNullable<T>}
*/
export function assertNonNull<T>(v: T): asserts v is NonNullable<T>;
export declare function assertNonNull<T>(v: T): asserts v is NonNullable<T>;
//# sourceMappingURL=assertNonNull.d.ts.map

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

import { ExternalArgs, DataViewAndAllocatorCarrier, InternalAPI, DateEntry, ArrayEntry, ObjectEntry, MapEntry, SetEntry } from "./interfaces";
import { IMemPool } from "@thi.ng/malloc";
import { ExternalArgs, GlobalCarrier, InternalAPI, DateEntry, ArrayEntry, ObjectEntry, MapEntry, SetEntry } from "./interfaces";
export declare class BaseProxyTrap<T extends ObjectEntry | DateEntry | ArrayEntry | MapEntry | SetEntry> 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(dataView: DataView, allocator: IMemPool): void;
getCarrier(): GlobalCarrier;
replaceCarrierContent(newCarrierContent: GlobalCarrier): void;
getEntryPointer(): number;

@@ -16,3 +15,2 @@ getExternalArgs(): Readonly<{

arrayAdditionalAllocation: number;
minimumStringAllocation: number;
textDecoder: import("./textEncoderDecoderTypes").TextDecoder;

@@ -19,0 +17,0 @@ textEncoder: import("./textEncoderDecoderTypes").TextEncoder;

@@ -8,7 +8,7 @@ import { incrementRefCount, decrementRefCount, readEntry } from "./store";

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

@@ -22,5 +22,4 @@ return newRefCount;

replaceCarrierContent(dataView, allocator) {
this.carrier.dataView = dataView;
this.carrier.allocator = allocator;
replaceCarrierContent(newCarrierContent) {
Object.assign(this.carrier, newCarrierContent);
}

@@ -45,5 +44,5 @@

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

@@ -5,2 +5,6 @@ export declare const LOCK_OFFSET = 0;

export declare const MEM_POOL_START: number;
export declare const UNDEFINED_KNOWN_ADDRESS = 0;
export declare const NULL_KNOWN_ADDRESS = 1;
export declare const TRUE_KNOWN_ADDRESS = 2;
export declare const FALSE_KNOWN_ADDRESS = 3;
//# sourceMappingURL=consts.d.ts.map
export const LOCK_OFFSET = 0;
export const INITIAL_ENTRY_POINTER_TO_POINTER = LOCK_OFFSET + Uint32Array.BYTES_PER_ELEMENT;
export const INITIAL_ENTRY_POINTER_VALUE = INITIAL_ENTRY_POINTER_TO_POINTER + Uint32Array.BYTES_PER_ELEMENT;
export const MEM_POOL_START = INITIAL_ENTRY_POINTER_VALUE + Uint32Array.BYTES_PER_ELEMENT;
export const MEM_POOL_START = INITIAL_ENTRY_POINTER_VALUE + Uint32Array.BYTES_PER_ELEMENT;
export const UNDEFINED_KNOWN_ADDRESS = 0;
export const NULL_KNOWN_ADDRESS = 1;
export const TRUE_KNOWN_ADDRESS = 2;
export const FALSE_KNOWN_ADDRESS = 3;

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

import { ExternalArgs, DataViewAndAllocatorCarrier, DateEntry } from "./interfaces";
import { ExternalArgs, GlobalCarrier, DateEntry } from "./interfaces";
import { BaseProxyTrap } from "./BaseProxyTrap";

@@ -6,3 +6,3 @@ export declare class DateWrapper extends BaseProxyTrap<DateEntry> implements ProxyHandler<Date> {

private useMeToGiveNamesToFunctionsAndCacheThem;
constructor(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, entryPointer: number);
constructor(externalArgs: ExternalArgs, carrier: GlobalCarrier, entryPointer: number);
get(target: Date, p: PropertyKey): any;

@@ -15,3 +15,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

@@ -49,3 +49,3 @@ import { readEntry, writeEntry } from "./store";

updateDateObjectForReuse() {
const entry = readEntry(this.externalArgs, this.carrier.dataView, this.entryPointer);
const entry = readEntry(this.carrier, this.entryPointer);
this.dateObjectForReuse.setTime(entry.value);

@@ -55,3 +55,3 @@ }

persistDateObject() {
writeEntry(this.externalArgs, this.carrier.dataView, this.entryPointer, {
writeEntry(this.carrier, this.entryPointer, {
type: ENTRY_TYPE.DATE,

@@ -58,0 +58,0 @@ refsCount: this.entry.refsCount,

import { getInternalAPI } from "./utils";
import { getCacheFor } from "./externalObjectsCache";
import { getAllLinkedAddresses } from "./getAllLinkedAddresses";
import { decrementRefCount } from "./store";
/**

@@ -16,8 +17,12 @@ * Dispose the given objectWrapper, and re-claim the memory

if (newRefCount === 0) {
const addressesToFree = getAllLinkedAddresses(internalApi.getExternalArgs(), internalApi.getCarrier().dataView, false, entryPointer);
const addressesToFree = getAllLinkedAddresses(internalApi.getCarrier(), false, entryPointer);
for (const address of addressesToFree) {
for (const address of addressesToFree.leafAddresses) {
internalApi.getCarrier().allocator.free(address);
}
for (const address of addressesToFree.arcAddresses) {
decrementRefCount(internalApi.getExternalArgs(), internalApi.getCarrier(), address);
}
return true;

@@ -24,0 +29,0 @@ }

export declare enum ENTRY_TYPE {
/**
* @deprecated
*/
UNDEFINED = 0,
/**
* @deprecated
*/
NULL = 1,

@@ -8,4 +14,10 @@ NUMBER = 2,

STRING = 5,
/**
* @deprecated
*/
BOOLEAN = 6,
OBJECT = 7,
/**
* @deprecated
*/
OBJECT_PROP = 8,

@@ -18,4 +30,4 @@ ARRAY = 9,

}
export declare const PRIMITIVE_TYPES: readonly [ENTRY_TYPE.NULL, ENTRY_TYPE.UNDEFINED, ENTRY_TYPE.NUMBER, ENTRY_TYPE.BIGINT_POSITIVE, ENTRY_TYPE.BIGINT_NEGATIVE, ENTRY_TYPE.BOOLEAN, ENTRY_TYPE.STRING];
export declare const isPrimitiveEntryType: (v: unknown) => v is ENTRY_TYPE.UNDEFINED | ENTRY_TYPE.NULL | ENTRY_TYPE.NUMBER | ENTRY_TYPE.BIGINT_POSITIVE | ENTRY_TYPE.BIGINT_NEGATIVE | ENTRY_TYPE.STRING | ENTRY_TYPE.BOOLEAN;
export declare const PRIMITIVE_TYPES: readonly [ENTRY_TYPE.NUMBER, ENTRY_TYPE.BIGINT_POSITIVE, ENTRY_TYPE.BIGINT_NEGATIVE, ENTRY_TYPE.STRING];
export declare const isPrimitiveEntryType: (v: unknown) => v is ENTRY_TYPE.NUMBER | ENTRY_TYPE.BIGINT_POSITIVE | ENTRY_TYPE.BIGINT_NEGATIVE | ENTRY_TYPE.STRING;
//# sourceMappingURL=entry-types.d.ts.map

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

export const PRIMITIVE_TYPES = [ENTRY_TYPE.NULL, ENTRY_TYPE.UNDEFINED, ENTRY_TYPE.NUMBER, ENTRY_TYPE.BIGINT_POSITIVE, ENTRY_TYPE.BIGINT_NEGATIVE, ENTRY_TYPE.BOOLEAN, ENTRY_TYPE.STRING];
export const PRIMITIVE_TYPES = [ENTRY_TYPE.NUMBER, ENTRY_TYPE.BIGINT_POSITIVE, ENTRY_TYPE.BIGINT_NEGATIVE, ENTRY_TYPE.STRING];
export const isPrimitiveEntryType = createKnownTypeGuard(PRIMITIVE_TYPES);

@@ -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

@@ -9,3 +9,4 @@ import { ENTRY_TYPE, isPrimitiveEntryType } from "./entry-types";

import { createMapWrapper } from "./mapWrapper";
import { createSetWrapper } from "./setWrapper"; // declare const FinalizationGroup: any;
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;

@@ -21,12 +22,20 @@

export function entryToFinalJavaScriptValue(externalArgs, carrier, pointerToEntry) {
const valueEntry = readEntry(externalArgs, carrier.dataView, pointerToEntry);
if (pointerToEntry === UNDEFINED_KNOWN_ADDRESS) {
return undefined;
}
if (valueEntry.type === ENTRY_TYPE.NULL) {
if (pointerToEntry === NULL_KNOWN_ADDRESS) {
return null;
}
if (valueEntry.type === ENTRY_TYPE.UNDEFINED) {
return undefined;
if (pointerToEntry === TRUE_KNOWN_ADDRESS) {
return true;
}
if (pointerToEntry === FALSE_KNOWN_ADDRESS) {
return false;
}
const valueEntry = readEntry(carrier, pointerToEntry);
if (isPrimitiveEntryType(valueEntry.type)) {

@@ -56,11 +65,15 @@ return valueEntry.value;

function finalizer(memoryAddress, carrier, externalArgs) {
const newRefsCount = decrementRefCount(externalArgs, carrier.dataView, memoryAddress);
const newRefsCount = decrementRefCount(externalArgs, carrier, memoryAddress);
if (newRefsCount === 0) {
const freeUs = getAllLinkedAddresses(externalArgs, carrier.dataView, false, memoryAddress);
const freeUs = getAllLinkedAddresses(carrier, false, memoryAddress);
for (const address of freeUs) {
for (const address of freeUs.leafAddresses) {
carrier.allocator.free(address);
}
for (const address of freeUs.arcAddresses) {
decrementRefCount(externalArgs, carrier, address);
}
}
}

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

import { ExternalArgs } from "./interfaces";
export declare function getAllLinkedAddresses(externalArgs: ExternalArgs, dataView: DataView, ignoreRefCount: boolean, entryPointer: number): 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: GlobalCarrier, internalHashmapPointer: number, leafAddresses: Set<number>, addressesToProcessQueue: number[]): void;
//# sourceMappingURL=getAllLinkedAddresses.d.ts.map
import { readEntry } from "./store";
import { ENTRY_TYPE } from "./entry-types";
import { hashMapGetPointersToFree } from "./hashmap/hashmap";
export function getAllLinkedAddresses(externalArgs, dataView, ignoreRefCount, entryPointer) {
const allAddresses = [];
getAllLinkedAddressesStep(externalArgs, dataView, ignoreRefCount, entryPointer, allAddresses);
return allAddresses;
import { isKnownAddressValuePointer } from "./utils";
export function getAllLinkedAddresses(carrier, ignoreRefCount, entryPointer) {
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 {
leafAddresses,
arcAddresses
};
}
function getAllLinkedAddressesStep(externalArgs, dataView, ignoreRefCount, entryPointer, pushTo) {
if (entryPointer === 0) {
function getAllLinkedAddressesStep(carrier, ignoreRefCount, entryPointer, leafAddresses, arcAddresses, addressesToProcessQueue) {
if (isKnownAddressValuePointer(entryPointer) || leafAddresses.has(entryPointer) || arcAddresses.has(entryPointer)) {
return;
}
const entry = readEntry(externalArgs, dataView, entryPointer);
const entry = readEntry(carrier, entryPointer);
switch (entry.type) {
case ENTRY_TYPE.UNDEFINED:
case ENTRY_TYPE.NULL:
case ENTRY_TYPE.BOOLEAN:
case ENTRY_TYPE.NUMBER:

@@ -25,9 +39,13 @@ case ENTRY_TYPE.STRING:

case ENTRY_TYPE.BIGINT_POSITIVE:
pushTo.push(entryPointer);
leafAddresses.add(entryPointer);
break;
case ENTRY_TYPE.OBJECT:
if (entry.refsCount < 2 || ignoreRefCount) {
pushTo.push(entryPointer);
getObjectAddresses(externalArgs, dataView, ignoreRefCount, entry, pushTo);
case ENTRY_TYPE.MAP:
case ENTRY_TYPE.SET:
if (entry.refsCount <= 1 || ignoreRefCount) {
leafAddresses.add(entryPointer);
getObjectOrMapOrSetAddresses(carrier, entry.value, leafAddresses, addressesToProcessQueue);
} else {
arcAddresses.add(entryPointer);
}

@@ -38,13 +56,12 @@

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

@@ -55,4 +72,6 @@

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

@@ -69,12 +88,15 @@

function getObjectAddresses(externalArgs, dataView, ignoreRefCount, objectEntry, pushTo) {
export function getObjectOrMapOrSetAddresses(carrier, internalHashmapPointer, leafAddresses, addressesToProcessQueue) {
const {
pointersToValuePointers,
pointers
} = hashMapGetPointersToFree(dataView, objectEntry.value);
pushTo.push(...pointers);
} = hashMapGetPointersToFree(carrier, internalHashmapPointer);
for (const leafPointer of pointers) {
leafAddresses.add(leafPointer);
}
for (const pointer of pointersToValuePointers) {
getAllLinkedAddressesStep(externalArgs, dataView, ignoreRefCount, dataView.getUint32(pointer), pushTo);
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, { dataView, allocator }: 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(externalArgs: ExternalArgs, dataView: DataView, mapPointer: number, externalKeyValue: number | string): number;
export declare function hashMapValueLookup(externalArgs: ExternalArgs, dataView: DataView, 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(externalArgs: ExternalArgs, { dataView, allocator }: 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

@@ -15,3 +15,3 @@ import { MAP_MACHINE, NODE_MACHINE } from "./memoryLayout";

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

@@ -28,23 +28,20 @@ mapMachine.set("CAPACITY", initialCapacity);

export function hashMapInsertUpdate(externalArgs, {
dataView,
allocator
}, mapPointer, externalKeyValue) {
const mapOperator = MAP_MACHINE.createOperator(dataView, mapPointer);
const keyEntry = primitiveValueToEntry({ ...externalArgs,
minimumStringAllocation: 0
}, externalKeyValue, 0); // allocate all possible needed memory upfront, so we won't oom in the middle of something
export function hashMapInsertUpdate(externalArgs, carrier, mapPointer, externalKeyValue) {
const mapOperator = MAP_MACHINE.createOperator(carrier, mapPointer);
const keyEntry = primitiveValueToEntry(externalKeyValue); // 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 = allocator.calloc(NODE_MACHINE.map.SIZE_OF);
const memoryForNewNode = carrier.allocator.calloc(NODE_MACHINE.map.SIZE_OF);
const memorySizeOfKey = sizeOfEntry(keyEntry);
const keyEntryMemory = allocator.calloc(memorySizeOfKey);
writeEntry(externalArgs, dataView, keyEntryMemory, keyEntry);
const keyHeaderOverhead = keyEntry.type === ENTRY_TYPE.STRING ? 5 : 1;
const keyHashCode = hashCodeInPlace(dataView, mapOperator.get("CAPACITY"), // + 1 for the type of key
const keyEntryMemory = carrier.allocator.calloc(memorySizeOfKey);
writeEntry(carrier, keyEntryMemory, keyEntry);
const keyHeaderOverhead = keyEntry.type === ENTRY_TYPE.STRING ? // type + string length
8 + 4 : // type
8;
const keyHashCode = hashCodeInPlace(carrier.uint8, mapOperator.get("CAPACITY"), // + 1 for the type of key
keyEntryMemory + keyHeaderOverhead, memorySizeOfKey - keyHeaderOverhead);
let ptrToPtrToSaveTheNodeTo = mapOperator.get("ARRAY_POINTER") + keyHashCode * Uint32Array.BYTES_PER_ELEMENT;
const commonNodeOperator = NODE_MACHINE.createOperator(dataView, 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(dataView, commonNodeOperator.get("KEY_POINTER"), keyEntryMemory)) {
while (commonNodeOperator.startAddress !== 0 && !compareStringOrNumberEntriesInPlace(carrier, commonNodeOperator.get("KEY_POINTER"), keyEntryMemory)) {
ptrToPtrToSaveTheNodeTo = commonNodeOperator.pointerTo("NEXT_NODE_POINTER");

@@ -62,4 +59,4 @@ commonNodeOperator.startAddress = commonNodeOperator.get("NEXT_NODE_POINTER");

// we don't need the new memory
allocator.free(keyEntryMemory);
allocator.free(memoryForNewNode);
carrier.allocator.free(keyEntryMemory);
carrier.allocator.free(memoryForNewNode);
return commonNodeOperator.pointerTo("VALUE_POINTER");

@@ -69,7 +66,4 @@ } else {

commonNodeOperator.set("KEY_POINTER", keyEntryMemory);
commonNodeOperator.set("LINKED_LIST_ITEM_POINTER", linkedListItemInsert({
dataView,
allocator
}, mapOperator.get("LINKED_LIST_POINTER"), memoryForNewNode));
dataView.setUint32(ptrToPtrToSaveTheNodeTo, memoryForNewNode);
commonNodeOperator.set("LINKED_LIST_ITEM_POINTER", linkedListItemInsert(carrier, mapOperator.get("LINKED_LIST_POINTER"), memoryForNewNode));
carrier.uint32[ptrToPtrToSaveTheNodeTo / Uint32Array.BYTES_PER_ELEMENT] = memoryForNewNode;
mapOperator.set("LINKED_LIST_SIZE", mapOperator.get("LINKED_LIST_SIZE") + 1);

@@ -81,6 +75,3 @@

// });
hashMapRehash({
dataView,
allocator
}, mapOperator, mapOperator.get("CAPACITY") * 2);
hashMapRehash(carrier, mapOperator, mapOperator.get("CAPACITY") * 2);
}

@@ -95,10 +86,10 @@

export function hashMapNodeLookup(externalArgs, dataView, mapPointer, externalKeyValue) {
const mapMachine = MAP_MACHINE.createOperator(dataView, mapPointer);
const keyHashCode = hashCodeExternalValue(externalArgs, mapMachine.get("CAPACITY"), externalKeyValue);
export function hashMapNodeLookup(carrier, mapPointer, externalKeyValue) {
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(dataView, dataView.getUint32(ptrToPtr));
const node = NODE_MACHINE.createOperator(carrier, carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT]);
while (node.startAddress !== 0) {
const keyEntry = readEntry(externalArgs, dataView, node.get("KEY_POINTER"));
const keyEntry = readEntry(carrier, node.get("KEY_POINTER"));

@@ -115,4 +106,4 @@ if (keyEntry.value === externalKeyValue) {

}
export function hashMapValueLookup(externalArgs, dataView, mapPointer, externalKeyValue) {
const nodePtrToPtr = hashMapNodeLookup(externalArgs, dataView, mapPointer, externalKeyValue);
export function hashMapValueLookup(carrier, mapPointer, externalKeyValue) {
const nodePtrToPtr = hashMapNodeLookup(carrier, mapPointer, externalKeyValue);

@@ -123,3 +114,3 @@ if (nodePtrToPtr === 0) {

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

@@ -131,7 +122,4 @@ }

export function hashMapDelete(externalArgs, {
dataView,
allocator
}, mapPointer, externalKeyValue) {
const foundNodePtrToPtr = hashMapNodeLookup(externalArgs, dataView, mapPointer, externalKeyValue);
export function hashMapDelete(carrier, mapPointer, externalKeyValue) {
const foundNodePtrToPtr = hashMapNodeLookup(carrier, mapPointer, externalKeyValue);

@@ -142,14 +130,11 @@ if (foundNodePtrToPtr === 0) {

const nodeToDeletePointer = dataView.getUint32(foundNodePtrToPtr);
const nodeOperator = NODE_MACHINE.createOperator(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({
dataView,
allocator
}, nodeOperator.get("LINKED_LIST_ITEM_POINTER")); // remove node from bucket
linkedListItemRemove(carrier, nodeOperator.get("LINKED_LIST_ITEM_POINTER")); // remove node from bucket
dataView.setUint32(foundNodePtrToPtr, nodeOperator.get("NEXT_NODE_POINTER"));
allocator.free(nodeOperator.get("KEY_POINTER"));
allocator.free(nodeOperator.startAddress);
dataView.setUint32(mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset, dataView.getUint32(mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset) - 1);
carrier.uint32[foundNodePtrToPtr / Uint32Array.BYTES_PER_ELEMENT] = nodeOperator.get("NEXT_NODE_POINTER");
carrier.allocator.free(nodeOperator.get("KEY_POINTER"));
carrier.allocator.free(nodeOperator.startAddress);
carrier.uint32[(mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset) / Uint32Array.BYTES_PER_ELEMENT]--;
return valuePointer;

@@ -162,11 +147,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);

@@ -177,6 +162,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 {

@@ -187,12 +172,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);

@@ -233,3 +218,3 @@ for (const nodePointer of pointersOfLinkedList.valuePointers) {

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

@@ -239,15 +224,13 @@ }

function hashMapRehashInsert({
dataView
}, bucketsArrayPointer, arraySize, nodePointer) {
const nodeOperator = NODE_MACHINE.createOperator(dataView, nodePointer);
const keyInfo = getKeyStartLength(dataView, nodeOperator.get("KEY_POINTER"));
const keyHashCode = hashCodeInPlace(dataView, arraySize, keyInfo.start, keyInfo.length);
function hashMapRehashInsert(carrier, bucketsArrayPointer, arraySize, nodePointer) {
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 = dataView.getUint32(bucketStartPointer);
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
// if (nodeOperator.startAddress === 0) {
// dataView.setUint32(bucketStartPointer, nodePointer);
// carrier.dataView.setUint32(bucketStartPointer, nodePointer);
// return;

@@ -268,8 +251,8 @@ // }

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,6 +0,6 @@

import { ExternalArgs } from "../interfaces";
export declare function hashCodeInPlace(dataView: DataView, capacity: number, keyStart: number, keyBytesLength: number): number;
export declare function hashCodeExternalValue(externalArgs: ExternalArgs, 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): {
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(carrier: GlobalCarrier, capacity: number, pointer: number): number;
export declare function getKeyStartLength(carrier: GlobalCarrier, keyPointer: number): {
start: number;

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

import { ENTRY_TYPE } from "../entry-types";
export function hashCodeInPlace(dataView, capacity, keyStart, keyBytesLength) {
import { stringEncodeInto } from "../stringEncodeInto";
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);

@@ -13,25 +13,26 @@

}
export function hashCodeExternalValue(externalArgs, capacity, value) {
let dv;
export function hashCodeExternalValue(capacity, value) {
const ab = new ArrayBuffer(typeof value === "string" ? value.length * 3 : 8);
const uint8 = new Uint8Array(ab);
let keyBytesLength = ab.byteLength;
if (typeof value === "string") {
dv = new DataView(externalArgs.textEncoder.encode(value).buffer);
keyBytesLength = stringEncodeInto(new Uint8Array(ab), 0, value);
} else {
dv = new DataView(new ArrayBuffer(8));
dv.setFloat64(0, value);
new Float64Array(ab)[0] = value;
}
return hashCodeInPlace(dv, capacity, 0, dv.buffer.byteLength);
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 {

@@ -44,5 +45,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 { IMemPool } from "@thi.ng/malloc";
export declare type primitive = string | number | bigint | boolean | undefined | null;
export declare type Entry = NullEntry | NullUndefined | BooleanEntry | StringEntry | NumberEntry | BigIntPositiveEntry | BigIntNegativeEntry | ObjectEntry | ArrayEntry | DateEntry | MapEntry | SetEntry;
export interface NullEntry {
type: ENTRY_TYPE.NULL;
}
export interface NullUndefined {
type: ENTRY_TYPE.UNDEFINED;
}
export interface BooleanEntry {
type: ENTRY_TYPE.BOOLEAN;
value: boolean;
}
export declare type Entry = StringEntry | NumberEntry | BigIntPositiveEntry | BigIntNegativeEntry | ObjectEntry | ArrayEntry | DateEntry | MapEntry | SetEntry;
export interface StringEntry {

@@ -72,4 +61,8 @@ type: ENTRY_TYPE.STRING;

*/
export interface DataViewAndAllocatorCarrier {
dataView: DataView;
export interface GlobalCarrier {
uint8: Uint8Array;
uint16: Uint16Array;
uint32: Uint32Array;
float64: Float64Array;
bigUint64: BigUint64Array;
allocator: import("@thi.ng/malloc").IMemPool;

@@ -81,3 +74,2 @@ }

arrayAdditionalAllocation: number;
minimumStringAllocation: number;
textDecoder: TextDecoder;

@@ -90,3 +82,2 @@ textEncoder: TextEncoder;

arrayAdditionalAllocation?: number;
minimumStringAllocation?: number;
textDecoder: TextDecoder;

@@ -97,4 +88,4 @@ textEncoder: TextEncoder;

getExternalArgs(): ExternalArgs;
getCarrier(): Readonly<DataViewAndAllocatorCarrier>;
replaceCarrierContent(dataView: DataView, pool: IMemPool): void;
getCarrier(): Readonly<GlobalCarrier>;
replaceCarrierContent(carrier: GlobalCarrier): void;
getEntryPointer(): number;

@@ -101,0 +92,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) {

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

import { ExternalArgs, DataViewAndAllocatorCarrier, MapEntry, InternalAPI } from "./interfaces";
import { ExternalArgs, GlobalCarrier, MapEntry, InternalAPI } from "./interfaces";
import { INTERNAL_API_SYMBOL } from "./symbols";

@@ -20,3 +20,3 @@ import { BaseProxyTrap } from "./BaseProxyTrap";

}
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

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

import { deleteObjectPropertyEntryByKey, objectGet, objectSet } from "./objectWrapperHelpers";
import { deleteObjectPropertyEntryByKey, objectGet, objectSet, mapOrSetClear } from "./objectWrapperHelpers";
import { INTERNAL_API_SYMBOL } from "./symbols";

@@ -9,6 +9,3 @@ import { allocationsTransaction } from "./allocationsTransaction";

clear() {
// @todo impl using helper function with direct list access
for (const key of [...this.keys()]) {
this.delete(key);
}
mapOrSetClear(this.externalArgs, this.carrier, this.entryPointer);
}

@@ -23,3 +20,3 @@

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

@@ -32,8 +29,8 @@

*entries() {
for (const nodePointer of hashmapNodesPointerIterator(this.carrier.dataView, this.entry.value)) {
for (const nodePointer of hashmapNodesPointerIterator(this.carrier, this.entry.value)) {
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])];
}

@@ -43,4 +40,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, this.entry.value)) {
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer);
yield entryToFinalJavaScriptValue(this.externalArgs, this.carrier, t.keyPointer);

@@ -51,7 +48,7 @@ }

*values() {
for (const nodePointer of hashmapNodesPointerIterator(this.carrier.dataView, this.entry.value)) {
for (const nodePointer of hashmapNodesPointerIterator(this.carrier, this.entry.value)) {
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]);
}

@@ -93,3 +90,3 @@ }

return hashMapNodeLookup(this.externalArgs, this.carrier.dataView, this.entry.value, p) !== 0;
return hashMapNodeLookup(this.carrier, this.entry.value, p) !== 0;
}

@@ -109,4 +106,4 @@

}
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
// 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"]]; // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
// 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 +29,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];
},

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

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

import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces";
export declare function objectSaver(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, referencedPointers: number[], objectToSave: any): number;
export declare function mapSaver(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, referencedPointers: number[], mapToSave: Map<string | number, any>): number;
export declare function setSaver(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, setToSave: Set<string | number>): number;
import { ExternalArgs, GlobalCarrier } from "./interfaces";
export declare function objectSaver(externalArgs: ExternalArgs, carrier: GlobalCarrier, referencedPointers: number[], objectToSave: any): number;
export declare function mapSaver(externalArgs: ExternalArgs, carrier: GlobalCarrier, referencedPointers: number[], mapToSave: Map<string | number, any>): number;
export declare function setSaver(externalArgs: ExternalArgs, carrier: GlobalCarrier, setToSave: Set<string | number>): number;
//# sourceMappingURL=objectSaver.d.ts.map

@@ -7,3 +7,3 @@ import { appendEntry } from "./store";

const objectEntries = Object.entries(objectToSave);
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, objectEntries.length * 1.3));
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, Math.ceil(objectEntries.length * 1.3)));

@@ -13,3 +13,3 @@ for (const [key, value] of objectEntries) {

const pointerToValue = saveValue(externalArgs, carrier, referencedPointers, value);
carrier.dataView.setUint32(ptrToPtr, pointerToValue);
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = pointerToValue;
}

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

export function mapSaver(externalArgs, carrier, referencedPointers, mapToSave) {
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, mapToSave.size * 1.3));
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, Math.ceil(mapToSave.size * 1.3)));

@@ -31,3 +31,3 @@ for (const [key, value] of mapToSave.entries()) {

const pointerToValue = saveValue(externalArgs, carrier, referencedPointers, value);
carrier.dataView.setUint32(ptrToPtr, pointerToValue);
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = pointerToValue;
}

@@ -43,7 +43,7 @@

export function setSaver(externalArgs, carrier, setToSave) {
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, setToSave.size * 1.3));
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, Math.ceil(setToSave.size * 1.3)));
for (const key of setToSave.keys()) {
const ptrToPtr = hashMapInsertUpdate(externalArgs, carrier, hashMapPointer, key);
carrier.dataView.setUint32(ptrToPtr, 1);
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = 1;
}

@@ -50,0 +50,0 @@

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

import { ObjectEntry, ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces";
import { ObjectEntry, ExternalArgs, GlobalCarrier } from "./interfaces";
import { BaseProxyTrap } from "./BaseProxyTrap";

@@ -19,3 +19,3 @@ export declare class ObjectWrapper extends BaseProxyTrap<ObjectEntry> implements ProxyHandler<{}> {

}
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

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

enumerate() {
const gotEntries = getObjectPropertiesEntries(this.externalArgs, this.carrier.dataView, this.entry.value);
const gotEntries = getObjectPropertiesEntries(this.carrier, this.entry.value);
return gotEntries.map(e => e.key);

@@ -35,3 +35,3 @@ }

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

@@ -60,3 +60,3 @@ }

return hashMapNodeLookup(this.externalArgs, this.carrier.dataView, this.entry.value, p) !== 0;
return hashMapNodeLookup(this.carrier, this.entry.value, p) !== 0;
}

@@ -100,6 +100,6 @@

}
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,9 +0,10 @@

import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces";
export declare function deleteObjectPropertyEntryByKey(externalArgs: ExternalArgs, { dataView, allocator }: DataViewAndAllocatorCarrier, hashmapPointer: number, keyToDeleteBy: string | number): boolean;
export declare function getObjectPropertiesEntries(externalArgs: ExternalArgs, dataView: DataView, hashmapPointer: number): Array<{
import { ExternalArgs, GlobalCarrier } from "./interfaces";
export declare function deleteObjectPropertyEntryByKey(externalArgs: ExternalArgs, 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 objectSet(externalArgs: ExternalArgs, carrier: GlobalCarrier, hashMapPointer: number, p: string | number, value: any): 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,52 +0,28 @@

import { readEntry, decrementRefCount, writeValueInPtrToPtrAndHandleMemory } from "./store";
import { readEntry, writeValueInPtrToPtrAndHandleMemory, handleArcForDeletedValuePointer, decrementRefCount, writeEntry, setRefCount } from "./store";
import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue";
import { hashMapDelete, hashMapLowLevelIterator, hashMapNodePointerToKeyValue, hashMapInsertUpdate, hashMapValueLookup } from "./hashmap/hashmap";
import { hashMapDelete, hashMapLowLevelIterator, hashMapNodePointerToKeyValue, hashMapInsertUpdate, hashMapValueLookup, createHashMap } from "./hashmap/hashmap";
import { getAllLinkedAddresses } from "./getAllLinkedAddresses";
export function deleteObjectPropertyEntryByKey(externalArgs, {
dataView,
allocator
}, hashmapPointer, keyToDeleteBy) {
const deletedValuePointerToPointer = hashMapDelete(externalArgs, {
dataView,
allocator
}, hashmapPointer, keyToDeleteBy);
const deletedValuePointer = dataView.getUint32(deletedValuePointerToPointer); // Nothing to delete here
export function deleteObjectPropertyEntryByKey(externalArgs, carrier, hashmapPointer, keyToDeleteBy) {
const deletedValuePointerToPointer = hashMapDelete(carrier, hashmapPointer, keyToDeleteBy); // no such key
if (deletedValuePointer === 0) {
if (deletedValuePointerToPointer === 0) {
return false;
} // handle memory free
if (deletedValuePointer !== 0) {
const existingValueEntry = readEntry(externalArgs, dataView, deletedValuePointer);
if (existingValueEntry && "refsCount" in existingValueEntry) {
const newRefCount = decrementRefCount(externalArgs, dataView, deletedValuePointer);
if (newRefCount === 0) {
const addressesToFree = getAllLinkedAddresses(externalArgs, dataView, false, deletedValuePointer);
for (const address of addressesToFree) {
allocator.free(address);
}
}
} else {
allocator.free(deletedValuePointer);
}
}
const deletedValuePointer = carrier.uint32[deletedValuePointerToPointer / Uint32Array.BYTES_PER_ELEMENT];
handleArcForDeletedValuePointer(externalArgs, carrier, deletedValuePointer);
return true;
}
export function getObjectPropertiesEntries(externalArgs, dataView, hashmapPointer) {
export function getObjectPropertiesEntries(carrier, hashmapPointer) {
let iterator = 0;
const foundValues = [];
while (iterator = hashMapLowLevelIterator(dataView, hashmapPointer, iterator)) {
while (iterator = hashMapLowLevelIterator(carrier, hashmapPointer, iterator)) {
const {
valuePointer,
keyPointer
} = hashMapNodePointerToKeyValue(dataView, iterator);
const keyEntry = readEntry(externalArgs, dataView, keyPointer);
} = hashMapNodePointerToKeyValue(carrier, iterator);
const keyEntry = readEntry(carrier, keyPointer);
foundValues.push({
valuePointer: dataView.getUint32(valuePointer),
valuePointer: carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT],
key: keyEntry.value

@@ -63,3 +39,3 @@ });

export function objectGet(externalArgs, carrier, entryPointer, key) {
const valuePointer = hashMapValueLookup(externalArgs, carrier.dataView, entryPointer, key);
const valuePointer = hashMapValueLookup(carrier, entryPointer, key);

@@ -70,3 +46,56 @@ if (valuePointer === 0) {

return entryToFinalJavaScriptValue(externalArgs, carrier, carrier.dataView.getUint32(valuePointer));
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);
// }
// }
export function mapOrSetClear(externalArgs, carrier, mapOrSetPtr) {
const entry = readEntry(carrier, mapOrSetPtr); // we fake the entry refCount as zero so getAllLinkedAddresses will visit what's needed
const prevCount = setRefCount(carrier, mapOrSetPtr, 0);
const {
leafAddresses,
arcAddresses
} = getAllLinkedAddresses(carrier, false, mapOrSetPtr);
for (const address of leafAddresses) {
// don't dispose the address we need to reuse
if (address === mapOrSetPtr) {
continue;
}
carrier.allocator.free(address);
}
for (const address of arcAddresses) {
// don't dispose the address we need to reuse
if (address === mapOrSetPtr) {
continue;
}
decrementRefCount(externalArgs, carrier, address);
} // hashmapClearFree(externalArgs, carrier, entry.value);
// Restore real ref count
setRefCount(carrier, mapOrSetPtr, prevCount);
entry.value = createHashMap(carrier, externalArgs.hashMapMinInitialCapacity);
writeEntry(carrier, mapOrSetPtr, entry);
}

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

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

@@ -6,2 +6,7 @@ import { primitiveValueToEntry, isPrimitive, getOurPointerIfApplicable } 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
*/
export function saveValue(externalArgs, carrier, referencedPointers, value) {

@@ -11,6 +16,22 @@ let valuePointer = 0;

if (value === undefined) {
return UNDEFINED_KNOWN_ADDRESS;
}
if (value === null) {
return NULL_KNOWN_ADDRESS;
}
if (value === true) {
return TRUE_KNOWN_ADDRESS;
}
if (value === false) {
return FALSE_KNOWN_ADDRESS;
}
if (isPrimitive(value)) {
const entry = primitiveValueToEntry(externalArgs, value, externalArgs.minimumStringAllocation);
const entry = primitiveValueToEntry(value);
valuePointer = appendEntry(externalArgs, carrier, entry);
} else if (maybeOurPointer = getOurPointerIfApplicable(value, carrier.dataView)) {
} else if (maybeOurPointer = getOurPointerIfApplicable(value, carrier.allocator)) {
valuePointer = maybeOurPointer;

@@ -17,0 +38,0 @@ referencedPointers.push(valuePointer);

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

import { ExternalArgs, DataViewAndAllocatorCarrier, MapEntry, InternalAPI } from "./interfaces";
import { ExternalArgs, GlobalCarrier, MapEntry, InternalAPI } from "./interfaces";
import { INTERNAL_API_SYMBOL } from "./symbols";

@@ -19,3 +19,3 @@ import { BaseProxyTrap } from "./BaseProxyTrap";

}
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

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

import { deleteObjectPropertyEntryByKey, objectSet } from "./objectWrapperHelpers";
import { deleteObjectPropertyEntryByKey, objectSet, mapOrSetClear } from "./objectWrapperHelpers";
import { INTERNAL_API_SYMBOL } from "./symbols";

@@ -9,6 +9,3 @@ import { allocationsTransaction } from "./allocationsTransaction";

clear() {
// @todo impl using helper function with direct list access
for (const key of [...this.keys()]) {
this.delete(key);
}
mapOrSetClear(this.externalArgs, this.carrier, this.entryPointer);
}

@@ -23,3 +20,3 @@

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

@@ -32,4 +29,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, this.entry.value)) {
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer);
const key = entryToFinalJavaScriptValue(this.externalArgs, this.carrier, t.keyPointer);

@@ -41,4 +38,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, this.entry.value)) {
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer);
yield entryToFinalJavaScriptValue(this.externalArgs, this.carrier, t.keyPointer);

@@ -49,4 +46,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, this.entry.value)) {
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer);
yield entryToFinalJavaScriptValue(this.externalArgs, this.carrier, t.keyPointer);

@@ -73,3 +70,3 @@ }

return hashMapNodeLookup(this.externalArgs, this.carrier.dataView, this.entry.value, p) !== 0;
return hashMapNodeLookup(this.carrier, this.entry.value, p) !== 0;
}

@@ -97,4 +94,4 @@

}
export function createSetWrapper(externalArgs, dataViewCarrier, entryPointer) {
return new SetWrapper(externalArgs, dataViewCarrier, entryPointer);
export function createSetWrapper(externalArgs, globalCarrier, entryPointer) {
return new SetWrapper(externalArgs, globalCarrier, entryPointer);
}

@@ -72,4 +72,11 @@ import { externalArgsApiToExternalArgsApi, isPrimitive, primitiveValueToEntry, align } from "./utils";

export function sizeOfValue(externalArgs, value) {
if (value === undefined || value === null || value === true || value === false) {
return {
memoryAllocated: 0,
numberOfAllocations: 0
};
}
if (isPrimitive(value)) {
const entry = primitiveValueToEntry(externalArgs, value, externalArgs.minimumStringAllocation);
const entry = primitiveValueToEntry(value);
return {

@@ -107,3 +114,3 @@ memoryAllocated: align(sizeOfEntry(entry)),

const hashMapNodesAllocationsSize = align(NODE_MACHINE.map.SIZE_OF) * keysArray.length;
const hashMapKeysSize = keysArray.map(k => sizeOfEntry(primitiveValueToEntry(externalArgs, k, 0))).reduce((p, c) => {
const hashMapKeysSize = keysArray.map(k => sizeOfEntry(primitiveValueToEntry(k))).reduce((p, c) => {
return p + align(c);

@@ -110,0 +117,0 @@ }, 0);

@@ -1,25 +0,23 @@

import { Entry, primitive, DataViewAndAllocatorCarrier } from "./interfaces";
import { Entry, primitive, GlobalCarrier } from "./interfaces";
import { ExternalArgs } from "./interfaces";
export declare function initializeArrayBuffer(arrayBuffer: ArrayBuffer): DataView;
export declare function initializeArrayBuffer(arrayBuffer: ArrayBuffer): void;
export declare function sizeOfEntry(entry: Entry): number;
export declare function writeEntry(externalArgs: ExternalArgs, dataView: DataView, startingCursor: number, entry: Entry): void;
export declare function appendEntry(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, entry: Entry): number;
export declare function readEntry(externalArgs: ExternalArgs, dataView: DataView, startingCursor: number): Entry;
export declare function writeEntry(carrier: GlobalCarrier, startingCursor: number, entry: Entry): void;
export declare function appendEntry(externalArgs: ExternalArgs, carrier: GlobalCarrier, entry: Entry): number;
export declare function readEntry(carrier: GlobalCarrier, startingCursor: number): Entry;
export declare function canReuseMemoryOfEntry(entryA: Entry, value: primitive): boolean;
export declare function writeValueInPtrToPtr(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, ptrToPtr: number, value: any): {
export declare function writeValueInPtrToPtr(externalArgs: ExternalArgs, carrier: GlobalCarrier, ptrToPtr: number, value: any): {
referencedPointers: number[];
existingEntryPointer: number;
existingValueEntry: Entry;
existingValueEntry: import("./interfaces").StringEntry | import("./interfaces").NumberEntry | import("./interfaces").BigIntPositiveEntry | import("./interfaces").BigIntNegativeEntry | import("./interfaces").ObjectEntry | import("./interfaces").ArrayEntry | import("./interfaces").DateEntry | import("./interfaces").MapEntry | import("./interfaces").SetEntry | undefined;
} | undefined;
export declare function writeValueInPtrToPtrAndHandleMemory(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, ptrToPtr: number, value: any): void;
export declare function incrementRefCount(externalArgs: ExternalArgs, dataView: DataView, entryPointer: number): number;
export declare function decrementRefCount(externalArgs: ExternalArgs, dataView: DataView, entryPointer: number): number;
export declare function getRefCount(externalArgs: ExternalArgs, dataView: DataView, entryPointer: number): number;
export declare function getObjectPropPtrToPtr({ dataView }: DataViewAndAllocatorCarrier, pointerToEntry: number): {
valuePtrToPtr: number;
nextPtrToPtr: number;
};
export declare function writeValueInPtrToPtrAndHandleMemory(externalArgs: ExternalArgs, carrier: GlobalCarrier, ptrToPtr: number, value: any): void;
export declare function handleArcForDeletedValuePointer(externalArgs: ExternalArgs, carrier: GlobalCarrier, deletedValuePointer: number): void;
export declare function incrementRefCount(externalArgs: ExternalArgs, carrier: GlobalCarrier, entryPointer: number): number;
export declare function decrementRefCount(externalArgs: ExternalArgs, carrier: GlobalCarrier, entryPointer: number): number;
export declare function getRefCount(carrier: GlobalCarrier, entryPointer: number): number;
export declare function setRefCount(carrier: GlobalCarrier, entryPointer: number, newRefCount: 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(carrier: GlobalCarrier, entryAPointer: number, entryBPointer: number): boolean;
//# sourceMappingURL=store.d.ts.map
import { ENTRY_TYPE, isPrimitiveEntryType } from "./entry-types";
import { arrayBufferCopyTo, isPrimitive, primitiveValueToEntry, strByteLength } from "./utils";
import { isPrimitive, primitiveValueToEntry, isKnownAddressValuePointer } from "./utils";
import { BigInt64OverflowError } from "./exceptions";

@@ -7,26 +7,16 @@ import { INITIAL_ENTRY_POINTER_TO_POINTER, INITIAL_ENTRY_POINTER_VALUE } from "./consts";

import { getAllLinkedAddresses } from "./getAllLinkedAddresses";
import { stringEncodeInto } from "./stringEncodeInto";
import { stringDecode } from "./stringDecode";
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) {
case ENTRY_TYPE.UNDEFINED:
break;
case ENTRY_TYPE.NULL:
break;
case ENTRY_TYPE.BOOLEAN:
cursor += Uint8Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.NUMBER:

@@ -37,5 +27,5 @@ cursor += Float64Array.BYTES_PER_ELEMENT;

case ENTRY_TYPE.STRING:
cursor += Uint16Array.BYTES_PER_ELEMENT;
cursor += Uint16Array.BYTES_PER_ELEMENT;
cursor += Math.max(strByteLength(entry.value), entry.allocatedBytes); // oh boy. i don't want to change it now, but no choice
// string length
cursor += Uint32Array.BYTES_PER_ELEMENT;
cursor += entry.allocatedBytes; // oh boy. i don't want to change it now, but no choice
// @todo: this is incorrect? should be Math.max

@@ -58,3 +48,5 @@ // cursor += entry.allocatedBytes;

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

@@ -64,11 +56,17 @@ break;

case ENTRY_TYPE.ARRAY:
// refsCount
cursor += Uint32Array.BYTES_PER_ELEMENT; // pointer
cursor += Uint32Array.BYTES_PER_ELEMENT; // length
cursor += Uint32Array.BYTES_PER_ELEMENT; // allocated length
cursor += Uint32Array.BYTES_PER_ELEMENT;
cursor += Uint32Array.BYTES_PER_ELEMENT;
cursor += Uint32Array.BYTES_PER_ELEMENT;
cursor += Uint8Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.DATE:
cursor += Float64Array.BYTES_PER_ELEMENT;
cursor += Uint8Array.BYTES_PER_ELEMENT;
// timestamp
cursor += Float64Array.BYTES_PER_ELEMENT; // ref count
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;

@@ -84,3 +82,3 @@

}
export function writeEntry(externalArgs, dataView, startingCursor, entry) {
export function writeEntry(carrier, startingCursor, entry) {
let cursor = startingCursor; // let writtenDataSizeInBytes = 0;

@@ -90,19 +88,8 @@ // write type

dataView.setUint8(cursor, entry.type);
cursor += Uint8Array.BYTES_PER_ELEMENT;
carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT] = entry.type;
cursor += Float64Array.BYTES_PER_ELEMENT;
switch (entry.type) {
case ENTRY_TYPE.UNDEFINED:
break;
case ENTRY_TYPE.NULL:
break;
case ENTRY_TYPE.BOOLEAN:
dataView.setUint8(cursor, entry.value ? 1 : 0);
cursor += Uint8Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.NUMBER:
dataView.setFloat64(cursor, entry.value);
carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT] = entry.value;
cursor += Float64Array.BYTES_PER_ELEMENT;

@@ -112,12 +99,15 @@ break;

case ENTRY_TYPE.STRING:
// eslint-disable-next-line no-case-declarations
const encodedString = externalArgs.textEncoder.encode(entry.value);
dataView.setUint16(cursor, encodedString.byteLength);
cursor += Uint16Array.BYTES_PER_ELEMENT;
dataView.setUint16(cursor, entry.allocatedBytes);
cursor += Uint16Array.BYTES_PER_ELEMENT;
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.allocatedBytes;
cursor += Uint32Array.BYTES_PER_ELEMENT; // eslint-disable-next-line no-case-declarations
for (let i = 0; i < encodedString.length; i++) {
dataView.setUint8(cursor, encodedString[i]);
cursor += Uint8Array.BYTES_PER_ELEMENT;
const writtenBytes = stringEncodeInto(carrier.uint8, cursor, entry.value);
if (writtenBytes !== entry.allocatedBytes) {
// eslint-disable-next-line no-undef
console.warn({
value: entry.value,
writtenBytes,
allocatedBytes: entry.allocatedBytes
}, true);
throw new Error("WTF???");
}

@@ -134,4 +124,4 @@

dataView.setBigUint64(cursor, entry.type === ENTRY_TYPE.BIGINT_NEGATIVE ? -entry.value : entry.value);
cursor += BigInt64Array.BYTES_PER_ELEMENT;
carrier.bigUint64[cursor / BigUint64Array.BYTES_PER_ELEMENT] = entry.type === ENTRY_TYPE.BIGINT_NEGATIVE ? -entry.value : entry.value;
cursor += BigUint64Array.BYTES_PER_ELEMENT;
break;

@@ -142,24 +132,24 @@

case ENTRY_TYPE.MAP:
dataView.setUint8(cursor, entry.refsCount);
cursor += Uint8Array.BYTES_PER_ELEMENT;
dataView.setUint32(cursor, entry.value);
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.refsCount;
cursor += Uint32Array.BYTES_PER_ELEMENT;
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = 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);
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.refsCount;
cursor += Uint32Array.BYTES_PER_ELEMENT;
dataView.setUint32(cursor, entry.length);
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.value;
cursor += Uint32Array.BYTES_PER_ELEMENT;
dataView.setUint32(cursor, entry.allocatedLength);
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.length;
cursor += Uint32Array.BYTES_PER_ELEMENT;
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = 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);
carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT] = entry.value;
cursor += Float64Array.BYTES_PER_ELEMENT;
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.refsCount;
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;

@@ -176,9 +166,9 @@

const memoryAddress = carrier.allocator.calloc(size);
writeEntry(externalArgs, carrier.dataView, memoryAddress, entry);
writeEntry(carrier, memoryAddress, entry);
return memoryAddress;
}
export function readEntry(externalArgs, dataView, startingCursor) {
export function readEntry(carrier, startingCursor) {
let cursor = startingCursor;
const entryType = dataView.getUint8(cursor);
cursor += Uint8Array.BYTES_PER_ELEMENT;
const entryType = carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT];
cursor += Float64Array.BYTES_PER_ELEMENT;
const entry = {

@@ -190,15 +180,13 @@ type: entryType,

switch (entryType) {
case ENTRY_TYPE.UNDEFINED:
break;
case ENTRY_TYPE.NULL:
break;
case ENTRY_TYPE.BOOLEAN:
entry.value = dataView.getUint8(cursor) !== 0;
cursor += Uint8Array.BYTES_PER_ELEMENT;
break;
// handled by well-known addresses
// 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 = dataView.getFloat64(cursor);
entry.value = carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT];
cursor += Float64Array.BYTES_PER_ELEMENT;

@@ -209,6 +197,5 @@ break;

// eslint-disable-next-line no-case-declarations
const stringLength = dataView.getUint16(cursor);
cursor += Uint16Array.BYTES_PER_ELEMENT;
entry.allocatedBytes = dataView.getUint16(cursor);
cursor += Uint16Array.BYTES_PER_ELEMENT; // decode fails with zero length array
const stringLength = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT];
entry.allocatedBytes = stringLength;
cursor += Uint32Array.BYTES_PER_ELEMENT; // decode fails with zero length array

@@ -219,5 +206,5 @@ if (stringLength > 0) {

// eslint-disable-next-line no-case-declarations
const tempAB = new ArrayBuffer(stringLength);
arrayBufferCopyTo(dataView.buffer, cursor, stringLength, tempAB, 0);
entry.value = externalArgs.textDecoder.decode(tempAB);
// const tempAB = new ArrayBuffer(stringLength, true);
// arrayBufferCopyTo(dataView.buffer, cursor, stringLength, tempAB, 0, true);
entry.value = stringDecode(carrier.uint8, cursor, stringLength);
} else {

@@ -231,3 +218,3 @@ entry.value = "";

case ENTRY_TYPE.BIGINT_POSITIVE:
entry.value = dataView.getBigUint64(cursor);
entry.value = carrier.bigUint64[cursor / BigUint64Array.BYTES_PER_ELEMENT];
cursor += BigUint64Array.BYTES_PER_ELEMENT;

@@ -237,3 +224,3 @@ break;

case ENTRY_TYPE.BIGINT_NEGATIVE:
entry.value = -dataView.getBigUint64(cursor);
entry.value = -carrier.bigUint64[cursor / BigUint64Array.BYTES_PER_ELEMENT];
cursor += BigUint64Array.BYTES_PER_ELEMENT;

@@ -245,24 +232,24 @@ break;

case ENTRY_TYPE.SET:
entry.refsCount = dataView.getUint8(cursor);
cursor += Uint8Array.BYTES_PER_ELEMENT;
entry.value = dataView.getUint32(cursor);
entry.refsCount = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT];
cursor += Uint32Array.BYTES_PER_ELEMENT;
entry.value = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT];
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.ARRAY:
entry.refsCount = dataView.getUint8(cursor);
cursor += Uint8Array.BYTES_PER_ELEMENT;
entry.value = dataView.getUint32(cursor);
entry.refsCount = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT];
cursor += Uint32Array.BYTES_PER_ELEMENT;
entry.length = dataView.getUint32(cursor);
entry.value = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT];
cursor += Uint32Array.BYTES_PER_ELEMENT;
entry.allocatedLength = dataView.getUint32(cursor);
entry.length = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT];
cursor += Uint32Array.BYTES_PER_ELEMENT;
entry.allocatedLength = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT];
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.DATE:
entry.refsCount = dataView.getUint8(cursor);
cursor += Uint8Array.BYTES_PER_ELEMENT;
entry.value = dataView.getFloat64(cursor);
entry.value = carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT];
cursor += Float64Array.BYTES_PER_ELEMENT;
entry.refsCount = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT];
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;

@@ -277,35 +264,36 @@

export function canReuseMemoryOfEntry(entryA, value) {
const typeofTheValue = typeof value;
const typeofTheValue = typeof value; // number & bigint 64 are the same size
if (entryA.type === ENTRY_TYPE.BOOLEAN && typeofTheValue === "boolean") {
return true;
} // 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;
}
} // kill for strings for now
// if (
// entryA.type === ENTRY_TYPE.STRING &&
// typeofTheValue === "string" &&
// entryA.allocatedBytes >= strByteLength(value as string)
// ) {
// return true;
// }
if (entryA.type === ENTRY_TYPE.STRING && typeofTheValue === "string" && entryA.allocatedBytes >= strByteLength(value)) {
return true;
}
if ((entryA.type === ENTRY_TYPE.NULL || entryA.type === ENTRY_TYPE.UNDEFINED) && value === undefined || value === null) {
return true;
}
return false;
}
export function writeValueInPtrToPtr(externalArgs, carrier, ptrToPtr, value) {
const existingEntryPointer = carrier.dataView.getUint32(ptrToPtr);
const existingValueEntry = readEntry(externalArgs, carrier.dataView, existingEntryPointer); // try to re use memory
const existingEntryPointer = carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT];
let reuse = false;
let existingValueEntry;
if (isPrimitive(value) && isPrimitiveEntryType(existingValueEntry.type) && canReuseMemoryOfEntry(existingValueEntry, value) && existingEntryPointer !== 0) {
const stringAllocatedBytes = existingValueEntry.type === ENTRY_TYPE.STRING ? existingValueEntry.allocatedBytes : 0;
const newEntry = primitiveValueToEntry(externalArgs, value, stringAllocatedBytes);
writeEntry(externalArgs, carrier.dataView, existingEntryPointer, newEntry);
if (!isKnownAddressValuePointer(existingEntryPointer)) {
existingValueEntry = readEntry(carrier, existingEntryPointer);
reuse = isPrimitive(value) && isPrimitiveEntryType(existingValueEntry.type) && canReuseMemoryOfEntry(existingValueEntry, value);
} // try to re use memory
if (reuse) {
const newEntry = primitiveValueToEntry(value);
writeEntry(carrier, existingEntryPointer, newEntry);
} else {
const referencedPointers = [];
const newEntryPointer = saveValue(externalArgs, carrier, referencedPointers, value);
carrier.dataView.setUint32(ptrToPtr, newEntryPointer);
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = newEntryPointer;
return {

@@ -327,3 +315,3 @@ referencedPointers,

for (const ptr of referencedPointers) {
incrementRefCount(externalArgs, carrier.dataView, ptr);
incrementRefCount(externalArgs, carrier, ptr);
}

@@ -333,10 +321,14 @@ }

if (existingValueEntry && "refsCount" in existingValueEntry) {
const newRefCount = decrementRefCount(externalArgs, carrier.dataView, existingEntryPointer);
const newRefCount = decrementRefCount(externalArgs, carrier, existingEntryPointer);
if (newRefCount === 0) {
const addressesToFree = getAllLinkedAddresses(externalArgs, carrier.dataView, false, existingEntryPointer);
const addressesToFree = getAllLinkedAddresses(carrier, false, existingEntryPointer);
for (const address of addressesToFree) {
for (const address of addressesToFree.leafAddresses) {
carrier.allocator.free(address);
}
for (const address of addressesToFree.arcAddresses) {
decrementRefCount(externalArgs, carrier, address);
}
}

@@ -347,8 +339,34 @@ } else {

}
export function incrementRefCount(externalArgs, dataView, entryPointer) {
const entry = readEntry(externalArgs, dataView, entryPointer);
export function handleArcForDeletedValuePointer(externalArgs, carrier, deletedValuePointer) {
// No memory to free/ARC
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);
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);
}
}
export function incrementRefCount(externalArgs, carrier, entryPointer) {
const entry = readEntry(carrier, entryPointer);
if ("refsCount" in entry) {
entry.refsCount += 1;
writeEntry(externalArgs, dataView, entryPointer, entry);
writeEntry(carrier, entryPointer, entry);
return entry.refsCount;

@@ -359,8 +377,8 @@ }

}
export function decrementRefCount(externalArgs, dataView, entryPointer) {
const entry = readEntry(externalArgs, dataView, entryPointer);
export function decrementRefCount(externalArgs, carrier, entryPointer) {
const entry = readEntry(carrier, entryPointer);
if ("refsCount" in entry) {
entry.refsCount -= 1;
writeEntry(externalArgs, dataView, entryPointer, entry);
writeEntry(carrier, entryPointer, entry);
return entry.refsCount;

@@ -371,4 +389,4 @@ }

}
export function getRefCount(externalArgs, dataView, entryPointer) {
const entry = readEntry(externalArgs, dataView, entryPointer);
export function getRefCount(carrier, entryPointer) {
const entry = readEntry(carrier, entryPointer);

@@ -381,18 +399,32 @@ if ("refsCount" in entry) {

}
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 setRefCount(carrier, entryPointer, newRefCount) {
const entry = readEntry(carrier, entryPointer);
if ("refsCount" in entry) {
const prevCount = entry.refsCount;
entry.refsCount = newRefCount;
writeEntry(carrier, entryPointer, entry);
return prevCount;
}
throw new Error("unexpected");
} // export function getObjectPropPtrToPtr(
// { dataView }: GlobalCarrier,
// pointerToEntry: number
// ) {
// 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 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;

@@ -403,3 +435,3 @@ }

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

@@ -411,7 +443,7 @@ }

}
export function compareStringOrNumberEntriesInPlace(dataView, entryAPointer, entryBPointer) {
export function compareStringOrNumberEntriesInPlace(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;

@@ -423,4 +455,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];

@@ -432,9 +464,7 @@ if (aLength !== bLength) {

cursor += Uint16Array.BYTES_PER_ELEMENT; // allocated length, skip.
cursor += Uint16Array.BYTES_PER_ELEMENT;
return memComp(dataView, entryAPointer + cursor, entryBPointer + cursor, aLength);
cursor += Uint32Array.BYTES_PER_ELEMENT;
return memComp(carrier.uint8, entryAPointer + cursor, entryBPointer + cursor, aLength);
}
return dataView.getFloat64(entryAPointer + cursor) === dataView.getFloat64(entryBPointer + cursor);
return carrier.float64[(entryAPointer + cursor) / Float64Array.BYTES_PER_ELEMENT] === carrier.float64[(entryBPointer + cursor) / Float64Array.BYTES_PER_ELEMENT];
}

@@ -14,3 +14,5 @@ export function arrayBuffer2HexArray(buffer, withByteNumber = false) {

}
import { OutOfMemoryError } from "./exceptions"; // extend pool and not monkey patch? need to think about it
import { MemPool } from "@thi.ng/malloc";
import { OutOfMemoryError } from "./exceptions";
import { MEM_POOL_START } from "./consts"; // extend pool and not monkey patch? need to think about it

@@ -82,2 +84,18 @@ export function recordAllocations(operation, pool) {

};
}
export function makeCarrier(arrayBuffer) {
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const carrier = {
// dataView: new DataView(arrayBuffer),
allocator,
uint8: new Uint8Array(arrayBuffer),
uint16: new Uint16Array(arrayBuffer),
uint32: new Uint32Array(arrayBuffer),
float64: new Float64Array(arrayBuffer),
bigUint64: new BigUint64Array(arrayBuffer)
};
return carrier;
}
import { primitive, Entry, ExternalArgs, InternalAPI, ExternalArgsApi } from "./interfaces";
import { IMemPool } from "@thi.ng/malloc";
export declare function isPrimitive(value: unknown): value is primitive;
export declare function primitiveValueToEntry(externalArgs: ExternalArgs, value: primitive, stringAllocatedBytes: number): Entry;
export declare function primitiveValueToEntry(value: primitive): Entry;
export declare function createKnownTypeGuard<T>(arr: ReadonlyArray<T>): (v: unknown) => v is T;
export declare function invariant(condition: boolean, message: string): void;
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;

@@ -12,2 +13,3 @@ export declare function getInternalAPI(value: any): InternalAPI;

export declare function align(value: number, alignTo?: number): number;
export declare function isKnownAddressValuePointer(entryPointer: number): 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"];

@@ -15,3 +16,3 @@ export function isPrimitive(value) {

}
export function primitiveValueToEntry(externalArgs, value, stringAllocatedBytes) {
export function primitiveValueToEntry(value) {
if (typeof value === "string") {

@@ -21,3 +22,3 @@ return {

value,
allocatedBytes: Math.max(externalArgs.textEncoder.encode(value).length, stringAllocatedBytes)
allocatedBytes: strByteLength(value)
};

@@ -40,21 +41,2 @@ }

if (typeof value === "boolean") {
return {
type: ENTRY_TYPE.BOOLEAN,
value
};
}
if (typeof value === "undefined") {
return {
type: ENTRY_TYPE.UNDEFINED
};
}
if (value === null) {
return {
type: ENTRY_TYPE.NULL
};
}
throw new Error("unexpected");

@@ -75,12 +57,9 @@ }

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();

@@ -94,4 +73,3 @@ }

hashMapLoadFactor: p.hashMapLoadFactor ? p.hashMapLoadFactor : 0.75,
arrayAdditionalAllocation: p.arrayAdditionalAllocation ? p.arrayAdditionalAllocation : 0,
minimumStringAllocation: p.minimumStringAllocation ? p.minimumStringAllocation : 0
arrayAdditionalAllocation: p.arrayAdditionalAllocation ? p.arrayAdditionalAllocation : 0
};

@@ -118,2 +96,5 @@ }

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;
}

@@ -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-4b90e23",
"version": "0.0.0-547d018",
"main": "dist/objectbuffer.cjs.js",

@@ -39,34 +39,37 @@ "module": "dist/index.js",

"devDependencies": {
"@babel/cli": "^7.7.0",
"@babel/core": "^7.7.0",
"@babel/preset-env": "^7.7.1",
"@babel/preset-typescript": "^7.7.0",
"@types/jest": "^24.0.22",
"@types/node": "^12.12.6",
"@typescript-eslint/eslint-plugin": "^2.6.1",
"@typescript-eslint/parser": "^2.6.1",
"babel-loader": "^8.0.6",
"concurrently": "^5.0.0",
"core-js": "^3.4.0",
"eslint": "^6.6.0",
"eslint-config-prettier": "^6.5.0",
"eslint-plugin-prettier": "^3.1.1",
"gh-pages": "^2.1.1",
"html-webpack-plugin": "^3.2.0",
"husky": "^3.0.9",
"jest": "^24.9.0",
"prettier": "^1.18.2",
"prettier-eslint": "^9.0.0",
"rimraf": "^3.0.0",
"rollup": "^1.26.3",
"rollup-plugin-babel": "^4.3.3",
"@babel/cli": "^7.8.4",
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.5",
"@babel/preset-typescript": "^7.9.0",
"@types/benchmark": "^1.0.31",
"@types/jest": "^25.2.1",
"@types/node": "^12.12.21",
"@typescript-eslint/eslint-plugin": "^2.27.0",
"@typescript-eslint/parser": "^2.27.0",
"babel-loader": "^8.1.0",
"benchmark": "^2.1.4",
"concurrently": "^5.1.0",
"core-js": "^3.6.5",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.1",
"eslint-plugin-prettier": "^3.1.2",
"gh-pages": "^2.2.0",
"html-webpack-plugin": "^4.2.0",
"husky": "^4.2.5",
"jest": "^25.3.0",
"kind-of": "^6.0.3",
"prettier": "^2.0.4",
"prettier-eslint": "^9.0.1",
"rimraf": "^3.0.2",
"rollup": "^2.4.0",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-node-resolve": "^5.2.0",
"typedoc": "npm:@gnd/typedoc",
"typedoc-plugin-markdown": "^2.2.11",
"typescript": "^3.7.2",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.9.0",
"typedoc": "^0.17.4",
"typedoc-plugin-markdown": "^2.2.17",
"typescript": "^3.8.3",
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3",
"worker-loader": "^2.0.0",
"yarn-deduplicate": "^1.1.1"
"yarn-deduplicate": "^2.0.0"
},

@@ -85,8 +88,5 @@ "husky": {

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

@@ -15,3 +15,2 @@ /* eslint-env jest */

arrayAdditionalAllocation: 0,
minimumStringAllocation: 0
});

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

expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`624`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`592`);
});
});

@@ -14,3 +14,2 @@ /* eslint-env jest */

arrayAdditionalAllocation: 0,
minimumStringAllocation: 0
});

@@ -21,3 +20,3 @@

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

@@ -51,4 +50,4 @@

expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`240`);
expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`264`);
});
});

@@ -14,3 +14,2 @@ /* eslint-env jest */

arrayAdditionalAllocation: 0,
minimumStringAllocation: 0
});

@@ -58,4 +57,4 @@

expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`728`);
expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`776`);
});
});

@@ -12,3 +12,3 @@ /* eslint-env jest */

textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder()
textDecoder: new util.TextDecoder(),
});

@@ -18,6 +18,6 @@

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(`592`);
expect(objectBuffer.foo).toMatchInlineSnapshot(`

@@ -32,7 +32,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(`504`);
expect(objectBuffer.foo).toMatchInlineSnapshot(`

@@ -56,11 +56,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(`504`);
objectBuffer.foo.delete(1);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`632`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`592`);

@@ -76,17 +76,16 @@ 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();
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`680`);
objectBuffer.foo.set(1, "a");
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`592`);
objectBuffer.foo.set("2", "b");
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`504`);
objectBuffer.foo.clear();
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`704`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`680`);
expect(objectBuffer.foo).toMatchInlineSnapshot(`
Map {
"2" => "b",
}
`);
expect(objectBuffer.foo).toMatchInlineSnapshot(`Map {}`);
});

@@ -96,3 +95,3 @@

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

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

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

@@ -128,3 +127,6 @@ expect(objectBuffer.foo).toMatchInlineSnapshot(`

test.skip("iterate + delete compare", () => {
const nativeMap = new Map([[1, "a"], [2, "b"]]);
const nativeMap = new Map([
[1, "a"],
[2, "b"],
]);
for (const [key] of nativeMap) {

@@ -135,3 +137,6 @@ nativeMap.delete(key);

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

@@ -147,3 +152,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`);

@@ -161,3 +166,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);

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

@@ -14,3 +14,2 @@ /* eslint-env jest */

arrayAdditionalAllocation: 0,
minimumStringAllocation: 0
});

@@ -21,3 +20,3 @@

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

@@ -27,4 +26,4 @@

Object {
"available": 424,
"used": 600,
"available": 376,
"used": 648,
}

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

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

@@ -43,4 +42,4 @@

Object {
"available": 1448,
"used": 600,
"available": 1400,
"used": 648,
}

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

Object {
"available": 424,
"used": 600,
"available": 376,
"used": 648,
}

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

Object {
"available": 168,
"used": 600,
"available": 120,
"used": 648,
}

@@ -69,8 +68,8 @@ `);

expect(memoryStats(objectBuffer)).toMatchInlineSnapshot(`
Object {
"available": 1448,
"used": 600,
}
`);
Object {
"available": 1400,
"used": 648,
}
`);
});
});

@@ -12,3 +12,3 @@ /* eslint-env jest */

textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder()
textDecoder: new util.TextDecoder(),
});

@@ -18,13 +18,43 @@

const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {});
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`);
objectBuffer.foo = "a";
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`800`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`776`);
// objectBuffer.foo = "b";
delete objectBuffer.foo;
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`);
expect(objectBuffer).toMatchInlineSnapshot(`Object {}`);
});
test("Basic object with values", () => {
const input = {
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, 2048, input);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`1016`);
expect(input).toEqual(objectBuffer);
expect(objectBuffer).toMatchInlineSnapshot(`
Object {
"a": 1,
"b": true,
"c": false,
"d": null,
"e": undefined,
"foo": Object {
"a": 1,
"b": true,
"c": false,
"d": null,
"e": undefined,
},
}
`);
});
});

@@ -9,7 +9,7 @@ /* eslint-env jest */

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

@@ -22,3 +22,2 @@

arrayAdditionalAllocation: 0,
minimumStringAllocation: 0
});

@@ -28,3 +27,3 @@

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

@@ -43,3 +42,3 @@

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

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

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

@@ -57,0 +56,0 @@

@@ -15,3 +15,2 @@ /* eslint-env jest */

arrayAdditionalAllocation: 0,
minimumStringAllocation: 0
});

@@ -26,4 +25,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",
});

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

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

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

@@ -12,3 +12,3 @@ /* eslint-env jest */

textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder()
textDecoder: new util.TextDecoder(),
});

@@ -18,6 +18,6 @@

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(`616`);
expect(objectBuffer.foo).toMatchInlineSnapshot(`

@@ -32,7 +32,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(`576`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`);
expect(objectBuffer.foo).toMatchInlineSnapshot(`

@@ -56,11 +56,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(`576`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`);
objectBuffer.foo.delete(1);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`576`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`);

@@ -77,17 +77,13 @@ 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(`576`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`);
objectBuffer.foo.clear();
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`704`);
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`680`);
expect(objectBuffer.foo).toMatchInlineSnapshot(`
Set {
"b",
}
`);
expect(objectBuffer.foo).toMatchInlineSnapshot(`Set {}`);
});

@@ -97,3 +93,3 @@

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

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

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

@@ -135,3 +131,3 @@ expect(objectBuffer.foo).toMatchInlineSnapshot(`

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

@@ -147,3 +143,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`);

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

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

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

@@ -6,3 +6,3 @@ /* eslint-env jest */

import { createObjectBuffer } from "../";
import { memoryStats } from "../internal/api";
import { memoryStats, disposeWrapperObject } from "../internal/api";
import { externalArgsApiToExternalArgsApi } from "../internal/utils";

@@ -16,3 +16,2 @@

arrayAdditionalAllocation: 0,
minimumStringAllocation: 0
});

@@ -40,4 +39,53 @@

expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`440`);
expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`480`);
});
test("basic 2", () => {
const objectBuffer = createObjectBuffer<any>(
externalArgs,
1024,
{ o: { a: { a: { v: [1] } } } },
{ useSharedArrayBuffer: true }
);
const prev1 = objectBuffer.o;
objectBuffer.o = undefined;
const prev2 = prev1.a;
const prev3 = prev1.a.a;
disposeWrapperObject(prev1);
// disposeWrapperObject(prev2);
// disposeWrapperObject(prev3);
// objectBuffer.arr = [{ bar: 666 }];
// objectBuffer.arr = [];
objectBuffer.o = undefined;
// disposeWrapperObject(objectBuffer.arr);
expect(prev2).toMatchInlineSnapshot(`
Object {
"a": Object {
"v": Array [
1,
],
},
}
`);
expect(prev3).toMatchInlineSnapshot(`
Object {
"v": Array [
1,
],
}
`);
expect(objectBuffer).toMatchInlineSnapshot(`
Object {
"o": undefined,
}
`);
expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`664`);
});
});

@@ -30,3 +30,3 @@ /* eslint-disable */

arrayAdditionalAllocation: 0,
minimumStringAllocation: 0
});

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

@@ -13,3 +13,2 @@ import * as util from "util";

arrayAdditionalAllocation: 0,
minimumStringAllocation: 0
});

@@ -19,3 +18,3 @@

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

@@ -31,3 +30,3 @@

more: "than size",
arr: [1, 2, 3]
arr: [1, 2, 3],
};

@@ -34,0 +33,0 @@ }).toThrowErrorMatchingInlineSnapshot(`"OutOfMemoryError"`);

@@ -13,3 +13,2 @@ import * as util from "util";

arrayAdditionalAllocation: 0,
minimumStringAllocation: 0
});

@@ -19,3 +18,3 @@

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

@@ -55,3 +54,3 @@

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

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

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

@@ -87,0 +86,0 @@

@@ -7,3 +7,3 @@ /* eslint-env jest */

getUnderlyingArrayBuffer,
loadObjectBuffer
loadObjectBuffer,
} from ".";

@@ -18,3 +18,2 @@ import { arrayBuffer2HexArray } from "./internal/testUtils";

arrayAdditionalAllocation: 0,
minimumStringAllocation: 0
});

@@ -26,3 +25,3 @@

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

@@ -47,3 +46,2 @@

arrayAdditionalAllocation: 0,
minimumStringAllocation: 0
});

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

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

@@ -71,3 +69,2 @@

arrayAdditionalAllocation: 0,
minimumStringAllocation: 0
});

@@ -79,3 +76,3 @@

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

@@ -82,0 +79,0 @@

@@ -20,3 +20,3 @@ /**

disposeWrapperObject,
updateExternalArgs
updateExternalArgs,
} from "./internal/api";

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

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

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

import { MemPool } from "@thi.ng/malloc";
import { UnsupportedOperationError } from "./exceptions";

@@ -36,13 +38,32 @@ export interface CreateObjectBufferOptions {

): T {
if (
Array.isArray(initialValue) ||
initialValue instanceof Date ||
initialValue instanceof Map ||
initialValue instanceof Set ||
isPrimitive(initialValue)
) {
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 = { dataView, allocator };
const carrier: GlobalCarrier = {
// dataView,
allocator,
uint8: new Uint8Array(arrayBuffer),
uint16: new Uint16Array(arrayBuffer),
uint32: new Uint32Array(arrayBuffer),
float64: new Float64Array(arrayBuffer),
bigUint64: new BigUint64Array(arrayBuffer),
};

@@ -56,3 +77,5 @@ const start = objectSaver(

dataView.setUint32(INITIAL_ENTRY_POINTER_TO_POINTER, start);
carrier.uint32[
INITIAL_ENTRY_POINTER_TO_POINTER / Uint32Array.BYTES_PER_ELEMENT
] = start;

@@ -92,3 +115,3 @@ return createObjectWrapper(

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

@@ -109,13 +132,26 @@

): 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: GlobalCarrier = {
// dataView,
allocator,
uint8: new Uint8Array(arrayBuffer),
uint16: new Uint16Array(arrayBuffer),
uint32: new Uint32Array(arrayBuffer),
float64: new Float64Array(arrayBuffer),
bigUint64: new BigUint64Array(arrayBuffer),
};
return createObjectWrapper(
externalArgsApiToExternalArgsApi(externalArgs),
{ dataView, allocator },
dataView.getUint32(INITIAL_ENTRY_POINTER_TO_POINTER)
carrier,
carrier.uint32[
INITIAL_ENTRY_POINTER_TO_POINTER / Uint32Array.BYTES_PER_ELEMENT
]
);

@@ -149,7 +185,18 @@ }

const allocator = new MemPool({
align: 8,
buf: newArrayBuffer,
start: MEM_POOL_START,
skipInitialization: true
skipInitialization: true,
});
const carrier: GlobalCarrier = {
// dataView: new DataView(newArrayBuffer),
allocator,
uint8: new Uint8Array(newArrayBuffer),
uint16: new Uint16Array(newArrayBuffer),
uint32: new Uint32Array(newArrayBuffer),
float64: new Float64Array(newArrayBuffer),
bigUint64: new BigUint64Array(newArrayBuffer),
};
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore

@@ -159,6 +206,3 @@ // @ts-ignore

getInternalAPI(objectBuffer).replaceCarrierContent(
new DataView(newArrayBuffer),
allocator
);
getInternalAPI(objectBuffer).replaceCarrierContent(carrier);
}

@@ -175,5 +219,6 @@

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

@@ -180,0 +225,0 @@

@@ -9,3 +9,3 @@ /* eslint-env jest */

getFinalValueAtArrayIndex,
setValueAtArrayIndex
setValueAtArrayIndex,
} from "./arrayHelpers";

@@ -16,2 +16,3 @@ import { ExternalArgs } from "./interfaces";

import { externalArgsApiToExternalArgsApi } from "./utils";
import { makeCarrier } from "./testUtils";

@@ -22,3 +23,2 @@ const externalArgs: ExternalArgs = externalArgsApiToExternalArgsApi({

arrayAdditionalAllocation: 0,
minimumStringAllocation: 0
});

@@ -29,19 +29,10 @@

const arrayBuffer = new ArrayBuffer(256);
const dataView = new DataView(arrayBuffer);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const arrayToSave = [1, 2];
const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
arrayToSave
);
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const metadata = arrayGetMetadata(externalArgs, dataView, saverOutput);
const metadata = arrayGetMetadata(carrier, saverOutput);

@@ -58,3 +49,3 @@ expect(metadata).toMatchInlineSnapshot(`

expect(allocator.stats().available).toMatchInlineSnapshot(`128`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`120`);
});

@@ -66,7 +57,7 @@

const dataView = new DataView(arrayBuffer);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -76,12 +67,7 @@

const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
arrayToSave
);
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const finalValue = getFinalValueAtArrayIndex(
externalArgs,
{ dataView, allocator },
carrier,
saverOutput,

@@ -92,3 +78,3 @@ 0

expect(finalValue).toMatchInlineSnapshot(`1`);
expect(allocator.stats().available).toMatchInlineSnapshot(`128`);
expect(allocator.stats().available).toMatchInlineSnapshot(`120`);
});

@@ -99,7 +85,7 @@

const dataView = new DataView(arrayBuffer);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -109,12 +95,7 @@

const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
arrayToSave
);
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const finalValue = getFinalValueAtArrayIndex(
externalArgs,
{ dataView, allocator },
carrier,
saverOutput,

@@ -125,3 +106,3 @@ 10

expect(finalValue).toMatchInlineSnapshot(`undefined`);
expect(allocator.stats().available).toMatchInlineSnapshot(`128`);
expect(allocator.stats().available).toMatchInlineSnapshot(`120`);
});

@@ -132,7 +113,7 @@

const dataView = new DataView(arrayBuffer);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -142,12 +123,7 @@

const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
arrayToSave
);
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const finalValue = getFinalValueAtArrayIndex(
externalArgs,
{ dataView, allocator },
carrier,
saverOutput,

@@ -158,3 +134,3 @@ 1

expect(finalValue).toMatchInlineSnapshot(`"b"`);
expect(allocator.stats().available).toMatchInlineSnapshot(`144`);
expect(allocator.stats().available).toMatchInlineSnapshot(`120`);
});

@@ -166,7 +142,7 @@ });

const dataView = new DataView(arrayBuffer);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -176,12 +152,7 @@

const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
arrayToSave
);
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
setValueAtArrayIndex(
externalArgs,
{ dataView, allocator },
carrier,
saverOutput,

@@ -194,3 +165,3 @@ 1,

externalArgs,
{ dataView, allocator },
carrier,
saverOutput,

@@ -201,4 +172,4 @@ 1

expect(finalValue).toMatchInlineSnapshot(`"im the new value"`);
expect(allocator.stats().available).toMatchInlineSnapshot(`120`);
expect(allocator.stats().available).toMatchInlineSnapshot(`104`);
});
});
import {
readEntry,
writeEntry,
writeValueInPtrToPtrAndHandleMemory
writeValueInPtrToPtrAndHandleMemory,
} from "./store";
import {
ArrayEntry,
ExternalArgs,
DataViewAndAllocatorCarrier
} from "./interfaces";
import { ArrayEntry, ExternalArgs, GlobalCarrier } from "./interfaces";
import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue";

@@ -16,11 +12,6 @@ import { ENTRY_TYPE } from "./entry-types";

export function arrayGetMetadata(
externalArgs: ExternalArgs,
dataView: DataView,
carrier: GlobalCarrier,
pointerToArrayEntry: number
) {
const arrayEntry = readEntry(
externalArgs,
dataView,
pointerToArrayEntry
) as ArrayEntry;
const arrayEntry = readEntry(carrier, pointerToArrayEntry) as ArrayEntry;

@@ -31,12 +22,7 @@ return arrayEntry;

export function arrayGetPointersToValueInIndex(
externalArgs: ExternalArgs,
dataView: DataView,
carrier: GlobalCarrier,
pointerToArrayEntry: number,
indexToGet: number
) {
const metadata = arrayGetMetadata(
externalArgs,
dataView,
pointerToArrayEntry
);
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry);

@@ -51,7 +37,8 @@ // out of bound

const pointer = dataView.getUint32(pointerToThePointer);
const pointer =
carrier.uint32[pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT];
return {
pointer,
pointerToThePointer
pointerToThePointer,
};

@@ -62,3 +49,3 @@ }

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

@@ -68,4 +55,3 @@ indexToGet: number

const pointers = arrayGetPointersToValueInIndex(
externalArgs,
dataViewCarrier.dataView,
globalCarrier,
pointerToArrayEntry,

@@ -81,3 +67,3 @@ indexToGet

externalArgs,
dataViewCarrier,
globalCarrier,
pointers.pointer

@@ -88,4 +74,3 @@ );

export function setValuePointerAtArrayIndex(
externalArgs: ExternalArgs,
dataView: DataView,
carrier: GlobalCarrier,
pointerToArrayEntry: number,

@@ -96,4 +81,3 @@ indexToSet: number,

const pointers = arrayGetPointersToValueInIndex(
externalArgs,
dataView,
carrier,
pointerToArrayEntry,

@@ -104,4 +88,5 @@ indexToSet

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

@@ -111,3 +96,3 @@

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

@@ -119,4 +104,3 @@ indexToSet: number,

const pointers = arrayGetPointersToValueInIndex(
externalArgs,
carrier.dataView,
carrier,
pointerToArrayEntry,

@@ -139,11 +123,7 @@ indexToSet

externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
pointerToArrayEntry: number,
wishedLength: number
) {
const metadata = arrayGetMetadata(
externalArgs,
carrier.dataView,
pointerToArrayEntry
);
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry);

@@ -161,3 +141,3 @@ if (wishedLength > metadata.length) {

// no need to re-allocated, just push the length forward
writeEntry(externalArgs, carrier.dataView, pointerToArrayEntry, {
writeEntry(carrier, pointerToArrayEntry, {
type: ENTRY_TYPE.ARRAY,

@@ -167,3 +147,3 @@ refsCount: metadata.refsCount,

allocatedLength: metadata.allocatedLength,
length: wishedLength
length: wishedLength,
});

@@ -179,13 +159,9 @@ }

externalArgs: ExternalArgs,
dataView: DataView,
carrier: GlobalCarrier,
pointerToArrayEntry: number,
wishedLength: number
) {
const metadata = arrayGetMetadata(
externalArgs,
dataView,
pointerToArrayEntry
);
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry);
writeEntry(externalArgs, dataView, pointerToArrayEntry, {
writeEntry(carrier, pointerToArrayEntry, {
type: ENTRY_TYPE.ARRAY,

@@ -195,3 +171,3 @@ refsCount: metadata.refsCount,

allocatedLength: metadata.allocatedLength,
length: wishedLength
length: wishedLength,
});

@@ -202,3 +178,3 @@ }

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

@@ -208,7 +184,3 @@ newAllocatedLength: number,

) {
const metadata = arrayGetMetadata(
externalArgs,
carrier.dataView,
pointerToArrayEntry
);
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry);

@@ -233,3 +205,3 @@ const newArrayValueLocation = carrier.allocator.realloc(

writeEntry(externalArgs, carrier.dataView, pointerToArrayEntry, {
writeEntry(carrier, pointerToArrayEntry, {
type: ENTRY_TYPE.ARRAY,

@@ -239,3 +211,3 @@ refsCount: metadata.refsCount,

allocatedLength: newAllocatedLength,
length: newLength
length: newLength,
});

@@ -246,21 +218,18 @@ }

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

@@ -274,6 +243,6 @@ });

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

@@ -321,10 +290,6 @@ }

externalArgs: ExternalArgs,
dataView: DataView,
carrier: GlobalCarrier,
pointerToArrayEntry: number
) {
const metadata = arrayGetMetadata(
externalArgs,
dataView,
pointerToArrayEntry
);
const metadata = arrayGetMetadata(carrier, pointerToArrayEntry);

@@ -335,13 +300,7 @@ for (let i = 0; i < Math.floor(metadata.length / 2); i += 1) {

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const a = arrayGetPointersToValueInIndex(
externalArgs,
dataView,
pointerToArrayEntry,
i
)!;
const a = arrayGetPointersToValueInIndex(carrier, pointerToArrayEntry, i)!;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const b = arrayGetPointersToValueInIndex(
externalArgs,
dataView,
carrier,
pointerToArrayEntry,

@@ -351,13 +310,6 @@ theOtherIndex

setValuePointerAtArrayIndex(
externalArgs,
dataView,
pointerToArrayEntry,
i,
b.pointer
);
setValuePointerAtArrayIndex(carrier, pointerToArrayEntry, i, b.pointer);
setValuePointerAtArrayIndex(
externalArgs,
dataView,
carrier,
pointerToArrayEntry,

@@ -364,0 +316,0 @@ theOtherIndex,

@@ -5,6 +5,4 @@ /* eslint-env jest */

import * as util from "util";
import { arrayBuffer2HexArray } from "./testUtils";
import { arrayBuffer2HexArray, makeCarrier } from "./testUtils";
import { arraySaver } from "./arraySaver";
import { MemPool } from "@thi.ng/malloc";
import { MEM_POOL_START } from "./consts";
import { externalArgsApiToExternalArgsApi } from "./utils";

@@ -16,3 +14,3 @@

textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});

@@ -24,17 +22,8 @@

const dataView = new DataView(arrayBuffer);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const arrayToSave = [1, 2, 3];
const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
arrayToSave
);
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);

@@ -41,0 +30,0 @@ expect(saverOutput).toMatchInlineSnapshot(`224`);

import { appendEntry } from "./store";
import { ENTRY_TYPE } from "./entry-types";
import {
ArrayEntry,
ExternalArgs,
DataViewAndAllocatorCarrier
} from "./interfaces";
import { ArrayEntry, ExternalArgs, GlobalCarrier } from "./interfaces";
import { saveValue } from "./saveValue";

@@ -12,3 +8,3 @@

externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
referencedPointers: number[],

@@ -28,3 +24,3 @@ arrayToSave: Array<any>

arrayToSave.length + externalArgs.arrayAdditionalAllocation,
length: arrayToSave.length
length: arrayToSave.length,
};

@@ -35,3 +31,6 @@

carrier.dataView.setUint32(memoryForPointersCursor, rOfValue);
carrier.uint32[
memoryForPointersCursor / Uint32Array.BYTES_PER_ELEMENT
] = rOfValue;
memoryForPointersCursor += Uint32Array.BYTES_PER_ELEMENT;

@@ -38,0 +37,0 @@ }

@@ -10,2 +10,3 @@ /* eslint-env jest */

import { externalArgsApiToExternalArgsApi } from "./utils";
import { makeCarrier } from "./testUtils";

@@ -16,3 +17,3 @@ describe("arraySplice tests", () => {

textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});

@@ -22,7 +23,7 @@

const arrayBuffer = new ArrayBuffer(512);
const dataView = new DataView(arrayBuffer);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -32,12 +33,7 @@

const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
plainJSArray
);
const saverOutput = arraySaver(externalArgs, carrier, [], plainJSArray);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
{ dataView, allocator },
carrier,
saverOutput

@@ -97,3 +93,3 @@ );

expect(allocator.stats().available).toMatchInlineSnapshot(`32`);
expect(allocator.stats().available).toMatchInlineSnapshot(`0`);
});

@@ -103,7 +99,7 @@

const arrayBuffer = new ArrayBuffer(512);
const dataView = new DataView(arrayBuffer);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -113,12 +109,7 @@

const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
plainJSArray
);
const saverOutput = arraySaver(externalArgs, carrier, [], plainJSArray);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
{ dataView, allocator },
carrier,
saverOutput

@@ -155,3 +146,3 @@ );

expect(allocator.stats().available).toMatchInlineSnapshot(`80`);
expect(allocator.stats().available).toMatchInlineSnapshot(`72`);
});

@@ -161,7 +152,7 @@

const arrayBuffer = new ArrayBuffer(512);
const dataView = new DataView(arrayBuffer);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -171,12 +162,7 @@

const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
plainJSArray
);
const saverOutput = arraySaver(externalArgs, carrier, [], plainJSArray);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
{ dataView, allocator },
carrier,
saverOutput

@@ -222,12 +208,12 @@ );

expect(plainJSArray).toEqual([...arrayWrapper]);
expect(allocator.stats().available).toMatchInlineSnapshot(`48`);
expect(allocator.stats().available).toMatchInlineSnapshot(`24`);
});
test("arrayWrapper splice - add + delete - array will get longer", () => {
const arrayBuffer = new ArrayBuffer(512);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(1024);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -237,15 +223,12 @@

const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
plainJSArray
);
const saverOutput = arraySaver(externalArgs, carrier, [], plainJSArray);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
{ dataView, allocator },
carrier,
saverOutput
);
const availableCheckpoint = allocator.stats().available;
const removed = arrayWrapper.splice(2, 2, "a", "b", "c", "d");

@@ -306,12 +289,14 @@ const removedFromPlain = plainJSArray.splice(2, 2, "a", "b", "c", "d");

expect(allocator.stats().available).toMatchInlineSnapshot(`16`);
expect(
availableCheckpoint - allocator.stats().available
).toMatchInlineSnapshot(`96`);
});
test("arrayWrapper splice - add + delete - array will get shorter", () => {
const arrayBuffer = new ArrayBuffer(512);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(1024);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -321,15 +306,12 @@

const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
plainJSArray
);
const saverOutput = arraySaver(externalArgs, carrier, [], plainJSArray);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
{ dataView, allocator },
carrier,
saverOutput
);
const availableCheckpoint = allocator.stats().available;
const removed = arrayWrapper.splice(2, 6, "a", "b", "c", "d");

@@ -391,3 +373,5 @@ const removedFromPlain = plainJSArray.splice(2, 6, "a", "b", "c", "d");

expect(allocator.stats().available).toMatchInlineSnapshot(`16`);
expect(
availableCheckpoint - allocator.stats().available
).toMatchInlineSnapshot(`96`);
});

@@ -397,7 +381,7 @@

const arrayBuffer = new ArrayBuffer(512);
const dataView = new DataView(arrayBuffer);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -407,12 +391,7 @@

const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
plainJSArray
);
const saverOutput = arraySaver(externalArgs, carrier, [], plainJSArray);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
{ dataView, allocator },
carrier,
saverOutput

@@ -467,3 +446,3 @@ );

expect(allocator.stats().available).toMatchInlineSnapshot(`48`);
expect(allocator.stats().available).toMatchInlineSnapshot(`24`);
});

@@ -473,7 +452,7 @@

const arrayBuffer = new ArrayBuffer(512);
const dataView = new DataView(arrayBuffer);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -483,12 +462,7 @@

const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
plainJSArray
);
const saverOutput = arraySaver(externalArgs, carrier, [], plainJSArray);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
{ dataView, allocator },
carrier,
saverOutput

@@ -549,3 +523,3 @@ );

expect(allocator.stats().available).toMatchInlineSnapshot(`48`);
expect(allocator.stats().available).toMatchInlineSnapshot(`24`);
});

@@ -555,7 +529,7 @@

const arrayBuffer = new ArrayBuffer(512);
const dataView = new DataView(arrayBuffer);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -565,12 +539,7 @@

const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
plainJSArray
);
const saverOutput = arraySaver(externalArgs, carrier, [], plainJSArray);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
{ dataView, allocator },
carrier,
saverOutput

@@ -631,3 +600,3 @@ );

expect(allocator.stats().available).toMatchInlineSnapshot(`48`);
expect(allocator.stats().available).toMatchInlineSnapshot(`24`);
});

@@ -637,7 +606,7 @@

const arrayBuffer = new ArrayBuffer(512);
const dataView = new DataView(arrayBuffer);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -647,12 +616,7 @@

const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
plainJSArray
);
const saverOutput = arraySaver(externalArgs, carrier, [], plainJSArray);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
{ dataView, allocator },
carrier,
saverOutput

@@ -707,4 +671,4 @@ );

expect(allocator.stats().available).toMatchInlineSnapshot(`32`);
expect(allocator.stats().available).toMatchInlineSnapshot(`24`);
});
});

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

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

@@ -17,3 +17,3 @@

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

@@ -24,7 +24,3 @@ startArg: number,

) {
const metadata = arrayGetMetadata(
externalArgs,
dataViewCarrier.dataView,
pointerToArrayEntry
);
const metadata = arrayGetMetadata(globalCarrier, pointerToArrayEntry);

@@ -43,3 +39,3 @@ const calcedStart = calculateSpliceStart(metadata.length, startArg);

externalArgs,
dataViewCarrier,
globalCarrier,
pointerToArrayEntry,

@@ -61,3 +57,3 @@ newLength

externalArgs,
dataViewCarrier,
globalCarrier,
pointerToArrayEntry,

@@ -82,4 +78,3 @@ deletedItemIndexToSave

const valueToCopyPointers = arrayGetPointersToValueInIndex(
externalArgs,
dataViewCarrier.dataView,
globalCarrier,
pointerToArrayEntry,

@@ -92,4 +87,3 @@ writeValueToIndex - itemCountChange

setValuePointerAtArrayIndex(
externalArgs,
dataViewCarrier.dataView,
globalCarrier,
pointerToArrayEntry,

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

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

@@ -120,4 +113,3 @@ }

const valueToCopyPointers = arrayGetPointersToValueInIndex(
externalArgs,
dataViewCarrier.dataView,
globalCarrier,
pointerToArrayEntry,

@@ -130,4 +122,3 @@ writeValueToIndex - itemCountChange

setValuePointerAtArrayIndex(
externalArgs,
dataViewCarrier.dataView,
globalCarrier,
pointerToArrayEntry,

@@ -139,7 +130,7 @@ writeValueToIndex,

// empty old array index, its still allocated!
dataViewCarrier.dataView.setUint32(
valueToCopyPointers.pointerToThePointer,
0
);
globalCarrier.uint32[
valueToCopyPointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT
] = 0;
// using that is wastefull

@@ -160,4 +151,3 @@ // setValueAtArrayIndex(

const valueToSetPointers = arrayGetPointersToValueInIndex(
externalArgs,
dataViewCarrier.dataView,
globalCarrier,
pointerToArrayEntry,

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

externalArgs,
dataViewCarrier,
globalCarrier,
valueToSetPointers.pointerToThePointer,

@@ -179,8 +169,3 @@ itemsToAddArg[i]

if (newLength < metadata.length) {
shrinkArray(
externalArgs,
dataViewCarrier.dataView,
pointerToArrayEntry,
newLength
);
shrinkArray(externalArgs, globalCarrier, pointerToArrayEntry, newLength);
}

@@ -187,0 +172,0 @@

@@ -10,2 +10,3 @@ /* eslint-env jest */

import { externalArgsApiToExternalArgsApi } from "./utils";
import { makeCarrier } from "./testUtils";

@@ -16,3 +17,3 @@ describe("arrayWrapper tests", () => {

textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});

@@ -22,9 +23,8 @@

test("arrayWrapper class 1", () => {
const arrayBuffer = new ArrayBuffer(256);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(512);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -34,12 +34,7 @@

const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
arrayToSave
);
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper: any = createArrayWrapper(
externalArgs,
{ dataView, allocator },
carrier,
saverOutput

@@ -56,26 +51,20 @@ );

expect(allocator.stats().available).toMatchInlineSnapshot(`32`);
expect(allocator.stats().available).toMatchInlineSnapshot(`264`);
});
test("arrayWrapper array.keys()", () => {
const arrayBuffer = new ArrayBuffer(256);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(512);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});
const arrayToSave = ["a", "b", 1];
const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
arrayToSave
);
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper = createArrayWrapper(
externalArgs,
{ dataView, allocator },
carrier,
saverOutput

@@ -86,26 +75,20 @@ );

expect(allocator.stats().available).toMatchInlineSnapshot(`32`);
expect(allocator.stats().available).toMatchInlineSnapshot(`264`);
});
test("arrayWrapper array.entries()", () => {
const arrayBuffer = new ArrayBuffer(256);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(512);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});
const arrayToSave = ["a", "b", 1];
const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
arrayToSave
);
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper = createArrayWrapper(
externalArgs,
{ dataView, allocator },
carrier,
saverOutput

@@ -131,26 +114,20 @@ );

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

@@ -174,26 +151,16 @@ );

expect(allocator.stats().available).toMatchInlineSnapshot(`32`);
expect(allocator.stats().available).toMatchInlineSnapshot(`264`);
});
test("arrayWrapper set value in bound", () => {
const arrayBuffer = new ArrayBuffer(256);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(512);
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,
{ dataView, allocator },
[],
arrayToSave
);
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper: any = createArrayWrapper(
externalArgs,
{ dataView, allocator },
carrier,
saverOutput

@@ -214,10 +181,5 @@ );

test("arrayWrapper set value out of bound, but inside allocated space", () => {
const arrayBuffer = new ArrayBuffer(256);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(512);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const arrayToSave = ["a", "b", 1];

@@ -227,3 +189,3 @@

{ ...externalArgs, arrayAdditionalAllocation: 15 },
{ dataView, allocator },
carrier,
[],

@@ -235,3 +197,3 @@ arrayToSave

{ ...externalArgs, arrayAdditionalAllocation: 15 },
{ dataView, allocator },
carrier,
saverOutput

@@ -260,22 +222,16 @@ );

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

@@ -301,3 +257,3 @@ );

`);
expect(allocator.stats().available).toMatchInlineSnapshot(`8`);
expect(allocator.stats().available).toMatchInlineSnapshot(`232`);
});

@@ -308,7 +264,7 @@ });

const arrayBuffer = new ArrayBuffer(512);
const dataView = new DataView(arrayBuffer);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -318,12 +274,7 @@

const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
arrayToSave
);
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
{ dataView, allocator },
carrier,
saverOutput

@@ -347,3 +298,3 @@ );

expect(allocator.stats().available).toMatchInlineSnapshot(`152`);
expect(allocator.stats().available).toMatchInlineSnapshot(`176`);
});

@@ -353,23 +304,18 @@

const arrayBuffer = new ArrayBuffer(2048);
const dataView = new DataView(arrayBuffer);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
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,
{ dataView, allocator },
[],
arrayToSave
);
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
{ dataView, allocator },
carrier,
saverOutput

@@ -411,3 +357,3 @@ );

expect(allocator.stats().available).toMatchInlineSnapshot(`672`);
expect(allocator.stats().available).toMatchInlineSnapshot(`568`);
});

@@ -417,7 +363,7 @@

const arrayBuffer = new ArrayBuffer(512);
const dataView = new DataView(arrayBuffer);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -427,12 +373,7 @@

const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
arrayToSave
);
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
{ dataView, allocator },
carrier,
saverOutput

@@ -459,3 +400,3 @@ );

expect(allocator.stats().available).toMatchInlineSnapshot(`160`);
expect(allocator.stats().available).toMatchInlineSnapshot(`152`);
});

@@ -465,7 +406,7 @@

const arrayBuffer = new ArrayBuffer(512);
const dataView = new DataView(arrayBuffer);
const carrier = makeCarrier(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
start: MEM_POOL_START,
});

@@ -475,12 +416,7 @@

const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
arrayToSave
);
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper = createArrayWrapper(
{ ...externalArgs, arrayAdditionalAllocation: 3 },
{ dataView, allocator },
carrier,
saverOutput

@@ -524,4 +460,4 @@ );

expect(allocator.stats().available).toMatchInlineSnapshot(`160`);
expect(allocator.stats().available).toMatchInlineSnapshot(`152`);
});
});

@@ -7,14 +7,10 @@ import {

extendArrayIfNeeded,
arrayReverse
arrayReverse,
} from "./arrayHelpers";
import { INTERNAL_API_SYMBOL } from "./symbols";
import { arraySplice } from "./arraySplice";
import { ExternalArgs, GlobalCarrier, ArrayEntry } from "./interfaces";
import {
ExternalArgs,
DataViewAndAllocatorCarrier,
ArrayEntry
} from "./interfaces";
import {
IllegalArrayIndexError,
UnsupportedOperationError
UnsupportedOperationError,
} from "./exceptions";

@@ -38,7 +34,3 @@ import { allocationsTransaction } from "./allocationsTransaction";

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

@@ -75,7 +67,3 @@

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

@@ -102,7 +90,3 @@ return [...new Array(length).keys(), "length"];

const length = arrayGetMetadata(
this.externalArgs,
this.carrier.dataView,
this.entryPointer
).length;
const length = arrayGetMetadata(this.carrier, this.entryPointer).length;

@@ -128,7 +112,4 @@ if (typeof p === "number") {

const currentLength = arrayGetMetadata(
this.externalArgs,
this.carrier.dataView,
this.entryPointer
).length;
const currentLength = arrayGetMetadata(this.carrier, this.entryPointer)
.length;

@@ -195,3 +176,3 @@ if (currentLength === value) {

index
)
),
];

@@ -201,7 +182,3 @@

length = arrayGetMetadata(
this.externalArgs,
this.carrier.dataView,
this.entryPointer
).length;
length = arrayGetMetadata(this.carrier, this.entryPointer).length;
} while (index < length);

@@ -219,7 +196,3 @@ }

length = arrayGetMetadata(
this.externalArgs,
this.carrier.dataView,
this.entryPointer
).length;
length = arrayGetMetadata(this.carrier, this.entryPointer).length;
} while (index < length);

@@ -242,7 +215,3 @@ }

length = arrayGetMetadata(
this.externalArgs,
this.carrier.dataView,
this.entryPointer
).length;
length = arrayGetMetadata(this.carrier, this.entryPointer).length;
} while (index < length);

@@ -271,3 +240,3 @@ }

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

@@ -289,12 +258,8 @@ }

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

@@ -337,3 +302,3 @@ public getEntryPointer() {

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

@@ -343,4 +308,4 @@ ): Array<any> {

[],
new ArrayWrapper(externalArgs, dataViewCarrier, entryPointer)
new ArrayWrapper(externalArgs, globalCarrier, entryPointer)
) as any;
}
import {
ExternalArgs,
DataViewAndAllocatorCarrier,
GlobalCarrier,
InternalAPI,

@@ -9,5 +9,4 @@ DateEntry,

MapEntry,
SetEntry
SetEntry,
} from "./interfaces";
import { IMemPool } from "@thi.ng/malloc";
import { incrementRefCount, decrementRefCount, readEntry } from "./store";

@@ -21,10 +20,6 @@ import { WrapperDestroyed } from "./exceptions";

protected externalArgs: ExternalArgs,
protected carrier: DataViewAndAllocatorCarrier,
protected carrier: GlobalCarrier,
protected _entryPointer: number
) {
incrementRefCount(
this.externalArgs,
this.carrier.dataView,
this.entryPointer
);
incrementRefCount(this.externalArgs, this.carrier, this.entryPointer);
}

@@ -35,3 +30,3 @@

this.externalArgs,
this.carrier.dataView,
this.carrier,
this.entryPointer

@@ -48,5 +43,4 @@ );

public replaceCarrierContent(dataView: DataView, allocator: IMemPool) {
this.carrier.dataView = dataView;
this.carrier.allocator = allocator;
public replaceCarrierContent(newCarrierContent: GlobalCarrier) {
Object.assign(this.carrier, newCarrierContent);
}

@@ -71,8 +65,4 @@

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

@@ -10,1 +10,6 @@ export const LOCK_OFFSET = 0;

INITIAL_ENTRY_POINTER_VALUE + Uint32Array.BYTES_PER_ELEMENT;
export const UNDEFINED_KNOWN_ADDRESS = 0;
export const NULL_KNOWN_ADDRESS = 1;
export const TRUE_KNOWN_ADDRESS = 2;
export const FALSE_KNOWN_ADDRESS = 3;

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

import {
ExternalArgs,
DataViewAndAllocatorCarrier,
DateEntry
} from "./interfaces";
import { ExternalArgs, GlobalCarrier, DateEntry } from "./interfaces";

@@ -42,3 +38,3 @@ import { readEntry, writeEntry } from "./store";

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

@@ -62,3 +58,3 @@

"setUTCMonth",
"setUTCSeconds"
"setUTCSeconds",
// "setYear"

@@ -74,3 +70,3 @@ ];

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

@@ -114,7 +110,3 @@ ) {

private updateDateObjectForReuse() {
const entry = readEntry(
this.externalArgs,
this.carrier.dataView,
this.entryPointer
) as DateEntry;
const entry = readEntry(this.carrier, this.entryPointer) as DateEntry;

@@ -125,6 +117,6 @@ this.dateObjectForReuse.setTime(entry.value);

private persistDateObject() {
writeEntry(this.externalArgs, this.carrier.dataView, this.entryPointer, {
writeEntry(this.carrier, this.entryPointer, {
type: ENTRY_TYPE.DATE,
refsCount: this.entry.refsCount,
value: this.dateObjectForReuse.getTime()
value: this.dateObjectForReuse.getTime(),
});

@@ -148,3 +140,3 @@ }

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

@@ -151,0 +143,0 @@ ): Date {

@@ -11,3 +11,3 @@ import * as util from "util";

textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});

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

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

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

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

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

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

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

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

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

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

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

import { getInternalAPI } from "./utils";
import { getCacheFor } from "./externalObjectsCache";
import { getAllLinkedAddresses } from "./getAllLinkedAddresses";
import { decrementRefCount } from "./store";

@@ -19,4 +20,3 @@ /**

const addressesToFree = getAllLinkedAddresses(
internalApi.getExternalArgs(),
internalApi.getCarrier().dataView,
internalApi.getCarrier(),
false,

@@ -26,6 +26,14 @@ entryPointer

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

@@ -32,0 +40,0 @@ }

import { createKnownTypeGuard } from "./utils";
export enum ENTRY_TYPE {
/**
* @deprecated
*/
UNDEFINED,
/**
* @deprecated
*/
NULL,

@@ -10,5 +16,10 @@ NUMBER,

STRING,
/**
* @deprecated
*/
BOOLEAN,
OBJECT,
// deprecated
/**
* @deprecated
*/
OBJECT_PROP,

@@ -19,15 +30,12 @@ ARRAY,

SET,
DATE
DATE,
}
export const PRIMITIVE_TYPES = [
ENTRY_TYPE.NULL,
ENTRY_TYPE.UNDEFINED,
ENTRY_TYPE.NUMBER,
ENTRY_TYPE.BIGINT_POSITIVE,
ENTRY_TYPE.BIGINT_NEGATIVE,
ENTRY_TYPE.BOOLEAN,
ENTRY_TYPE.STRING
ENTRY_TYPE.STRING,
] as const;
export const isPrimitiveEntryType = createKnownTypeGuard(PRIMITIVE_TYPES);

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

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

@@ -11,2 +11,8 @@ import { createObjectWrapper } from "./objectWrapper";

import { createSetWrapper } from "./setWrapper";
import {
UNDEFINED_KNOWN_ADDRESS,
NULL_KNOWN_ADDRESS,
TRUE_KNOWN_ADDRESS,
FALSE_KNOWN_ADDRESS,
} from "./consts";

@@ -21,3 +27,3 @@ // declare const FinalizationGroup: any;

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

@@ -27,15 +33,23 @@

externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
pointerToEntry: number
) {
const valueEntry = readEntry(externalArgs, carrier.dataView, pointerToEntry);
if (pointerToEntry === UNDEFINED_KNOWN_ADDRESS) {
return undefined;
}
if (valueEntry.type === ENTRY_TYPE.NULL) {
if (pointerToEntry === NULL_KNOWN_ADDRESS) {
return null;
}
if (valueEntry.type === ENTRY_TYPE.UNDEFINED) {
return undefined;
if (pointerToEntry === TRUE_KNOWN_ADDRESS) {
return true;
}
if (pointerToEntry === FALSE_KNOWN_ADDRESS) {
return false;
}
const valueEntry = readEntry(carrier, pointerToEntry);
if (isPrimitiveEntryType(valueEntry.type)) {

@@ -52,3 +66,3 @@ return valueEntry.value;

) {
const cache = getCacheFor(carrier, key => {
const cache = getCacheFor(carrier, (key) => {
finalizer(key, carrier, externalArgs);

@@ -78,23 +92,18 @@ });

memoryAddress: number,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
externalArgs: ExternalArgs
) {
const newRefsCount = decrementRefCount(
externalArgs,
carrier.dataView,
memoryAddress
);
const newRefsCount = decrementRefCount(externalArgs, carrier, memoryAddress);
if (newRefsCount === 0) {
const freeUs = getAllLinkedAddresses(
externalArgs,
carrier.dataView,
false,
memoryAddress
);
const freeUs = getAllLinkedAddresses(carrier, false, memoryAddress);
for (const address of freeUs) {
for (const address of freeUs.leafAddresses) {
carrier.allocator.free(address);
}
for (const address of freeUs.arcAddresses) {
decrementRefCount(externalArgs, carrier, address);
}
}
}

@@ -5,7 +5,3 @@ /* eslint-env jest */

import { MemPool } from "@thi.ng/malloc";
import {
createObjectBuffer,
memoryStats,
getUnderlyingArrayBuffer
} from "./api";
import { createObjectBuffer, memoryStats } from "./api";
import { getAllLinkedAddresses } from "./getAllLinkedAddresses";

@@ -18,7 +14,7 @@ import { getInternalAPI, externalArgsApiToExternalArgsApi } from "./utils";

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[] = [];

@@ -35,12 +31,86 @@ const origMalloc = MemPool.prototype.malloc;

const objectBuffer = createObjectBuffer(externalArgs, 2048, {
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();
const linkedAddresses = getAllLinkedAddresses(
carrier,
false,
entryPointer
);
expect([...linkedAddresses.leafAddresses].slice().sort()).toEqual(
allocatedAddresses.slice().sort()
);
});
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 }]
arr: [new Date(0), "somestring", { a: "6", h: null }],
});
const dataView = new DataView(getUnderlyingArrayBuffer(objectBuffer));
// const a = objectBuffer.nestedObject;
// getInternalAPI(a).destroy();
// // a.toString();
const carrier = getInternalAPI(objectBuffer).getCarrier();
getInternalAPI(objectBuffer).destroy();
const linkedAddresses = getAllLinkedAddresses(
externalArgs,
dataView,
carrier,
false,

@@ -50,17 +120,20 @@ allocatedAddresses[allocatedAddresses.length - 1]

expect(linkedAddresses.slice().sort()).toEqual(
expect([...linkedAddresses.leafAddresses].slice().sort()).toEqual(
allocatedAddresses.slice().sort()
);
expect(linkedAddresses.slice().sort()).toMatchInlineSnapshot(`
expect([...linkedAddresses.leafAddresses].slice().sort())
.toMatchInlineSnapshot(`
Array [
1008,
1024,
1048,
1064,
1080,
1032,
1056,
1072,
1096,
1112,
112,
1136,
1120,
1144,
1160,
1184,
1216,
128,

@@ -76,7 +149,6 @@ 144,

336,
352,
368,
392,
416,
432,
360,
376,
400,
424,
448,

@@ -86,21 +158,18 @@ 464,

488,
504,
520,
544,
568,
592,
608,
512,
528,
560,
584,
616,
632,
648,
672,
688,
656,
680,
704,
72,
808,
832,
856,
728,
744,
848,
880,
920,
912,
936,
952,
976,

@@ -127,13 +196,13 @@ 992,

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 }],
});
expect(memoryStats(objectBuffer)).toMatchInlineSnapshot(`
Object {
"available": 904,
"used": 1144,
}
`);
Object {
"available": 816,
"used": 1232,
}
`);
const dataView = new DataView(getUnderlyingArrayBuffer(objectBuffer));
const carrier = getInternalAPI(objectBuffer).getCarrier();

@@ -143,4 +212,3 @@ getInternalAPI(objectBuffer).destroy();

const linkedAddresses = getAllLinkedAddresses(
externalArgs,
dataView,
carrier,
false,

@@ -150,3 +218,3 @@ allocatedAddresses[allocatedAddresses.length - 1]

linkedAddresses.forEach(address => {
linkedAddresses.leafAddresses.forEach((address) => {
pool.free(address);

@@ -153,0 +221,0 @@ });

import { readEntry } from "./store";
import { ExternalArgs, ObjectEntry } from "./interfaces";
import { GlobalCarrier } from "./interfaces";
import { ENTRY_TYPE } from "./entry-types";
import { hashMapGetPointersToFree } from "./hashmap/hashmap";
import { isKnownAddressValuePointer } from "./utils";
export function getAllLinkedAddresses(
externalArgs: ExternalArgs,
dataView: DataView,
carrier: GlobalCarrier,
ignoreRefCount: boolean,
entryPointer: number
) {
const allAddresses: number[] = [];
getAllLinkedAddressesStep(
externalArgs,
dataView,
ignoreRefCount,
entryPointer,
allAddresses
);
const leafAddresses: Set<number> = new Set<number>();
const arcAddresses: Set<number> = new Set<number>();
const addressesToProcessQueue: number[] = [entryPointer];
return allAddresses;
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 };
}
function getAllLinkedAddressesStep(
externalArgs: ExternalArgs,
dataView: DataView,
carrier: GlobalCarrier,
ignoreRefCount: boolean,
entryPointer: number,
pushTo: number[]
leafAddresses: Set<number>,
arcAddresses: Set<number>,
addressesToProcessQueue: number[]
) {
if (entryPointer === 0) {
if (
isKnownAddressValuePointer(entryPointer) ||
leafAddresses.has(entryPointer) ||
arcAddresses.has(entryPointer)
) {
return;
}
const entry = readEntry(externalArgs, dataView, entryPointer);
const entry = readEntry(carrier, entryPointer);
switch (entry.type) {
case ENTRY_TYPE.UNDEFINED:
case ENTRY_TYPE.NULL:
case ENTRY_TYPE.BOOLEAN:
case ENTRY_TYPE.NUMBER:

@@ -45,15 +67,18 @@ case ENTRY_TYPE.STRING:

case ENTRY_TYPE.BIGINT_POSITIVE:
pushTo.push(entryPointer);
leafAddresses.add(entryPointer);
break;
case ENTRY_TYPE.OBJECT:
if (entry.refsCount < 2 || ignoreRefCount) {
pushTo.push(entryPointer);
getObjectAddresses(
externalArgs,
dataView,
ignoreRefCount,
entry,
pushTo
case ENTRY_TYPE.MAP:
case ENTRY_TYPE.SET:
if (entry.refsCount <= 1 || ignoreRefCount) {
leafAddresses.add(entryPointer);
getObjectOrMapOrSetAddresses(
carrier,
entry.value,
leafAddresses,
addressesToProcessQueue
);
} else {
arcAddresses.add(entryPointer);
}

@@ -64,20 +89,17 @@

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

@@ -87,4 +109,6 @@ break;

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

@@ -100,25 +124,22 @@ break;

function getObjectAddresses(
externalArgs: ExternalArgs,
dataView: DataView,
ignoreRefCount: boolean,
objectEntry: ObjectEntry,
pushTo: number[]
export function getObjectOrMapOrSetAddresses(
carrier: GlobalCarrier,
internalHashmapPointer: number,
leafAddresses: Set<number>,
addressesToProcessQueue: number[]
) {
const { pointersToValuePointers, pointers } = hashMapGetPointersToFree(
dataView,
objectEntry.value
carrier,
internalHashmapPointer
);
pushTo.push(...pointers);
for (const leafPointer of pointers) {
leafAddresses.add(leafPointer);
}
for (const pointer of pointersToValuePointers) {
getAllLinkedAddressesStep(
externalArgs,
dataView,
ignoreRefCount,
dataView.getUint32(pointer),
pushTo
addressesToProcessQueue.push(
carrier.uint32[pointer / Uint32Array.BYTES_PER_ELEMENT]
);
}
}
/* eslint-env jest */
import * as util from "util";
import { arrayBuffer2HexArray, recordAllocations } from "../testUtils";
import { MemPool } from "@thi.ng/malloc";
import { MEM_POOL_START } from "../consts";
import {
arrayBuffer2HexArray,
recordAllocations,
makeCarrier,
} from "../testUtils";
import {
createHashMap,

@@ -14,5 +16,5 @@ hashMapInsertUpdate,

hashMapDelete,
hashMapGetPointersToFree
hashMapGetPointersToFree,
} from "./hashmap";
import { DataViewAndAllocatorCarrier, StringEntry } from "../interfaces";
import { GlobalCarrier, StringEntry } from "../interfaces";
import { readEntry } from "../store";

@@ -25,26 +27,11 @@ import { externalArgsApiToExternalArgsApi } from "../utils";

textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});
let ab = new ArrayBuffer(128);
let dataView = new DataView(ab);
let allocator = new MemPool({
buf: ab
});
let carrier: DataViewAndAllocatorCarrier = {
dataView,
allocator
};
let carrier: GlobalCarrier = makeCarrier(ab);
function setABSize(size: number) {
ab = new ArrayBuffer(size);
dataView = new DataView(ab);
allocator = new MemPool({
buf: ab,
start: MEM_POOL_START
});
carrier = {
dataView,
allocator
};
carrier = makeCarrier(ab);
}

@@ -69,3 +56,3 @@

externalArgs,
{ dataView, allocator },
carrier,
mapPointer,

@@ -75,3 +62,3 @@ 3

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

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

externalArgs,
{ dataView, allocator },
carrier,
mapPointer,

@@ -92,3 +79,3 @@ "abc"

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

@@ -103,15 +90,5 @@ expect(arrayBuffer2HexArray(ab, true)).toMatchSnapshot("after insert");

const pointer = hashMapInsertUpdate(
externalArgs,
{ dataView, allocator },
mapPointer,
key
);
const pointer = hashMapInsertUpdate(externalArgs, carrier, mapPointer, key);
const foundValuePointer = hashMapValueLookup(
externalArgs,
dataView,
mapPointer,
key
);
const foundValuePointer = hashMapValueLookup(carrier, mapPointer, key);

@@ -128,3 +105,3 @@ expect(pointer).toBe(foundValuePointer);

externalArgs,
{ dataView, allocator },
carrier,
mapPointer,

@@ -134,8 +111,3 @@ key

const foundValuePointer = hashMapValueLookup(
externalArgs,
dataView,
mapPointer,
key
);
const foundValuePointer = hashMapValueLookup(carrier, mapPointer, key);
expect(foundValuePointer).toBe(valuePointer);

@@ -151,3 +123,3 @@ });

externalArgs,
{ dataView, allocator },
carrier,
mapPointer,

@@ -159,8 +131,3 @@ key

const foundValuePointer = hashMapValueLookup(
externalArgs,
dataView,
mapPointer,
key
);
const foundValuePointer = hashMapValueLookup(carrier, mapPointer, key);

@@ -177,3 +144,3 @@ expect(foundValuePointer).toBe(firstValuePointer);

externalArgs,
{ dataView, allocator },
carrier,
mapPointer,

@@ -186,4 +153,3 @@ key

const foundValuePointer = hashMapValueLookup(
externalArgs,
dataView,
carrier,
mapPointer,

@@ -201,3 +167,3 @@ "Not a real key"

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

@@ -208,10 +174,8 @@ const inserts: number[] = [];

inserts.push(
hashMapInsertUpdate(
externalArgs,
{ dataView, allocator },
mapPointer,
value
)
hashMapInsertUpdate(externalArgs, carrier, mapPointer, value)
);
dataView.setUint32(inserts[inserts.length - 1], index);
carrier.uint32[
inserts[inserts.length - 1] / Uint32Array.BYTES_PER_ELEMENT
] = index;
}

@@ -227,3 +191,3 @@

(iteratorToken = hashMapLowLevelIterator(
dataView,
carrier,
mapPointer,

@@ -233,9 +197,6 @@ iteratorToken

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

@@ -277,63 +238,58 @@ Array [

expect(hashMapSize(dataView, mapPointer)).toMatchInlineSnapshot(`0`);
const memAvailableAfterEachStep = [allocator.stats().available];
expect(hashMapSize(carrier, mapPointer)).toMatchInlineSnapshot(`0`);
const memAvailableAfterEachStep = [carrier.allocator.stats().available];
const input = [...new Array(26).keys()]
.map((i): number => i + "a".charCodeAt(0))
.map(n => String.fromCharCode(n));
.map((n) => String.fromCharCode(n));
for (const [index, useThatAsKey] of input.entries()) {
dataView.setUint32(
hashMapInsertUpdate(
externalArgs,
{ dataView, allocator },
mapPointer,
useThatAsKey
),
index
);
carrier.uint32[
hashMapInsertUpdate(externalArgs, carrier, mapPointer, useThatAsKey) /
Uint32Array.BYTES_PER_ELEMENT
] = index;
memAvailableAfterEachStep.push(allocator.stats().available);
memAvailableAfterEachStep.push(carrier.allocator.stats().available);
}
expect(hashMapSize(dataView, mapPointer)).toMatchInlineSnapshot(`26`);
expect(hashMapSize(carrier, mapPointer)).toMatchInlineSnapshot(`26`);
hashMapDelete(externalArgs, carrier, mapPointer, "a");
hashMapDelete(externalArgs, carrier, mapPointer, "b");
hashMapDelete(externalArgs, carrier, mapPointer, "c");
expect(hashMapSize(dataView, mapPointer)).toMatchInlineSnapshot(`23`);
memAvailableAfterEachStep.push(allocator.stats().available);
hashMapDelete(carrier, mapPointer, "a");
hashMapDelete(carrier, mapPointer, "b");
hashMapDelete(carrier, mapPointer, "c");
expect(hashMapSize(carrier, mapPointer)).toMatchInlineSnapshot(`26`);
memAvailableAfterEachStep.push(carrier.allocator.stats().available);
expect(memAvailableAfterEachStep).toMatchInlineSnapshot(`
Array [
1904,
1848,
1792,
1736,
1680,
1624,
1568,
1512,
1416,
1352,
1296,
1240,
1184,
1128,
1072,
1016,
880,
824,
760,
704,
648,
592,
536,
480,
424,
368,
312,
480,
]
`);
Array [
1904,
1840,
1776,
1712,
1648,
1584,
1520,
1456,
1352,
1288,
1224,
1160,
1096,
1032,
968,
904,
760,
696,
632,
568,
504,
440,
376,
312,
248,
184,
120,
120,
]
`);
});

@@ -348,9 +304,9 @@

.map((i): number => i + "a".charCodeAt(0))
.map(n => String.fromCharCode(n));
.map((n) => String.fromCharCode(n));
const inputCopy = input.slice();
const { allocations } = recordAllocations(() => {
hashmapPointer = createHashMap({ dataView, allocator });
hashmapPointer = createHashMap(carrier);
expect(allocator.stats().available).toMatchInlineSnapshot(`880`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`880`);

@@ -360,68 +316,63 @@ let toAdd: undefined | string;

while ((toAdd = inputCopy.pop()) !== undefined) {
dataView.setUint32(
hashMapInsertUpdate(
externalArgs,
{ dataView, allocator },
hashmapPointer,
toAdd
),
toAdd.charCodeAt(0)
);
carrier.uint32[
hashMapInsertUpdate(externalArgs, carrier, hashmapPointer, toAdd) /
Uint32Array.BYTES_PER_ELEMENT
] = toAdd.charCodeAt(0);
}
}, allocator);
}, carrier.allocator);
const r = hashMapGetPointersToFree(dataView, hashmapPointer);
const r = hashMapGetPointersToFree(carrier, hashmapPointer);
expect(r).toMatchInlineSnapshot(`
Object {
"pointers": Array [
48,
600,
120,
136,
192,
248,
304,
360,
416,
472,
528,
584,
688,
744,
152,
176,
208,
232,
264,
288,
320,
344,
376,
400,
432,
456,
488,
512,
544,
568,
72,
96,
704,
728,
],
"pointersToValuePointers": Array [
152,
208,
264,
320,
376,
432,
488,
544,
72,
704,
],
}
`);
Object {
"pointers": Array [
48,
664,
120,
136,
200,
264,
328,
392,
456,
520,
584,
648,
752,
816,
152,
176,
216,
240,
280,
304,
344,
368,
408,
432,
472,
496,
536,
560,
600,
624,
72,
96,
768,
792,
],
"pointersToValuePointers": Array [
152,
216,
280,
344,
408,
472,
536,
600,
72,
768,
],
}
`);

@@ -431,3 +382,5 @@ expect(r.pointers.sort()).toEqual(allocations.sort());

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

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

import { MAP_MACHINE, NODE_MACHINE } from "./memoryLayout";
import {
DataViewAndAllocatorCarrier,
GlobalCarrier,
ExternalArgs,
NumberEntry,
StringEntry
StringEntry,
} from "../interfaces";

@@ -11,3 +11,3 @@ import {

hashCodeExternalValue,
getKeyStartLength
getKeyStartLength,
} from "./hashmapUtils";

@@ -19,3 +19,3 @@ import { primitiveValueToEntry } from "../utils";

readEntry,
compareStringOrNumberEntriesInPlace
compareStringOrNumberEntriesInPlace,
} from "../store";

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

linkedListGetValue,
linkedListGetPointersToFree
linkedListGetPointersToFree,
} from "../linkedList/linkedList";

@@ -36,3 +36,3 @@

export function createHashMap(
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
/**

@@ -50,6 +50,3 @@ * number of buckets

const mapMachine = MAP_MACHINE.createOperator(
carrier.dataView,
hashMapMemory
);
const mapMachine = MAP_MACHINE.createOperator(carrier, hashMapMemory);

@@ -70,24 +67,27 @@ mapMachine.set("ARRAY_POINTER", arrayMemory);

externalArgs: ExternalArgs,
{ dataView, allocator }: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
mapPointer: number,
externalKeyValue: number | string
) {
const mapOperator = MAP_MACHINE.createOperator(dataView, mapPointer);
const keyEntry = primitiveValueToEntry(
{ ...externalArgs, minimumStringAllocation: 0 },
externalKeyValue,
0
) as NumberEntry | StringEntry;
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 = allocator.calloc(NODE_MACHINE.map.SIZE_OF);
const memoryForNewNode = carrier.allocator.calloc(NODE_MACHINE.map.SIZE_OF);
const memorySizeOfKey = sizeOfEntry(keyEntry);
const keyEntryMemory = allocator.calloc(memorySizeOfKey);
const keyEntryMemory = carrier.allocator.calloc(memorySizeOfKey);
writeEntry(externalArgs, dataView, keyEntryMemory, keyEntry);
writeEntry(carrier, keyEntryMemory, keyEntry);
const keyHeaderOverhead = keyEntry.type === ENTRY_TYPE.STRING ? 5 : 1;
const keyHeaderOverhead =
keyEntry.type === ENTRY_TYPE.STRING
? // type + string length
8 + 4
: // type
8;
const keyHashCode = hashCodeInPlace(
dataView,
carrier.uint8,
mapOperator.get("CAPACITY"),

@@ -104,4 +104,4 @@ // + 1 for the type of key

const commonNodeOperator = NODE_MACHINE.createOperator(
dataView,
dataView.getUint32(ptrToPtrToSaveTheNodeTo)
carrier,
carrier.uint32[ptrToPtrToSaveTheNodeTo / Uint32Array.BYTES_PER_ELEMENT]
);

@@ -113,3 +113,3 @@

!compareStringOrNumberEntriesInPlace(
dataView,
carrier,
commonNodeOperator.get("KEY_POINTER"),

@@ -137,4 +137,4 @@ keyEntryMemory

// we don't need the new memory
allocator.free(keyEntryMemory);
allocator.free(memoryForNewNode);
carrier.allocator.free(keyEntryMemory);
carrier.allocator.free(memoryForNewNode);

@@ -148,3 +148,3 @@ return commonNodeOperator.pointerTo("VALUE_POINTER");

linkedListItemInsert(
{ dataView, allocator },
carrier,
mapOperator.get("LINKED_LIST_POINTER"),

@@ -155,3 +155,5 @@ memoryForNewNode

dataView.setUint32(ptrToPtrToSaveTheNodeTo, memoryForNewNode);
carrier.uint32[
ptrToPtrToSaveTheNodeTo / Uint32Array.BYTES_PER_ELEMENT
] = memoryForNewNode;

@@ -174,7 +176,3 @@ mapOperator.set(

// });
hashMapRehash(
{ dataView, allocator },
mapOperator,
mapOperator.get("CAPACITY") * 2
);
hashMapRehash(carrier, mapOperator, mapOperator.get("CAPACITY") * 2);
}

@@ -190,11 +188,9 @@

export function hashMapNodeLookup(
externalArgs: ExternalArgs,
dataView: DataView,
carrier: GlobalCarrier,
mapPointer: number,
externalKeyValue: number | string
) {
const mapMachine = MAP_MACHINE.createOperator(dataView, mapPointer);
const mapMachine = MAP_MACHINE.createOperator(carrier, mapPointer);
const keyHashCode = hashCodeExternalValue(
externalArgs,
mapMachine.get("CAPACITY"),

@@ -209,12 +205,10 @@ externalKeyValue

const node = NODE_MACHINE.createOperator(
dataView,
dataView.getUint32(ptrToPtr)
carrier,
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT]
);
while (node.startAddress !== 0) {
const keyEntry = readEntry(
externalArgs,
dataView,
node.get("KEY_POINTER")
) as NumberEntry | StringEntry;
const keyEntry = readEntry(carrier, node.get("KEY_POINTER")) as
| NumberEntry
| StringEntry;

@@ -233,13 +227,7 @@ if (keyEntry.value === externalKeyValue) {

export function hashMapValueLookup(
externalArgs: ExternalArgs,
dataView: DataView,
carrier: GlobalCarrier,
mapPointer: number,
externalKeyValue: number | string
) {
const nodePtrToPtr = hashMapNodeLookup(
externalArgs,
dataView,
mapPointer,
externalKeyValue
);
const nodePtrToPtr = hashMapNodeLookup(carrier, mapPointer, externalKeyValue);

@@ -251,4 +239,4 @@ if (nodePtrToPtr === 0) {

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

@@ -263,4 +251,3 @@

export function hashMapDelete(
externalArgs: ExternalArgs,
{ dataView, allocator }: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
mapPointer: number,

@@ -270,4 +257,3 @@ externalKeyValue: number | string

const foundNodePtrToPtr = hashMapNodeLookup(
externalArgs,
dataView,
carrier,
mapPointer,

@@ -281,6 +267,7 @@ externalKeyValue

const nodeToDeletePointer = dataView.getUint32(foundNodePtrToPtr);
const nodeToDeletePointer =
carrier.uint32[foundNodePtrToPtr / Uint32Array.BYTES_PER_ELEMENT];
const nodeOperator = NODE_MACHINE.createOperator(
dataView,
carrier,
nodeToDeletePointer

@@ -291,19 +278,16 @@ );

linkedListItemRemove(
{ dataView, allocator },
nodeOperator.get("LINKED_LIST_ITEM_POINTER")
);
linkedListItemRemove(carrier, nodeOperator.get("LINKED_LIST_ITEM_POINTER"));
// remove node from bucket
dataView.setUint32(foundNodePtrToPtr, nodeOperator.get("NEXT_NODE_POINTER"));
carrier.uint32[
foundNodePtrToPtr / Uint32Array.BYTES_PER_ELEMENT
] = nodeOperator.get("NEXT_NODE_POINTER");
allocator.free(nodeOperator.get("KEY_POINTER"));
allocator.free(nodeOperator.startAddress);
carrier.allocator.free(nodeOperator.get("KEY_POINTER"));
carrier.allocator.free(nodeOperator.startAddress);
dataView.setUint32(
mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset,
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
]--;

@@ -318,7 +302,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;

@@ -328,3 +312,3 @@

tokenToUseForLinkedListIterator = NODE_MACHINE.createOperator(
dataView,
carrier,
nodePointerIteratorToken

@@ -335,3 +319,3 @@ ).get("LINKED_LIST_ITEM_POINTER");

const pointerToNextLinkedListItem = linkedListLowLevelIterator(
dataView,
carrier,
mapOperator.get("LINKED_LIST_POINTER"),

@@ -345,28 +329,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")];

@@ -376,3 +361,3 @@ const pointersToValuePointers: number[] = [];

const pointersOfLinkedList = linkedListGetPointersToFree(
dataView,
carrier,
mapOperator.get("LINKED_LIST_POINTER")

@@ -382,3 +367,3 @@ );

pointers.push(...pointersOfLinkedList.pointers);
const nodeOperator = NODE_MACHINE.createOperator(dataView, 0);
const nodeOperator = NODE_MACHINE.createOperator(carrier, 0);

@@ -393,3 +378,3 @@ for (const nodePointer of pointersOfLinkedList.valuePointers) {

pointers,
pointersToValuePointers
pointersToValuePointers,
};

@@ -399,3 +384,3 @@ }

function hashMapRehash(
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
mapOperator: MemoryOperator<

@@ -439,3 +424,3 @@ | "CAPACITY"

(pointerToNode = hashMapLowLevelIterator(
carrier.dataView,
carrier,
mapOperator.startAddress,

@@ -450,3 +435,3 @@ pointerToNode

function hashMapRehashInsert(
{ dataView }: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
bucketsArrayPointer: number,

@@ -456,7 +441,7 @@ arraySize: number,

) {
const nodeOperator = NODE_MACHINE.createOperator(dataView, nodePointer);
const keyInfo = getKeyStartLength(dataView, nodeOperator.get("KEY_POINTER"));
const nodeOperator = NODE_MACHINE.createOperator(carrier, nodePointer);
const keyInfo = getKeyStartLength(carrier, nodeOperator.get("KEY_POINTER"));
const keyHashCode = hashCodeInPlace(
dataView,
carrier.uint8,
arraySize,

@@ -471,4 +456,9 @@ keyInfo.start,

const prevFirstNodeInBucket = dataView.getUint32(bucketStartPointer);
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);

@@ -478,3 +468,3 @@

// if (nodeOperator.startAddress === 0) {
// dataView.setUint32(bucketStartPointer, nodePointer);
// carrier.dataView.setUint32(bucketStartPointer, nodePointer);
// return;

@@ -503,3 +493,3 @@ // }

export function* hashmapNodesPointerIterator(
dataView: DataView,
carrier: GlobalCarrier,
mapPointer: number

@@ -511,3 +501,3 @@ ) {

(iteratorToken = hashMapLowLevelIterator(
dataView,
carrier,
mapPointer,

@@ -514,0 +504,0 @@ iteratorToken

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

import { ExternalArgs } from "../interfaces";
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;
}

@@ -26,34 +26,33 @@

export function hashCodeExternalValue(
externalArgs: ExternalArgs,
capacity: number,
value: string | number
): number {
let dv: DataView;
const ab = new ArrayBuffer(typeof value === "string" ? value.length * 3 : 8);
const uint8 = new Uint8Array(ab);
let keyBytesLength = ab.byteLength;
if (typeof value === "string") {
dv = new DataView(externalArgs.textEncoder.encode(value).buffer);
keyBytesLength = stringEncodeInto(new Uint8Array(ab), 0, value);
} else {
dv = new DataView(new ArrayBuffer(8));
dv.setFloat64(0, value);
new Float64Array(ab)[0] = value;
}
return hashCodeInPlace(dv, capacity, 0, dv.buffer.byteLength);
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]
);

@@ -63,7 +62,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,
};

@@ -73,5 +75,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";

@@ -8,5 +7,2 @@ export type primitive = string | number | bigint | boolean | undefined | null;

export type Entry =
| NullEntry
| NullUndefined
| BooleanEntry
| StringEntry

@@ -22,15 +18,2 @@ | NumberEntry

export interface NullEntry {
type: ENTRY_TYPE.NULL;
}
export interface NullUndefined {
type: ENTRY_TYPE.UNDEFINED;
}
export interface BooleanEntry {
type: ENTRY_TYPE.BOOLEAN;
value: boolean;
}
export interface StringEntry {

@@ -103,4 +86,9 @@ type: ENTRY_TYPE.STRING;

*/
export interface DataViewAndAllocatorCarrier {
dataView: DataView;
export interface GlobalCarrier {
// dataView: DataView;
uint8: Uint8Array;
uint16: Uint16Array;
uint32: Uint32Array;
float64: Float64Array;
bigUint64: BigUint64Array;
allocator: import("@thi.ng/malloc").IMemPool;

@@ -113,3 +101,2 @@ }

arrayAdditionalAllocation: number;
minimumStringAllocation: number;
textDecoder: TextDecoder;

@@ -123,3 +110,2 @@ textEncoder: TextEncoder;

arrayAdditionalAllocation?: number;
minimumStringAllocation?: number;
textDecoder: TextDecoder;

@@ -131,6 +117,6 @@ textEncoder: TextEncoder;

getExternalArgs(): ExternalArgs;
getCarrier(): Readonly<DataViewAndAllocatorCarrier>;
replaceCarrierContent(dataView: DataView, pool: IMemPool): void;
getCarrier(): Readonly<GlobalCarrier>;
replaceCarrierContent(carrier: GlobalCarrier): void;
getEntryPointer(): number;
destroy(): number;
}
/* eslint-env jest */
import { arrayBuffer2HexArray, recordAllocations } from "../testUtils";
import { MemPool } from "@thi.ng/malloc";
import { MEM_POOL_START } from "../consts";
import {
arrayBuffer2HexArray,
recordAllocations,
makeCarrier,
} from "../testUtils";

@@ -17,3 +19,3 @@ // eslint-disable-next-line @typescript-eslint/ban-ts-ignore

linkedListGetValue,
linkedListGetPointersToFree
linkedListGetPointersToFree,
// LINKED_LIST_ITEM_MACHINE

@@ -24,14 +26,7 @@ } from "./linkedList";

let ab = new ArrayBuffer(64);
let dataView = new DataView(ab);
let allocator = new MemPool({
buf: ab
});
let carrier = makeCarrier(ab);
function setABSize(size: number) {
ab = new ArrayBuffer(size);
dataView = new DataView(ab);
allocator = new MemPool({
buf: ab,
start: MEM_POOL_START
});
carrier = makeCarrier(ab);
}

@@ -46,11 +41,7 @@

const linkedListPointer = initLinkedList({ dataView, allocator });
const linkedListPointer = initLinkedList(carrier);
expect(arrayBuffer2HexArray(ab, true)).toMatchSnapshot();
const itemPointer = linkedListItemInsert(
{ dataView, allocator },
linkedListPointer,
7
);
const itemPointer = linkedListItemInsert(carrier, linkedListPointer, 7);

@@ -63,19 +54,11 @@ expect(itemPointer).toBe(64);

test("linkedList init & add 2 & delete 2", () => {
const linkedListPointer = initLinkedList({ dataView, allocator });
const linkedListPointer = initLinkedList(carrier);
// const copyToCompare = ab.slice(0);
expect(allocator.stats().available).toMatchInlineSnapshot(`56`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`56`);
const pointer1 = linkedListItemInsert(
{ dataView, allocator },
linkedListPointer,
7
);
const pointer2 = linkedListItemInsert(
{ dataView, allocator },
linkedListPointer,
8
);
const pointer1 = linkedListItemInsert(carrier, linkedListPointer, 7);
const pointer2 = linkedListItemInsert(carrier, linkedListPointer, 8);
expect(allocator.stats().available).toMatchInlineSnapshot(`24`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`24`);

@@ -85,4 +68,4 @@ expect(pointer1).toBe(64);

linkedListItemRemove({ dataView, allocator }, pointer2);
linkedListItemRemove({ dataView, allocator }, pointer1);
linkedListItemRemove(carrier, pointer2);
linkedListItemRemove(carrier, pointer1);

@@ -111,3 +94,3 @@ // fails on github action ??

expect(allocator.stats().available).toMatchInlineSnapshot(`56`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`56`);
});

@@ -117,11 +100,11 @@

setABSize(256);
const linkedListPointer = initLinkedList({ dataView, allocator });
const linkedListPointer = initLinkedList(carrier);
expect(allocator.stats().available).toMatchInlineSnapshot(`184`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`);
const itemsPointers = [
linkedListItemInsert({ dataView, allocator }, linkedListPointer, 7),
linkedListItemInsert({ dataView, allocator }, linkedListPointer, 6),
linkedListItemInsert({ dataView, allocator }, linkedListPointer, 5),
linkedListItemInsert({ dataView, allocator }, linkedListPointer, 4)
linkedListItemInsert(carrier, linkedListPointer, 7),
linkedListItemInsert(carrier, linkedListPointer, 6),
linkedListItemInsert(carrier, linkedListPointer, 5),
linkedListItemInsert(carrier, linkedListPointer, 4),
];

@@ -134,3 +117,3 @@

(iteratorPointer = linkedListLowLevelIterator(
dataView,
carrier,
linkedListPointer,

@@ -140,3 +123,3 @@ iteratorPointer

) {
values.push(linkedListGetValue(dataView, iteratorPointer));
values.push(linkedListGetValue(carrier, iteratorPointer));
}

@@ -153,9 +136,7 @@

expect(allocator.stats().available).toMatchInlineSnapshot(`120`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`120`);
itemsPointers.forEach(p =>
linkedListItemRemove({ dataView, allocator }, p)
);
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p));
expect(allocator.stats().available).toMatchInlineSnapshot(`184`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`);
});

@@ -165,11 +146,11 @@

setABSize(256);
const linkedListPointer = initLinkedList({ dataView, allocator });
const linkedListPointer = initLinkedList(carrier);
expect(allocator.stats().available).toMatchInlineSnapshot(`184`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`);
const itemsPointers = [
linkedListItemInsert({ dataView, allocator }, linkedListPointer, 7),
linkedListItemInsert({ dataView, allocator }, linkedListPointer, 6),
linkedListItemInsert({ dataView, allocator }, linkedListPointer, 5),
linkedListItemInsert({ dataView, allocator }, linkedListPointer, 4)
linkedListItemInsert(carrier, linkedListPointer, 7),
linkedListItemInsert(carrier, linkedListPointer, 6),
linkedListItemInsert(carrier, linkedListPointer, 5),
linkedListItemInsert(carrier, linkedListPointer, 4),
];

@@ -182,3 +163,3 @@

(iteratorPointer = linkedListLowLevelIterator(
dataView,
carrier,
linkedListPointer,

@@ -188,4 +169,4 @@ iteratorPointer

) {
values.push(linkedListGetValue(dataView, iteratorPointer));
linkedListItemRemove({ dataView, allocator }, iteratorPointer);
values.push(linkedListGetValue(carrier, iteratorPointer));
linkedListItemRemove(carrier, iteratorPointer);
}

@@ -208,20 +189,75 @@

expect(allocator.stats().available).toMatchInlineSnapshot(`152`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`152`);
itemsPointers.forEach(p =>
linkedListItemRemove({ dataView, allocator }, p)
);
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p));
expect(allocator.stats().available).toMatchInlineSnapshot(`184`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`);
});
test.skip("linkedList linkedListLowLevelIterator - delete while iteration - delete current value", () => {
setABSize(256);
const linkedListPointer = initLinkedList(carrier);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`);
const regularSet = new Set([7, 6, 5, 4]);
const itemsPointers = [
linkedListItemInsert(carrier, linkedListPointer, 7),
linkedListItemInsert(carrier, linkedListPointer, 6),
linkedListItemInsert(carrier, linkedListPointer, 5),
linkedListItemInsert(carrier, linkedListPointer, 4),
];
const linkedLintResults = [];
let iteratorPointer = 0;
while (
(iteratorPointer = linkedListLowLevelIterator(
carrier,
linkedListPointer,
iteratorPointer
))
) {
linkedLintResults.push(linkedListGetValue(carrier, iteratorPointer));
linkedListItemRemove(carrier, iteratorPointer);
}
const regularSetResults: number[] = [];
for (const v of regularSet) {
regularSetResults.push(v);
regularSet.delete(v);
}
expect(regularSetResults).toMatchInlineSnapshot(`
Array [
7,
6,
5,
4,
]
`);
expect(linkedLintResults).toMatchInlineSnapshot(`
Array [
7,
5,
]
`);
expect(regularSetResults).toEqual(linkedLintResults);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`152`);
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p));
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`);
});
test("linkedList linkedListLowLevelIterator - add while iteration", () => {
setABSize(256);
const linkedListPointer = initLinkedList({ dataView, allocator });
const linkedListPointer = initLinkedList(carrier);
expect(allocator.stats().available).toMatchInlineSnapshot(`184`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`);
const itemsPointers = [
linkedListItemInsert({ dataView, allocator }, linkedListPointer, 7),
linkedListItemInsert({ dataView, allocator }, linkedListPointer, 6)
linkedListItemInsert(carrier, linkedListPointer, 7),
linkedListItemInsert(carrier, linkedListPointer, 6),
];

@@ -237,3 +273,3 @@

(iteratorPointer = linkedListLowLevelIterator(
dataView,
carrier,
linkedListPointer,

@@ -243,9 +279,5 @@ iteratorPointer

) {
values.push(linkedListGetValue(dataView, iteratorPointer));
values.push(linkedListGetValue(carrier, iteratorPointer));
if (c < toAdd.length) {
linkedListItemInsert(
{ dataView, allocator },
linkedListPointer,
toAdd[c++]
);
linkedListItemInsert(carrier, linkedListPointer, toAdd[c++]);
}

@@ -275,7 +307,5 @@ }

expect(allocator.stats().available).toMatchInlineSnapshot(`120`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`120`);
itemsPointers.forEach(p =>
linkedListItemRemove({ dataView, allocator }, p)
);
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p));

@@ -285,3 +315,3 @@ const iteratorPointerToFree = 0;

(iteratorPointer = linkedListLowLevelIterator(
dataView,
carrier,
linkedListPointer,

@@ -291,6 +321,6 @@ iteratorPointerToFree

) {
linkedListItemRemove({ dataView, allocator }, iteratorPointer);
linkedListItemRemove(carrier, iteratorPointer);
}
expect(allocator.stats().available).toMatchInlineSnapshot(`184`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`);
});

@@ -305,5 +335,5 @@

const { allocations } = recordAllocations(() => {
linkedListPointer = initLinkedList({ dataView, allocator });
linkedListPointer = initLinkedList(carrier);
expect(allocator.stats().available).toMatchInlineSnapshot(`64`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`64`);

@@ -313,7 +343,7 @@ let toAdd: undefined | number = 0;

while ((toAdd = toAddItemsCopy.pop()) !== undefined) {
linkedListItemInsert({ dataView, allocator }, linkedListPointer, toAdd);
linkedListItemInsert(carrier, linkedListPointer, toAdd);
}
}, allocator);
}, carrier.allocator);
const r = linkedListGetPointersToFree(dataView, linkedListPointer);
const r = linkedListGetPointersToFree(carrier, linkedListPointer);

@@ -320,0 +350,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,
};
}
import {
ExternalArgs,
DataViewAndAllocatorCarrier,
GlobalCarrier,
MapEntry,
InternalAPI
InternalAPI,
} from "./interfaces";

@@ -10,3 +10,4 @@ import {

objectGet,
objectSet
objectSet,
mapOrSetClear,
} from "./objectWrapperHelpers";

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

hashMapNodePointerToKeyValue,
hashmapNodesPointerIterator
hashmapNodesPointerIterator,
} from "./hashmap/hashmap";

@@ -31,6 +32,3 @@ import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue";

clear(): void {
// @todo impl using helper function with direct list access
for (const key of [...this.keys()]) {
this.delete(key);
}
mapOrSetClear(this.externalArgs, this.carrier, this.entryPointer);
}

@@ -48,3 +46,3 @@

get size(): number {
return hashMapSize(this.carrier.dataView, this.entry.value);
return hashMapSize(this.carrier, this.entry.value);
}

@@ -58,7 +56,7 @@

for (const nodePointer of hashmapNodesPointerIterator(
this.carrier.dataView,
this.carrier,
this.entry.value
)) {
const { valuePointer, keyPointer } = hashMapNodePointerToKeyValue(
this.carrier.dataView,
this.carrier,
nodePointer

@@ -76,4 +74,4 @@ );

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

@@ -85,9 +83,6 @@ }

for (const nodePointer of hashmapNodesPointerIterator(
this.carrier.dataView,
this.carrier,
this.entry.value
)) {
const t = hashMapNodePointerToKeyValue(
this.carrier.dataView,
nodePointer
);
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer);

@@ -104,7 +99,7 @@ yield entryToFinalJavaScriptValue(

for (const nodePointer of hashmapNodesPointerIterator(
this.carrier.dataView,
this.carrier,
this.entry.value
)) {
const { valuePointer } = hashMapNodePointerToKeyValue(
this.carrier.dataView,
this.carrier,
nodePointer

@@ -116,3 +111,3 @@ );

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

@@ -160,10 +155,3 @@ }

return (
hashMapNodeLookup(
this.externalArgs,
this.carrier.dataView,
this.entry.value,
p
) !== 0
);
return hashMapNodeLookup(this.carrier, this.entry.value, p) !== 0;
}

@@ -186,6 +174,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
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,9 +25,16 @@

// 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;

@@ -35,7 +44,9 @@

// @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> {

@@ -51,3 +62,3 @@ set(key: T, value: number): void;

memoryMap: MemoryMap<T>,
dataView: DataView,
carrier: GlobalCarrier,
startAddress: number

@@ -58,15 +69,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
];
},

@@ -82,3 +95,3 @@ pointerTo(key: T): number {

},
size: memoryMap.SIZE_OF
size: memoryMap.SIZE_OF,
};

@@ -91,5 +104,6 @@ }

const oldEntries = Object.entries(input);
const newObjectEntries: Array<
[string, { type: TypedArrayCtor; bytesOffset: number }]
> = [];
const newObjectEntries: Array<[
string,
{ type: TypedArrayCtor; bytesOffset: number }
]> = [];

@@ -106,4 +120,4 @@ for (const [index, [key, type]] of oldEntries.entries()) {

(oldEntries[index - 1][1] as any).BYTES_PER_ELEMENT,
type: type as any
}
type: type as any,
},
]);

@@ -117,3 +131,3 @@ }

(oldEntries[newObjectEntries.length - 1][1] as TypedArrayCtor)
.BYTES_PER_ELEMENT
.BYTES_PER_ELEMENT,
]);

@@ -132,5 +146,5 @@

createOperator: createMemoryOperator.bind(null, map) as (
dataView: DataView,
carrier: GlobalCarrier,
address: number
) => MemoryOperator<T>
) => MemoryOperator<T>,
};

@@ -151,3 +165,3 @@ }

key,
newObjectEntries[index - 1][1] + oldEntries[index - 1][1]
newObjectEntries[index - 1][1] + oldEntries[index - 1][1],
]);

@@ -160,3 +174,3 @@ }

newObjectEntries[newObjectEntries.length - 1][1] +
oldEntries[newObjectEntries.length - 1][1]
oldEntries[newObjectEntries.length - 1][1],
]);

@@ -163,0 +177,0 @@

@@ -7,5 +7,4 @@ /* eslint-env jest */

import { arraySaver } from "./arraySaver";
import { MemPool } from "@thi.ng/malloc";
import { MEM_POOL_START } from "./consts";
import { externalArgsApiToExternalArgsApi } from "./utils";
import { makeCarrier } from "./testUtils";

@@ -16,3 +15,3 @@ describe("pop it all", () => {

textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});

@@ -22,8 +21,4 @@

const arrayBuffer = new ArrayBuffer(512);
const dataView = new DataView(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const carrier = makeCarrier(arrayBuffer);

@@ -33,14 +28,5 @@ const arrayToSave = ["a", "b", -100];

const saverOutput = arraySaver(
externalArgs,
{ dataView, allocator },
[],
arrayToSave
);
const saverOutput = arraySaver(externalArgs, carrier, [], arrayToSave);
const arrayWrapper = createArrayWrapper(
externalArgs,
{ dataView, allocator },
saverOutput
);
const arrayWrapper = createArrayWrapper(externalArgs, carrier, saverOutput);

@@ -52,3 +38,3 @@ const sizeAfterEachPush: number[] = [];

arrayToCompare.push(i);
sizeAfterEachPush.push(allocator.stats().available);
sizeAfterEachPush.push(carrier.allocator.stats().available);
}

@@ -58,3 +44,2 @@

Array [
264,
240,

@@ -69,2 +54,3 @@ 216,

48,
24,
]

@@ -100,4 +86,4 @@ `);

expect(arrayToCompare).toEqual(arrayWrapper);
expect(allocator.stats().available).toMatchInlineSnapshot(`48`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`24`);
});
});

@@ -5,6 +5,4 @@ /* eslint-env jest */

import * as util from "util";
import { arrayBuffer2HexArray } from "./testUtils";
import { arrayBuffer2HexArray, makeCarrier } from "./testUtils";
import { objectSaver } from "./objectSaver";
import { MemPool } from "@thi.ng/malloc";
import { MEM_POOL_START } from "./consts";
import { externalArgsApiToExternalArgsApi } from "./utils";

@@ -15,3 +13,3 @@

textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder()
textDecoder: new util.TextDecoder(),
});

@@ -22,8 +20,4 @@

const arrayBuffer = new ArrayBuffer(1024);
const dataView = new DataView(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const carrier = makeCarrier(arrayBuffer);

@@ -34,22 +28,19 @@ const objectToSave = {

6: null,
10: true,
11: false,
ab: undefined,
abc: BigInt("100"),
nestedObject: {
nestedProp: 7
}
nestedProp: 7,
},
};
const saverOutput = objectSaver(
externalArgs,
{ dataView, allocator },
[],
objectToSave
);
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
expect(saverOutput).toMatchInlineSnapshot(`800`);
expect(saverOutput).toMatchInlineSnapshot(`976`);
expect(arrayBuffer2HexArray(arrayBuffer, true)).toMatchSnapshot();
expect(allocator.stats().available).toMatchInlineSnapshot(`216`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`32`);
});
});
});

@@ -6,5 +6,5 @@ import { appendEntry } from "./store";

ExternalArgs,
DataViewAndAllocatorCarrier,
GlobalCarrier,
MapEntry,
SetEntry
SetEntry,
} from "./interfaces";

@@ -16,3 +16,3 @@ import { saveValue } from "./saveValue";

externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
referencedPointers: number[],

@@ -25,3 +25,6 @@ objectToSave: any

carrier,
Math.max(externalArgs.hashMapMinInitialCapacity, objectEntries.length * 1.3)
Math.max(
externalArgs.hashMapMinInitialCapacity,
Math.ceil(objectEntries.length * 1.3)
)
);

@@ -44,3 +47,3 @@

carrier.dataView.setUint32(ptrToPtr, pointerToValue);
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = pointerToValue;
}

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

refsCount: 1,
value: hashMapPointer
value: hashMapPointer,
};

@@ -60,3 +63,3 @@

externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
referencedPointers: number[],

@@ -67,3 +70,6 @@ mapToSave: Map<string | number, any>

carrier,
Math.max(externalArgs.hashMapMinInitialCapacity, mapToSave.size * 1.3)
Math.max(
externalArgs.hashMapMinInitialCapacity,
Math.ceil(mapToSave.size * 1.3)
)
);

@@ -86,3 +92,3 @@

carrier.dataView.setUint32(ptrToPtr, pointerToValue);
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = pointerToValue;
}

@@ -93,3 +99,3 @@

refsCount: 1,
value: hashMapPointer
value: hashMapPointer,
};

@@ -102,3 +108,3 @@

externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
setToSave: Set<string | number>

@@ -108,3 +114,6 @@ ) {

carrier,
Math.max(externalArgs.hashMapMinInitialCapacity, setToSave.size * 1.3)
Math.max(
externalArgs.hashMapMinInitialCapacity,
Math.ceil(setToSave.size * 1.3)
)
);

@@ -120,3 +129,3 @@

carrier.dataView.setUint32(ptrToPtr, 1);
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = 1;
}

@@ -127,3 +136,3 @@

refsCount: 1,
value: hashMapPointer
value: hashMapPointer,
};

@@ -130,0 +139,0 @@

@@ -7,5 +7,4 @@ /* eslint-env jest */

import { createObjectWrapper } from "./objectWrapper";
import { MEM_POOL_START } from "./consts";
import { MemPool } from "@thi.ng/malloc";
import { externalArgsApiToExternalArgsApi } from "./utils";
import { makeCarrier } from "./testUtils";

@@ -15,3 +14,3 @@ describe("objectWrapper tests", () => {

textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder()
textDecoder: new util.TextDecoder(),
});

@@ -22,8 +21,4 @@

const arrayBuffer = new ArrayBuffer(1024);
const dataView = new DataView(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const carrier = makeCarrier(arrayBuffer);

@@ -36,16 +31,11 @@ const objectToSave = {

nestedObject: {
nestedProp: 7
}
nestedProp: 7,
},
};
const saverOutput = objectSaver(
externalArgs,
{ dataView, allocator },
[],
objectToSave
);
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
const objectWrapper: any = createObjectWrapper(
externalArgs,
{ dataView, allocator },
carrier,
saverOutput

@@ -70,3 +60,3 @@ );

expect(allocator.stats().top).toMatchInlineSnapshot(`736`);
expect(carrier.allocator.stats().top).toMatchInlineSnapshot(`768`);
});

@@ -76,9 +66,6 @@

const arrayBuffer = new ArrayBuffer(1024);
const dataView = new DataView(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const carrier = makeCarrier(arrayBuffer);
const objectToSave = {

@@ -90,16 +77,11 @@ a: 6,

nestedObject: {
nestedProp: 7
}
nestedProp: 7,
},
};
const saverOutput = objectSaver(
externalArgs,
{ dataView, allocator },
[],
objectToSave
);
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
const objectWrapper: any = createObjectWrapper(
externalArgs,
{ dataView, allocator },
carrier,
saverOutput

@@ -111,3 +93,3 @@ );

expect(allocator.stats().top).toMatchInlineSnapshot(`736`);
expect(carrier.allocator.stats().top).toMatchInlineSnapshot(`768`);
});

@@ -117,9 +99,6 @@

const arrayBuffer = new ArrayBuffer(1024);
const dataView = new DataView(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const carrier = makeCarrier(arrayBuffer);
const objectToSave = {

@@ -131,16 +110,11 @@ a: 6,

nestedObject: {
nestedProp: 7
}
nestedProp: 7,
},
};
const saverOutput = objectSaver(
externalArgs,
{ dataView, allocator },
[],
objectToSave
);
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
const objectWrapper = createObjectWrapper(
externalArgs,
{ dataView, allocator },
carrier,
saverOutput

@@ -163,3 +137,3 @@ );

expect(allocator.stats().top).toMatchInlineSnapshot(`736`);
expect(carrier.allocator.stats().top).toMatchInlineSnapshot(`800`);
});

@@ -169,9 +143,6 @@

const arrayBuffer = new ArrayBuffer(1024);
const dataView = new DataView(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const carrier = makeCarrier(arrayBuffer);
const objectToSave = {

@@ -183,16 +154,11 @@ a: 6,

nestedObject: {
nestedProp: 7
}
nestedProp: 7,
},
};
const saverOutput = objectSaver(
externalArgs,
{ dataView, allocator },
[],
objectToSave
);
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
const objectWrapper = createObjectWrapper(
externalArgs,
{ dataView, allocator },
carrier,
saverOutput

@@ -216,3 +182,3 @@ );

expect(allocator.stats().top).toMatchInlineSnapshot(`832`);
expect(carrier.allocator.stats().top).toMatchInlineSnapshot(`880`);
});

@@ -222,9 +188,6 @@

const arrayBuffer = new ArrayBuffer(1024);
const dataView = new DataView(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const carrier = makeCarrier(arrayBuffer);
const objectToSave = {

@@ -236,16 +199,11 @@ a: 6,

nestedObject: {
nestedProp: 7
}
nestedProp: 7,
},
};
const saverOutput = objectSaver(
externalArgs,
{ dataView, allocator },
[],
objectToSave
);
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
const objectWrapper = createObjectWrapper(
externalArgs,
{ dataView, allocator },
carrier,
saverOutput

@@ -267,5 +225,5 @@ );

expect(allocator.stats().top).toMatchInlineSnapshot(`736`);
expect(carrier.allocator.stats().top).toMatchInlineSnapshot(`768`);
});
});
});

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

import { ObjectEntry, 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";

@@ -52,8 +48,7 @@ import { allocationsTransaction } from "./allocationsTransaction";

const gotEntries = getObjectPropertiesEntries(
this.externalArgs,
this.carrier.dataView,
this.carrier,
this.entry.value
);
return gotEntries.map(e => e.key);
return gotEntries.map((e) => e.key);
}

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

const gotEntries = getObjectPropertiesEntries(
this.externalArgs,
this.carrier.dataView,
this.carrier,
this.entry.value
);
return gotEntries.map(e => e.key);
return gotEntries.map((e) => e.key);
}

@@ -89,10 +83,3 @@

return (
hashMapNodeLookup(
this.externalArgs,
this.carrier.dataView,
this.entry.value,
p
) !== 0
);
return hashMapNodeLookup(this.carrier, this.entry.value, p) !== 0;
}

@@ -144,3 +131,3 @@

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

@@ -150,4 +137,4 @@ ): T {

{ objectBufferWrapper: "objectBufferWrapper" },
new ObjectWrapper(externalArgs, dataViewCarrier, entryPointer)
new ObjectWrapper(externalArgs, globalCarrier, entryPointer)
) as any;
}

@@ -8,8 +8,7 @@ /* eslint-env jest */

getObjectPropertiesEntries,
deleteObjectPropertyEntryByKey
deleteObjectPropertyEntryByKey,
} from "./objectWrapperHelpers";
import { MemPool } from "@thi.ng/malloc";
import { MEM_POOL_START } from "./consts";
import { externalArgsApiToExternalArgsApi } from "./utils";
import { ObjectEntry } from "./interfaces";
import { makeCarrier } from "./testUtils";

@@ -20,3 +19,3 @@ describe("objectWrapperHelpers tests", () => {

textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});

@@ -27,8 +26,3 @@

const arrayBuffer = new ArrayBuffer(1024);
const dataView = new DataView(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const carrier = makeCarrier(arrayBuffer);

@@ -41,24 +35,12 @@ const objectToSave = {

nestedObject: {
nestedProp: 7
}
nestedProp: 7,
},
};
const saverOutput = objectSaver(
externalArgs,
{ dataView, allocator },
[],
objectToSave
);
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
const hashmapPointer = (readEntry(
externalArgs,
dataView,
saverOutput
) as ObjectEntry).value;
const hashmapPointer = (readEntry(carrier, saverOutput) as ObjectEntry)
.value;
const gotEntries = getObjectPropertiesEntries(
externalArgs,
dataView,
hashmapPointer
);
const gotEntries = getObjectPropertiesEntries(carrier, hashmapPointer);

@@ -69,3 +51,3 @@ expect(gotEntries).toMatchInlineSnapshot(`

"key": "5",
"valuePointer": 200,
"valuePointer": 0,
},

@@ -78,3 +60,3 @@ Object {

"key": "kawabanga",
"valuePointer": 360,
"valuePointer": 1,
},

@@ -87,3 +69,3 @@ Object {

"key": "nestedObject",
"valuePointer": 712,
"valuePointer": 728,
},

@@ -95,9 +77,6 @@ ]

const arrayBuffer = new ArrayBuffer(512);
const dataView = new DataView(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const carrier = makeCarrier(arrayBuffer);
const objectToSave = {

@@ -107,23 +86,15 @@ a: 6,

c: undefined,
d: null
d: null,
};
const saverOutput = objectSaver(
externalArgs,
{ dataView, allocator },
[],
objectToSave
);
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
expect(allocator.stats().available).toMatchInlineSnapshot(`56`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`40`);
const hashmapPointer = (readEntry(
externalArgs,
dataView,
saverOutput
) as ObjectEntry).value;
const hashmapPointer = (readEntry(carrier, saverOutput) as ObjectEntry)
.value;
deleteObjectPropertyEntryByKey(
externalArgs,
{ dataView, allocator },
carrier,
hashmapPointer,

@@ -133,26 +104,22 @@ "a"

expect(allocator.stats().available).toMatchInlineSnapshot(`136`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`128`);
const gotEntries = getObjectPropertiesEntries(
externalArgs,
dataView,
hashmapPointer
);
const gotEntries = getObjectPropertiesEntries(carrier, hashmapPointer);
expect(gotEntries).toMatchInlineSnapshot(`
Array [
Object {
"key": "b",
"valuePointer": 280,
},
Object {
"key": "c",
"valuePointer": 360,
},
Object {
"key": "d",
"valuePointer": 432,
},
]
`);
Array [
Object {
"key": "b",
"valuePointer": 296,
},
Object {
"key": "c",
"valuePointer": 0,
},
Object {
"key": "d",
"valuePointer": 1,
},
]
`);
});

@@ -162,9 +129,6 @@

const arrayBuffer = new ArrayBuffer(512);
const dataView = new DataView(arrayBuffer);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const carrier = makeCarrier(arrayBuffer);
const objectToSave = {

@@ -174,23 +138,15 @@ a: 6,

c: undefined,
d: null
d: null,
};
const saverOutput = objectSaver(
externalArgs,
{ dataView, allocator },
[],
objectToSave
);
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
expect(allocator.stats().available).toMatchInlineSnapshot(`56`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`40`);
const hashmapPointer = (readEntry(
externalArgs,
dataView,
saverOutput
) as ObjectEntry).value;
const hashmapPointer = (readEntry(carrier, saverOutput) as ObjectEntry)
.value;
deleteObjectPropertyEntryByKey(
externalArgs,
{ dataView, allocator },
carrier,
hashmapPointer,

@@ -200,31 +156,27 @@ "d"

expect(getObjectPropertiesEntries(externalArgs, dataView, hashmapPointer))
expect(getObjectPropertiesEntries(carrier, hashmapPointer))
.toMatchInlineSnapshot(`
Array [
Object {
"key": "a",
"valuePointer": 200,
},
Object {
"key": "b",
"valuePointer": 280,
},
Object {
"key": "c",
"valuePointer": 360,
},
]
`);
Array [
Object {
"key": "a",
"valuePointer": 208,
},
Object {
"key": "b",
"valuePointer": 296,
},
Object {
"key": "c",
"valuePointer": 0,
},
]
`);
expect(allocator.stats().available).toMatchInlineSnapshot(`128`);
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`104`);
});
test("deleteObjectPropertyEntryByKey - delete in the middle", () => {
const arrayBuffer = new ArrayBuffer(512);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(1024);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
});
const carrier = makeCarrier(arrayBuffer);

@@ -236,22 +188,13 @@ const objectToSave = {

d: null,
e: 66
e: 66,
};
const saverOutput = objectSaver(
externalArgs,
{ dataView, allocator },
[],
objectToSave
);
expect(allocator.stats().available).toMatchInlineSnapshot(`0`);
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave);
// expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`8`);
const hashmapPointer = readEntry(
externalArgs,
dataView,
saverOutput
) as ObjectEntry;
const hashmapPointer = readEntry(carrier, saverOutput) as ObjectEntry;
deleteObjectPropertyEntryByKey(
externalArgs,
{ dataView, allocator },
carrier,
hashmapPointer.value,

@@ -261,28 +204,27 @@ "c"

expect(
getObjectPropertiesEntries(externalArgs, dataView, hashmapPointer.value)
).toMatchInlineSnapshot(`
Array [
Object {
"key": "a",
"valuePointer": 200,
},
Object {
"key": "b",
"valuePointer": 280,
},
Object {
"key": "d",
"valuePointer": 432,
},
Object {
"key": "e",
"valuePointer": 0,
},
]
`);
expect(getObjectPropertiesEntries(carrier, hashmapPointer.value))
.toMatchInlineSnapshot(`
Array [
Object {
"key": "a",
"valuePointer": 208,
},
Object {
"key": "b",
"valuePointer": 296,
},
Object {
"key": "d",
"valuePointer": 1,
},
Object {
"key": "e",
"valuePointer": 520,
},
]
`);
expect(allocator.stats().available).toMatchInlineSnapshot(`72`);
// expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`64`);
});
});
});
import {
ExternalArgs,
DataViewAndAllocatorCarrier,
GlobalCarrier,
StringEntry,
NumberEntry
NumberEntry,
MapEntry,
SetEntry,
} from "./interfaces";
import {
readEntry,
writeValueInPtrToPtrAndHandleMemory,
handleArcForDeletedValuePointer,
decrementRefCount,
writeValueInPtrToPtrAndHandleMemory
writeEntry,
setRefCount,
} from "./store";

@@ -18,3 +23,4 @@ import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue";

hashMapInsertUpdate,
hashMapValueLookup
hashMapValueLookup,
createHashMap,
} from "./hashmap/hashmap";

@@ -25,3 +31,3 @@ import { getAllLinkedAddresses } from "./getAllLinkedAddresses";

externalArgs: ExternalArgs,
{ dataView, allocator }: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
hashmapPointer: number,

@@ -31,4 +37,3 @@ keyToDeleteBy: string | number

const deletedValuePointerToPointer = hashMapDelete(
externalArgs,
{ dataView, allocator },
carrier,
hashmapPointer,

@@ -38,40 +43,14 @@ keyToDeleteBy

const deletedValuePointer = dataView.getUint32(deletedValuePointerToPointer);
// Nothing to delete here
if (deletedValuePointer === 0) {
// no such key
if (deletedValuePointerToPointer === 0) {
return false;
}
// handle memory free
if (deletedValuePointer !== 0) {
const existingValueEntry = readEntry(
externalArgs,
dataView,
deletedValuePointer
);
if (existingValueEntry && "refsCount" in existingValueEntry) {
const newRefCount = decrementRefCount(
externalArgs,
dataView,
deletedValuePointer
);
const deletedValuePointer =
carrier.uint32[
deletedValuePointerToPointer / Uint32Array.BYTES_PER_ELEMENT
];
if (newRefCount === 0) {
const addressesToFree = getAllLinkedAddresses(
externalArgs,
dataView,
false,
deletedValuePointer
);
handleArcForDeletedValuePointer(externalArgs, carrier, deletedValuePointer);
for (const address of addressesToFree) {
allocator.free(address);
}
}
} else {
allocator.free(deletedValuePointer);
}
}
return true;

@@ -81,4 +60,3 @@ }

export function getObjectPropertiesEntries(
externalArgs: ExternalArgs,
dataView: DataView,
carrier: GlobalCarrier,
hashmapPointer: number

@@ -90,10 +68,10 @@ ): Array<{ key: string | number; valuePointer: number }> {

while (
(iterator = hashMapLowLevelIterator(dataView, hashmapPointer, iterator))
(iterator = hashMapLowLevelIterator(carrier, hashmapPointer, iterator))
) {
const { valuePointer, keyPointer } = hashMapNodePointerToKeyValue(
dataView,
carrier,
iterator
);
const keyEntry = readEntry(externalArgs, dataView, keyPointer) as
const keyEntry = readEntry(carrier, keyPointer) as
| StringEntry

@@ -103,4 +81,5 @@ | NumberEntry;

foundValues.push({
valuePointer: dataView.getUint32(valuePointer),
key: keyEntry.value
valuePointer:
carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT],
key: keyEntry.value,
});

@@ -114,3 +93,3 @@ }

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

@@ -132,12 +111,7 @@ p: string | number,

externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
entryPointer: number,
key: string | number
) {
const valuePointer = hashMapValueLookup(
externalArgs,
carrier.dataView,
entryPointer,
key
);
const valuePointer = hashMapValueLookup(carrier, entryPointer, key);

@@ -151,4 +125,73 @@ if (valuePointer === 0) {

carrier,
carrier.dataView.getUint32(valuePointer)
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);
// }
// }
export function mapOrSetClear(
externalArgs: ExternalArgs,
carrier: GlobalCarrier,
mapOrSetPtr: number
) {
const entry = readEntry(carrier, mapOrSetPtr) as MapEntry | SetEntry;
// we fake the entry refCount as zero so getAllLinkedAddresses will visit what's needed
const prevCount = setRefCount(carrier, mapOrSetPtr, 0);
const { leafAddresses, arcAddresses } = getAllLinkedAddresses(
carrier,
false,
mapOrSetPtr
);
for (const address of leafAddresses) {
// don't dispose the address we need to reuse
if (address === mapOrSetPtr) {
continue;
}
carrier.allocator.free(address);
}
for (const address of arcAddresses) {
// don't dispose the address we need to reuse
if (address === mapOrSetPtr) {
continue;
}
decrementRefCount(externalArgs, carrier, address);
}
// hashmapClearFree(externalArgs, carrier, entry.value);
// Restore real ref count
setRefCount(carrier, mapOrSetPtr, prevCount);
entry.value = createHashMap(carrier, externalArgs.hashMapMinInitialCapacity);
writeEntry(carrier, mapOrSetPtr, entry);
}
import {
primitiveValueToEntry,
isPrimitive,
getOurPointerIfApplicable
getOurPointerIfApplicable,
} from "./utils";

@@ -9,8 +9,17 @@ import { appendEntry } from "./store";

import { arraySaver } from "./arraySaver";
import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces";
import { ExternalArgs, GlobalCarrier } from "./interfaces";
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
*/
export function saveValue(
externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
referencedPointers: number[],

@@ -22,11 +31,23 @@ value: any

if (value === undefined) {
return UNDEFINED_KNOWN_ADDRESS;
}
if (value === null) {
return NULL_KNOWN_ADDRESS;
}
if (value === true) {
return TRUE_KNOWN_ADDRESS;
}
if (value === false) {
return FALSE_KNOWN_ADDRESS;
}
if (isPrimitive(value)) {
const entry = primitiveValueToEntry(
externalArgs,
value,
externalArgs.minimumStringAllocation
);
const entry = primitiveValueToEntry(value);
valuePointer = appendEntry(externalArgs, carrier, entry);
} else if (
(maybeOurPointer = getOurPointerIfApplicable(value, carrier.dataView))
(maybeOurPointer = getOurPointerIfApplicable(value, carrier.allocator))
) {

@@ -41,3 +62,3 @@ valuePointer = maybeOurPointer;

refsCount: 1,
value: value.getTime()
value: value.getTime(),
});

@@ -44,0 +65,0 @@ } else if (value instanceof Map) {

import {
ExternalArgs,
DataViewAndAllocatorCarrier,
GlobalCarrier,
MapEntry,
InternalAPI
InternalAPI,
} from "./interfaces";
import {
deleteObjectPropertyEntryByKey,
objectSet
objectSet,
mapOrSetClear,
} from "./objectWrapperHelpers";

@@ -20,3 +21,3 @@

hashMapNodePointerToKeyValue,
hashmapNodesPointerIterator
hashmapNodesPointerIterator,
} from "./hashmap/hashmap";

@@ -29,6 +30,3 @@ import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue";

clear(): void {
// @todo impl using helper function with direct list access
for (const key of [...this.keys()]) {
this.delete(key);
}
mapOrSetClear(this.externalArgs, this.carrier, this.entryPointer);
}

@@ -46,3 +44,3 @@

get size(): number {
return hashMapSize(this.carrier.dataView, this.entry.value);
return hashMapSize(this.carrier, this.entry.value);
}

@@ -56,9 +54,6 @@

for (const nodePointer of hashmapNodesPointerIterator(
this.carrier.dataView,
this.carrier,
this.entry.value
)) {
const t = hashMapNodePointerToKeyValue(
this.carrier.dataView,
nodePointer
);
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer);

@@ -77,9 +72,6 @@ const key = entryToFinalJavaScriptValue(

for (const nodePointer of hashmapNodesPointerIterator(
this.carrier.dataView,
this.carrier,
this.entry.value
)) {
const t = hashMapNodePointerToKeyValue(
this.carrier.dataView,
nodePointer
);
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer);

@@ -95,9 +87,6 @@ yield entryToFinalJavaScriptValue(

for (const nodePointer of hashmapNodesPointerIterator(
this.carrier.dataView,
this.carrier,
this.entry.value
)) {
const t = hashMapNodePointerToKeyValue(
this.carrier.dataView,
nodePointer
);
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer);

@@ -129,10 +118,3 @@ yield entryToFinalJavaScriptValue(

return (
hashMapNodeLookup(
this.externalArgs,
this.carrier.dataView,
this.entry.value,
p
) !== 0
);
return hashMapNodeLookup(this.carrier, this.entry.value, p) !== 0;
}

@@ -174,6 +156,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);
}

@@ -12,3 +12,3 @@ /* eslint-env jest */

textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});

@@ -28,3 +28,3 @@

calcedSize,
realSize: beforeSave - afterSave
realSize: beforeSave - afterSave,
};

@@ -38,8 +38,8 @@ }

Object {
"calcedSize": 64,
"realSize": 48,
"calcedSize": 72,
"realSize": 72,
}
`);
// ???
expect(r.calcedSize).toBe(r.realSize + 16);
expect(r.calcedSize).toBe(r.realSize);
});

@@ -52,11 +52,11 @@

test("string", () => {
expect(sizeOf(externalArgs, "סלאם עליכום")).toMatchInlineSnapshot(`40`);
expect(sizeOf(externalArgs, "סלאם עליכום")).toMatchInlineSnapshot(`48`);
});
test("undefined", () => {
expect(sizeOf(externalArgs, undefined)).toMatchInlineSnapshot(`16`);
expect(sizeOf(externalArgs, undefined)).toMatchInlineSnapshot(`0`);
});
test("null", () => {
expect(sizeOf(externalArgs, null)).toMatchInlineSnapshot(`16`);
expect(sizeOf(externalArgs, null)).toMatchInlineSnapshot(`0`);
});

@@ -67,3 +67,3 @@

sizeOf(externalArgs, ["a", { a: "u" }, null, undefined, 1])
).toMatchInlineSnapshot(`388`);
).toMatchInlineSnapshot(`396`);
});

@@ -74,4 +74,4 @@

sizeOf(externalArgs, { a: 1, b: "some string" })
).toMatchInlineSnapshot(`256`);
).toMatchInlineSnapshot(`296`);
});
});

@@ -5,3 +5,3 @@ import {

ArrayEntry,
ObjectEntry
ObjectEntry,
} from "./interfaces";

@@ -12,3 +12,3 @@ import {

primitiveValueToEntry,
align
align,
} from "./utils";

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

LINKED_LIST_MACHINE,
LINKED_LIST_ITEM_MACHINE
LINKED_LIST_ITEM_MACHINE,
} from "./linkedList/linkedList";

@@ -63,3 +63,3 @@ import { MAP_MACHINE, NODE_MACHINE } from "./hashmap/memoryLayout";

arrayToSave.length + externalArgs.arrayAdditionalAllocation,
length: arrayToSave.length
length: arrayToSave.length,
};

@@ -79,3 +79,3 @@

memoryAllocated,
numberOfAllocations
numberOfAllocations,
};

@@ -93,3 +93,6 @@ }

const r = sizeOfHashmap(externalArgs, objectEntries.map(([key]) => key));
const r = sizeOfHashmap(
externalArgs,
objectEntries.map(([key]) => key)
);

@@ -108,3 +111,3 @@ memoryAllocated += r.memoryAllocated;

refsCount: 0,
value: 0
value: 0,
};

@@ -117,3 +120,3 @@

memoryAllocated,
numberOfAllocations
numberOfAllocations,
};

@@ -126,12 +129,20 @@ }

): CheckerResult {
if (
value === undefined ||
value === null ||
value === true ||
value === false
) {
return {
memoryAllocated: 0,
numberOfAllocations: 0,
};
}
if (isPrimitive(value)) {
const entry = primitiveValueToEntry(
externalArgs,
value,
externalArgs.minimumStringAllocation
);
const entry = primitiveValueToEntry(value);
return {
memoryAllocated: align(sizeOfEntry(entry)),
numberOfAllocations: 1
numberOfAllocations: 1,
};

@@ -146,6 +157,6 @@ } else if (Array.isArray(value)) {

refsCount: 0,
value: value.getTime()
value: value.getTime(),
})
),
numberOfAllocations: 1
numberOfAllocations: 1,
};

@@ -186,3 +197,3 @@ } else if (typeof value === "object") {

const hashMapKeysSize = keysArray
.map(k => sizeOfEntry(primitiveValueToEntry(externalArgs, k, 0)))
.map((k) => sizeOfEntry(primitiveValueToEntry(k)))
.reduce((p, c) => {

@@ -204,4 +215,4 @@ return p + align(c);

hashMapNodesAllocationsSize +
hashMapKeysSize
hashMapKeysSize,
};
}

@@ -7,10 +7,8 @@ /* eslint-env jest */

readEntry,
appendEntry
appendEntry,
} from "./store";
import { ENTRY_TYPE } from "./entry-types";
import * as util from "util";
import { arrayBuffer2HexArray } from "./testUtils";
import { ObjectEntry, ExternalArgs } from "./interfaces";
import { MemPool } from "@thi.ng/malloc";
import { MEM_POOL_START } from "./consts";
import { arrayBuffer2HexArray, makeCarrier } from "./testUtils";
import { ObjectEntry } from "./interfaces";
import { externalArgsApiToExternalArgsApi } from "./utils";

@@ -20,6 +18,7 @@

test("initializeArrayBuffer", () => {
const arrayBuffer = new ArrayBuffer(20);
const arrayBuffer = new ArrayBuffer(64);
initializeArrayBuffer(arrayBuffer);
expect(arrayBuffer2HexArray(arrayBuffer, true)).toMatchInlineSnapshot(`
expect(arrayBuffer2HexArray(arrayBuffer.slice(0, 20), true))
.toMatchInlineSnapshot(`
Array [

@@ -30,6 +29,6 @@ "0:0x00",

"3:0x00",
"4:0x00",
"4:0x08",
"5:0x00",
"6:0x00",
"7:0x08",
"7:0x00",
"8:0x00",

@@ -53,25 +52,13 @@ "9:0x00",

describe("Store tests writeEntry", () => {
const externalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
});
test("writeEntry max number", () => {
const externalArgs: ExternalArgs = externalArgsApiToExternalArgsApi({
textEncoder: new util.TextEncoder(),
textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 0,
minimumStringAllocation: 0
});
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
const arrayBuffer = new ArrayBuffer(17);
const dataView = new DataView(arrayBuffer);
writeEntry(externalArgs, dataView, 8, {
writeEntry(carrier, 8, {
type: ENTRY_TYPE.NUMBER,
value: Number.MAX_VALUE
value: Number.MAX_VALUE,
});
expect(arrayBuffer2HexArray(arrayBuffer)).toMatchInlineSnapshot(`
expect(arrayBuffer2HexArray(arrayBuffer.slice(0, 17)))
.toMatchInlineSnapshot(`
Array [

@@ -86,25 +73,2 @@ "0x00",

"0x00",
"0x02",
"0x7f",
"0xef",
"0xff",
"0xff",
"0xff",
"0xff",
"0xff",
"0xff",
]
`);
});
test("writeEntry min number", () => {
const arrayBuffer = new ArrayBuffer(17);
const dataView = new DataView(arrayBuffer);
writeEntry(externalArgs, dataView, 8, {
type: ENTRY_TYPE.NUMBER,
value: Number.MIN_VALUE
});
expect(arrayBuffer2HexArray(arrayBuffer)).toMatchInlineSnapshot(`
Array [
"0x00",

@@ -117,49 +81,74 @@ "0x00",

"0x00",
"0x00",
"0x02",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x01",
"0x40",
"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",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x40",
"0x01",
]
`);
});
test("writeEntry string", () => {
const arrayBuffer = new ArrayBuffer(19);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
writeEntry(externalArgs, dataView, 8, {
writeEntry(carrier, 8, {
type: ENTRY_TYPE.STRING,
value: "aא弟",
allocatedBytes: 0
allocatedBytes: 6,
});
expect(arrayBuffer2HexArray(arrayBuffer)).toMatchInlineSnapshot(`
Array [
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x05",
"0x00",
"0x06",
"0x00",
"0x00",
"0x61",
"0xd7",
"0x90",
"0xe5",
"0xbc",
"0x9f",
]
`);
expect(arrayBuffer2HexArray(arrayBuffer.slice(0, 19)))
.toMatchInlineSnapshot(`
Array [
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x00",
"0x14",
"0x40",
"0x06",
"0x00",
"0x00",
]
`);
});

@@ -172,15 +161,15 @@ });

textDecoder: new util.TextDecoder(),
arrayAdditionalAllocation: 20
arrayAdditionalAllocation: 20,
});
test("readEntry max number", () => {
const arrayBuffer = new ArrayBuffer(17);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
writeEntry(externalArgs, dataView, 8, {
writeEntry(carrier, 8, {
type: ENTRY_TYPE.NUMBER,
value: Number.MAX_VALUE
value: Number.MAX_VALUE,
});
const redEntry = readEntry(externalArgs, dataView, 8);
const redEntry = readEntry(carrier, 8);

@@ -198,11 +187,11 @@ // expect(redBytesLength).toBe(writtenLength);

test("readEntry min number", () => {
const arrayBuffer = new ArrayBuffer(17);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
writeEntry(externalArgs, dataView, 8, {
writeEntry(carrier, 8, {
type: ENTRY_TYPE.NUMBER,
value: Number.MIN_VALUE
value: Number.MIN_VALUE,
});
const redEntry = readEntry(externalArgs, dataView, 8);
const redEntry = readEntry(carrier, 8);

@@ -218,16 +207,16 @@ expect(redEntry).toMatchInlineSnapshot(`

test("readEntry string", () => {
const arrayBuffer = new ArrayBuffer(12);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
writeEntry(externalArgs, dataView, 0, {
writeEntry(carrier, 0, {
type: ENTRY_TYPE.STRING,
value: "aא弟",
allocatedBytes: 0
allocatedBytes: 6,
});
const entry = readEntry(externalArgs, dataView, 0);
const entry = readEntry(carrier, 0);
expect(entry).toMatchInlineSnapshot(`
Object {
"allocatedBytes": 0,
"allocatedBytes": 6,
"type": 5,

@@ -240,11 +229,11 @@ "value": "aא弟",

test("readEntry BigInt", () => {
const arrayBuffer = new ArrayBuffer(20);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
writeEntry(externalArgs, dataView, 0, {
writeEntry(carrier, 0, {
type: ENTRY_TYPE.BIGINT_POSITIVE,
value: BigInt("0b0" + "1".repeat(63))
value: BigInt("0b0" + "1".repeat(63)),
});
const entry = readEntry(externalArgs, dataView, 0);
const entry = readEntry(carrier, 0);

@@ -260,11 +249,11 @@ expect(entry).toMatchInlineSnapshot(`

test("readEntry UBigInt", () => {
const arrayBuffer = new ArrayBuffer(16);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
writeEntry(externalArgs, dataView, 0, {
writeEntry(carrier, 0, {
type: ENTRY_TYPE.BIGINT_POSITIVE,
value: BigInt("0b" + "1".repeat(64))
value: BigInt("0b" + "1".repeat(64)),
});
const entry = readEntry(externalArgs, dataView, 0);
const entry = readEntry(carrier, 0);

@@ -279,11 +268,11 @@ expect(entry).toMatchInlineSnapshot(`

test("ENTRY_TYPE.BIGINT_POSITIVE max value", () => {
const arrayBuffer = new ArrayBuffer(16);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
writeEntry(externalArgs, dataView, 0, {
writeEntry(carrier, 0, {
type: ENTRY_TYPE.BIGINT_POSITIVE,
value: BigInt("0b" + "1".repeat(64))
value: BigInt("0b" + "1".repeat(64)),
});
expect(readEntry(externalArgs, dataView, 0)).toMatchInlineSnapshot(`
expect(readEntry(carrier, 0)).toMatchInlineSnapshot(`
Object {

@@ -297,11 +286,11 @@ "type": 3,

test("ENTRY_TYPE.BIGINT_NEGATIVE min value", () => {
const arrayBuffer = new ArrayBuffer(16);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
writeEntry(externalArgs, dataView, 0, {
writeEntry(carrier, 0, {
type: ENTRY_TYPE.BIGINT_NEGATIVE,
value: -BigInt("0b" + "1".repeat(64))
value: -BigInt("0b" + "1".repeat(64)),
});
expect(readEntry(externalArgs, dataView, 0)).toMatchInlineSnapshot(`
expect(readEntry(carrier, 0)).toMatchInlineSnapshot(`
Object {

@@ -315,9 +304,9 @@ "type": 4,

test("BigInt64 overflow error", () => {
const arrayBuffer = new ArrayBuffer(16);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);
expect(() => {
writeEntry(externalArgs, dataView, 0, {
writeEntry(carrier, 0, {
type: ENTRY_TYPE.BIGINT_POSITIVE,
value: BigInt("0b" + "1".repeat(65))
value: BigInt("0b" + "1".repeat(65)),
});

@@ -329,4 +318,4 @@ }).toThrowErrorMatchingInlineSnapshot(`"BigInt64OverflowError"`);

test("object entry", () => {
const arrayBuffer = new ArrayBuffer(8);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(64);
const carrier = makeCarrier(arrayBuffer);

@@ -336,8 +325,8 @@ const entryToWrite: ObjectEntry = {

refsCount: 0,
value: 10
value: 10,
};
writeEntry(externalArgs, dataView, 0, entryToWrite);
writeEntry(carrier, 0, entryToWrite);
const entry = readEntry(externalArgs, dataView, 0);
const entry = readEntry(carrier, 0);

@@ -356,243 +345,218 @@ expect(entry).toMatchInlineSnapshot(`

test("appendEntry", () => {
const arrayBuffer = new ArrayBuffer(100);
const dataView = new DataView(arrayBuffer);
const arrayBuffer = new ArrayBuffer(96);
initializeArrayBuffer(arrayBuffer);
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START
const carrier = makeCarrier(arrayBuffer);
const r1 = appendEntry(externalArgs, carrier, {
type: ENTRY_TYPE.STRING,
value: "im a string",
allocatedBytes: 11,
});
const r1 = appendEntry(
externalArgs,
{ dataView, allocator },
{
type: ENTRY_TYPE.STRING,
value: "im a string",
allocatedBytes: 0
}
);
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:0x64",
"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:0x00",
"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",
"96:0x00",
"97:0x00",
"98:0x00",
"99:0x00",
]
`);
Array [
"0:0x00",
"1:0x00",
"2:0x00",
"3:0x00",
"4:0x08",
"5:0x00",
"6:0x00",
"7:0x00",
"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:0x48",
"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:0x20",
"41:0x00",
"42:0x00",
"43:0x00",
"44:0x00",
"45:0x00",
"46:0x00",
"47:0x00",
"48:0x00",
"49:0x00",
"50:0x00",
"51:0x00",
"52:0x00",
"53:0x00",
"54:0x14",
"55:0x40",
"56:0x0b",
"57:0x00",
"58:0x00",
"59:0x00",
"60:0x69",
"61:0x6d",
"62:0x20",
"63:0x61",
"64:0x20",
"65:0x73",
"66:0x74",
"67:0x72",
"68:0x69",
"69:0x6e",
"70:0x67",
"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",
]
`);
const r2 = appendEntry(
externalArgs,
{ dataView, allocator },
{
type: ENTRY_TYPE.BOOLEAN,
value: true
}
);
expect(r2).toMatchInlineSnapshot(`72`);
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:0x40",
"17:0x00",
"18:0x00",
"19:0x00",
"20:0x50",
"21:0x00",
"22:0x00",
"23:0x00",
"24:0x64",
"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:0x00",
"53:0x69",
"54:0x6d",
"55:0x20",
"56:0x61",
"57:0x20",
"58:0x73",
"59:0x74",
"60:0x72",
"61:0x69",
"62:0x6e",
"63:0x67",
"64:0x10",
"65:0x00",
"66:0x00",
"67:0x00",
"68:0x28",
"69:0x00",
"70:0x00",
"71:0x00",
"72:0x06",
"73:0x01",
"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",
"96:0x00",
"97:0x00",
"98:0x00",
"99:0x00",
]
`);
Array [
"0:0x00",
"1:0x00",
"2:0x00",
"3:0x00",
"4:0x08",
"5:0x00",
"6:0x00",
"7:0x00",
"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:0x48",
"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:0x20",
"41:0x00",
"42:0x00",
"43:0x00",
"44:0x00",
"45:0x00",
"46:0x00",
"47:0x00",
"48:0x00",
"49:0x00",
"50:0x00",
"51:0x00",
"52:0x00",
"53:0x00",
"54:0x14",
"55:0x40",
"56:0x0b",
"57:0x00",
"58:0x00",
"59:0x00",
"60:0x69",
"61:0x6d",
"62:0x20",
"63:0x61",
"64:0x20",
"65:0x73",
"66:0x74",
"67:0x72",
"68:0x69",
"69:0x6e",
"70:0x67",
"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",
]
`);
});
});
});
import { ENTRY_TYPE, isPrimitiveEntryType } from "./entry-types";
import { Entry, primitive, DataViewAndAllocatorCarrier } from "./interfaces";
import { Entry, primitive, GlobalCarrier } from "./interfaces";
import {
arrayBufferCopyTo,
isPrimitive,
primitiveValueToEntry,
strByteLength
isKnownAddressValuePointer,
} from "./utils";

@@ -13,6 +12,8 @@ import { ExternalArgs } from "./interfaces";

INITIAL_ENTRY_POINTER_TO_POINTER,
INITIAL_ENTRY_POINTER_VALUE
INITIAL_ENTRY_POINTER_VALUE,
} from "./consts";
import { saveValue } from "./saveValue";
import { getAllLinkedAddresses } from "./getAllLinkedAddresses";
import { stringEncodeInto } from "./stringEncodeInto";
import { stringDecode } from "./stringDecode";

@@ -22,14 +23,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;
}

@@ -40,15 +35,6 @@

cursor += Uint8Array.BYTES_PER_ELEMENT;
// type
cursor += Float64Array.BYTES_PER_ELEMENT;
switch (entry.type) {
case ENTRY_TYPE.UNDEFINED:
break;
case ENTRY_TYPE.NULL:
break;
case ENTRY_TYPE.BOOLEAN:
cursor += Uint8Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.NUMBER:

@@ -59,8 +45,7 @@ cursor += Float64Array.BYTES_PER_ELEMENT;

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

@@ -84,16 +69,24 @@ // @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;
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;

@@ -111,4 +104,3 @@

export function writeEntry(
externalArgs: ExternalArgs,
dataView: DataView,
carrier: GlobalCarrier,
startingCursor: number,

@@ -123,19 +115,8 @@ entry: Entry

// undo on throw ?
dataView.setUint8(cursor, entry.type);
cursor += Uint8Array.BYTES_PER_ELEMENT;
carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT] = entry.type;
cursor += Float64Array.BYTES_PER_ELEMENT;
switch (entry.type) {
case ENTRY_TYPE.UNDEFINED:
break;
case ENTRY_TYPE.NULL:
break;
case ENTRY_TYPE.BOOLEAN:
dataView.setUint8(cursor, entry.value ? 1 : 0);
cursor += Uint8Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.NUMBER:
dataView.setFloat64(cursor, entry.value);
carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT] = entry.value;
cursor += Float64Array.BYTES_PER_ELEMENT;

@@ -145,15 +126,20 @@ break;

case ENTRY_TYPE.STRING:
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] =
entry.allocatedBytes;
cursor += Uint32Array.BYTES_PER_ELEMENT;
// eslint-disable-next-line no-case-declarations
const encodedString: Uint8Array = externalArgs.textEncoder.encode(
entry.value
);
dataView.setUint16(cursor, encodedString.byteLength);
cursor += Uint16Array.BYTES_PER_ELEMENT;
const writtenBytes = stringEncodeInto(carrier.uint8, cursor, entry.value);
dataView.setUint16(cursor, entry.allocatedBytes);
cursor += Uint16Array.BYTES_PER_ELEMENT;
for (let i = 0; i < encodedString.length; i++) {
dataView.setUint8(cursor, encodedString[i]);
cursor += Uint8Array.BYTES_PER_ELEMENT;
if (writtenBytes !== entry.allocatedBytes) {
// eslint-disable-next-line no-undef
console.warn(
{
value: entry.value,
writtenBytes,
allocatedBytes: entry.allocatedBytes,
},
true
);
throw new Error("WTF???");
}

@@ -170,8 +156,6 @@

}
carrier.bigUint64[cursor / BigUint64Array.BYTES_PER_ELEMENT] =
entry.type === ENTRY_TYPE.BIGINT_NEGATIVE ? -entry.value : entry.value;
dataView.setBigUint64(
cursor,
entry.type === ENTRY_TYPE.BIGINT_NEGATIVE ? -entry.value : entry.value
);
cursor += BigInt64Array.BYTES_PER_ELEMENT;
cursor += BigUint64Array.BYTES_PER_ELEMENT;
break;

@@ -182,24 +166,25 @@

case ENTRY_TYPE.MAP:
dataView.setUint8(cursor, entry.refsCount);
cursor += Uint8Array.BYTES_PER_ELEMENT;
dataView.setUint32(cursor, entry.value);
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.refsCount;
cursor += Uint32Array.BYTES_PER_ELEMENT;
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = 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);
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.refsCount;
cursor += Uint32Array.BYTES_PER_ELEMENT;
dataView.setUint32(cursor, entry.length);
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.value;
cursor += Uint32Array.BYTES_PER_ELEMENT;
dataView.setUint32(cursor, entry.allocatedLength);
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.length;
cursor += Uint32Array.BYTES_PER_ELEMENT;
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] =
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);
carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT] = entry.value;
cursor += Float64Array.BYTES_PER_ELEMENT;
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.refsCount;
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;

@@ -216,3 +201,3 @@

externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
entry: Entry

@@ -224,3 +209,3 @@ ) {

writeEntry(externalArgs, carrier.dataView, memoryAddress, entry);
writeEntry(carrier, memoryAddress, entry);

@@ -231,4 +216,3 @@ return memoryAddress;

export function readEntry(
externalArgs: ExternalArgs,
dataView: DataView,
carrier: GlobalCarrier,
startingCursor: number

@@ -238,8 +222,9 @@ ): Entry {

const entryType: ENTRY_TYPE = dataView.getUint8(cursor);
cursor += Uint8Array.BYTES_PER_ELEMENT;
const entryType: ENTRY_TYPE =
carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT];
cursor += Float64Array.BYTES_PER_ELEMENT;
const entry: any = {
type: entryType,
value: undefined as any
value: undefined as any,
};

@@ -250,15 +235,16 @@

switch (entryType) {
case ENTRY_TYPE.UNDEFINED:
break;
// handled by well-known addresses
// case ENTRY_TYPE.UNDEFINED:
// break;
case ENTRY_TYPE.NULL:
break;
// case ENTRY_TYPE.NULL:
// break;
case ENTRY_TYPE.BOOLEAN:
entry.value = dataView.getUint8(cursor) !== 0;
cursor += Uint8Array.BYTES_PER_ELEMENT;
break;
// case ENTRY_TYPE.BOOLEAN:
// entry.value = carrier.dataView.getUint8(cursor) !== 0;
// cursor += Uint8Array.BYTES_PER_ELEMENT;
// break;
case ENTRY_TYPE.NUMBER:
entry.value = dataView.getFloat64(cursor);
entry.value = carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT];
cursor += Float64Array.BYTES_PER_ELEMENT;

@@ -269,8 +255,7 @@ break;

// eslint-disable-next-line no-case-declarations
const stringLength = dataView.getUint16(cursor);
cursor += Uint16Array.BYTES_PER_ELEMENT;
const stringLength =
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT];
entry.allocatedBytes = stringLength;
cursor += Uint32Array.BYTES_PER_ELEMENT;
entry.allocatedBytes = dataView.getUint16(cursor);
cursor += Uint16Array.BYTES_PER_ELEMENT;
// decode fails with zero length array

@@ -281,6 +266,6 @@ if (stringLength > 0) {

// eslint-disable-next-line no-case-declarations
const tempAB = new ArrayBuffer(stringLength);
arrayBufferCopyTo(dataView.buffer, cursor, stringLength, tempAB, 0);
// const tempAB = new ArrayBuffer(stringLength, true);
// arrayBufferCopyTo(dataView.buffer, cursor, stringLength, tempAB, 0, true);
entry.value = externalArgs.textDecoder.decode(tempAB);
entry.value = stringDecode(carrier.uint8, cursor, stringLength);
} else {

@@ -295,3 +280,4 @@ entry.value = "";

case ENTRY_TYPE.BIGINT_POSITIVE:
entry.value = dataView.getBigUint64(cursor);
entry.value =
carrier.bigUint64[cursor / BigUint64Array.BYTES_PER_ELEMENT];
cursor += BigUint64Array.BYTES_PER_ELEMENT;

@@ -301,3 +287,5 @@ break;

case ENTRY_TYPE.BIGINT_NEGATIVE:
entry.value = -dataView.getBigUint64(cursor);
entry.value = -carrier.bigUint64[
cursor / BigUint64Array.BYTES_PER_ELEMENT
];
cursor += BigUint64Array.BYTES_PER_ELEMENT;

@@ -309,24 +297,25 @@ break;

case ENTRY_TYPE.SET:
entry.refsCount = dataView.getUint8(cursor);
cursor += Uint8Array.BYTES_PER_ELEMENT;
entry.value = dataView.getUint32(cursor);
entry.refsCount = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT];
cursor += Uint32Array.BYTES_PER_ELEMENT;
entry.value = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT];
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.ARRAY:
entry.refsCount = dataView.getUint8(cursor);
cursor += Uint8Array.BYTES_PER_ELEMENT;
entry.value = dataView.getUint32(cursor);
entry.refsCount = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT];
cursor += Uint32Array.BYTES_PER_ELEMENT;
entry.length = dataView.getUint32(cursor);
entry.value = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT];
cursor += Uint32Array.BYTES_PER_ELEMENT;
entry.allocatedLength = dataView.getUint32(cursor);
entry.length = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT];
cursor += Uint32Array.BYTES_PER_ELEMENT;
entry.allocatedLength =
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT];
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;
case ENTRY_TYPE.DATE:
entry.refsCount = dataView.getUint8(cursor);
cursor += Uint8Array.BYTES_PER_ELEMENT;
entry.value = dataView.getFloat64(cursor);
entry.value = carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT];
cursor += Float64Array.BYTES_PER_ELEMENT;
entry.refsCount = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT];
cursor += Uint32Array.BYTES_PER_ELEMENT;
break;

@@ -343,7 +332,2 @@

const typeofTheValue = typeof value;
if (entryA.type === ENTRY_TYPE.BOOLEAN && typeofTheValue === "boolean") {
return true;
}
// number & bigint 64 are the same size

@@ -359,19 +343,11 @@ if (

if (
entryA.type === ENTRY_TYPE.STRING &&
typeofTheValue === "string" &&
entryA.allocatedBytes >= strByteLength(value as string)
) {
return true;
}
// kill for strings for now
// if (
// entryA.type === ENTRY_TYPE.STRING &&
// typeofTheValue === "string" &&
// entryA.allocatedBytes >= strByteLength(value as string)
// ) {
// return true;
// }
if (
((entryA.type === ENTRY_TYPE.NULL ||
entryA.type === ENTRY_TYPE.UNDEFINED) &&
value === undefined) ||
value === null
) {
return true;
}
return false;

@@ -382,32 +358,25 @@ }

externalArgs: ExternalArgs,
carrier: DataViewAndAllocatorCarrier,
carrier: GlobalCarrier,
ptrToPtr: number,
value: any
) {
const existingEntryPointer = carrier.dataView.getUint32(ptrToPtr);
const existingValueEntry = readEntry(
externalArgs,
carrier.dataView,
existingEntryPointer
);
const existingEntryPointer =
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT];
let reuse = false;
let existingValueEntry: Entry | undefined;
if (!isKnownAddressValuePointer(existingEntryPointer)) {
existingValueEntry = readEntry(carrier, existingEntryPointer);
reuse =
isPrimitive(value) &&
isPrimitiveEntryType(existingValueEntry.type) &&
canReuseMemoryOfEntry(existingValueEntry, value);
}
// try to re use memory
if (
isPrimitive(value) &&
isPrimitiveEntryType(existingValueEntry.type) &&
canReuseMemoryOfEntry(existingValueEntry, value) &&
existingEntryPointer !== 0
) {
const stringAllocatedBytes =
existingValueEntry.type === ENTRY_TYPE.STRING
? existingValueEntry.allocatedBytes
: 0;
if (reuse) {
const newEntry = primitiveValueToEntry(value);
const newEntry = primitiveValueToEntry(
externalArgs,
value,
stringAllocatedBytes
);
writeEntry(externalArgs, carrier.dataView, existingEntryPointer, newEntry);
writeEntry(carrier, existingEntryPointer, newEntry);
} else {

@@ -422,3 +391,3 @@ const referencedPointers: number[] = [];

carrier.dataView.setUint32(ptrToPtr, newEntryPointer);
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = newEntryPointer;

@@ -428,3 +397,3 @@ return {

existingEntryPointer,
existingValueEntry
existingValueEntry,
};

@@ -436,3 +405,3 @@ }

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

@@ -444,3 +413,3 @@ value: any

existingEntryPointer = 0,
referencedPointers = []
referencedPointers = [],
} = writeValueInPtrToPtr(externalArgs, carrier, ptrToPtr, value) || {};

@@ -450,3 +419,3 @@

for (const ptr of referencedPointers) {
incrementRefCount(externalArgs, carrier.dataView, ptr);
incrementRefCount(externalArgs, carrier, ptr);
}

@@ -458,3 +427,3 @@ }

externalArgs,
carrier.dataView,
carrier,
existingEntryPointer

@@ -465,4 +434,3 @@ );

const addressesToFree = getAllLinkedAddresses(
externalArgs,
carrier.dataView,
carrier,
false,

@@ -472,5 +440,9 @@ existingEntryPointer

for (const address of addressesToFree) {
for (const address of addressesToFree.leafAddresses) {
carrier.allocator.free(address);
}
for (const address of addressesToFree.arcAddresses) {
decrementRefCount(externalArgs, carrier, address);
}
}

@@ -482,12 +454,50 @@ } else {

export function handleArcForDeletedValuePointer(
externalArgs: ExternalArgs,
carrier: GlobalCarrier,
deletedValuePointer: number
): void {
// No memory to free/ARC
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
);
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);
}
}
export function incrementRefCount(
externalArgs: ExternalArgs,
dataView: DataView,
carrier: GlobalCarrier,
entryPointer: number
) {
const entry = readEntry(externalArgs, dataView, entryPointer);
const entry = readEntry(carrier, entryPointer);
if ("refsCount" in entry) {
entry.refsCount += 1;
writeEntry(externalArgs, dataView, entryPointer, entry);
writeEntry(carrier, entryPointer, entry);

@@ -502,10 +512,10 @@ return entry.refsCount;

externalArgs: ExternalArgs,
dataView: DataView,
carrier: GlobalCarrier,
entryPointer: number
) {
const entry = readEntry(externalArgs, dataView, entryPointer);
const entry = readEntry(carrier, entryPointer);
if ("refsCount" in entry) {
entry.refsCount -= 1;
writeEntry(externalArgs, dataView, entryPointer, entry);
writeEntry(carrier, entryPointer, entry);

@@ -518,8 +528,4 @@ return entry.refsCount;

export function getRefCount(
externalArgs: ExternalArgs,
dataView: DataView,
entryPointer: number
) {
const entry = readEntry(externalArgs, dataView, entryPointer);
export function getRefCount(carrier: GlobalCarrier, entryPointer: number) {
const entry = readEntry(carrier, entryPointer);

@@ -533,17 +539,34 @@ if ("refsCount" in entry) {

export function getObjectPropPtrToPtr(
{ dataView }: DataViewAndAllocatorCarrier,
pointerToEntry: number
export function setRefCount(
carrier: GlobalCarrier,
entryPointer: number,
newRefCount: number
) {
const keyStringLength = dataView.getUint16(pointerToEntry + 1);
const valuePtrToPtr =
Uint16Array.BYTES_PER_ELEMENT + pointerToEntry + 1 + keyStringLength;
const nextPtrToPtr = valuePtrToPtr + Uint32Array.BYTES_PER_ELEMENT;
const entry = readEntry(carrier, entryPointer);
return {
valuePtrToPtr,
nextPtrToPtr
};
if ("refsCount" in entry) {
const prevCount = entry.refsCount;
entry.refsCount = newRefCount;
writeEntry(carrier, entryPointer, entry);
return prevCount;
}
throw new Error("unexpected");
}
// export function getObjectPropPtrToPtr(
// { dataView }: GlobalCarrier,
// pointerToEntry: number
// ) {
// 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 getObjectValuePtrToPtr(pointerToEntry: number) {

@@ -554,3 +577,3 @@ return pointerToEntry + 1 + 1;

export function memComp(
dataView: DataView,
uint8: Uint8Array,
aStart: number,

@@ -561,4 +584,4 @@ bStart: number,

if (
dataView.byteLength < aStart + length ||
dataView.byteLength < bStart + length
uint8.byteLength < aStart + length ||
uint8.byteLength < bStart + length
) {

@@ -569,3 +592,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;

@@ -579,3 +602,3 @@ }

export function compareStringOrNumberEntriesInPlace(
dataView: DataView,
carrier: GlobalCarrier,
entryAPointer: number,

@@ -585,5 +608,7 @@ 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;

@@ -595,4 +620,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];

@@ -604,8 +631,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,

@@ -618,5 +643,7 @@ 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]
);
}

@@ -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

@@ -24,4 +24,6 @@ setTimeout(res, time);

import { IMemPool } from "@thi.ng/malloc";
import { IMemPool, MemPool } from "@thi.ng/malloc";
import { OutOfMemoryError } from "./exceptions";
import { GlobalCarrier } from "./interfaces";
import { MEM_POOL_START } from "./consts";

@@ -97,1 +99,20 @@ // extend pool and not monkey patch? need to think about it

}
export function makeCarrier(arrayBuffer: ArrayBuffer) {
const allocator = new MemPool({
buf: arrayBuffer,
start: MEM_POOL_START,
});
const carrier: GlobalCarrier = {
// dataView: new DataView(arrayBuffer),
allocator,
uint8: new Uint8Array(arrayBuffer),
uint16: new Uint16Array(arrayBuffer),
uint32: new Uint32Array(arrayBuffer),
float64: new Float64Array(arrayBuffer),
bigUint64: new BigUint64Array(arrayBuffer),
};
return carrier;
}

@@ -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;

@@ -33,7 +40,3 @@

export function primitiveValueToEntry(
externalArgs: ExternalArgs,
value: primitive,
stringAllocatedBytes: number
): Entry {
export function primitiveValueToEntry(value: primitive): Entry {
if (typeof value === "string") {

@@ -43,6 +46,3 @@ return {

value,
allocatedBytes: Math.max(
externalArgs.textEncoder.encode(value).length,
stringAllocatedBytes
)
allocatedBytes: strByteLength(value),
};

@@ -54,3 +54,3 @@ }

type: ENTRY_TYPE.NUMBER,
value
value,
};

@@ -65,25 +65,6 @@ }

: ENTRY_TYPE.BIGINT_NEGATIVE,
value
value,
};
}
if (typeof value === "boolean") {
return {
type: ENTRY_TYPE.BOOLEAN,
value
};
}
if (typeof value === "undefined") {
return {
type: ENTRY_TYPE.UNDEFINED
};
}
if (value === null) {
return {
type: ENTRY_TYPE.NULL
};
}
throw new Error("unexpected");

@@ -114,11 +95,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();

@@ -141,5 +120,2 @@ }

: 0,
minimumStringAllocation: p.minimumStringAllocation
? p.minimumStringAllocation
: 0
};

@@ -170,1 +146,10 @@ }

}
export function isKnownAddressValuePointer(entryPointer: number) {
return (
entryPointer === UNDEFINED_KNOWN_ADDRESS ||
entryPointer === NULL_KNOWN_ADDRESS ||
entryPointer === TRUE_KNOWN_ADDRESS ||
entryPointer === FALSE_KNOWN_ADDRESS
);
}

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 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

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