@bnaya/objectbuffer
Advanced tools
Comparing version 0.0.0-dfae000 to 0.0.0-f1ba10a
@@ -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,2 +16,6 @@ /** | ||
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); | ||
@@ -32,3 +37,3 @@ initializeArrayBuffer(arrayBuffer); | ||
}; | ||
const start = objectSaver(externalArgsApiToExternalArgsApi(externalArgs), carrier, [], initialValue); | ||
const start = objectSaver(externalArgsApiToExternalArgsApi(externalArgs), carrier, [], new Map(), initialValue); | ||
carrier.uint32[INITIAL_ENTRY_POINTER_TO_POINTER / Uint32Array.BYTES_PER_ELEMENT] = start; | ||
@@ -35,0 +40,0 @@ return createObjectWrapper(externalArgsApiToExternalArgsApi(externalArgs), carrier, start); |
@@ -7,3 +7,3 @@ import { ArrayEntry, ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
} | undefined; | ||
export declare function getFinalValueAtArrayIndex(externalArgs: ExternalArgs, dataViewCarrier: GlobalCarrier, pointerToArrayEntry: number, indexToGet: number): any; | ||
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; | ||
@@ -19,4 +19,4 @@ export declare function setValueAtArrayIndex(externalArgs: ExternalArgs, carrier: GlobalCarrier, pointerToArrayEntry: number, indexToSet: number, value: any): void; | ||
export declare function shrinkArray(externalArgs: ExternalArgs, carrier: GlobalCarrier, pointerToArrayEntry: number, wishedLength: number): void; | ||
export declare function arraySort(externalArgs: ExternalArgs, dataViewCarrier: GlobalCarrier, pointerToArrayEntry: number, sortComparator?: (a: any, b: any) => 1 | -1 | 0): 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 |
@@ -23,4 +23,4 @@ import { readEntry, writeEntry, writeValueInPtrToPtrAndHandleMemory } from "./store"; | ||
} | ||
export function getFinalValueAtArrayIndex(externalArgs, dataViewCarrier, pointerToArrayEntry, indexToGet) { | ||
const pointers = arrayGetPointersToValueInIndex(dataViewCarrier, pointerToArrayEntry, indexToGet); | ||
export function getFinalValueAtArrayIndex(externalArgs, globalCarrier, pointerToArrayEntry, indexToGet) { | ||
const pointers = arrayGetPointersToValueInIndex(globalCarrier, pointerToArrayEntry, indexToGet); | ||
@@ -31,3 +31,3 @@ if (pointers === undefined) { | ||
return entryToFinalJavaScriptValue(externalArgs, dataViewCarrier, pointers.pointer); | ||
return entryToFinalJavaScriptValue(externalArgs, globalCarrier, pointers.pointer); | ||
} | ||
@@ -105,7 +105,7 @@ export function setValuePointerAtArrayIndex(carrier, pointerToArrayEntry, indexToSet, pointerToEntry) { | ||
export function arraySort(externalArgs, dataViewCarrier, pointerToArrayEntry, sortComparator = defaultCompareFunction) { | ||
const metadata = arrayGetMetadata(dataViewCarrier, pointerToArrayEntry); | ||
const pointersToValues = [...new Array(metadata.length).keys()].map(index => metadata.value + index * Uint32Array.BYTES_PER_ELEMENT).map(pointerToPointer => dataViewCarrier.uint32[pointerToPointer / Uint32Array.BYTES_PER_ELEMENT]); | ||
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)]; | ||
}); | ||
@@ -117,3 +117,3 @@ sortMe.sort((a, b) => { | ||
for (let i = 0; i < sortMe.length; i += 1) { | ||
dataViewCarrier.uint32[(metadata.value + i * Uint32Array.BYTES_PER_ELEMENT) / Uint32Array.BYTES_PER_ELEMENT] = sortMe[i][0]; | ||
globalCarrier.uint32[(metadata.value + i * Uint32Array.BYTES_PER_ELEMENT) / Uint32Array.BYTES_PER_ELEMENT] = sortMe[i][0]; | ||
} | ||
@@ -120,0 +120,0 @@ } // https://stackoverflow.com/a/47349064/711152 |
@@ -15,3 +15,3 @@ import { appendEntry } from "./store"; | ||
for (const item of arrayToSave) { | ||
const rOfValue = saveValue(externalArgs, carrier, referencedPointers, item); | ||
const rOfValue = saveValue(externalArgs, carrier, referencedPointers, new Map(), item); | ||
carrier.uint32[memoryForPointersCursor / Uint32Array.BYTES_PER_ELEMENT] = rOfValue; | ||
@@ -18,0 +18,0 @@ memoryForPointersCursor += Uint32Array.BYTES_PER_ELEMENT; |
import { ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
export declare function arraySplice(externalArgs: ExternalArgs, dataViewCarrier: GlobalCarrier, pointerToArrayEntry: number, startArg: number, deleteCountArg?: number, ...itemsToAddArg: Array<any>): any[]; | ||
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(dataViewCarrier, 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(dataViewCarrier, pointerToArrayEntry, writeValueToIndex - itemCountChange); | ||
const valueToCopyPointers = arrayGetPointersToValueInIndex(globalCarrier, pointerToArrayEntry, writeValueToIndex - itemCountChange); | ||
assertNonNull(valueToCopyPointers); | ||
setValuePointerAtArrayIndex(dataViewCarrier, pointerToArrayEntry, writeValueToIndex, valueToCopyPointers.pointer); | ||
dataViewCarrier.uint32[valueToCopyPointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT] = 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(dataViewCarrier, pointerToArrayEntry, writeValueToIndex - itemCountChange); | ||
const valueToCopyPointers = arrayGetPointersToValueInIndex(globalCarrier, pointerToArrayEntry, writeValueToIndex - itemCountChange); | ||
assertNonNull(valueToCopyPointers); | ||
setValuePointerAtArrayIndex(dataViewCarrier, 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.uint32[valueToCopyPointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT] = 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(dataViewCarrier, 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, pointerToArrayEntry, newLength); | ||
shrinkArray(externalArgs, globalCarrier, pointerToArrayEntry, newLength); | ||
} | ||
@@ -73,0 +73,0 @@ |
@@ -34,3 +34,3 @@ import { ExternalArgs, GlobalCarrier, ArrayEntry } from "./interfaces"; | ||
} | ||
export declare function createArrayWrapper(externalArgs: ExternalArgs, dataViewCarrier: GlobalCarrier, entryPointer: number): Array<any>; | ||
export declare function createArrayWrapper(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, entryPointer: number): Array<any>; | ||
//# sourceMappingURL=arrayWrapper.d.ts.map |
@@ -220,4 +220,4 @@ import { getFinalValueAtArrayIndex, arrayGetMetadata, setValueAtArrayIndex, arraySort, extendArrayIfNeeded, arrayReverse } from "./arrayHelpers"; | ||
} | ||
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)); | ||
} |
@@ -15,4 +15,2 @@ import { ExternalArgs, GlobalCarrier, InternalAPI, DateEntry, ArrayEntry, ObjectEntry, MapEntry, SetEntry } from "./interfaces"; | ||
arrayAdditionalAllocation: number; | ||
textDecoder: import("./textEncoderDecoderTypes").TextDecoder; | ||
textEncoder: import("./textEncoderDecoderTypes").TextEncoder; | ||
}>; | ||
@@ -19,0 +17,0 @@ protected get entryPointer(): number; |
@@ -16,3 +16,3 @@ import { WeakValueMap } from "./WeakValueMap"; | ||
function supportWeakRef() { | ||
return typeof WeakRef !== "undefined"; | ||
return typeof WeakRef !== "undefined" && (typeof FinalizationGroup !== "undefined" || typeof "FinalizationRegistry" !== "undefined"); | ||
} |
import { GlobalCarrier } from "./interfaces"; | ||
export declare function getAllLinkedAddresses(carrier: GlobalCarrier, ignoreRefCount: boolean, entryPointer: number): { | ||
leafAddresses: number[]; | ||
arcAddresses: number[]; | ||
leafAddresses: Set<number>; | ||
arcAddresses: Set<number>; | ||
}; | ||
export declare function getObjectOrMapOrSetAddresses(carrier: GlobalCarrier, ignoreRefCount: boolean, internalHashmapPointer: number, leafAddresses: number[], arcAddresses: number[]): void; | ||
export declare function getObjectOrMapOrSetAddresses(carrier: GlobalCarrier, internalHashmapPointer: number, leafAddresses: Set<number>, addressesToProcessQueue: number[]): void; | ||
//# sourceMappingURL=getAllLinkedAddresses.d.ts.map |
@@ -6,5 +6,17 @@ import { readEntry } from "./store"; | ||
export function getAllLinkedAddresses(carrier, ignoreRefCount, entryPointer) { | ||
const leafAddresses = []; | ||
const arcAddresses = []; | ||
getAllLinkedAddressesStep(carrier, ignoreRefCount, entryPointer, leafAddresses, arcAddresses); | ||
const leafAddresses = new Set(); | ||
const arcAddresses = new Set(); | ||
const addressesToProcessQueue = [entryPointer]; | ||
let addressToProcess = undefined; // const diffs = []; | ||
while ((addressToProcess = addressesToProcessQueue.shift()) !== undefined) { | ||
// const before = addressesToProcessQueue.slice(); | ||
if (addressToProcess === 0) { | ||
continue; | ||
} | ||
getAllLinkedAddressesStep(carrier, ignoreRefCount, addressToProcess, leafAddresses, arcAddresses, addressesToProcessQueue); // diffs.push(addressesToProcessQueue.filter((p) => !before.includes(p))); | ||
} // console.log(diffs); | ||
return { | ||
@@ -16,4 +28,4 @@ leafAddresses, | ||
function getAllLinkedAddressesStep(carrier, ignoreRefCount, entryPointer, leafAddresses, arcAddresses) { | ||
if (isKnownAddressValuePointer(entryPointer)) { | ||
function getAllLinkedAddressesStep(carrier, ignoreRefCount, entryPointer, leafAddresses, arcAddresses, addressesToProcessQueue) { | ||
if (isKnownAddressValuePointer(entryPointer) || leafAddresses.has(entryPointer) || arcAddresses.has(entryPointer)) { | ||
return; | ||
@@ -29,3 +41,3 @@ } | ||
case ENTRY_TYPE.BIGINT_POSITIVE: | ||
leafAddresses.push(entryPointer); | ||
leafAddresses.add(entryPointer); | ||
break; | ||
@@ -37,6 +49,6 @@ | ||
if (entry.refsCount <= 1 || ignoreRefCount) { | ||
leafAddresses.push(entryPointer); | ||
getObjectOrMapOrSetAddresses(carrier, ignoreRefCount, entry.value, leafAddresses, arcAddresses); | ||
leafAddresses.add(entryPointer); | ||
getObjectOrMapOrSetAddresses(carrier, entry.value, leafAddresses, addressesToProcessQueue); | ||
} else { | ||
arcAddresses.push(entryPointer); | ||
arcAddresses.add(entryPointer); | ||
} | ||
@@ -48,11 +60,11 @@ | ||
if (entry.refsCount <= 1 || ignoreRefCount) { | ||
leafAddresses.push(entryPointer); | ||
leafAddresses.push(entry.value); | ||
leafAddresses.add(entryPointer); | ||
leafAddresses.add(entry.value); | ||
for (let i = 0; i < entry.allocatedLength; i += 1) { | ||
const valuePointer = carrier.uint32[(entry.value + i * Uint32Array.BYTES_PER_ELEMENT) / Uint32Array.BYTES_PER_ELEMENT]; | ||
getAllLinkedAddressesStep(carrier, ignoreRefCount, valuePointer, leafAddresses, arcAddresses); | ||
addressesToProcessQueue.push(valuePointer); | ||
} | ||
} else { | ||
arcAddresses.push(entryPointer); | ||
arcAddresses.add(entryPointer); | ||
} | ||
@@ -64,5 +76,5 @@ | ||
if (entry.refsCount <= 1 || ignoreRefCount) { | ||
leafAddresses.push(entryPointer); | ||
leafAddresses.add(entryPointer); | ||
} else { | ||
arcAddresses.push(entryPointer); | ||
arcAddresses.add(entryPointer); | ||
} | ||
@@ -79,3 +91,3 @@ | ||
export function getObjectOrMapOrSetAddresses(carrier, ignoreRefCount, internalHashmapPointer, leafAddresses, arcAddresses) { | ||
export function getObjectOrMapOrSetAddresses(carrier, internalHashmapPointer, leafAddresses, addressesToProcessQueue) { | ||
const { | ||
@@ -85,7 +97,10 @@ pointersToValuePointers, | ||
} = hashMapGetPointersToFree(carrier, internalHashmapPointer); | ||
leafAddresses.push(...pointers); | ||
for (const leafPointer of pointers) { | ||
leafAddresses.add(leafPointer); | ||
} | ||
for (const pointer of pointersToValuePointers) { | ||
getAllLinkedAddressesStep(carrier, ignoreRefCount, carrier.uint32[pointer / Uint32Array.BYTES_PER_ELEMENT], leafAddresses, arcAddresses); | ||
addressesToProcessQueue.push(carrier.uint32[pointer / Uint32Array.BYTES_PER_ELEMENT]); | ||
} | ||
} |
import { ENTRY_TYPE } from "./entry-types"; | ||
import { TextDecoder, TextEncoder } from "./textEncoderDecoderTypes"; | ||
export declare type primitive = string | number | bigint | boolean | undefined | null; | ||
@@ -72,5 +71,7 @@ export declare type Entry = StringEntry | NumberEntry | BigIntPositiveEntry | BigIntNegativeEntry | ObjectEntry | ArrayEntry | DateEntry | MapEntry | SetEntry; | ||
hashMapMinInitialCapacity: number; | ||
/** | ||
* Allocate additional memory for array pointers, | ||
* will prevent the reallocation and copy when array is getting bigger | ||
*/ | ||
arrayAdditionalAllocation: number; | ||
textDecoder: TextDecoder; | ||
textEncoder: TextEncoder; | ||
}>; | ||
@@ -81,4 +82,2 @@ export declare type ExternalArgsApi = Readonly<{ | ||
arrayAdditionalAllocation?: number; | ||
textDecoder: TextDecoder; | ||
textEncoder: TextEncoder; | ||
}>; | ||
@@ -85,0 +84,0 @@ export interface InternalAPI { |
@@ -20,3 +20,3 @@ import { ExternalArgs, GlobalCarrier, MapEntry, InternalAPI } from "./interfaces"; | ||
} | ||
export declare function createMapWrapper<K extends string | number, V>(externalArgs: ExternalArgs, dataViewCarrier: GlobalCarrier, 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 |
@@ -100,4 +100,4 @@ import { deleteObjectPropertyEntryByKey, objectGet, objectSet, mapOrSetClear } from "./objectWrapperHelpers"; | ||
} | ||
export function createMapWrapper(externalArgs, dataViewCarrier, entryPointer) { | ||
return new MapWrapper(externalArgs, dataViewCarrier, entryPointer); | ||
export function createMapWrapper(externalArgs, globalCarrier, entryPointer) { | ||
return new MapWrapper(externalArgs, globalCarrier, entryPointer); | ||
} |
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 objectSaver(externalArgs: ExternalArgs, carrier: GlobalCarrier, referencedPointers: number[], visitedValues: Map<object, number>, objectToSave: any): number; | ||
export declare function mapSaver(externalArgs: ExternalArgs, carrier: GlobalCarrier, referencedPointers: number[], visitedValues: Map<object, 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 |
@@ -5,9 +5,9 @@ import { appendEntry } from "./store"; | ||
import { createHashMap, hashMapInsertUpdate } from "./hashmap/hashmap"; | ||
export function objectSaver(externalArgs, carrier, referencedPointers, objectToSave) { | ||
export function objectSaver(externalArgs, carrier, referencedPointers, visitedValues, objectToSave) { | ||
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))); | ||
for (const [key, value] of objectEntries) { | ||
const ptrToPtr = hashMapInsertUpdate(externalArgs, carrier, hashMapPointer, key); | ||
const pointerToValue = saveValue(externalArgs, carrier, referencedPointers, value); | ||
const pointerToValue = saveValue(externalArgs, carrier, referencedPointers, visitedValues, value); | ||
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = pointerToValue; | ||
@@ -23,8 +23,8 @@ } | ||
} | ||
export function mapSaver(externalArgs, carrier, referencedPointers, mapToSave) { | ||
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, mapToSave.size * 1.3)); | ||
export function mapSaver(externalArgs, carrier, referencedPointers, visitedValues, mapToSave) { | ||
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, Math.ceil(mapToSave.size * 1.3))); | ||
for (const [key, value] of mapToSave.entries()) { | ||
const ptrToPtr = hashMapInsertUpdate(externalArgs, carrier, hashMapPointer, key); | ||
const pointerToValue = saveValue(externalArgs, carrier, referencedPointers, value); | ||
const pointerToValue = saveValue(externalArgs, carrier, referencedPointers, visitedValues, value); | ||
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = pointerToValue; | ||
@@ -41,3 +41,3 @@ } | ||
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))); | ||
@@ -44,0 +44,0 @@ for (const key of setToSave.keys()) { |
@@ -19,3 +19,3 @@ import { ObjectEntry, ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
} | ||
export declare function createObjectWrapper<T = any>(externalArgs: ExternalArgs, dataViewCarrier: GlobalCarrier, entryPointer: number): T; | ||
export declare function createObjectWrapper<T = any>(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, entryPointer: number): T; | ||
//# sourceMappingURL=objectWrapper.d.ts.map |
@@ -97,6 +97,6 @@ import { getObjectPropertiesEntries, deleteObjectPropertyEntryByKey, objectGet, objectSet } from "./objectWrapperHelpers"; | ||
} | ||
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)); | ||
} |
@@ -9,4 +9,3 @@ import { ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
export declare function objectGet(externalArgs: ExternalArgs, carrier: GlobalCarrier, entryPointer: number, key: string | number): any; | ||
export declare function hashmapClearFree(externalArgs: ExternalArgs, carrier: GlobalCarrier, hashmapPointer: number): void; | ||
export declare function mapOrSetClear(externalArgs: ExternalArgs, carrier: GlobalCarrier, mapOrSetPtr: number): void; | ||
//# sourceMappingURL=objectWrapperHelpers.d.ts.map |
@@ -1,5 +0,5 @@ | ||
import { readEntry, writeValueInPtrToPtrAndHandleMemory, handleArcForDeletedValuePointer, decrementRefCount, writeEntry } from "./store"; | ||
import { readEntry, writeValueInPtrToPtrAndHandleMemory, handleArcForDeletedValuePointer, decrementRefCount, writeEntry, setRefCount } from "./store"; | ||
import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue"; | ||
import { hashMapDelete, hashMapLowLevelIterator, hashMapNodePointerToKeyValue, hashMapInsertUpdate, hashMapValueLookup, createHashMap } from "./hashmap/hashmap"; | ||
import { getObjectOrMapOrSetAddresses } from "./getAllLinkedAddresses"; | ||
import { getAllLinkedAddresses } from "./getAllLinkedAddresses"; | ||
export function deleteObjectPropertyEntryByKey(externalArgs, carrier, hashmapPointer, keyToDeleteBy) { | ||
@@ -46,9 +46,38 @@ const deletedValuePointerToPointer = hashMapDelete(carrier, hashmapPointer, keyToDeleteBy); // no such key | ||
return entryToFinalJavaScriptValue(externalArgs, carrier, carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT]); | ||
} | ||
export function hashmapClearFree(externalArgs, carrier, hashmapPointer) { | ||
const leafAddresses = []; | ||
const arcAddresses = []; | ||
getObjectOrMapOrSetAddresses(carrier, false, hashmapPointer, leafAddresses, arcAddresses); | ||
} // 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); | ||
@@ -58,10 +87,15 @@ } | ||
for (const address of arcAddresses) { | ||
// don't dispose the address we need to reuse | ||
if (address === mapOrSetPtr) { | ||
continue; | ||
} | ||
decrementRefCount(externalArgs, carrier, address); | ||
} | ||
} | ||
export function mapOrSetClear(externalArgs, carrier, mapOrSetPtr) { | ||
const entry = readEntry(carrier, mapOrSetPtr); | ||
hashmapClearFree(externalArgs, carrier, entry.value); | ||
} // hashmapClearFree(externalArgs, carrier, entry.value); | ||
// Restore real ref count | ||
setRefCount(carrier, mapOrSetPtr, prevCount); | ||
entry.value = createHashMap(carrier, externalArgs.hashMapMinInitialCapacity); | ||
writeEntry(carrier, mapOrSetPtr, entry); | ||
} |
@@ -5,3 +5,3 @@ import { ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
*/ | ||
export declare function saveValue(externalArgs: ExternalArgs, carrier: GlobalCarrier, referencedPointers: number[], value: any): number; | ||
export declare function saveValue(externalArgs: ExternalArgs, carrier: GlobalCarrier, referencedPointers: number[], visitedValuesOnCurrentSaveOperation: Map<object, number>, value: any): number; | ||
//# sourceMappingURL=saveValue.d.ts.map |
@@ -11,3 +11,4 @@ import { primitiveValueToEntry, isPrimitive, getOurPointerIfApplicable } from "./utils"; | ||
export function saveValue(externalArgs, carrier, referencedPointers, value) { | ||
export function saveValue(externalArgs, carrier, referencedPointers, // Not really working yet. we need iterative saving for it | ||
visitedValuesOnCurrentSaveOperation, value) { | ||
let valuePointer = 0; | ||
@@ -38,2 +39,5 @@ let maybeOurPointer; | ||
referencedPointers.push(valuePointer); | ||
} else if (maybeOurPointer = visitedValuesOnCurrentSaveOperation.get(value)) { | ||
valuePointer = maybeOurPointer; | ||
referencedPointers.push(valuePointer); | ||
} else if (Array.isArray(value)) { | ||
@@ -48,7 +52,10 @@ valuePointer = arraySaver(externalArgs, carrier, referencedPointers, value); | ||
} else if (value instanceof Map) { | ||
valuePointer = mapSaver(externalArgs, carrier, referencedPointers, value); | ||
valuePointer = mapSaver(externalArgs, carrier, referencedPointers, visitedValuesOnCurrentSaveOperation, value); | ||
visitedValuesOnCurrentSaveOperation.set(value, valuePointer); | ||
} else if (value instanceof Set) { | ||
valuePointer = setSaver(externalArgs, carrier, value); | ||
visitedValuesOnCurrentSaveOperation.set(value, valuePointer); | ||
} else if (typeof value === "object") { | ||
valuePointer = objectSaver(externalArgs, carrier, referencedPointers, value); | ||
valuePointer = objectSaver(externalArgs, carrier, referencedPointers, visitedValuesOnCurrentSaveOperation, value); | ||
visitedValuesOnCurrentSaveOperation.set(value, valuePointer); | ||
} else { | ||
@@ -55,0 +62,0 @@ throw new Error("unsupported yet"); |
@@ -19,3 +19,3 @@ import { ExternalArgs, GlobalCarrier, MapEntry, InternalAPI } from "./interfaces"; | ||
} | ||
export declare function createSetWrapper<K extends string | number>(externalArgs: ExternalArgs, dataViewCarrier: GlobalCarrier, 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 |
@@ -88,4 +88,4 @@ import { deleteObjectPropertyEntryByKey, objectSet, mapOrSetClear } from "./objectWrapperHelpers"; | ||
} | ||
export function createSetWrapper(externalArgs, dataViewCarrier, entryPointer) { | ||
return new SetWrapper(externalArgs, dataViewCarrier, entryPointer); | ||
export function createSetWrapper(externalArgs, globalCarrier, entryPointer) { | ||
return new SetWrapper(externalArgs, globalCarrier, entryPointer); | ||
} |
@@ -18,2 +18,4 @@ import { Entry, primitive, GlobalCarrier } from "./interfaces"; | ||
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; | ||
@@ -20,0 +22,0 @@ export declare function memComp(uint8: Uint8Array, aStart: number, bStart: number, length: number): boolean; |
@@ -280,3 +280,3 @@ import { ENTRY_TYPE, isPrimitiveEntryType } from "./entry-types"; | ||
const referencedPointers = []; | ||
const newEntryPointer = saveValue(externalArgs, carrier, referencedPointers, value); | ||
const newEntryPointer = saveValue(externalArgs, carrier, referencedPointers, new Map(), value); | ||
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = newEntryPointer; | ||
@@ -368,2 +368,23 @@ return { | ||
throw new Error("unexpected"); | ||
} | ||
export function getRefCount(carrier, entryPointer) { | ||
const entry = readEntry(carrier, entryPointer); | ||
if ("refsCount" in entry) { | ||
return entry.refsCount; | ||
} | ||
throw new Error("unexpected"); | ||
} | ||
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( | ||
@@ -370,0 +391,0 @@ // { dataView }: GlobalCarrier, |
@@ -15,3 +15,4 @@ const KEYS = 1; | ||
this.map = new Map(); | ||
this.group = new FinalizationGroup(iterator => { | ||
const FinalizationSomething = typeof FinalizationRegistry !== "undefined" ? FinalizationRegistry : FinalizationGroup; | ||
this.group = new FinalizationSomething(iterator => { | ||
for (const key of iterator) { | ||
@@ -18,0 +19,0 @@ this.map.delete(key); |
@@ -9,3 +9,3 @@ /** | ||
*/ /** */ | ||
export { createObjectBuffer, resizeObjectBuffer, getUnderlyingArrayBuffer, loadObjectBuffer, replaceUnderlyingArrayBuffer, sizeOf as unreliable_sizeOf, memoryStats, disposeWrapperObject, updateExternalArgs } from "./internal/api"; | ||
export { createObjectBuffer, resizeObjectBuffer, getUnderlyingArrayBuffer, loadObjectBuffer, replaceUnderlyingArrayBuffer, sizeOf as unreliable_sizeOf, memoryStats, disposeWrapperObject, updateExternalArgs, } from "./internal/api"; | ||
export { acquireLock, acquireLockWait, releaseLock } from "./internal/locks"; | ||
@@ -12,0 +12,0 @@ export declare type ExternalArgs = import("./internal/interfaces").ExternalArgsApi; |
{ | ||
"name": "@bnaya/objectbuffer", | ||
"description": "Object-like api, backed by an array buffer", | ||
"version": "0.0.0-dfae000", | ||
"version": "0.0.0-f1ba10a", | ||
"main": "dist/objectbuffer.cjs.js", | ||
@@ -36,39 +36,40 @@ "module": "dist/index.js", | ||
"webpack-playground": "webpack-dev-server --mode=development --config playground/webpack.config.js --open", | ||
"generate-docs": "rimraf -f docs/generated/ && typedoc --out docs/generated/ --includes . --name objectbuffer --readme none --entryPoint \"\\\"index\\\"\" --excludeNotExported --ignoreCompilerErrors --mode modules src/index.ts" | ||
"generate-docs": "rimraf -f docs/generated/ && typedoc --mode library --readme none --out docs/generated/ --excludeNotExported --ignoreCompilerErrors src/index.ts" | ||
}, | ||
"devDependencies": { | ||
"@babel/cli": "^7.8.4", | ||
"@babel/core": "^7.8.4", | ||
"@babel/preset-env": "^7.8.4", | ||
"@babel/preset-typescript": "^7.8.3", | ||
"@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.1.2", | ||
"@types/jest": "^25.2.1", | ||
"@types/node": "^12.12.21", | ||
"@typescript-eslint/eslint-plugin": "^2.19.0", | ||
"@typescript-eslint/parser": "^2.19.0", | ||
"babel-loader": "^8.0.6", | ||
"@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.4", | ||
"core-js": "^3.6.5", | ||
"eslint": "^6.8.0", | ||
"eslint-config-prettier": "^6.10.0", | ||
"eslint-config-prettier": "^6.10.1", | ||
"eslint-plugin-prettier": "^3.1.2", | ||
"gh-pages": "^2.2.0", | ||
"html-webpack-plugin": "^3.2.0", | ||
"husky": "^4.2.1", | ||
"jest": "^25.1.0", | ||
"prettier": "^1.19.1", | ||
"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.1", | ||
"rollup": "^1.31.0", | ||
"rollup-plugin-babel": "^4.3.3", | ||
"rimraf": "^3.0.2", | ||
"rollup": "^2.4.0", | ||
"rollup-plugin-babel": "^4.4.0", | ||
"rollup-plugin-node-resolve": "^5.2.0", | ||
"typedoc": "^0.16.9", | ||
"typedoc-plugin-markdown": "^2.2.16", | ||
"typescript": "^3.7.5", | ||
"webpack": "^4.41.5", | ||
"webpack-cli": "^3.3.10", | ||
"typedoc": "^0.17.0-3", | ||
"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" | ||
}, | ||
@@ -88,4 +89,4 @@ "husky": { | ||
"dependencies": { | ||
"@thi.ng/malloc": "^4.1.3" | ||
"@thi.ng/malloc": "^4.1.10" | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
# ObjectBuffer: object-like API, backed by a [shared]arraybuffer | ||
# ObjectBuffer: object-like API, backed by a [shared]arraybuffer 👀 | ||
@@ -6,14 +6,17 @@ [![npm version](https://badge.fury.io/js/%40bnaya%2Fobjectbuffer.svg)](https://badge.fury.io/js/%40bnaya%2Fobjectbuffer) | ||
## The readme is for latest release `v0.10.0`.big refactor ongoing (allocator, hashmap) | ||
For Modern browsers and node. | ||
For Modern browsers and node. Zero direct dependencies. | ||
Save, read and update plain javascript objects into `ArrayBuffer` (And not only TypedArrays), using regular javascript object api, without serialization/deserialization, or pre-defined schema. | ||
In other words, It's an implementation of javascript objects in user-land. | ||
Save, read and update plain javascript objects into `ArrayBuffer` (And not only TypedArrays), using regular javascript object api, without serialization/deserialization. | ||
Look at it as a simple implementation of javascript objects in user-land. | ||
That's enables us to `transfer` or share objects in-memory with `WebWorker` without additional memory or serialization | ||
While the library is not `1.0`, it is usable. | ||
The library is still not `1.0`, but already usable, and will never offer full compatibility with plain js (`Symbol` and such) | ||
A core part of the library is an allocator, that allocates & free memory on the `ArrayBuffer` for us! | ||
The allocator in use is [@thi.ng/malloc](https://www.npmjs.com/package/@thi.ng/malloc), part of the amazing [thi.ng/umbrella](https://github.com/thi-ng/umbrella) project | ||
For in-depth overview of how things are implemented, see [implementation details document](docs/implementationDetails.md) | ||
## 🐉🐉🐉 Adventurers Beware 🐉🐉🐉 | ||
Using this library, and workers in general, will not necessarily make you code faster. | ||
First be sure where are your bottlenecks and if you don't have a better and more simple workaround. | ||
I personally also really like what's going on around the [main thread scheduling proposal](https://github.com/WICG/main-thread-scheduling) and [react userland scheduler](https://www.npmjs.com/package/scheduler) that powers concurrent react | ||
@@ -30,7 +33,3 @@ ## Quick example | ||
const myObject = createObjectBuffer( | ||
{ | ||
// available globally in the browser, or inside `util` in node | ||
textEncoder: new TextEncoder(), | ||
textDecoder: new TextDecoder() | ||
}, | ||
{}, | ||
// size in bytes | ||
@@ -84,15 +83,17 @@ 1024, | ||
* Date | ||
* Internal references (`foo.bar2 = foo.bar` will not create a copy) | ||
* BigInt | ||
* Internal references (`foo.bar2 = foo.bar` will not create a copy, but a reference) | ||
* Automatic reference counting, to dispose a value you need to use the `disposeWrapperObject` or to have WeakRef support | ||
* Internal equality between objects (`foo.bar === foo.bar` will be true) | ||
* global lock for shared memory using [Atomics](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics) (i hope its really working) | ||
* global lock for shared memory using [Atomics](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics) (I hope its really working) | ||
## Caveats & Limitations | ||
* Need to specify size for the `ArrayBuffer`. When exceed that size, exception will be thrown. (Can be extended with a utility function, but not automatically) | ||
* Not memory re-use. memory allocation is append based, or overwrite when possible [#21](https://github.com/Bnaya/objectbuffer/issues/21) | ||
* Object are implemented using simple linked list [#26](https://github.com/Bnaya/objectbuffer/issues/26) | ||
* Maps & Sets are not supported yet [#15](https://github.com/Bnaya/objectbuffer/issues/15) & [#24](https://github.com/Bnaya/objectbuffer/issues/24) | ||
* No prototype chain. objects props will simply be copied | ||
* Additional props on Array, Date, primitives will not be saved. | ||
* getters, setters, will not work/break the library | ||
* Need to specify size for the `ArrayBuffer`. When exceed that size, exception will be thrown. (Can be extended later with a utility function, but not automatically) | ||
* Set, Map, Object keys can be only string or numbers. no symbols or other things | ||
* You can't save objects with circularities (But you can create them on objectbuffer) | ||
* No prototype chain. no methods on the objects | ||
* Adding getters, setters, will not work/break the library | ||
* deleting/removing the current key of Map/Set while iteration will make you skip the next key [#60](https://github.com/Bnaya/objectbuffer/issues/60) | ||
* unreliable_sizeOf is unreliable due to hashmap array side depends on actual keys, Also It's an expensive operation | ||
@@ -103,3 +104,3 @@ ### What's not working yet, but can be | ||
### What's probably never going to work (convince me otherwise ) | ||
### What's probably never going to work | ||
@@ -112,2 +113,10 @@ * Anything that cannot go into `JSON.stringify` | ||
There's a huge place for optimizations, code hygiene, and features! | ||
Feel free to open issues and maybe implementing missing parts | ||
Feel free to open issues and maybe implementing missing parts. | ||
The code is Written in TypeScript 🦾, but the semantics are more like `C` 🥵 | ||
Have a look on the [issues](https://github.com/Bnaya/objectbuffer/issues) and see if you find something interesting | ||
## If you came this far, you better also look at: | ||
* [GoogleChromeLabs/buffer-backed-object](https://github.com/GoogleChromeLabs/buffer-backed-object#readme) | ||
* [FlatBuffers](https://google.github.io/flatbuffers/flatbuffers_guide_use_javascript.html) | ||
/* eslint-env jest */ | ||
import * as util from "util"; | ||
import { createObjectBuffer } from "../"; | ||
@@ -12,5 +10,3 @@ import { memoryStats } from "../internal/api"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -17,0 +13,0 @@ |
/* eslint-env jest */ | ||
import * as util from "util"; | ||
import { createObjectBuffer } from "../"; | ||
@@ -11,5 +9,3 @@ import { memoryStats } from "../internal/api"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -20,3 +16,3 @@ | ||
// 1/1 2000 | ||
myDate: new Date(946684800000) | ||
myDate: new Date(946684800000), | ||
}); | ||
@@ -23,0 +19,0 @@ |
/* eslint-env jest */ | ||
import * as util from "util"; | ||
import { createObjectBuffer } from "../"; | ||
@@ -11,5 +9,3 @@ import { memoryStats } from "../internal/api"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -16,0 +12,0 @@ |
/* eslint-env jest */ | ||
import * as util from "util"; | ||
import { createObjectBuffer } from "../"; | ||
@@ -10,6 +8,3 @@ import { memoryStats } from "../internal/api"; | ||
describe("Map", () => { | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder() | ||
}); | ||
const externalArgs = externalArgsApiToExternalArgsApi({}); | ||
@@ -75,3 +70,6 @@ test("creation", () => { | ||
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"); | ||
@@ -121,3 +119,3 @@ expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`504`); | ||
[1, "a"], | ||
[2, "b"] | ||
[2, "b"], | ||
]); | ||
@@ -131,4 +129,4 @@ for (const [key] of nativeMap) { | ||
[1, "a"], | ||
[2, "b"] | ||
]) | ||
[2, "b"], | ||
]), | ||
}); | ||
@@ -157,3 +155,3 @@ for (const [key] of objectBuffer.foo) { | ||
expect(thisArgs.every(v => v === objectBuffer.foo)).toBe(true); | ||
expect(thisArgs.every((v) => v === objectBuffer.foo)).toBe(true); | ||
@@ -160,0 +158,0 @@ expect(dump).toMatchInlineSnapshot(` |
/* eslint-env jest */ | ||
import * as util from "util"; | ||
import { createObjectBuffer } from "../"; | ||
@@ -11,5 +9,3 @@ import { resizeObjectBuffer, memoryStats } from "../internal/api"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -20,3 +16,3 @@ | ||
arr: [1, 2, 3, 4], | ||
obj: { a: 1 } | ||
obj: { a: 1 }, | ||
}); | ||
@@ -35,3 +31,3 @@ | ||
arr: [1, 2, 3, 4], | ||
obj: { a: 1 } | ||
obj: { a: 1 }, | ||
}); | ||
@@ -38,0 +34,0 @@ |
/* eslint-env jest */ | ||
import * as util from "util"; | ||
import { createObjectBuffer } from "../"; | ||
@@ -10,6 +8,3 @@ import { memoryStats } from "../internal/api"; | ||
describe("object tests", () => { | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder() | ||
}); | ||
const externalArgs = externalArgsApiToExternalArgsApi({}); | ||
@@ -36,3 +31,3 @@ test("delete object prop", () => { | ||
e: undefined, | ||
foo: { a: 1, b: true, c: false, d: null, e: undefined } | ||
foo: { a: 1, b: true, c: false, d: null, e: undefined }, | ||
}; | ||
@@ -60,2 +55,28 @@ | ||
}); | ||
// Not working. will make infinite loop | ||
test.skip("With circular", () => { | ||
const input: any = { | ||
a: 1, | ||
b: true, | ||
c: false, | ||
d: null, | ||
e: undefined, | ||
foo: { a: 1, b: true, c: false, d: null, e: undefined }, | ||
}; | ||
// Create circularity | ||
input.foo.circular = input.foo; | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 2048, input); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`1016`); | ||
expect(input).toEqual(objectBuffer); | ||
expect(objectBuffer.foo.circular).toEqual(objectBuffer.foo); | ||
expect(objectBuffer.foo.circular.d).toMatchInlineSnapshot(); | ||
objectBuffer.foo.circular = "severe the circularity"; | ||
expect(objectBuffer).toMatchInlineSnapshot(); | ||
}); | ||
}); |
/* eslint-env jest */ | ||
import * as util from "util"; | ||
import { createObjectBuffer, resizeObjectBuffer } from "../"; | ||
@@ -9,7 +7,7 @@ import { | ||
replaceUnderlyingArrayBuffer, | ||
memoryStats | ||
memoryStats, | ||
} from "../internal/api"; | ||
import { | ||
arrayBufferCopyTo, | ||
externalArgsApiToExternalArgsApi | ||
externalArgsApiToExternalArgsApi, | ||
} from "../internal/utils"; | ||
@@ -19,5 +17,3 @@ | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -27,3 +23,3 @@ | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 512, { | ||
a: 1 | ||
a: 1, | ||
}); | ||
@@ -52,3 +48,3 @@ | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, { | ||
obj1: { a: 1 } | ||
obj1: { a: 1 }, | ||
}); | ||
@@ -55,0 +51,0 @@ |
/* eslint-env jest */ | ||
import * as util from "util"; | ||
import { createObjectBuffer } from "../"; | ||
@@ -12,5 +10,3 @@ import { memoryStats } from "../internal/api"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -26,3 +22,3 @@ | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 312, { | ||
value: "first value 123" | ||
value: "first value 123", | ||
}); | ||
@@ -29,0 +25,0 @@ const freeSpaceLeft = memoryStats(objectBuffer).available; |
/* eslint-env jest */ | ||
import * as util from "util"; | ||
import { createObjectBuffer } from "../"; | ||
@@ -10,6 +8,3 @@ import { memoryStats } from "../internal/api"; | ||
describe("Set tests", () => { | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder() | ||
}); | ||
const externalArgs = externalArgsApiToExternalArgsApi({}); | ||
@@ -125,3 +120,3 @@ test("creation", () => { | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, { | ||
foo: new Set(["a", "b"]) | ||
foo: new Set(["a", "b"]), | ||
}); | ||
@@ -150,3 +145,3 @@ for (const [key] of objectBuffer.foo) { | ||
expect(thisArgs.every(v => v === objectBuffer.foo)).toBe(true); | ||
expect(thisArgs.every((v) => v === objectBuffer.foo)).toBe(true); | ||
@@ -153,0 +148,0 @@ expect(dump).toMatchInlineSnapshot(` |
/* eslint-env jest */ | ||
import * as util from "util"; | ||
import { createObjectBuffer } from "../"; | ||
@@ -12,5 +10,3 @@ import { memoryStats, disposeWrapperObject } from "../internal/api"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -17,0 +13,0 @@ |
/* eslint-disable */ | ||
import { ExternalArgs } from "../internal/interfaces"; | ||
import * as util from "util"; | ||
import { createObjectBuffer } from ".."; | ||
@@ -27,6 +27,6 @@ import { memoryStats } from "../internal/api"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -33,0 +33,0 @@ |
@@ -1,2 +0,1 @@ | ||
import * as util from "util"; | ||
import { createObjectBuffer } from ".."; | ||
@@ -10,5 +9,3 @@ import { memoryStats } from "../internal/api"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -18,3 +15,3 @@ | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 256, { | ||
foo: null | ||
foo: null, | ||
}); | ||
@@ -30,3 +27,3 @@ | ||
more: "than size", | ||
arr: [1, 2, 3] | ||
arr: [1, 2, 3], | ||
}; | ||
@@ -33,0 +30,0 @@ }).toThrowErrorMatchingInlineSnapshot(`"OutOfMemoryError"`); |
@@ -1,2 +0,1 @@ | ||
import * as util from "util"; | ||
import { createObjectBuffer } from ".."; | ||
@@ -10,5 +9,3 @@ import { memoryStats } from "../internal/api"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -18,3 +15,3 @@ | ||
const objectBuffer = createObjectBuffer(externalArgs, 128, { | ||
num: 1 as number | bigint | ||
num: 1 as number | bigint, | ||
}); | ||
@@ -54,3 +51,3 @@ | ||
const objectBuffer = createObjectBuffer(externalArgs, 128, { | ||
nullContainer: null as null | undefined | ||
nullContainer: null as null | undefined, | ||
}); | ||
@@ -83,3 +80,3 @@ | ||
const objectBuffer = createObjectBuffer(externalArgs, 128, { | ||
booleanContainer: false | ||
booleanContainer: false, | ||
}); | ||
@@ -86,0 +83,0 @@ |
/* eslint-env jest */ | ||
import * as util from "util"; | ||
@@ -7,3 +6,3 @@ import { | ||
getUnderlyingArrayBuffer, | ||
loadObjectBuffer | ||
loadObjectBuffer, | ||
} from "."; | ||
@@ -15,5 +14,3 @@ import { arrayBuffer2HexArray } from "./internal/testUtils"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -25,3 +22,3 @@ | ||
b: null, | ||
c: { t: 5 } | ||
c: { t: 5 }, | ||
}); | ||
@@ -43,5 +40,3 @@ | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -51,3 +46,3 @@ test("getUnderlyingArrayBuffer simple", () => { | ||
b: null, | ||
c: { t: 5 } | ||
c: { t: 5 }, | ||
}); | ||
@@ -66,5 +61,3 @@ | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -76,3 +69,3 @@ | ||
b: null, | ||
c: { t: 5 } | ||
c: { t: 5 }, | ||
}); | ||
@@ -79,0 +72,0 @@ |
@@ -20,3 +20,3 @@ /** | ||
disposeWrapperObject, | ||
updateExternalArgs | ||
updateExternalArgs, | ||
} from "./internal/api"; | ||
@@ -23,0 +23,0 @@ export { acquireLock, acquireLockWait, releaseLock } from "./internal/locks"; |
@@ -8,3 +8,4 @@ import { initializeArrayBuffer } from "./store"; | ||
externalArgsApiToExternalArgsApi, | ||
getInternalAPI | ||
getInternalAPI, | ||
isPrimitive, | ||
} from "./utils"; | ||
@@ -14,2 +15,3 @@ import { getCacheFor } from "./externalObjectsCache"; | ||
import { MemPool } from "@thi.ng/malloc"; | ||
import { UnsupportedOperationError } from "./exceptions"; | ||
@@ -37,2 +39,12 @@ 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 | ||
@@ -46,3 +58,3 @@ ? SharedArrayBuffer | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -57,3 +69,3 @@ | ||
float64: new Float64Array(arrayBuffer), | ||
bigUint64: new BigUint64Array(arrayBuffer) | ||
bigUint64: new BigUint64Array(arrayBuffer), | ||
}; | ||
@@ -65,2 +77,3 @@ | ||
[], | ||
new Map(), | ||
initialValue | ||
@@ -127,3 +140,3 @@ ); | ||
start: MEM_POOL_START, | ||
skipInitialization: true | ||
skipInitialization: true, | ||
}); | ||
@@ -138,3 +151,3 @@ | ||
float64: new Float64Array(arrayBuffer), | ||
bigUint64: new BigUint64Array(arrayBuffer) | ||
bigUint64: new BigUint64Array(arrayBuffer), | ||
}; | ||
@@ -179,3 +192,3 @@ | ||
start: MEM_POOL_START, | ||
skipInitialization: true | ||
skipInitialization: true, | ||
}); | ||
@@ -190,3 +203,3 @@ | ||
float64: new Float64Array(newArrayBuffer), | ||
bigUint64: new BigUint64Array(newArrayBuffer) | ||
bigUint64: new BigUint64Array(newArrayBuffer), | ||
}; | ||
@@ -213,3 +226,3 @@ | ||
skipInitialization: true, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -216,0 +229,0 @@ |
/* eslint-env jest */ | ||
import { initializeArrayBuffer } from "./store"; | ||
import * as util from "util"; | ||
import { arraySaver } from "./arraySaver"; | ||
@@ -9,3 +9,3 @@ import { | ||
getFinalValueAtArrayIndex, | ||
setValueAtArrayIndex | ||
setValueAtArrayIndex, | ||
} from "./arrayHelpers"; | ||
@@ -19,5 +19,3 @@ import { ExternalArgs } from "./interfaces"; | ||
const externalArgs: ExternalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -58,3 +56,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -84,3 +82,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -110,3 +108,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -137,3 +135,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -140,0 +138,0 @@ |
import { | ||
readEntry, | ||
writeEntry, | ||
writeValueInPtrToPtrAndHandleMemory | ||
writeValueInPtrToPtrAndHandleMemory, | ||
} from "./store"; | ||
@@ -40,3 +40,3 @@ import { ArrayEntry, ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
pointer, | ||
pointerToThePointer | ||
pointerToThePointer, | ||
}; | ||
@@ -47,3 +47,3 @@ } | ||
externalArgs: ExternalArgs, | ||
dataViewCarrier: GlobalCarrier, | ||
globalCarrier: GlobalCarrier, | ||
pointerToArrayEntry: number, | ||
@@ -53,3 +53,3 @@ indexToGet: number | ||
const pointers = arrayGetPointersToValueInIndex( | ||
dataViewCarrier, | ||
globalCarrier, | ||
pointerToArrayEntry, | ||
@@ -65,3 +65,3 @@ indexToGet | ||
externalArgs, | ||
dataViewCarrier, | ||
globalCarrier, | ||
pointers.pointer | ||
@@ -138,3 +138,3 @@ ); | ||
allocatedLength: metadata.allocatedLength, | ||
length: wishedLength | ||
length: wishedLength, | ||
}); | ||
@@ -161,3 +161,3 @@ } | ||
allocatedLength: metadata.allocatedLength, | ||
length: wishedLength | ||
length: wishedLength, | ||
}); | ||
@@ -198,3 +198,3 @@ } | ||
allocatedLength: newAllocatedLength, | ||
length: newLength | ||
length: newLength, | ||
}); | ||
@@ -205,18 +205,18 @@ } | ||
externalArgs: ExternalArgs, | ||
dataViewCarrier: GlobalCarrier, | ||
globalCarrier: GlobalCarrier, | ||
pointerToArrayEntry: number, | ||
sortComparator: (a: any, b: any) => 1 | -1 | 0 = defaultCompareFunction | ||
) { | ||
const metadata = arrayGetMetadata(dataViewCarrier, pointerToArrayEntry); | ||
const metadata = arrayGetMetadata(globalCarrier, pointerToArrayEntry); | ||
const pointersToValues = [...new Array(metadata.length).keys()] | ||
.map(index => metadata.value + index * Uint32Array.BYTES_PER_ELEMENT) | ||
.map((index) => metadata.value + index * Uint32Array.BYTES_PER_ELEMENT) | ||
.map( | ||
pointerToPointer => | ||
dataViewCarrier.uint32[pointerToPointer / Uint32Array.BYTES_PER_ELEMENT] | ||
(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; | ||
@@ -230,3 +230,3 @@ }); | ||
for (let i = 0; i < sortMe.length; i += 1) { | ||
dataViewCarrier.uint32[ | ||
globalCarrier.uint32[ | ||
(metadata.value + i * Uint32Array.BYTES_PER_ELEMENT) / | ||
@@ -233,0 +233,0 @@ Uint32Array.BYTES_PER_ELEMENT |
/* eslint-env jest */ | ||
import { initializeArrayBuffer } from "./store"; | ||
import * as util from "util"; | ||
import { arrayBuffer2HexArray, makeCarrier } from "./testUtils"; | ||
@@ -11,5 +11,3 @@ import { arraySaver } from "./arraySaver"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
@@ -16,0 +14,0 @@ |
@@ -23,7 +23,13 @@ import { appendEntry } from "./store"; | ||
arrayToSave.length + externalArgs.arrayAdditionalAllocation, | ||
length: arrayToSave.length | ||
length: arrayToSave.length, | ||
}; | ||
for (const item of arrayToSave) { | ||
const rOfValue = saveValue(externalArgs, carrier, referencedPointers, item); | ||
const rOfValue = saveValue( | ||
externalArgs, | ||
carrier, | ||
referencedPointers, | ||
new Map(), | ||
item | ||
); | ||
@@ -30,0 +36,0 @@ carrier.uint32[ |
/* eslint-env jest */ | ||
import { initializeArrayBuffer } from "./store"; | ||
import * as util from "util"; | ||
import { createArrayWrapper } from "./arrayWrapper"; | ||
@@ -14,5 +14,3 @@ import { arraySaver } from "./arraySaver"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
@@ -26,3 +24,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -100,3 +98,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -151,3 +149,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -211,3 +209,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -293,3 +291,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -376,3 +374,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -445,3 +443,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -520,3 +518,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -595,3 +593,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -598,0 +596,0 @@ |
@@ -7,3 +7,3 @@ import { | ||
arrayGetPointersToValueInIndex, | ||
setValuePointerAtArrayIndex | ||
setValuePointerAtArrayIndex, | ||
} from "./arrayHelpers"; | ||
@@ -17,3 +17,3 @@ import { assertNonNull } from "./assertNonNull"; | ||
externalArgs: ExternalArgs, | ||
dataViewCarrier: GlobalCarrier, | ||
globalCarrier: GlobalCarrier, | ||
pointerToArrayEntry: number, | ||
@@ -24,3 +24,3 @@ startArg: number, | ||
) { | ||
const metadata = arrayGetMetadata(dataViewCarrier, pointerToArrayEntry); | ||
const metadata = arrayGetMetadata(globalCarrier, pointerToArrayEntry); | ||
@@ -39,3 +39,3 @@ const calcedStart = calculateSpliceStart(metadata.length, startArg); | ||
externalArgs, | ||
dataViewCarrier, | ||
globalCarrier, | ||
pointerToArrayEntry, | ||
@@ -57,3 +57,3 @@ newLength | ||
externalArgs, | ||
dataViewCarrier, | ||
globalCarrier, | ||
pointerToArrayEntry, | ||
@@ -78,3 +78,3 @@ deletedItemIndexToSave | ||
const valueToCopyPointers = arrayGetPointersToValueInIndex( | ||
dataViewCarrier, | ||
globalCarrier, | ||
pointerToArrayEntry, | ||
@@ -87,3 +87,3 @@ writeValueToIndex - itemCountChange | ||
setValuePointerAtArrayIndex( | ||
dataViewCarrier, | ||
globalCarrier, | ||
pointerToArrayEntry, | ||
@@ -94,3 +94,3 @@ writeValueToIndex, | ||
dataViewCarrier.uint32[ | ||
globalCarrier.uint32[ | ||
valueToCopyPointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT | ||
@@ -113,3 +113,3 @@ ] = 0; | ||
const valueToCopyPointers = arrayGetPointersToValueInIndex( | ||
dataViewCarrier, | ||
globalCarrier, | ||
pointerToArrayEntry, | ||
@@ -122,3 +122,3 @@ writeValueToIndex - itemCountChange | ||
setValuePointerAtArrayIndex( | ||
dataViewCarrier, | ||
globalCarrier, | ||
pointerToArrayEntry, | ||
@@ -131,3 +131,3 @@ writeValueToIndex, | ||
dataViewCarrier.uint32[ | ||
globalCarrier.uint32[ | ||
valueToCopyPointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT | ||
@@ -151,3 +151,3 @@ ] = 0; | ||
const valueToSetPointers = arrayGetPointersToValueInIndex( | ||
dataViewCarrier, | ||
globalCarrier, | ||
pointerToArrayEntry, | ||
@@ -161,3 +161,3 @@ calcedStart + i | ||
externalArgs, | ||
dataViewCarrier, | ||
globalCarrier, | ||
valueToSetPointers.pointerToThePointer, | ||
@@ -169,3 +169,3 @@ itemsToAddArg[i] | ||
if (newLength < metadata.length) { | ||
shrinkArray(externalArgs, dataViewCarrier, pointerToArrayEntry, newLength); | ||
shrinkArray(externalArgs, globalCarrier, pointerToArrayEntry, newLength); | ||
} | ||
@@ -172,0 +172,0 @@ |
/* eslint-env jest */ | ||
import { initializeArrayBuffer } from "./store"; | ||
import * as util from "util"; | ||
import { createArrayWrapper } from "./arrayWrapper"; | ||
@@ -14,5 +14,3 @@ import { arraySaver } from "./arraySaver"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
@@ -27,3 +25,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -58,3 +56,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -82,3 +80,3 @@ const arrayToSave = ["a", "b", 1]; | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -121,3 +119,3 @@ const arrayToSave = ["a", "b", 1]; | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -221,3 +219,3 @@ const arrayToSave = ["a", "b", 1]; | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -261,3 +259,3 @@ const arrayToSave = ["a", "b", 1]; | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -299,7 +297,7 @@ | ||
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, | ||
})); | ||
@@ -357,3 +355,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -398,3 +396,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -401,0 +399,0 @@ |
@@ -7,3 +7,3 @@ import { | ||
extendArrayIfNeeded, | ||
arrayReverse | ||
arrayReverse, | ||
} from "./arrayHelpers"; | ||
@@ -15,3 +15,3 @@ import { INTERNAL_API_SYMBOL } from "./symbols"; | ||
IllegalArrayIndexError, | ||
UnsupportedOperationError | ||
UnsupportedOperationError, | ||
} from "./exceptions"; | ||
@@ -173,3 +173,3 @@ import { allocationsTransaction } from "./allocationsTransaction"; | ||
index | ||
) | ||
), | ||
]; | ||
@@ -294,3 +294,3 @@ | ||
externalArgs: ExternalArgs, | ||
dataViewCarrier: GlobalCarrier, | ||
globalCarrier: GlobalCarrier, | ||
entryPointer: number | ||
@@ -300,4 +300,4 @@ ): Array<any> { | ||
[], | ||
new ArrayWrapper(externalArgs, dataViewCarrier, entryPointer) | ||
new ArrayWrapper(externalArgs, globalCarrier, entryPointer) | ||
) as any; | ||
} |
@@ -9,3 +9,3 @@ import { | ||
MapEntry, | ||
SetEntry | ||
SetEntry, | ||
} from "./interfaces"; | ||
@@ -12,0 +12,0 @@ import { incrementRefCount, decrementRefCount, readEntry } from "./store"; |
@@ -38,3 +38,3 @@ import { ExternalArgs, GlobalCarrier, DateEntry } from "./interfaces"; | ||
"toLocaleDateString", | ||
"toLocaleTimeString" | ||
"toLocaleTimeString", | ||
]; | ||
@@ -58,3 +58,3 @@ | ||
"setUTCMonth", | ||
"setUTCSeconds" | ||
"setUTCSeconds", | ||
// "setYear" | ||
@@ -118,3 +118,3 @@ ]; | ||
refsCount: this.entry.refsCount, | ||
value: this.dateObjectForReuse.getTime() | ||
value: this.dateObjectForReuse.getTime(), | ||
}); | ||
@@ -121,0 +121,0 @@ } |
@@ -1,2 +0,1 @@ | ||
import * as util from "util"; | ||
import { createObjectBuffer } from ".."; | ||
@@ -9,5 +8,3 @@ import { externalArgsApiToExternalArgsApi } from "./utils"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
@@ -19,3 +16,3 @@ | ||
array: [1], | ||
object: {} | ||
object: {}, | ||
}); | ||
@@ -35,3 +32,3 @@ | ||
Object.defineProperty(objectBuffer.date, "propy", { | ||
enumerable: true | ||
enumerable: true, | ||
}); | ||
@@ -59,3 +56,3 @@ }).toThrowErrorMatchingInlineSnapshot(`"UnsupportedOperationError"`); | ||
array: [1], | ||
object: {} | ||
object: {}, | ||
}); | ||
@@ -92,3 +89,3 @@ | ||
array: [1], | ||
object: {} | ||
object: {}, | ||
}); | ||
@@ -99,3 +96,3 @@ | ||
configurable: false, | ||
enumerable: false | ||
enumerable: false, | ||
}); | ||
@@ -102,0 +99,0 @@ }).toThrowErrorMatchingInlineSnapshot(`"UnsupportedOperationError"`); |
@@ -29,3 +29,3 @@ import { createKnownTypeGuard } from "./utils"; | ||
SET, | ||
DATE | ||
DATE, | ||
} | ||
@@ -37,5 +37,5 @@ | ||
ENTRY_TYPE.BIGINT_NEGATIVE, | ||
ENTRY_TYPE.STRING | ||
ENTRY_TYPE.STRING, | ||
] as const; | ||
export const isPrimitiveEntryType = createKnownTypeGuard(PRIMITIVE_TYPES); |
@@ -15,3 +15,3 @@ import { ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
TRUE_KNOWN_ADDRESS, | ||
FALSE_KNOWN_ADDRESS | ||
FALSE_KNOWN_ADDRESS, | ||
} from "./consts"; | ||
@@ -27,3 +27,3 @@ | ||
[ENTRY_TYPE.MAP]: createMapWrapper, | ||
[ENTRY_TYPE.SET]: createSetWrapper | ||
[ENTRY_TYPE.SET]: createSetWrapper, | ||
} as const; | ||
@@ -65,3 +65,3 @@ | ||
) { | ||
const cache = getCacheFor(carrier, key => { | ||
const cache = getCacheFor(carrier, (key) => { | ||
finalizer(key, carrier, externalArgs); | ||
@@ -68,0 +68,0 @@ }); |
@@ -26,3 +26,7 @@ import { WeakValueMap } from "./WeakValueMap"; | ||
function supportWeakRef() { | ||
return typeof WeakRef !== "undefined"; | ||
return ( | ||
typeof WeakRef !== "undefined" && | ||
(typeof FinalizationGroup !== "undefined" || | ||
typeof "FinalizationRegistry" !== "undefined") | ||
); | ||
} |
/* eslint-env jest */ | ||
import * as util from "util"; | ||
import { MemPool } from "@thi.ng/malloc"; | ||
@@ -11,9 +10,7 @@ import { createObjectBuffer, memoryStats } from "./api"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
describe("getAllLinkedAddresses no reference counting", () => { | ||
test("getAllLinkedAddresses", () => { | ||
describe("Make sure all allocated are discovered", () => { | ||
test("Small object", () => { | ||
const allocatedAddresses: number[] = []; | ||
@@ -30,4 +27,74 @@ 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 }], | ||
}); | ||
@@ -49,7 +116,7 @@ | ||
expect(linkedAddresses.leafAddresses.slice().sort()).toEqual( | ||
expect([...linkedAddresses.leafAddresses].slice().sort()).toEqual( | ||
allocatedAddresses.slice().sort() | ||
); | ||
expect(linkedAddresses.leafAddresses.slice().sort()) | ||
expect([...linkedAddresses.leafAddresses].slice().sort()) | ||
.toMatchInlineSnapshot(` | ||
@@ -123,3 +190,3 @@ Array [ | ||
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 }], | ||
}); | ||
@@ -144,3 +211,3 @@ | ||
linkedAddresses.leafAddresses.forEach(address => { | ||
linkedAddresses.leafAddresses.forEach((address) => { | ||
pool.free(address); | ||
@@ -147,0 +214,0 @@ }); |
@@ -12,13 +12,31 @@ import { readEntry } from "./store"; | ||
) { | ||
const leafAddresses: number[] = []; | ||
const arcAddresses: number[] = []; | ||
const leafAddresses: Set<number> = new Set<number>(); | ||
const arcAddresses: Set<number> = new Set<number>(); | ||
const addressesToProcessQueue: number[] = [entryPointer]; | ||
getAllLinkedAddressesStep( | ||
carrier, | ||
ignoreRefCount, | ||
entryPointer, | ||
leafAddresses, | ||
arcAddresses | ||
); | ||
let addressToProcess: number | undefined = undefined; | ||
// const diffs = []; | ||
while ((addressToProcess = addressesToProcessQueue.shift()) !== undefined) { | ||
// const before = addressesToProcessQueue.slice(); | ||
if (addressToProcess === 0) { | ||
continue; | ||
} | ||
getAllLinkedAddressesStep( | ||
carrier, | ||
ignoreRefCount, | ||
addressToProcess, | ||
leafAddresses, | ||
arcAddresses, | ||
addressesToProcessQueue | ||
); | ||
// diffs.push(addressesToProcessQueue.filter((p) => !before.includes(p))); | ||
} | ||
// console.log(diffs); | ||
return { leafAddresses, arcAddresses }; | ||
@@ -31,6 +49,11 @@ } | ||
entryPointer: number, | ||
leafAddresses: number[], | ||
arcAddresses: number[] | ||
leafAddresses: Set<number>, | ||
arcAddresses: Set<number>, | ||
addressesToProcessQueue: number[] | ||
) { | ||
if (isKnownAddressValuePointer(entryPointer)) { | ||
if ( | ||
isKnownAddressValuePointer(entryPointer) || | ||
leafAddresses.has(entryPointer) || | ||
arcAddresses.has(entryPointer) | ||
) { | ||
return; | ||
@@ -46,3 +69,3 @@ } | ||
case ENTRY_TYPE.BIGINT_POSITIVE: | ||
leafAddresses.push(entryPointer); | ||
leafAddresses.add(entryPointer); | ||
break; | ||
@@ -54,12 +77,11 @@ | ||
if (entry.refsCount <= 1 || ignoreRefCount) { | ||
leafAddresses.push(entryPointer); | ||
leafAddresses.add(entryPointer); | ||
getObjectOrMapOrSetAddresses( | ||
carrier, | ||
ignoreRefCount, | ||
entry.value, | ||
leafAddresses, | ||
arcAddresses | ||
addressesToProcessQueue | ||
); | ||
} else { | ||
arcAddresses.push(entryPointer); | ||
arcAddresses.add(entryPointer); | ||
} | ||
@@ -71,4 +93,4 @@ | ||
if (entry.refsCount <= 1 || ignoreRefCount) { | ||
leafAddresses.push(entryPointer); | ||
leafAddresses.push(entry.value); | ||
leafAddresses.add(entryPointer); | ||
leafAddresses.add(entry.value); | ||
@@ -82,12 +104,6 @@ for (let i = 0; i < entry.allocatedLength; i += 1) { | ||
getAllLinkedAddressesStep( | ||
carrier, | ||
ignoreRefCount, | ||
valuePointer, | ||
leafAddresses, | ||
arcAddresses | ||
); | ||
addressesToProcessQueue.push(valuePointer); | ||
} | ||
} else { | ||
arcAddresses.push(entryPointer); | ||
arcAddresses.add(entryPointer); | ||
} | ||
@@ -98,5 +114,5 @@ break; | ||
if (entry.refsCount <= 1 || ignoreRefCount) { | ||
leafAddresses.push(entryPointer); | ||
leafAddresses.add(entryPointer); | ||
} else { | ||
arcAddresses.push(entryPointer); | ||
arcAddresses.add(entryPointer); | ||
} | ||
@@ -114,6 +130,5 @@ break; | ||
carrier: GlobalCarrier, | ||
ignoreRefCount: boolean, | ||
internalHashmapPointer: number, | ||
leafAddresses: number[], | ||
arcAddresses: number[] | ||
leafAddresses: Set<number>, | ||
addressesToProcessQueue: number[] | ||
) { | ||
@@ -125,13 +140,11 @@ const { pointersToValuePointers, pointers } = hashMapGetPointersToFree( | ||
leafAddresses.push(...pointers); | ||
for (const leafPointer of pointers) { | ||
leafAddresses.add(leafPointer); | ||
} | ||
for (const pointer of pointersToValuePointers) { | ||
getAllLinkedAddressesStep( | ||
carrier, | ||
ignoreRefCount, | ||
carrier.uint32[pointer / Uint32Array.BYTES_PER_ELEMENT], | ||
leafAddresses, | ||
arcAddresses | ||
addressesToProcessQueue.push( | ||
carrier.uint32[pointer / Uint32Array.BYTES_PER_ELEMENT] | ||
); | ||
} | ||
} |
/* eslint-env jest */ | ||
import * as util from "util"; | ||
import { | ||
arrayBuffer2HexArray, | ||
recordAllocations, | ||
makeCarrier | ||
makeCarrier, | ||
} from "../testUtils"; | ||
@@ -16,3 +16,3 @@ import { | ||
hashMapDelete, | ||
hashMapGetPointersToFree | ||
hashMapGetPointersToFree, | ||
} from "./hashmap"; | ||
@@ -25,5 +25,3 @@ import { GlobalCarrier, StringEntry } from "../interfaces"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
@@ -156,3 +154,3 @@ | ||
.map((i): number => i + "a".charCodeAt(0)) | ||
.map(n => String.fromCharCode(n)); | ||
.map((n) => String.fromCharCode(n)); | ||
@@ -187,3 +185,3 @@ const inserts: number[] = []; | ||
expect( | ||
values.map(v => (readEntry(carrier, v.keyPointer) as StringEntry).value) | ||
values.map((v) => (readEntry(carrier, v.keyPointer) as StringEntry).value) | ||
).toMatchInlineSnapshot(` | ||
@@ -230,3 +228,3 @@ Array [ | ||
.map((i): number => i + "a".charCodeAt(0)) | ||
.map(n => String.fromCharCode(n)); | ||
.map((n) => String.fromCharCode(n)); | ||
@@ -291,3 +289,3 @@ for (const [index, useThatAsKey] of input.entries()) { | ||
.map((i): number => i + "a".charCodeAt(0)) | ||
.map(n => String.fromCharCode(n)); | ||
.map((n) => String.fromCharCode(n)); | ||
const inputCopy = input.slice(); | ||
@@ -368,3 +366,3 @@ | ||
r.pointersToValuePointers | ||
.map(v => | ||
.map((v) => | ||
String.fromCharCode(carrier.uint32[v / Uint32Array.BYTES_PER_ELEMENT]) | ||
@@ -371,0 +369,0 @@ ) |
@@ -6,3 +6,3 @@ import { MAP_MACHINE, NODE_MACHINE } from "./memoryLayout"; | ||
NumberEntry, | ||
StringEntry | ||
StringEntry, | ||
} from "../interfaces"; | ||
@@ -12,3 +12,3 @@ import { | ||
hashCodeExternalValue, | ||
getKeyStartLength | ||
getKeyStartLength, | ||
} from "./hashmapUtils"; | ||
@@ -20,3 +20,3 @@ import { primitiveValueToEntry } from "../utils"; | ||
readEntry, | ||
compareStringOrNumberEntriesInPlace | ||
compareStringOrNumberEntriesInPlace, | ||
} from "../store"; | ||
@@ -30,3 +30,3 @@ import { ENTRY_TYPE } from "../entry-types"; | ||
linkedListGetValue, | ||
linkedListGetPointersToFree | ||
linkedListGetPointersToFree, | ||
} from "../linkedList/linkedList"; | ||
@@ -321,3 +321,3 @@ | ||
valuePointer: operator.pointerTo("VALUE_POINTER"), | ||
keyPointer: operator.get("KEY_POINTER") | ||
keyPointer: operator.get("KEY_POINTER"), | ||
}; | ||
@@ -357,3 +357,3 @@ } | ||
pointers, | ||
pointersToValuePointers | ||
pointersToValuePointers, | ||
}; | ||
@@ -360,0 +360,0 @@ } |
@@ -67,3 +67,3 @@ import { ENTRY_TYPE } from "../entry-types"; | ||
start: keyPointer + 1, | ||
length: Float64Array.BYTES_PER_ELEMENT | ||
length: Float64Array.BYTES_PER_ELEMENT, | ||
}; | ||
@@ -73,5 +73,5 @@ } else { | ||
start: keyPointer + 1 + 2 + 2, | ||
length: carrier.uint16[(keyPointer + 1) / Uint16Array.BYTES_PER_ELEMENT] | ||
length: carrier.uint16[(keyPointer + 1) / Uint16Array.BYTES_PER_ELEMENT], | ||
}; | ||
} | ||
} |
@@ -9,3 +9,3 @@ import { createMemoryMachine } from "../memoryMachinery"; | ||
CAPACITY: Uint8Array, | ||
USED_CAPACITY: Uint8Array | ||
USED_CAPACITY: Uint8Array, | ||
}); | ||
@@ -17,3 +17,3 @@ | ||
KEY_POINTER: Uint32Array, | ||
LINKED_LIST_ITEM_POINTER: Uint32Array | ||
LINKED_LIST_ITEM_POINTER: Uint32Array, | ||
}); | ||
@@ -20,0 +20,0 @@ |
import { ENTRY_TYPE } from "./entry-types"; | ||
import { TextDecoder, TextEncoder } from "./textEncoderDecoderTypes"; | ||
@@ -97,5 +96,7 @@ export type primitive = string | number | bigint | boolean | undefined | null; | ||
hashMapMinInitialCapacity: number; | ||
/** | ||
* Allocate additional memory for array pointers, | ||
* will prevent the reallocation and copy when array is getting bigger | ||
*/ | ||
arrayAdditionalAllocation: number; | ||
textDecoder: TextDecoder; | ||
textEncoder: TextEncoder; | ||
}>; | ||
@@ -107,4 +108,2 @@ | ||
arrayAdditionalAllocation?: number; | ||
textDecoder: TextDecoder; | ||
textEncoder: TextEncoder; | ||
}>; | ||
@@ -111,0 +110,0 @@ |
@@ -6,3 +6,3 @@ /* eslint-env jest */ | ||
recordAllocations, | ||
makeCarrier | ||
makeCarrier, | ||
} from "../testUtils"; | ||
@@ -20,3 +20,3 @@ | ||
linkedListGetValue, | ||
linkedListGetPointersToFree | ||
linkedListGetPointersToFree, | ||
// LINKED_LIST_ITEM_MACHINE | ||
@@ -104,3 +104,3 @@ } from "./linkedList"; | ||
linkedListItemInsert(carrier, linkedListPointer, 5), | ||
linkedListItemInsert(carrier, linkedListPointer, 4) | ||
linkedListItemInsert(carrier, linkedListPointer, 4), | ||
]; | ||
@@ -132,3 +132,3 @@ | ||
itemsPointers.forEach(p => linkedListItemRemove(carrier, p)); | ||
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p)); | ||
@@ -148,3 +148,3 @@ expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`); | ||
linkedListItemInsert(carrier, linkedListPointer, 5), | ||
linkedListItemInsert(carrier, linkedListPointer, 4) | ||
linkedListItemInsert(carrier, linkedListPointer, 4), | ||
]; | ||
@@ -183,3 +183,3 @@ | ||
itemsPointers.forEach(p => linkedListItemRemove(carrier, p)); | ||
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p)); | ||
@@ -200,3 +200,3 @@ expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`); | ||
linkedListItemInsert(carrier, linkedListPointer, 5), | ||
linkedListItemInsert(carrier, linkedListPointer, 4) | ||
linkedListItemInsert(carrier, linkedListPointer, 4), | ||
]; | ||
@@ -242,3 +242,3 @@ | ||
itemsPointers.forEach(p => linkedListItemRemove(carrier, p)); | ||
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p)); | ||
@@ -256,3 +256,3 @@ expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`); | ||
linkedListItemInsert(carrier, linkedListPointer, 7), | ||
linkedListItemInsert(carrier, linkedListPointer, 6) | ||
linkedListItemInsert(carrier, linkedListPointer, 6), | ||
]; | ||
@@ -302,3 +302,3 @@ | ||
itemsPointers.forEach(p => linkedListItemRemove(carrier, p)); | ||
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p)); | ||
@@ -305,0 +305,0 @@ const iteratorPointerToFree = 0; |
@@ -21,3 +21,3 @@ import { createMemoryMachine } from "../memoryMachinery"; | ||
NEXT_POINTER: Uint32Array, | ||
VALUE: Uint32Array | ||
VALUE: Uint32Array, | ||
}); | ||
@@ -31,3 +31,3 @@ | ||
END_POINTER: Uint32Array, | ||
START_POINTER: Uint32Array | ||
START_POINTER: Uint32Array, | ||
}); | ||
@@ -202,4 +202,4 @@ export type LinkedListMachineType = ReturnType< | ||
pointers, | ||
valuePointers | ||
valuePointers, | ||
}; | ||
} |
@@ -5,3 +5,3 @@ import { | ||
MapEntry, | ||
InternalAPI | ||
InternalAPI, | ||
} from "./interfaces"; | ||
@@ -12,3 +12,3 @@ import { | ||
objectSet, | ||
mapOrSetClear | ||
mapOrSetClear, | ||
} from "./objectWrapperHelpers"; | ||
@@ -24,3 +24,3 @@ | ||
hashMapNodePointerToKeyValue, | ||
hashmapNodesPointerIterator | ||
hashmapNodesPointerIterator, | ||
} from "./hashmap/hashmap"; | ||
@@ -73,3 +73,3 @@ import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue"; | ||
this.carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT] | ||
) | ||
), | ||
]; | ||
@@ -168,6 +168,6 @@ } | ||
externalArgs: ExternalArgs, | ||
dataViewCarrier: GlobalCarrier, | ||
globalCarrier: GlobalCarrier, | ||
entryPointer: number | ||
): Map<K, V> { | ||
return new MapWrapper<K, V>(externalArgs, dataViewCarrier, entryPointer); | ||
return new MapWrapper<K, V>(externalArgs, globalCarrier, entryPointer); | ||
} |
@@ -5,3 +5,3 @@ /* eslint-env jest */ | ||
createMemoryOperator, | ||
_buildMemoryLayout | ||
_buildMemoryLayout, | ||
} from "./memoryMachinery"; | ||
@@ -15,3 +15,3 @@ import { arrayBuffer2HexArray, makeCarrier } from "./testUtils"; | ||
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,3 +54,3 @@ ).toEqual(Object.entries(input)); | ||
POINTER_TO_NODE: Uint32Array, | ||
LENGTH_OF_KEY: Uint32Array | ||
LENGTH_OF_KEY: Uint32Array, | ||
}); | ||
@@ -194,3 +194,3 @@ | ||
POINTER_TO_NODE: Uint32Array, | ||
LENGTH_OF_KEY: Uint32Array | ||
LENGTH_OF_KEY: Uint32Array, | ||
}); | ||
@@ -215,3 +215,3 @@ | ||
NODE_KEY_POINTER: Uint32Array.BYTES_PER_ELEMENT, | ||
NODE_KEY_LENGTH: Uint16Array.BYTES_PER_ELEMENT | ||
NODE_KEY_LENGTH: Uint16Array.BYTES_PER_ELEMENT, | ||
}); | ||
@@ -218,0 +218,0 @@ |
@@ -7,3 +7,3 @@ import { GlobalCarrier } from "./interfaces"; | ||
// BigUint64Array, | ||
Uint16Array | ||
Uint16Array, | ||
] as const; | ||
@@ -38,3 +38,3 @@ | ||
// [BigUint64Array, dataViewInstance.getBigUint64, dataViewInstance.setBigUint64], | ||
[Uint16Array, "uint16"] | ||
[Uint16Array, "uint16"], | ||
] as const; | ||
@@ -49,3 +49,3 @@ | ||
const READ_WRITE_MAP_V2 = new Map(READ_WRITE_MAPS_V2.map(e => [e[0], e[1]])); | ||
const READ_WRITE_MAP_V2 = new Map(READ_WRITE_MAPS_V2.map((e) => [e[0], e[1]])); | ||
@@ -93,3 +93,3 @@ export interface MemoryOperator<T extends string> { | ||
}, | ||
size: memoryMap.SIZE_OF | ||
size: memoryMap.SIZE_OF, | ||
}; | ||
@@ -117,4 +117,4 @@ } | ||
(oldEntries[index - 1][1] as any).BYTES_PER_ELEMENT, | ||
type: type as any | ||
} | ||
type: type as any, | ||
}, | ||
]); | ||
@@ -128,3 +128,3 @@ } | ||
(oldEntries[newObjectEntries.length - 1][1] as TypedArrayCtor) | ||
.BYTES_PER_ELEMENT | ||
.BYTES_PER_ELEMENT, | ||
]); | ||
@@ -145,3 +145,3 @@ | ||
address: number | ||
) => MemoryOperator<T> | ||
) => MemoryOperator<T>, | ||
}; | ||
@@ -162,3 +162,3 @@ } | ||
key, | ||
newObjectEntries[index - 1][1] + oldEntries[index - 1][1] | ||
newObjectEntries[index - 1][1] + oldEntries[index - 1][1], | ||
]); | ||
@@ -171,3 +171,3 @@ } | ||
newObjectEntries[newObjectEntries.length - 1][1] + | ||
oldEntries[newObjectEntries.length - 1][1] | ||
oldEntries[newObjectEntries.length - 1][1], | ||
]); | ||
@@ -174,0 +174,0 @@ |
/* eslint-env jest */ | ||
import { initializeArrayBuffer } from "./store"; | ||
import * as util from "util"; | ||
import { createArrayWrapper } from "./arrayWrapper"; | ||
@@ -12,5 +12,3 @@ import { arraySaver } from "./arraySaver"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
@@ -17,0 +15,0 @@ |
/* eslint-env jest */ | ||
import { initializeArrayBuffer } from "./store"; | ||
import * as util from "util"; | ||
import { arrayBuffer2HexArray, makeCarrier } from "./testUtils"; | ||
@@ -10,6 +10,3 @@ import { objectSaver } from "./objectSaver"; | ||
describe("objectSaver tests", () => { | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder() | ||
}); | ||
const externalArgs = externalArgsApiToExternalArgsApi({}); | ||
@@ -31,7 +28,13 @@ describe("objectSaver - general", () => { | ||
nestedObject: { | ||
nestedProp: 7 | ||
} | ||
nestedProp: 7, | ||
}, | ||
}; | ||
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave); | ||
const saverOutput = objectSaver( | ||
externalArgs, | ||
carrier, | ||
[], | ||
new Map(), | ||
objectToSave | ||
); | ||
@@ -38,0 +41,0 @@ expect(saverOutput).toMatchInlineSnapshot(`976`); |
@@ -8,3 +8,3 @@ import { appendEntry } from "./store"; | ||
MapEntry, | ||
SetEntry | ||
SetEntry, | ||
} from "./interfaces"; | ||
@@ -18,2 +18,3 @@ import { saveValue } from "./saveValue"; | ||
referencedPointers: number[], | ||
visitedValues: Map<object, number>, | ||
objectToSave: any | ||
@@ -25,3 +26,6 @@ ) { | ||
carrier, | ||
Math.max(externalArgs.hashMapMinInitialCapacity, objectEntries.length * 1.3) | ||
Math.max( | ||
externalArgs.hashMapMinInitialCapacity, | ||
Math.ceil(objectEntries.length * 1.3) | ||
) | ||
); | ||
@@ -41,2 +45,3 @@ | ||
referencedPointers, | ||
visitedValues, | ||
value | ||
@@ -51,3 +56,3 @@ ); | ||
refsCount: 1, | ||
value: hashMapPointer | ||
value: hashMapPointer, | ||
}; | ||
@@ -62,2 +67,3 @@ | ||
referencedPointers: number[], | ||
visitedValues: Map<object, number>, | ||
mapToSave: Map<string | number, any> | ||
@@ -67,3 +73,6 @@ ) { | ||
carrier, | ||
Math.max(externalArgs.hashMapMinInitialCapacity, mapToSave.size * 1.3) | ||
Math.max( | ||
externalArgs.hashMapMinInitialCapacity, | ||
Math.ceil(mapToSave.size * 1.3) | ||
) | ||
); | ||
@@ -83,2 +92,3 @@ | ||
referencedPointers, | ||
visitedValues, | ||
value | ||
@@ -93,3 +103,3 @@ ); | ||
refsCount: 1, | ||
value: hashMapPointer | ||
value: hashMapPointer, | ||
}; | ||
@@ -107,3 +117,6 @@ | ||
carrier, | ||
Math.max(externalArgs.hashMapMinInitialCapacity, setToSave.size * 1.3) | ||
Math.max( | ||
externalArgs.hashMapMinInitialCapacity, | ||
Math.ceil(setToSave.size * 1.3) | ||
) | ||
); | ||
@@ -125,3 +138,3 @@ | ||
refsCount: 1, | ||
value: hashMapPointer | ||
value: hashMapPointer, | ||
}; | ||
@@ -128,0 +141,0 @@ |
/* eslint-env jest */ | ||
import { initializeArrayBuffer } from "./store"; | ||
import * as util from "util"; | ||
import { objectSaver } from "./objectSaver"; | ||
@@ -11,6 +11,3 @@ import { createObjectWrapper } from "./objectWrapper"; | ||
describe("objectWrapper tests", () => { | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder() | ||
}); | ||
const externalArgs = externalArgsApiToExternalArgsApi({}); | ||
@@ -29,7 +26,13 @@ describe("objectWrapper - general", () => { | ||
nestedObject: { | ||
nestedProp: 7 | ||
} | ||
nestedProp: 7, | ||
}, | ||
}; | ||
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave); | ||
const saverOutput = objectSaver( | ||
externalArgs, | ||
carrier, | ||
[], | ||
new Map(), | ||
objectToSave | ||
); | ||
@@ -73,7 +76,13 @@ const objectWrapper: any = createObjectWrapper( | ||
nestedObject: { | ||
nestedProp: 7 | ||
} | ||
nestedProp: 7, | ||
}, | ||
}; | ||
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave); | ||
const saverOutput = objectSaver( | ||
externalArgs, | ||
carrier, | ||
[], | ||
new Map(), | ||
objectToSave | ||
); | ||
@@ -104,7 +113,13 @@ const objectWrapper: any = createObjectWrapper( | ||
nestedObject: { | ||
nestedProp: 7 | ||
} | ||
nestedProp: 7, | ||
}, | ||
}; | ||
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave); | ||
const saverOutput = objectSaver( | ||
externalArgs, | ||
carrier, | ||
[], | ||
new Map(), | ||
objectToSave | ||
); | ||
@@ -146,7 +161,13 @@ const objectWrapper = createObjectWrapper( | ||
nestedObject: { | ||
nestedProp: 7 | ||
} | ||
nestedProp: 7, | ||
}, | ||
}; | ||
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave); | ||
const saverOutput = objectSaver( | ||
externalArgs, | ||
carrier, | ||
[], | ||
new Map(), | ||
objectToSave | ||
); | ||
@@ -189,7 +210,13 @@ const objectWrapper = createObjectWrapper( | ||
nestedObject: { | ||
nestedProp: 7 | ||
} | ||
nestedProp: 7, | ||
}, | ||
}; | ||
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave); | ||
const saverOutput = objectSaver( | ||
externalArgs, | ||
carrier, | ||
[], | ||
new Map(), | ||
objectToSave | ||
); | ||
@@ -196,0 +223,0 @@ const objectWrapper = createObjectWrapper( |
@@ -6,3 +6,3 @@ import { ObjectEntry, ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
objectGet, | ||
objectSet | ||
objectSet, | ||
} from "./objectWrapperHelpers"; | ||
@@ -13,3 +13,3 @@ | ||
IllegalObjectPropConfigError, | ||
UnsupportedOperationError | ||
UnsupportedOperationError, | ||
} from "./exceptions"; | ||
@@ -53,3 +53,3 @@ import { allocationsTransaction } from "./allocationsTransaction"; | ||
return gotEntries.map(e => e.key); | ||
return gotEntries.map((e) => e.key); | ||
} | ||
@@ -63,3 +63,3 @@ | ||
return gotEntries.map(e => e.key); | ||
return gotEntries.map((e) => e.key); | ||
} | ||
@@ -131,3 +131,3 @@ | ||
externalArgs: ExternalArgs, | ||
dataViewCarrier: GlobalCarrier, | ||
globalCarrier: GlobalCarrier, | ||
entryPointer: number | ||
@@ -137,4 +137,4 @@ ): T { | ||
{ objectBufferWrapper: "objectBufferWrapper" }, | ||
new ObjectWrapper(externalArgs, dataViewCarrier, entryPointer) | ||
new ObjectWrapper(externalArgs, globalCarrier, entryPointer) | ||
) as any; | ||
} |
/* eslint-env jest */ | ||
import { initializeArrayBuffer, readEntry } from "./store"; | ||
import * as util from "util"; | ||
import { objectSaver } from "./objectSaver"; | ||
import { | ||
getObjectPropertiesEntries, | ||
deleteObjectPropertyEntryByKey | ||
deleteObjectPropertyEntryByKey, | ||
} from "./objectWrapperHelpers"; | ||
@@ -16,5 +16,3 @@ import { externalArgsApiToExternalArgsApi } from "./utils"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
@@ -33,7 +31,13 @@ | ||
nestedObject: { | ||
nestedProp: 7 | ||
} | ||
nestedProp: 7, | ||
}, | ||
}; | ||
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave); | ||
const saverOutput = objectSaver( | ||
externalArgs, | ||
carrier, | ||
[], | ||
new Map(), | ||
objectToSave | ||
); | ||
@@ -80,6 +84,12 @@ const hashmapPointer = (readEntry(carrier, saverOutput) as ObjectEntry) | ||
c: undefined, | ||
d: null | ||
d: null, | ||
}; | ||
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave); | ||
const saverOutput = objectSaver( | ||
externalArgs, | ||
carrier, | ||
[], | ||
new Map(), | ||
objectToSave | ||
); | ||
@@ -130,6 +140,12 @@ expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`40`); | ||
c: undefined, | ||
d: null | ||
d: null, | ||
}; | ||
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave); | ||
const saverOutput = objectSaver( | ||
externalArgs, | ||
carrier, | ||
[], | ||
new Map(), | ||
objectToSave | ||
); | ||
@@ -179,6 +195,12 @@ expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`40`); | ||
d: null, | ||
e: 66 | ||
e: 66, | ||
}; | ||
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave); | ||
const saverOutput = objectSaver( | ||
externalArgs, | ||
carrier, | ||
[], | ||
new Map(), | ||
objectToSave | ||
); | ||
// expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`8`); | ||
@@ -185,0 +207,0 @@ |
@@ -7,3 +7,3 @@ import { | ||
MapEntry, | ||
SetEntry | ||
SetEntry, | ||
} from "./interfaces"; | ||
@@ -15,3 +15,4 @@ import { | ||
decrementRefCount, | ||
writeEntry | ||
writeEntry, | ||
setRefCount, | ||
} from "./store"; | ||
@@ -25,5 +26,5 @@ import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue"; | ||
hashMapValueLookup, | ||
createHashMap | ||
createHashMap, | ||
} from "./hashmap/hashmap"; | ||
import { getObjectOrMapOrSetAddresses } from "./getAllLinkedAddresses"; | ||
import { getAllLinkedAddresses } from "./getAllLinkedAddresses"; | ||
@@ -79,3 +80,3 @@ export function deleteObjectPropertyEntryByKey( | ||
carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT], | ||
key: keyEntry.value | ||
key: keyEntry.value, | ||
}); | ||
@@ -123,19 +124,49 @@ } | ||
export function hashmapClearFree( | ||
// export function hashmapClearFree( | ||
// externalArgs: ExternalArgs, | ||
// carrier: GlobalCarrier, | ||
// hashmapPointer: number | ||
// ) { | ||
// const leafAddresses = new Set<number>(); | ||
// const addressesToProcessQueue: number[] = []; | ||
// getObjectOrMapOrSetAddresses( | ||
// carrier, | ||
// hashmapPointer, | ||
// leafAddresses, | ||
// addressesToProcessQueue | ||
// ); | ||
// for (const address of leafAddresses) { | ||
// carrier.allocator.free(address); | ||
// } | ||
// for (const address of arcAddresses) { | ||
// decrementRefCount(externalArgs, carrier, address); | ||
// } | ||
// } | ||
export function mapOrSetClear( | ||
externalArgs: ExternalArgs, | ||
carrier: GlobalCarrier, | ||
hashmapPointer: number | ||
mapOrSetPtr: number | ||
) { | ||
const leafAddresses: number[] = []; | ||
const arcAddresses: number[] = []; | ||
const entry = readEntry(carrier, mapOrSetPtr) as MapEntry | SetEntry; | ||
getObjectOrMapOrSetAddresses( | ||
// 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, | ||
hashmapPointer, | ||
leafAddresses, | ||
arcAddresses | ||
mapOrSetPtr | ||
); | ||
for (const address of leafAddresses) { | ||
// don't dispose the address we need to reuse | ||
if (address === mapOrSetPtr) { | ||
continue; | ||
} | ||
carrier.allocator.free(address); | ||
@@ -145,14 +176,14 @@ } | ||
for (const address of arcAddresses) { | ||
// don't dispose the address we need to reuse | ||
if (address === mapOrSetPtr) { | ||
continue; | ||
} | ||
decrementRefCount(externalArgs, carrier, address); | ||
} | ||
} | ||
export function mapOrSetClear( | ||
externalArgs: ExternalArgs, | ||
carrier: GlobalCarrier, | ||
mapOrSetPtr: number | ||
) { | ||
const entry = readEntry(carrier, mapOrSetPtr) as MapEntry | SetEntry; | ||
// hashmapClearFree(externalArgs, carrier, entry.value); | ||
hashmapClearFree(externalArgs, carrier, entry.value); | ||
// Restore real ref count | ||
setRefCount(carrier, mapOrSetPtr, prevCount); | ||
@@ -159,0 +190,0 @@ entry.value = createHashMap(carrier, externalArgs.hashMapMinInitialCapacity); |
import { | ||
primitiveValueToEntry, | ||
isPrimitive, | ||
getOurPointerIfApplicable | ||
getOurPointerIfApplicable, | ||
} from "./utils"; | ||
@@ -15,3 +15,3 @@ import { appendEntry } from "./store"; | ||
TRUE_KNOWN_ADDRESS, | ||
FALSE_KNOWN_ADDRESS | ||
FALSE_KNOWN_ADDRESS, | ||
} from "./consts"; | ||
@@ -26,2 +26,4 @@ | ||
referencedPointers: number[], | ||
// Not really working yet. we need iterative saving for it | ||
visitedValuesOnCurrentSaveOperation: Map<object, number>, | ||
value: any | ||
@@ -56,2 +58,7 @@ ) { | ||
referencedPointers.push(valuePointer); | ||
} else if ( | ||
(maybeOurPointer = visitedValuesOnCurrentSaveOperation.get(value)) | ||
) { | ||
valuePointer = maybeOurPointer; | ||
referencedPointers.push(valuePointer); | ||
} else if (Array.isArray(value)) { | ||
@@ -63,8 +70,16 @@ valuePointer = arraySaver(externalArgs, carrier, referencedPointers, value); | ||
refsCount: 1, | ||
value: value.getTime() | ||
value: value.getTime(), | ||
}); | ||
} else if (value instanceof Map) { | ||
valuePointer = mapSaver(externalArgs, carrier, referencedPointers, value); | ||
valuePointer = mapSaver( | ||
externalArgs, | ||
carrier, | ||
referencedPointers, | ||
visitedValuesOnCurrentSaveOperation, | ||
value | ||
); | ||
visitedValuesOnCurrentSaveOperation.set(value, valuePointer); | ||
} else if (value instanceof Set) { | ||
valuePointer = setSaver(externalArgs, carrier, value); | ||
visitedValuesOnCurrentSaveOperation.set(value, valuePointer); | ||
} else if (typeof value === "object") { | ||
@@ -75,4 +90,6 @@ valuePointer = objectSaver( | ||
referencedPointers, | ||
visitedValuesOnCurrentSaveOperation, | ||
value | ||
); | ||
visitedValuesOnCurrentSaveOperation.set(value, valuePointer); | ||
} else { | ||
@@ -79,0 +96,0 @@ throw new Error("unsupported yet"); |
@@ -5,3 +5,3 @@ import { | ||
MapEntry, | ||
InternalAPI | ||
InternalAPI, | ||
} from "./interfaces"; | ||
@@ -11,3 +11,3 @@ import { | ||
objectSet, | ||
mapOrSetClear | ||
mapOrSetClear, | ||
} from "./objectWrapperHelpers"; | ||
@@ -23,3 +23,3 @@ | ||
hashMapNodePointerToKeyValue, | ||
hashmapNodesPointerIterator | ||
hashmapNodesPointerIterator, | ||
} from "./hashmap/hashmap"; | ||
@@ -152,6 +152,6 @@ import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue"; | ||
externalArgs: ExternalArgs, | ||
dataViewCarrier: GlobalCarrier, | ||
globalCarrier: GlobalCarrier, | ||
entryPointer: number | ||
): Set<K> { | ||
return new SetWrapper<K>(externalArgs, dataViewCarrier, entryPointer); | ||
return new SetWrapper<K>(externalArgs, globalCarrier, entryPointer); | ||
} |
/* eslint-env jest */ | ||
import * as util from "util"; | ||
import { sizeOf } from "./sizeOf"; | ||
@@ -10,5 +9,3 @@ import { externalArgsApiToExternalArgsApi } from "./utils"; | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
@@ -28,3 +25,3 @@ | ||
calcedSize, | ||
realSize: beforeSave - afterSave | ||
realSize: beforeSave - afterSave, | ||
}; | ||
@@ -31,0 +28,0 @@ } |
@@ -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, | ||
}; | ||
@@ -110,3 +110,3 @@ } | ||
refsCount: 0, | ||
value: 0 | ||
value: 0, | ||
}; | ||
@@ -119,3 +119,3 @@ | ||
memoryAllocated, | ||
numberOfAllocations | ||
numberOfAllocations, | ||
}; | ||
@@ -136,3 +136,3 @@ } | ||
memoryAllocated: 0, | ||
numberOfAllocations: 0 | ||
numberOfAllocations: 0, | ||
}; | ||
@@ -146,3 +146,3 @@ } | ||
memoryAllocated: align(sizeOfEntry(entry)), | ||
numberOfAllocations: 1 | ||
numberOfAllocations: 1, | ||
}; | ||
@@ -157,6 +157,6 @@ } else if (Array.isArray(value)) { | ||
refsCount: 0, | ||
value: value.getTime() | ||
value: value.getTime(), | ||
}) | ||
), | ||
numberOfAllocations: 1 | ||
numberOfAllocations: 1, | ||
}; | ||
@@ -197,3 +197,3 @@ } else if (typeof value === "object") { | ||
const hashMapKeysSize = keysArray | ||
.map(k => sizeOfEntry(primitiveValueToEntry(k))) | ||
.map((k) => sizeOfEntry(primitiveValueToEntry(k))) | ||
.reduce((p, c) => { | ||
@@ -215,4 +215,4 @@ return p + align(c); | ||
hashMapNodesAllocationsSize + | ||
hashMapKeysSize | ||
hashMapKeysSize, | ||
}; | ||
} |
@@ -7,6 +7,6 @@ /* eslint-env jest */ | ||
readEntry, | ||
appendEntry | ||
appendEntry, | ||
} from "./store"; | ||
import { ENTRY_TYPE } from "./entry-types"; | ||
import * as util from "util"; | ||
import { arrayBuffer2HexArray, makeCarrier } from "./testUtils"; | ||
@@ -56,3 +56,3 @@ import { ObjectEntry } from "./interfaces"; | ||
type: ENTRY_TYPE.NUMBER, | ||
value: Number.MAX_VALUE | ||
value: Number.MAX_VALUE, | ||
}); | ||
@@ -89,3 +89,3 @@ | ||
type: ENTRY_TYPE.NUMBER, | ||
value: Number.MIN_VALUE | ||
value: Number.MIN_VALUE, | ||
}); | ||
@@ -124,3 +124,3 @@ | ||
value: "aא弟", | ||
allocatedBytes: 6 | ||
allocatedBytes: 6, | ||
}); | ||
@@ -157,5 +157,3 @@ | ||
const externalArgs = externalArgsApiToExternalArgsApi({ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
@@ -169,3 +167,3 @@ | ||
type: ENTRY_TYPE.NUMBER, | ||
value: Number.MAX_VALUE | ||
value: Number.MAX_VALUE, | ||
}); | ||
@@ -191,3 +189,3 @@ | ||
type: ENTRY_TYPE.NUMBER, | ||
value: Number.MIN_VALUE | ||
value: Number.MIN_VALUE, | ||
}); | ||
@@ -212,3 +210,3 @@ | ||
value: "aא弟", | ||
allocatedBytes: 6 | ||
allocatedBytes: 6, | ||
}); | ||
@@ -233,3 +231,3 @@ | ||
type: ENTRY_TYPE.BIGINT_POSITIVE, | ||
value: BigInt("0b0" + "1".repeat(63)) | ||
value: BigInt("0b0" + "1".repeat(63)), | ||
}); | ||
@@ -253,3 +251,3 @@ | ||
type: ENTRY_TYPE.BIGINT_POSITIVE, | ||
value: BigInt("0b" + "1".repeat(64)) | ||
value: BigInt("0b" + "1".repeat(64)), | ||
}); | ||
@@ -272,3 +270,3 @@ | ||
type: ENTRY_TYPE.BIGINT_POSITIVE, | ||
value: BigInt("0b" + "1".repeat(64)) | ||
value: BigInt("0b" + "1".repeat(64)), | ||
}); | ||
@@ -290,3 +288,3 @@ | ||
type: ENTRY_TYPE.BIGINT_NEGATIVE, | ||
value: -BigInt("0b" + "1".repeat(64)) | ||
value: -BigInt("0b" + "1".repeat(64)), | ||
}); | ||
@@ -309,3 +307,3 @@ | ||
type: ENTRY_TYPE.BIGINT_POSITIVE, | ||
value: BigInt("0b" + "1".repeat(65)) | ||
value: BigInt("0b" + "1".repeat(65)), | ||
}); | ||
@@ -323,3 +321,3 @@ }).toThrowErrorMatchingInlineSnapshot(`"BigInt64OverflowError"`); | ||
refsCount: 0, | ||
value: 10 | ||
value: 10, | ||
}; | ||
@@ -351,3 +349,3 @@ | ||
value: "im a string", | ||
allocatedBytes: 11 | ||
allocatedBytes: 11, | ||
}); | ||
@@ -354,0 +352,0 @@ |
@@ -6,3 +6,3 @@ import { ENTRY_TYPE, isPrimitiveEntryType } from "./entry-types"; | ||
primitiveValueToEntry, | ||
isKnownAddressValuePointer | ||
isKnownAddressValuePointer, | ||
} from "./utils"; | ||
@@ -13,3 +13,3 @@ import { ExternalArgs } from "./interfaces"; | ||
INITIAL_ENTRY_POINTER_TO_POINTER, | ||
INITIAL_ENTRY_POINTER_VALUE | ||
INITIAL_ENTRY_POINTER_VALUE, | ||
} from "./consts"; | ||
@@ -134,3 +134,3 @@ import { saveValue } from "./saveValue"; | ||
writtenBytes, | ||
allocatedBytes: entry.allocatedBytes | ||
allocatedBytes: entry.allocatedBytes, | ||
}, | ||
@@ -218,3 +218,3 @@ true | ||
type: entryType, | ||
value: undefined as any | ||
value: undefined as any, | ||
}; | ||
@@ -369,2 +369,3 @@ | ||
referencedPointers, | ||
new Map(), | ||
value | ||
@@ -378,3 +379,3 @@ ); | ||
existingEntryPointer, | ||
existingValueEntry | ||
existingValueEntry, | ||
}; | ||
@@ -393,3 +394,3 @@ } | ||
existingEntryPointer = 0, | ||
referencedPointers = [] | ||
referencedPointers = [], | ||
} = writeValueInPtrToPtr(externalArgs, carrier, ptrToPtr, value) || {}; | ||
@@ -502,2 +503,29 @@ | ||
export function getRefCount(carrier: GlobalCarrier, entryPointer: number) { | ||
const entry = readEntry(carrier, entryPointer); | ||
if ("refsCount" in entry) { | ||
return entry.refsCount; | ||
} | ||
throw new Error("unexpected"); | ||
} | ||
export function setRefCount( | ||
carrier: GlobalCarrier, | ||
entryPointer: number, | ||
newRefCount: number | ||
) { | ||
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( | ||
@@ -504,0 +532,0 @@ // { dataView }: GlobalCarrier, |
@@ -19,4 +19,4 @@ /* eslint-env jest */ | ||
`請教「署」在文中的含義。 文句中「署」是什么意思?「使直言署」,及下文的「署帛宛然」a`, | ||
125 | ||
] | ||
125, | ||
], | ||
]; | ||
@@ -23,0 +23,0 @@ |
@@ -21,4 +21,4 @@ /* eslint-env jest */ | ||
`請教「署」在文中的含義。 文句中「署」是什么意思?「使直言署」,及下文的「署帛宛然」`, | ||
124 | ||
] | ||
124, | ||
], | ||
]; | ||
@@ -25,0 +25,0 @@ |
@@ -17,3 +17,3 @@ export function arrayBuffer2HexArray( | ||
export function wait(time: number) { | ||
return new Promise(res => { | ||
return new Promise((res) => { | ||
// eslint-disable-next-line no-undef | ||
@@ -102,3 +102,3 @@ setTimeout(res, time); | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -113,3 +113,3 @@ | ||
float64: new Float64Array(arrayBuffer), | ||
bigUint64: new BigUint64Array(arrayBuffer) | ||
bigUint64: new BigUint64Array(arrayBuffer), | ||
}; | ||
@@ -116,0 +116,0 @@ |
@@ -6,3 +6,3 @@ import { | ||
InternalAPI, | ||
ExternalArgsApi | ||
ExternalArgsApi, | ||
} from "./interfaces"; | ||
@@ -15,3 +15,3 @@ import { ENTRY_TYPE } from "./entry-types"; | ||
TRUE_KNOWN_ADDRESS, | ||
FALSE_KNOWN_ADDRESS | ||
FALSE_KNOWN_ADDRESS, | ||
} from "./consts"; | ||
@@ -25,3 +25,3 @@ import { IMemPool } from "@thi.ng/malloc"; | ||
"boolean", | ||
"undefined" | ||
"undefined", | ||
] as const; | ||
@@ -46,3 +46,3 @@ | ||
value, | ||
allocatedBytes: strByteLength(value) | ||
allocatedBytes: strByteLength(value), | ||
}; | ||
@@ -54,3 +54,3 @@ } | ||
type: ENTRY_TYPE.NUMBER, | ||
value | ||
value, | ||
}; | ||
@@ -65,3 +65,3 @@ } | ||
: ENTRY_TYPE.BIGINT_NEGATIVE, | ||
value | ||
value, | ||
}; | ||
@@ -118,3 +118,3 @@ } | ||
? p.arrayAdditionalAllocation | ||
: 0 | ||
: 0, | ||
}; | ||
@@ -121,0 +121,0 @@ } |
@@ -6,2 +6,3 @@ const KEYS = 1; | ||
declare const FinalizationGroup: any; | ||
declare const FinalizationRegistry: any; | ||
declare const WeakRef: any; | ||
@@ -25,3 +26,8 @@ | ||
this.group = new FinalizationGroup((iterator: Iterable<any>) => { | ||
const FinalizationSomething = | ||
typeof FinalizationRegistry !== "undefined" | ||
? FinalizationRegistry | ||
: FinalizationGroup; | ||
this.group = new FinalizationSomething((iterator: Iterable<any>) => { | ||
for (const key of iterator) { | ||
@@ -28,0 +34,0 @@ this.map.delete(key); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is 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
817546
21200
118
35
198
Updated@thi.ng/malloc@^4.1.10