@bnaya/objectbuffer
Advanced tools
Comparing version 0.0.0-738fce6 to 0.0.0-7d79fe6
@@ -9,3 +9,3 @@ /** | ||
*/ /** */ | ||
export { createObjectBuffer, resizeObjectBuffer, getUnderlyingArrayBuffer, loadObjectBuffer, replaceUnderlyingArrayBuffer, sizeOf as unreliable_sizeOf, memoryStats, disposeWrapperObject, updateExternalArgs } from "./internal/api"; | ||
export { createObjectBuffer, resizeObjectBuffer, getUnderlyingArrayBuffer, loadObjectBuffer, replaceUnderlyingArrayBuffer, sizeOf as unreliable_sizeOf, memoryStats, disposeWrapperObject, updateExternalArgs, } from "./internal/api"; | ||
export { acquireLock, acquireLockWait, releaseLock } from "./internal/locks"; | ||
@@ -12,0 +12,0 @@ export declare type ExternalArgs = import("./internal/interfaces").ExternalArgsApi; |
import { initializeArrayBuffer } from "./store"; | ||
import { objectSaver } from "./objectSaver"; | ||
import { createObjectWrapper } from "./objectWrapper"; | ||
import { arrayBufferCopyTo, externalArgsApiToExternalArgsApi, getInternalAPI } from "./utils"; | ||
import { arrayBufferCopyTo, externalArgsApiToExternalArgsApi, getInternalAPI, isPrimitive } from "./utils"; | ||
import { getCacheFor } from "./externalObjectsCache"; | ||
import { INITIAL_ENTRY_POINTER_TO_POINTER, MEM_POOL_START } from "./consts"; | ||
import { MemPool } from "@thi.ng/malloc"; | ||
import { UnsupportedOperationError } from "./exceptions"; | ||
@@ -15,5 +16,10 @@ /** | ||
export function createObjectBuffer(externalArgs, size, initialValue, options = {}) { | ||
if (Array.isArray(initialValue) || initialValue instanceof Date || initialValue instanceof Map || initialValue instanceof Set || isPrimitive(initialValue)) { | ||
throw new UnsupportedOperationError(); | ||
} | ||
const arrayBuffer = new (options.useSharedArrayBuffer ? SharedArrayBuffer : ArrayBuffer)(size); | ||
const dataView = initializeArrayBuffer(arrayBuffer); | ||
initializeArrayBuffer(arrayBuffer); | ||
const allocator = new MemPool({ | ||
align: 8, | ||
buf: arrayBuffer, | ||
@@ -23,3 +29,3 @@ start: MEM_POOL_START | ||
const carrier = { | ||
dataView, | ||
// dataView, | ||
allocator, | ||
@@ -33,3 +39,3 @@ uint8: new Uint8Array(arrayBuffer), | ||
const start = objectSaver(externalArgsApiToExternalArgsApi(externalArgs), carrier, [], initialValue); | ||
dataView.setUint32(INITIAL_ENTRY_POINTER_TO_POINTER, start); | ||
carrier.uint32[INITIAL_ENTRY_POINTER_TO_POINTER / Uint32Array.BYTES_PER_ELEMENT] = start; | ||
return createObjectWrapper(externalArgsApiToExternalArgsApi(externalArgs), carrier, start); | ||
@@ -52,3 +58,3 @@ } | ||
export function getUnderlyingArrayBuffer(objectBuffer) { | ||
return getInternalAPI(objectBuffer).getCarrier().dataView.buffer; | ||
return getInternalAPI(objectBuffer).getCarrier().uint8.buffer; | ||
} | ||
@@ -66,4 +72,5 @@ /** | ||
export function loadObjectBuffer(externalArgs, arrayBuffer) { | ||
const dataView = new DataView(arrayBuffer); | ||
// const dataView = new DataView(arrayBuffer); | ||
const allocator = new MemPool({ | ||
align: 8, | ||
buf: arrayBuffer, | ||
@@ -74,3 +81,3 @@ start: MEM_POOL_START, | ||
const carrier = { | ||
dataView, | ||
// dataView, | ||
allocator, | ||
@@ -83,3 +90,3 @@ uint8: new Uint8Array(arrayBuffer), | ||
}; | ||
return createObjectWrapper(externalArgsApiToExternalArgsApi(externalArgs), carrier, dataView.getUint32(INITIAL_ENTRY_POINTER_TO_POINTER)); | ||
return createObjectWrapper(externalArgsApiToExternalArgsApi(externalArgs), carrier, carrier.uint32[INITIAL_ENTRY_POINTER_TO_POINTER / Uint32Array.BYTES_PER_ELEMENT]); | ||
} | ||
@@ -108,2 +115,3 @@ /** | ||
const allocator = new MemPool({ | ||
align: 8, | ||
buf: newArrayBuffer, | ||
@@ -114,3 +122,3 @@ start: MEM_POOL_START, | ||
const carrier = { | ||
dataView: new DataView(newArrayBuffer), | ||
// dataView: new DataView(newArrayBuffer), | ||
allocator, | ||
@@ -136,2 +144,3 @@ uint8: new Uint8Array(newArrayBuffer), | ||
const pool = new MemPool({ | ||
align: 8, | ||
buf, | ||
@@ -138,0 +147,0 @@ skipInitialization: true, |
@@ -1,20 +0,20 @@ | ||
import { ArrayEntry, ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces"; | ||
export declare function arrayGetMetadata(carrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number): ArrayEntry; | ||
export declare function arrayGetPointersToValueInIndex(carrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number, indexToGet: number): { | ||
import { ArrayEntry, ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
export declare function arrayGetMetadata(carrier: GlobalCarrier, pointerToArrayEntry: number): ArrayEntry; | ||
export declare function arrayGetPointersToValueInIndex(carrier: GlobalCarrier, pointerToArrayEntry: number, indexToGet: number): { | ||
pointer: number; | ||
pointerToThePointer: number; | ||
} | undefined; | ||
export declare function getFinalValueAtArrayIndex(externalArgs: ExternalArgs, dataViewCarrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number, indexToGet: number): any; | ||
export declare function setValuePointerAtArrayIndex(carrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number, indexToSet: number, pointerToEntry: number): void; | ||
export declare function setValueAtArrayIndex(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number, indexToSet: number, value: any): void; | ||
export declare function getFinalValueAtArrayIndex(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, pointerToArrayEntry: number, indexToGet: number): any; | ||
export declare function setValuePointerAtArrayIndex(carrier: GlobalCarrier, pointerToArrayEntry: number, indexToSet: number, pointerToEntry: number): void; | ||
export declare function setValueAtArrayIndex(externalArgs: ExternalArgs, carrier: GlobalCarrier, pointerToArrayEntry: number, indexToSet: number, value: any): void; | ||
/** | ||
* Will not shrink the array! | ||
*/ | ||
export declare function extendArrayIfNeeded(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number, wishedLength: number): void; | ||
export declare function extendArrayIfNeeded(externalArgs: ExternalArgs, carrier: GlobalCarrier, pointerToArrayEntry: number, wishedLength: number): void; | ||
/** | ||
* Will not empty memory or relocate the array! | ||
*/ | ||
export declare function shrinkArray(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number, wishedLength: number): void; | ||
export declare function arraySort(externalArgs: ExternalArgs, dataViewCarrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number, sortComparator?: (a: any, b: any) => 1 | -1 | 0): void; | ||
export declare function arrayReverse(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number): void; | ||
export declare function shrinkArray(externalArgs: ExternalArgs, carrier: GlobalCarrier, pointerToArrayEntry: number, wishedLength: number): void; | ||
export declare function arraySort(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, pointerToArrayEntry: number, sortComparator?: (a: any, b: any) => 1 | -1 | 0): void; | ||
export declare function arrayReverse(externalArgs: ExternalArgs, carrier: GlobalCarrier, pointerToArrayEntry: number): void; | ||
//# sourceMappingURL=arrayHelpers.d.ts.map |
@@ -17,3 +17,3 @@ import { readEntry, writeEntry, writeValueInPtrToPtrAndHandleMemory } from "./store"; | ||
const pointerToThePointer = metadata.value + indexToGet * Uint32Array.BYTES_PER_ELEMENT; | ||
const pointer = carrier.dataView.getUint32(pointerToThePointer); | ||
const pointer = carrier.uint32[pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT]; | ||
return { | ||
@@ -24,4 +24,4 @@ pointer, | ||
} | ||
export function getFinalValueAtArrayIndex(externalArgs, dataViewCarrier, pointerToArrayEntry, indexToGet) { | ||
const pointers = arrayGetPointersToValueInIndex(dataViewCarrier, pointerToArrayEntry, indexToGet); | ||
export function getFinalValueAtArrayIndex(externalArgs, globalCarrier, pointerToArrayEntry, indexToGet) { | ||
const pointers = arrayGetPointersToValueInIndex(globalCarrier, pointerToArrayEntry, indexToGet); | ||
@@ -32,3 +32,3 @@ if (pointers === undefined) { | ||
return entryToFinalJavaScriptValue(externalArgs, dataViewCarrier, pointers.pointer); | ||
return entryToFinalJavaScriptValue(externalArgs, globalCarrier, pointers.pointer); | ||
} | ||
@@ -38,3 +38,3 @@ export function setValuePointerAtArrayIndex(carrier, pointerToArrayEntry, indexToSet, pointerToEntry) { | ||
assertNonNull(pointers); | ||
carrier.dataView.setUint32(pointers.pointerToThePointer, pointerToEntry); | ||
carrier.uint32[pointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT] = pointerToEntry; | ||
} | ||
@@ -107,7 +107,7 @@ export function setValueAtArrayIndex(externalArgs, carrier, pointerToArrayEntry, indexToSet, value) { | ||
export function arraySort(externalArgs, dataViewCarrier, pointerToArrayEntry, sortComparator = defaultCompareFunction) { | ||
const metadata = arrayGetMetadata(dataViewCarrier, pointerToArrayEntry); | ||
const pointersToValues = [...new Array(metadata.length).keys()].map(index => metadata.value + index * Uint32Array.BYTES_PER_ELEMENT).map(pointerToPointer => dataViewCarrier.dataView.getUint32(pointerToPointer)); | ||
export function arraySort(externalArgs, 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)]; | ||
}); | ||
@@ -119,3 +119,3 @@ sortMe.sort((a, b) => { | ||
for (let i = 0; i < sortMe.length; i += 1) { | ||
dataViewCarrier.dataView.setUint32(metadata.value + i * Uint32Array.BYTES_PER_ELEMENT, sortMe[i][0]); | ||
globalCarrier.uint32[(metadata.value + i * Uint32Array.BYTES_PER_ELEMENT) / Uint32Array.BYTES_PER_ELEMENT] = sortMe[i][0]; | ||
} | ||
@@ -122,0 +122,0 @@ } // https://stackoverflow.com/a/47349064/711152 |
@@ -1,3 +0,3 @@ | ||
import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces"; | ||
export declare function arraySaver(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, referencedPointers: number[], arrayToSave: Array<any>): number; | ||
import { ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
export declare function arraySaver(externalArgs: ExternalArgs, carrier: GlobalCarrier, referencedPointers: number[], arrayToSave: Array<any>): number; | ||
//# sourceMappingURL=arraySaver.d.ts.map |
@@ -16,3 +16,3 @@ import { appendEntry } from "./store"; | ||
const rOfValue = saveValue(externalArgs, carrier, referencedPointers, item); | ||
carrier.dataView.setUint32(memoryForPointersCursor, rOfValue); | ||
carrier.uint32[memoryForPointersCursor / Uint32Array.BYTES_PER_ELEMENT] = rOfValue; | ||
memoryForPointersCursor += Uint32Array.BYTES_PER_ELEMENT; | ||
@@ -19,0 +19,0 @@ } |
@@ -1,3 +0,3 @@ | ||
import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces"; | ||
export declare function arraySplice(externalArgs: ExternalArgs, dataViewCarrier: DataViewAndAllocatorCarrier, pointerToArrayEntry: number, startArg: number, deleteCountArg?: number, ...itemsToAddArg: Array<any>): any[]; | ||
import { ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
export declare function arraySplice(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, pointerToArrayEntry: number, startArg: number, deleteCountArg?: number, ...itemsToAddArg: Array<any>): any[]; | ||
//# sourceMappingURL=arraySplice.d.ts.map |
@@ -5,8 +5,8 @@ import { arrayGetMetadata, getFinalValueAtArrayIndex, shrinkArray, extendArrayIfNeeded, arrayGetPointersToValueInIndex, setValuePointerAtArrayIndex } from "./arrayHelpers"; | ||
export function arraySplice(externalArgs, dataViewCarrier, pointerToArrayEntry, startArg, deleteCountArg, ...itemsToAddArg) { | ||
const metadata = arrayGetMetadata(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.dataView.setUint32(valueToCopyPointers.pointerToThePointer, 0); | ||
setValuePointerAtArrayIndex(globalCarrier, pointerToArrayEntry, writeValueToIndex, valueToCopyPointers.pointer); | ||
globalCarrier.uint32[valueToCopyPointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT] = 0; | ||
} | ||
@@ -45,7 +45,7 @@ } // copy-down items | ||
for (let writeValueToIndex = calcedStart + itemsToAddArg.length; writeValueToIndex < metadata.length + itemCountChange; writeValueToIndex += 1) { | ||
const valueToCopyPointers = arrayGetPointersToValueInIndex(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.dataView.setUint32(valueToCopyPointers.pointerToThePointer, 0); // using that is wastefull | ||
globalCarrier.uint32[valueToCopyPointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT] = 0; // using that is wastefull | ||
// setValueAtArrayIndex( | ||
@@ -64,9 +64,9 @@ // dataView, | ||
for (let i = 0; i < itemsToAddArg.length; i += 1) { | ||
const valueToSetPointers = arrayGetPointersToValueInIndex(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 @@ |
@@ -1,2 +0,2 @@ | ||
import { ExternalArgs, DataViewAndAllocatorCarrier, ArrayEntry } from "./interfaces"; | ||
import { ExternalArgs, GlobalCarrier, ArrayEntry } from "./interfaces"; | ||
import { BaseProxyTrap } from "./BaseProxyTrap"; | ||
@@ -28,3 +28,2 @@ export declare class ArrayWrapper extends BaseProxyTrap<ArrayEntry> implements ProxyHandler<{}> { | ||
unshift(...elements: any): number; | ||
getDataView(): DataView; | ||
getEntryPointer(): number; | ||
@@ -36,3 +35,3 @@ isExtensible(): boolean; | ||
} | ||
export declare function createArrayWrapper(externalArgs: ExternalArgs, dataViewCarrier: DataViewAndAllocatorCarrier, entryPointer: number): Array<any>; | ||
export declare function createArrayWrapper(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, entryPointer: number): Array<any>; | ||
//# sourceMappingURL=arrayWrapper.d.ts.map |
@@ -186,7 +186,6 @@ import { getFinalValueAtArrayIndex, arrayGetMetadata, setValueAtArrayIndex, arraySort, extendArrayIfNeeded, arrayReverse } from "./arrayHelpers"; | ||
return arrayGetMetadata(this.carrier, this.entryPointer).length; | ||
} | ||
} // public getDataView() { | ||
// return this.carrier.dataView; | ||
// } | ||
getDataView() { | ||
return this.carrier.dataView; | ||
} | ||
@@ -222,4 +221,4 @@ getEntryPointer() { | ||
} | ||
export function createArrayWrapper(externalArgs, dataViewCarrier, entryPointer) { | ||
return new Proxy([], new ArrayWrapper(externalArgs, dataViewCarrier, entryPointer)); | ||
export function createArrayWrapper(externalArgs, globalCarrier, entryPointer) { | ||
return new Proxy([], new ArrayWrapper(externalArgs, globalCarrier, entryPointer)); | ||
} |
@@ -1,10 +0,10 @@ | ||
import { ExternalArgs, DataViewAndAllocatorCarrier, InternalAPI, DateEntry, ArrayEntry, ObjectEntry, MapEntry, SetEntry } from "./interfaces"; | ||
import { ExternalArgs, GlobalCarrier, InternalAPI, DateEntry, ArrayEntry, ObjectEntry, MapEntry, SetEntry } from "./interfaces"; | ||
export declare class BaseProxyTrap<T extends ObjectEntry | DateEntry | ArrayEntry | MapEntry | SetEntry> implements InternalAPI { | ||
protected externalArgs: ExternalArgs; | ||
protected carrier: DataViewAndAllocatorCarrier; | ||
protected carrier: GlobalCarrier; | ||
protected _entryPointer: number; | ||
constructor(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, _entryPointer: number); | ||
constructor(externalArgs: ExternalArgs, carrier: GlobalCarrier, _entryPointer: number); | ||
destroy(): number; | ||
getCarrier(): DataViewAndAllocatorCarrier; | ||
replaceCarrierContent(newCarrierContent: DataViewAndAllocatorCarrier): void; | ||
getCarrier(): GlobalCarrier; | ||
replaceCarrierContent(newCarrierContent: GlobalCarrier): void; | ||
getEntryPointer(): number; | ||
@@ -11,0 +11,0 @@ getExternalArgs(): Readonly<{ |
@@ -1,2 +0,2 @@ | ||
import { ExternalArgs, DataViewAndAllocatorCarrier, DateEntry } from "./interfaces"; | ||
import { ExternalArgs, GlobalCarrier, DateEntry } from "./interfaces"; | ||
import { BaseProxyTrap } from "./BaseProxyTrap"; | ||
@@ -6,3 +6,3 @@ export declare class DateWrapper extends BaseProxyTrap<DateEntry> implements ProxyHandler<Date> { | ||
private useMeToGiveNamesToFunctionsAndCacheThem; | ||
constructor(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, entryPointer: number); | ||
constructor(externalArgs: ExternalArgs, carrier: GlobalCarrier, entryPointer: number); | ||
get(target: Date, p: PropertyKey): any; | ||
@@ -15,3 +15,3 @@ private updateDateObjectForReuse; | ||
} | ||
export declare function createDateWrapper(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, entryPointer: number): Date; | ||
export declare function createDateWrapper(externalArgs: ExternalArgs, carrier: GlobalCarrier, entryPointer: number): Date; | ||
//# sourceMappingURL=dateWrapper.d.ts.map |
@@ -1,3 +0,3 @@ | ||
import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces"; | ||
export declare function entryToFinalJavaScriptValue(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, pointerToEntry: number): any; | ||
import { ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
export declare function entryToFinalJavaScriptValue(externalArgs: ExternalArgs, carrier: GlobalCarrier, pointerToEntry: number): any; | ||
//# sourceMappingURL=entryToFinalJavaScriptValue.d.ts.map |
@@ -1,7 +0,7 @@ | ||
import { DataViewAndAllocatorCarrier } from "./interfaces"; | ||
export declare function getAllLinkedAddresses(carrier: DataViewAndAllocatorCarrier, ignoreRefCount: boolean, entryPointer: number): { | ||
leafAddresses: number[]; | ||
arcAddresses: number[]; | ||
import { GlobalCarrier } from "./interfaces"; | ||
export declare function getAllLinkedAddresses(carrier: GlobalCarrier, ignoreRefCount: boolean, entryPointer: number): { | ||
leafAddresses: Set<number>; | ||
arcAddresses: Set<number>; | ||
}; | ||
export declare function getObjectOrMapOrSetAddresses(carrier: DataViewAndAllocatorCarrier, ignoreRefCount: boolean, internalHashmapPointer: number, leafAddresses: number[], arcAddresses: number[]): void; | ||
export declare function getObjectOrMapOrSetAddresses(carrier: GlobalCarrier, internalHashmapPointer: number, leafAddresses: Set<number>, addressesToProcessQueue: number[]): void; | ||
//# sourceMappingURL=getAllLinkedAddresses.d.ts.map |
@@ -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.dataView.getUint32(entry.value + i * Uint32Array.BYTES_PER_ELEMENT); | ||
getAllLinkedAddressesStep(carrier, ignoreRefCount, valuePointer, leafAddresses, arcAddresses); | ||
const valuePointer = carrier.uint32[(entry.value + i * Uint32Array.BYTES_PER_ELEMENT) / Uint32Array.BYTES_PER_ELEMENT]; | ||
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,12 +91,15 @@ | ||
export function getObjectOrMapOrSetAddresses(carrier, ignoreRefCount, internalHashmapPointer, leafAddresses, arcAddresses) { | ||
export function getObjectOrMapOrSetAddresses(carrier, internalHashmapPointer, leafAddresses, addressesToProcessQueue) { | ||
const { | ||
pointersToValuePointers, | ||
pointers | ||
} = hashMapGetPointersToFree(carrier.dataView, internalHashmapPointer); | ||
leafAddresses.push(...pointers); | ||
} = hashMapGetPointersToFree(carrier, internalHashmapPointer); | ||
for (const leafPointer of pointers) { | ||
leafAddresses.add(leafPointer); | ||
} | ||
for (const pointer of pointersToValuePointers) { | ||
getAllLinkedAddressesStep(carrier, ignoreRefCount, carrier.dataView.getUint32(pointer), leafAddresses, arcAddresses); | ||
addressesToProcessQueue.push(carrier.uint32[pointer / Uint32Array.BYTES_PER_ELEMENT]); | ||
} | ||
} |
@@ -1,3 +0,3 @@ | ||
import { DataViewAndAllocatorCarrier, ExternalArgs } from "../interfaces"; | ||
export declare function createHashMap(carrier: DataViewAndAllocatorCarrier, | ||
import { GlobalCarrier, ExternalArgs } from "../interfaces"; | ||
export declare function createHashMap(carrier: GlobalCarrier, | ||
/** | ||
@@ -10,12 +10,12 @@ * number of buckets | ||
*/ | ||
export declare function hashMapInsertUpdate(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, mapPointer: number, externalKeyValue: number | string): number; | ||
export declare function hashMapInsertUpdate(externalArgs: ExternalArgs, carrier: GlobalCarrier, mapPointer: number, externalKeyValue: number | string): number; | ||
/** | ||
* @returns pointer of the pointer to the found node | ||
*/ | ||
export declare function hashMapNodeLookup(carrier: DataViewAndAllocatorCarrier, mapPointer: number, externalKeyValue: number | string): number; | ||
export declare function hashMapValueLookup(carrier: DataViewAndAllocatorCarrier, mapPointer: number, externalKeyValue: number | string): number; | ||
export declare function hashMapNodeLookup(carrier: GlobalCarrier, mapPointer: number, externalKeyValue: number | string): number; | ||
export declare function hashMapValueLookup(carrier: GlobalCarrier, mapPointer: number, externalKeyValue: number | string): number; | ||
/** | ||
* @returns the value pointer of the deleted key | ||
*/ | ||
export declare function hashMapDelete(carrier: DataViewAndAllocatorCarrier, mapPointer: number, externalKeyValue: number | string): number; | ||
export declare function hashMapDelete(carrier: GlobalCarrier, mapPointer: number, externalKeyValue: number | string): number; | ||
/** | ||
@@ -25,13 +25,13 @@ * | ||
*/ | ||
export declare function hashMapLowLevelIterator(dataView: DataView, mapPointer: number, nodePointerIteratorToken: number): number; | ||
export declare function hashMapNodePointerToKeyValue(dataView: DataView, nodePointer: number): { | ||
export declare function hashMapLowLevelIterator(carrier: GlobalCarrier, mapPointer: number, nodePointerIteratorToken: number): number; | ||
export declare function hashMapNodePointerToKeyValue(carrier: GlobalCarrier, nodePointer: number): { | ||
valuePointer: number; | ||
keyPointer: number; | ||
}; | ||
export declare function hashMapSize(dataView: DataView, mapPointer: number): number; | ||
export declare function hashMapGetPointersToFree(dataView: DataView, hashmapPointer: number): { | ||
export declare function hashMapSize(carrier: GlobalCarrier, mapPointer: number): number; | ||
export declare function hashMapGetPointersToFree(carrier: GlobalCarrier, hashmapPointer: number): { | ||
pointers: number[]; | ||
pointersToValuePointers: number[]; | ||
}; | ||
export declare function hashmapNodesPointerIterator(dataView: DataView, mapPointer: number): Generator<number, void, unknown>; | ||
export declare function hashmapNodesPointerIterator(carrier: GlobalCarrier, mapPointer: number): Generator<number, void, unknown>; | ||
//# sourceMappingURL=hashmap.d.ts.map |
@@ -15,3 +15,3 @@ import { MAP_MACHINE, NODE_MACHINE } from "./memoryLayout"; | ||
const linkedListPointer = initLinkedList(carrier); | ||
const mapMachine = MAP_MACHINE.createOperator(carrier.dataView, hashMapMemory); | ||
const mapMachine = MAP_MACHINE.createOperator(carrier, hashMapMemory); | ||
mapMachine.set("ARRAY_POINTER", arrayMemory); | ||
@@ -29,3 +29,3 @@ mapMachine.set("CAPACITY", initialCapacity); | ||
export function hashMapInsertUpdate(externalArgs, carrier, mapPointer, externalKeyValue) { | ||
const mapOperator = MAP_MACHINE.createOperator(carrier.dataView, mapPointer); | ||
const mapOperator = MAP_MACHINE.createOperator(carrier, mapPointer); | ||
const keyEntry = primitiveValueToEntry(externalKeyValue); // allocate all possible needed memory upfront, so we won't oom in the middle of something | ||
@@ -38,9 +38,11 @@ // in case of overwrite, we will not need this memory | ||
writeEntry(carrier, keyEntryMemory, keyEntry); | ||
const keyHeaderOverhead = keyEntry.type === ENTRY_TYPE.STRING ? 5 : 1; | ||
const keyHashCode = hashCodeInPlace(carrier.dataView, mapOperator.get("CAPACITY"), // + 1 for the type of key | ||
const keyHeaderOverhead = keyEntry.type === ENTRY_TYPE.STRING ? // type + string length | ||
8 + 4 : // type | ||
8; | ||
const keyHashCode = hashCodeInPlace(carrier.uint8, mapOperator.get("CAPACITY"), // + 1 for the type of key | ||
keyEntryMemory + keyHeaderOverhead, memorySizeOfKey - keyHeaderOverhead); | ||
let ptrToPtrToSaveTheNodeTo = mapOperator.get("ARRAY_POINTER") + keyHashCode * Uint32Array.BYTES_PER_ELEMENT; | ||
const commonNodeOperator = NODE_MACHINE.createOperator(carrier.dataView, carrier.dataView.getUint32(ptrToPtrToSaveTheNodeTo)); // todo: share code with hashMapNodeLookup? | ||
const commonNodeOperator = NODE_MACHINE.createOperator(carrier, carrier.uint32[ptrToPtrToSaveTheNodeTo / Uint32Array.BYTES_PER_ELEMENT]); // todo: share code with hashMapNodeLookup? | ||
while (commonNodeOperator.startAddress !== 0 && !compareStringOrNumberEntriesInPlace(carrier.dataView, commonNodeOperator.get("KEY_POINTER"), keyEntryMemory)) { | ||
while (commonNodeOperator.startAddress !== 0 && !compareStringOrNumberEntriesInPlace(carrier, commonNodeOperator.get("KEY_POINTER"), keyEntryMemory)) { | ||
ptrToPtrToSaveTheNodeTo = commonNodeOperator.pointerTo("NEXT_NODE_POINTER"); | ||
@@ -65,3 +67,3 @@ commonNodeOperator.startAddress = commonNodeOperator.get("NEXT_NODE_POINTER"); | ||
commonNodeOperator.set("LINKED_LIST_ITEM_POINTER", linkedListItemInsert(carrier, mapOperator.get("LINKED_LIST_POINTER"), memoryForNewNode)); | ||
carrier.dataView.setUint32(ptrToPtrToSaveTheNodeTo, memoryForNewNode); | ||
carrier.uint32[ptrToPtrToSaveTheNodeTo / Uint32Array.BYTES_PER_ELEMENT] = memoryForNewNode; | ||
mapOperator.set("LINKED_LIST_SIZE", mapOperator.get("LINKED_LIST_SIZE") + 1); | ||
@@ -84,6 +86,6 @@ | ||
export function hashMapNodeLookup(carrier, mapPointer, externalKeyValue) { | ||
const mapMachine = MAP_MACHINE.createOperator(carrier.dataView, mapPointer); | ||
const mapMachine = MAP_MACHINE.createOperator(carrier, mapPointer); | ||
const keyHashCode = hashCodeExternalValue(mapMachine.get("CAPACITY"), externalKeyValue); | ||
let ptrToPtr = mapMachine.get("ARRAY_POINTER") + keyHashCode * Uint32Array.BYTES_PER_ELEMENT; | ||
const node = NODE_MACHINE.createOperator(carrier.dataView, carrier.dataView.getUint32(ptrToPtr)); | ||
const node = NODE_MACHINE.createOperator(carrier, carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT]); | ||
@@ -110,3 +112,3 @@ while (node.startAddress !== 0) { | ||
const node = NODE_MACHINE.createOperator(carrier.dataView, carrier.dataView.getUint32(nodePtrToPtr)); | ||
const node = NODE_MACHINE.createOperator(carrier, carrier.uint32[nodePtrToPtr / Uint32Array.BYTES_PER_ELEMENT]); | ||
return node.pointerTo("VALUE_POINTER"); | ||
@@ -125,11 +127,11 @@ } | ||
const nodeToDeletePointer = carrier.dataView.getUint32(foundNodePtrToPtr); | ||
const nodeOperator = NODE_MACHINE.createOperator(carrier.dataView, nodeToDeletePointer); | ||
const nodeToDeletePointer = carrier.uint32[foundNodePtrToPtr / Uint32Array.BYTES_PER_ELEMENT]; | ||
const nodeOperator = NODE_MACHINE.createOperator(carrier, nodeToDeletePointer); | ||
const valuePointer = nodeOperator.pointerTo("VALUE_POINTER"); | ||
linkedListItemRemove(carrier, nodeOperator.get("LINKED_LIST_ITEM_POINTER")); // remove node from bucket | ||
carrier.dataView.setUint32(foundNodePtrToPtr, nodeOperator.get("NEXT_NODE_POINTER")); | ||
carrier.uint32[foundNodePtrToPtr / Uint32Array.BYTES_PER_ELEMENT] = nodeOperator.get("NEXT_NODE_POINTER"); | ||
carrier.allocator.free(nodeOperator.get("KEY_POINTER")); | ||
carrier.allocator.free(nodeOperator.startAddress); | ||
carrier.dataView.setUint32(mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset, carrier.dataView.getUint32(mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset) - 1); | ||
carrier.uint32[(mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset) / Uint32Array.BYTES_PER_ELEMENT]--; | ||
return valuePointer; | ||
@@ -142,11 +144,11 @@ } | ||
export function hashMapLowLevelIterator(dataView, mapPointer, nodePointerIteratorToken) { | ||
const mapOperator = MAP_MACHINE.createOperator(dataView, mapPointer); | ||
export function hashMapLowLevelIterator(carrier, mapPointer, nodePointerIteratorToken) { | ||
const mapOperator = MAP_MACHINE.createOperator(carrier, mapPointer); | ||
let tokenToUseForLinkedListIterator = 0; | ||
if (nodePointerIteratorToken !== 0) { | ||
tokenToUseForLinkedListIterator = NODE_MACHINE.createOperator(dataView, nodePointerIteratorToken).get("LINKED_LIST_ITEM_POINTER"); | ||
tokenToUseForLinkedListIterator = NODE_MACHINE.createOperator(carrier, nodePointerIteratorToken).get("LINKED_LIST_ITEM_POINTER"); | ||
} | ||
const pointerToNextLinkedListItem = linkedListLowLevelIterator(dataView, mapOperator.get("LINKED_LIST_POINTER"), tokenToUseForLinkedListIterator); | ||
const pointerToNextLinkedListItem = linkedListLowLevelIterator(carrier, mapOperator.get("LINKED_LIST_POINTER"), tokenToUseForLinkedListIterator); | ||
@@ -157,6 +159,6 @@ if (pointerToNextLinkedListItem === 0) { | ||
return linkedListGetValue(dataView, pointerToNextLinkedListItem); | ||
return linkedListGetValue(carrier, pointerToNextLinkedListItem); | ||
} | ||
export function hashMapNodePointerToKeyValue(dataView, nodePointer) { | ||
const operator = NODE_MACHINE.createOperator(dataView, nodePointer); | ||
export function hashMapNodePointerToKeyValue(carrier, nodePointer) { | ||
const operator = NODE_MACHINE.createOperator(carrier, nodePointer); | ||
return { | ||
@@ -167,12 +169,12 @@ valuePointer: operator.pointerTo("VALUE_POINTER"), | ||
} | ||
export function hashMapSize(dataView, mapPointer) { | ||
return dataView.getUint32(mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset); | ||
export function hashMapSize(carrier, mapPointer) { | ||
return carrier.uint32[(mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset) / Uint32Array.BYTES_PER_ELEMENT]; | ||
} | ||
export function hashMapGetPointersToFree(dataView, hashmapPointer) { | ||
const mapOperator = MAP_MACHINE.createOperator(dataView, hashmapPointer); | ||
export function hashMapGetPointersToFree(carrier, hashmapPointer) { | ||
const mapOperator = MAP_MACHINE.createOperator(carrier, hashmapPointer); | ||
const pointers = [hashmapPointer, mapOperator.get("ARRAY_POINTER")]; | ||
const pointersToValuePointers = []; | ||
const pointersOfLinkedList = linkedListGetPointersToFree(dataView, mapOperator.get("LINKED_LIST_POINTER")); | ||
const pointersOfLinkedList = linkedListGetPointersToFree(carrier, mapOperator.get("LINKED_LIST_POINTER")); | ||
pointers.push(...pointersOfLinkedList.pointers); | ||
const nodeOperator = NODE_MACHINE.createOperator(dataView, 0); | ||
const nodeOperator = NODE_MACHINE.createOperator(carrier, 0); | ||
@@ -213,3 +215,3 @@ for (const nodePointer of pointersOfLinkedList.valuePointers) { | ||
while ((pointerToNode = hashMapLowLevelIterator(carrier.dataView, mapOperator.startAddress, pointerToNode)) !== 0) { | ||
while ((pointerToNode = hashMapLowLevelIterator(carrier, mapOperator.startAddress, pointerToNode)) !== 0) { | ||
hashMapRehashInsert(carrier, biggerArray, newCapacity, pointerToNode); | ||
@@ -220,9 +222,9 @@ } | ||
function hashMapRehashInsert(carrier, bucketsArrayPointer, arraySize, nodePointer) { | ||
const nodeOperator = NODE_MACHINE.createOperator(carrier.dataView, nodePointer); | ||
const keyInfo = getKeyStartLength(carrier.dataView, nodeOperator.get("KEY_POINTER")); | ||
const keyHashCode = hashCodeInPlace(carrier.dataView, arraySize, keyInfo.start, keyInfo.length); | ||
const nodeOperator = NODE_MACHINE.createOperator(carrier, nodePointer); | ||
const keyInfo = getKeyStartLength(carrier, nodeOperator.get("KEY_POINTER")); | ||
const keyHashCode = hashCodeInPlace(carrier.uint8, arraySize, keyInfo.start, keyInfo.length); | ||
const bucket = keyHashCode % arraySize; | ||
const bucketStartPointer = bucketsArrayPointer + bucket * Uint32Array.BYTES_PER_ELEMENT; | ||
const prevFirstNodeInBucket = carrier.dataView.getUint32(bucketStartPointer); | ||
carrier.dataView.setUint32(bucketStartPointer, nodePointer); | ||
const prevFirstNodeInBucket = carrier.uint32[bucketStartPointer / Uint32Array.BYTES_PER_ELEMENT]; | ||
carrier.uint32[bucketStartPointer / Uint32Array.BYTES_PER_ELEMENT] = nodePointer; | ||
nodeOperator.set("NEXT_NODE_POINTER", prevFirstNodeInBucket); // // Add is first node in bucket | ||
@@ -246,8 +248,8 @@ // if (nodeOperator.startAddress === 0) { | ||
export function* hashmapNodesPointerIterator(dataView, mapPointer) { | ||
export function* hashmapNodesPointerIterator(carrier, mapPointer) { | ||
let iteratorToken = 0; | ||
while ((iteratorToken = hashMapLowLevelIterator(dataView, mapPointer, iteratorToken)) !== 0) { | ||
while ((iteratorToken = hashMapLowLevelIterator(carrier, mapPointer, iteratorToken)) !== 0) { | ||
yield iteratorToken; | ||
} | ||
} |
@@ -1,5 +0,6 @@ | ||
export declare function hashCodeInPlace(dataView: DataView, capacity: number, keyStart: number, keyBytesLength: number): number; | ||
import { GlobalCarrier } from "../interfaces"; | ||
export declare function hashCodeInPlace(uint8: Uint8Array, capacity: number, keyStart: number, keyBytesLength: number): number; | ||
export declare function hashCodeExternalValue(capacity: number, value: string | number): number; | ||
export declare function hashCodeEntry(dataView: DataView, capacity: number, pointer: number): number; | ||
export declare function getKeyStartLength(dataView: DataView, keyPointer: number): { | ||
export declare function hashCodeEntry(carrier: GlobalCarrier, capacity: number, pointer: number): number; | ||
export declare function getKeyStartLength(carrier: GlobalCarrier, keyPointer: number): { | ||
start: number; | ||
@@ -6,0 +7,0 @@ length: number; |
import { ENTRY_TYPE } from "../entry-types"; | ||
import { stringEncodeInto } from "../stringEncodeInto"; | ||
export function hashCodeInPlace(dataView, capacity, keyStart, keyBytesLength) { | ||
export function hashCodeInPlace(uint8, capacity, keyStart, keyBytesLength) { | ||
let h = 0 | 0; // const hashed: number[] = []; | ||
for (let i = 0; i < keyBytesLength; i++) { | ||
// hashed.push(dataView.getUint8(i + keyStart)); | ||
h = Math.imul(31, h) + dataView.getUint8(i + keyStart) | 0; | ||
h = Math.imul(31, h) + uint8[i + keyStart] | 0; | ||
} // console.log(hashed); | ||
@@ -16,3 +15,3 @@ | ||
const ab = new ArrayBuffer(typeof value === "string" ? value.length * 3 : 8); | ||
const dv = new DataView(ab); | ||
const uint8 = new Uint8Array(ab); | ||
let keyBytesLength = ab.byteLength; | ||
@@ -23,18 +22,18 @@ | ||
} else { | ||
dv.setFloat64(0, value); | ||
new Float64Array(ab)[0] = value; | ||
} | ||
return hashCodeInPlace(dv, capacity, 0, keyBytesLength); | ||
return hashCodeInPlace(uint8, capacity, 0, keyBytesLength); | ||
} | ||
export function hashCodeEntry(dataView, capacity, pointer) { | ||
const type = dataView.getUint8(pointer); | ||
export function hashCodeEntry(carrier, capacity, pointer) { | ||
const type = carrier.uint8[pointer]; | ||
if (type === ENTRY_TYPE.NUMBER) { | ||
return hashCodeInPlace(dataView, capacity, pointer + 1, 8); | ||
return hashCodeInPlace(carrier.uint8, capacity, pointer + 1, 8); | ||
} else { | ||
return hashCodeInPlace(dataView, capacity, pointer + 1 + Uint16Array.BYTES_PER_ELEMENT, dataView.getUint16(pointer + 1)); | ||
return hashCodeInPlace(carrier.uint8, capacity, pointer + 1 + Uint16Array.BYTES_PER_ELEMENT, carrier.uint16[(pointer + 1) / Uint16Array.BYTES_PER_ELEMENT]); | ||
} | ||
} | ||
export function getKeyStartLength(dataView, keyPointer) { | ||
if (dataView.getUint32(keyPointer) === ENTRY_TYPE.NUMBER) { | ||
export function getKeyStartLength(carrier, keyPointer) { | ||
if (carrier.uint32[keyPointer / Uint32Array.BYTES_PER_ELEMENT] === ENTRY_TYPE.NUMBER) { | ||
return { | ||
@@ -47,5 +46,5 @@ start: keyPointer + 1, | ||
start: keyPointer + 1 + 2 + 2, | ||
length: dataView.getUint16(keyPointer + 1) | ||
length: carrier.uint16[(keyPointer + 1) / Uint16Array.BYTES_PER_ELEMENT] | ||
}; | ||
} | ||
} |
export declare const MAP_MACHINE: { | ||
map: import("../memoryMachinery").MemoryMap<"CAPACITY" | "USED_CAPACITY" | "ARRAY_POINTER" | "LINKED_LIST_POINTER" | "LINKED_LIST_SIZE">; | ||
createOperator: (dataView: DataView, address: number) => import("../memoryMachinery").MemoryOperator<"CAPACITY" | "USED_CAPACITY" | "ARRAY_POINTER" | "LINKED_LIST_POINTER" | "LINKED_LIST_SIZE">; | ||
map: import("../memoryMachinery").MemoryMap<"ARRAY_POINTER" | "LINKED_LIST_POINTER" | "LINKED_LIST_SIZE" | "CAPACITY" | "USED_CAPACITY">; | ||
createOperator: (carrier: import("../interfaces").GlobalCarrier, address: number) => import("../memoryMachinery").MemoryOperator<"ARRAY_POINTER" | "LINKED_LIST_POINTER" | "LINKED_LIST_SIZE" | "CAPACITY" | "USED_CAPACITY">; | ||
}; | ||
export declare const NODE_MACHINE: { | ||
map: import("../memoryMachinery").MemoryMap<"VALUE_POINTER" | "NEXT_NODE_POINTER" | "KEY_POINTER" | "LINKED_LIST_ITEM_POINTER">; | ||
createOperator: (dataView: DataView, address: number) => import("../memoryMachinery").MemoryOperator<"VALUE_POINTER" | "NEXT_NODE_POINTER" | "KEY_POINTER" | "LINKED_LIST_ITEM_POINTER">; | ||
createOperator: (carrier: import("../interfaces").GlobalCarrier, address: number) => import("../memoryMachinery").MemoryOperator<"VALUE_POINTER" | "NEXT_NODE_POINTER" | "KEY_POINTER" | "LINKED_LIST_ITEM_POINTER">; | ||
}; | ||
@@ -9,0 +9,0 @@ export declare type MapMachineType = ReturnType<typeof MAP_MACHINE.createOperator>; |
import { createMemoryMachine } from "../memoryMachinery"; | ||
export const MAP_MACHINE = createMemoryMachine({ | ||
CAPACITY: Uint8Array, | ||
USED_CAPACITY: Uint8Array, | ||
ARRAY_POINTER: Uint32Array, | ||
LINKED_LIST_POINTER: Uint32Array, | ||
// maybe put save this value in the linked list? | ||
LINKED_LIST_SIZE: Uint32Array | ||
LINKED_LIST_SIZE: Uint32Array, | ||
CAPACITY: Uint8Array, | ||
USED_CAPACITY: Uint8Array | ||
}); | ||
@@ -10,0 +10,0 @@ export const NODE_MACHINE = createMemoryMachine({ |
@@ -61,4 +61,3 @@ import { ENTRY_TYPE } from "./entry-types"; | ||
*/ | ||
export interface DataViewAndAllocatorCarrier { | ||
dataView: DataView; | ||
export interface GlobalCarrier { | ||
uint8: Uint8Array; | ||
@@ -87,4 +86,4 @@ uint16: Uint16Array; | ||
getExternalArgs(): ExternalArgs; | ||
getCarrier(): Readonly<DataViewAndAllocatorCarrier>; | ||
replaceCarrierContent(carrier: DataViewAndAllocatorCarrier): void; | ||
getCarrier(): Readonly<GlobalCarrier>; | ||
replaceCarrierContent(carrier: GlobalCarrier): void; | ||
getEntryPointer(): number; | ||
@@ -91,0 +90,0 @@ destroy(): number; |
@@ -1,5 +0,5 @@ | ||
import { DataViewAndAllocatorCarrier } from "../interfaces"; | ||
import { GlobalCarrier } from "../interfaces"; | ||
export declare const LINKED_LIST_ITEM_MACHINE: { | ||
map: import("../memoryMachinery").MemoryMap<"NEXT_POINTER" | "VALUE">; | ||
createOperator: (dataView: DataView, address: number) => import("../memoryMachinery").MemoryOperator<"NEXT_POINTER" | "VALUE">; | ||
createOperator: (carrier: GlobalCarrier, address: number) => import("../memoryMachinery").MemoryOperator<"NEXT_POINTER" | "VALUE">; | ||
}; | ||
@@ -9,11 +9,11 @@ export declare type LinkedListItemMachineType = ReturnType<typeof LINKED_LIST_ITEM_MACHINE.createOperator>; | ||
map: import("../memoryMachinery").MemoryMap<"END_POINTER" | "START_POINTER">; | ||
createOperator: (dataView: DataView, address: number) => import("../memoryMachinery").MemoryOperator<"END_POINTER" | "START_POINTER">; | ||
createOperator: (carrier: GlobalCarrier, address: number) => import("../memoryMachinery").MemoryOperator<"END_POINTER" | "START_POINTER">; | ||
}; | ||
export declare type LinkedListMachineType = ReturnType<typeof LINKED_LIST_MACHINE.createOperator>; | ||
export declare function initLinkedList({ dataView, allocator }: DataViewAndAllocatorCarrier): number; | ||
export declare function linkedListItemInsert({ dataView, allocator }: DataViewAndAllocatorCarrier, linkedListPointer: number, nodeValuePointer: number): number; | ||
export declare function linkedListItemRemove({ dataView, allocator }: DataViewAndAllocatorCarrier, itemPointer: number): void; | ||
export declare function linkedListLowLevelIterator(dataView: DataView, linkedListPointer: number, itemPointer: number): number; | ||
export declare function linkedListGetValue(dataView: DataView, itemPointer: number): number; | ||
export declare function linkedListGetPointersToFree(dataView: DataView, linkedListPointer: number): { | ||
export declare function initLinkedList(carrier: GlobalCarrier): number; | ||
export declare function linkedListItemInsert(carrier: GlobalCarrier, linkedListPointer: number, nodeValuePointer: number): number; | ||
export declare function linkedListItemRemove(carrier: GlobalCarrier, itemPointer: number): void; | ||
export declare function linkedListLowLevelIterator(carrier: GlobalCarrier, linkedListPointer: number, itemPointer: number): number; | ||
export declare function linkedListGetValue(carrier: GlobalCarrier, itemPointer: number): number; | ||
export declare function linkedListGetPointersToFree(carrier: GlobalCarrier, linkedListPointer: number): { | ||
pointers: number[]; | ||
@@ -20,0 +20,0 @@ valuePointers: number[]; |
@@ -25,9 +25,9 @@ import { createMemoryMachine } from "../memoryMachinery"; | ||
}); | ||
export function initLinkedList({ | ||
dataView, | ||
allocator | ||
}) { | ||
export function initLinkedList(carrier) { | ||
const { | ||
allocator | ||
} = carrier; | ||
const memoryForLinkedList = allocator.calloc(LINKED_LIST_MACHINE.map.SIZE_OF); | ||
const memoryForEndMarkerItem = allocator.calloc(LINKED_LIST_ITEM_MACHINE.map.SIZE_OF); | ||
const linkedListMachine = LINKED_LIST_MACHINE.createOperator(dataView, memoryForLinkedList); | ||
const linkedListMachine = LINKED_LIST_MACHINE.createOperator(carrier, memoryForLinkedList); | ||
linkedListMachine.set("START_POINTER", memoryForEndMarkerItem); | ||
@@ -37,10 +37,7 @@ linkedListMachine.set("END_POINTER", memoryForEndMarkerItem); | ||
} | ||
export function linkedListItemInsert({ | ||
dataView, | ||
allocator | ||
}, linkedListPointer, nodeValuePointer) { | ||
const newItemMemory = allocator.calloc(LINKED_LIST_ITEM_MACHINE.map.SIZE_OF); | ||
const linkedListOperator = LINKED_LIST_MACHINE.createOperator(dataView, linkedListPointer); | ||
const wasEndMarkerOperator = LINKED_LIST_ITEM_MACHINE.createOperator(dataView, linkedListOperator.get("END_POINTER")); | ||
const toBeEndMarkerOperator = LINKED_LIST_ITEM_MACHINE.createOperator(dataView, newItemMemory); | ||
export function linkedListItemInsert(carrier, linkedListPointer, nodeValuePointer) { | ||
const newItemMemory = carrier.allocator.calloc(LINKED_LIST_ITEM_MACHINE.map.SIZE_OF); | ||
const linkedListOperator = LINKED_LIST_MACHINE.createOperator(carrier, linkedListPointer); | ||
const wasEndMarkerOperator = LINKED_LIST_ITEM_MACHINE.createOperator(carrier, linkedListOperator.get("END_POINTER")); | ||
const toBeEndMarkerOperator = LINKED_LIST_ITEM_MACHINE.createOperator(carrier, newItemMemory); | ||
toBeEndMarkerOperator.set("VALUE", 0); | ||
@@ -54,18 +51,15 @@ toBeEndMarkerOperator.set("NEXT_POINTER", 0); | ||
} | ||
export function linkedListItemRemove({ | ||
dataView, | ||
allocator | ||
}, itemPointer) { | ||
const itemToOverwrite = LINKED_LIST_ITEM_MACHINE.createOperator(dataView, itemPointer); | ||
const itemToOverwriteWith = LINKED_LIST_ITEM_MACHINE.createOperator(dataView, itemToOverwrite.get("NEXT_POINTER")); | ||
export function linkedListItemRemove(carrier, itemPointer) { | ||
const itemToOverwrite = LINKED_LIST_ITEM_MACHINE.createOperator(carrier, itemPointer); | ||
const itemToOverwriteWith = LINKED_LIST_ITEM_MACHINE.createOperator(carrier, itemToOverwrite.get("NEXT_POINTER")); | ||
const memoryToFree = itemToOverwrite.get("NEXT_POINTER"); | ||
itemToOverwrite.set("VALUE", itemToOverwriteWith.get("VALUE")); | ||
itemToOverwrite.set("NEXT_POINTER", itemToOverwriteWith.get("NEXT_POINTER")); | ||
allocator.free(memoryToFree); | ||
carrier.allocator.free(memoryToFree); | ||
} | ||
export function linkedListLowLevelIterator(dataView, linkedListPointer, itemPointer) { | ||
const listItem = LINKED_LIST_ITEM_MACHINE.createOperator(dataView, itemPointer); | ||
export function linkedListLowLevelIterator(carrier, linkedListPointer, itemPointer) { | ||
const listItem = LINKED_LIST_ITEM_MACHINE.createOperator(carrier, itemPointer); | ||
if (itemPointer === 0) { | ||
const list = LINKED_LIST_MACHINE.createOperator(dataView, linkedListPointer); | ||
const list = LINKED_LIST_MACHINE.createOperator(carrier, linkedListPointer); | ||
listItem.startAddress = list.get("START_POINTER"); // can be zero if START_POINTER pointes to the end marker | ||
@@ -94,9 +88,9 @@ | ||
} | ||
export function linkedListGetValue(dataView, itemPointer) { | ||
return LINKED_LIST_ITEM_MACHINE.createOperator(dataView, itemPointer).get("VALUE"); | ||
export function linkedListGetValue(carrier, itemPointer) { | ||
return LINKED_LIST_ITEM_MACHINE.createOperator(carrier, itemPointer).get("VALUE"); | ||
} | ||
export function linkedListGetPointersToFree(dataView, linkedListPointer) { | ||
export function linkedListGetPointersToFree(carrier, linkedListPointer) { | ||
const pointers = [linkedListPointer]; | ||
const valuePointers = []; | ||
const operator = LINKED_LIST_MACHINE.createOperator(dataView, linkedListPointer); | ||
const operator = LINKED_LIST_MACHINE.createOperator(carrier, linkedListPointer); | ||
const firstItem = operator.get("START_POINTER"); | ||
@@ -109,3 +103,3 @@ const lastItem = operator.get("END_POINTER"); // list empty | ||
const linkItemOperator = LINKED_LIST_ITEM_MACHINE.createOperator(dataView, linkedListLowLevelIterator(dataView, linkedListPointer, 0)); | ||
const linkItemOperator = LINKED_LIST_ITEM_MACHINE.createOperator(carrier, linkedListLowLevelIterator(carrier, linkedListPointer, 0)); | ||
@@ -112,0 +106,0 @@ while (linkItemOperator.startAddress !== 0) { |
@@ -1,2 +0,2 @@ | ||
import { ExternalArgs, DataViewAndAllocatorCarrier, MapEntry, InternalAPI } from "./interfaces"; | ||
import { ExternalArgs, GlobalCarrier, MapEntry, InternalAPI } from "./interfaces"; | ||
import { INTERNAL_API_SYMBOL } from "./symbols"; | ||
@@ -20,3 +20,3 @@ import { BaseProxyTrap } from "./BaseProxyTrap"; | ||
} | ||
export declare function createMapWrapper<K extends string | number, V>(externalArgs: ExternalArgs, dataViewCarrier: DataViewAndAllocatorCarrier, entryPointer: number): Map<K, V>; | ||
export declare function createMapWrapper<K extends string | number, V>(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, entryPointer: number): Map<K, V>; | ||
//# sourceMappingURL=mapWrapper.d.ts.map |
@@ -19,3 +19,3 @@ import { deleteObjectPropertyEntryByKey, objectGet, objectSet, mapOrSetClear } from "./objectWrapperHelpers"; | ||
get size() { | ||
return hashMapSize(this.carrier.dataView, this.entry.value); | ||
return hashMapSize(this.carrier, this.entry.value); | ||
} | ||
@@ -28,8 +28,8 @@ | ||
*entries() { | ||
for (const nodePointer of hashmapNodesPointerIterator(this.carrier.dataView, this.entry.value)) { | ||
for (const nodePointer of hashmapNodesPointerIterator(this.carrier, this.entry.value)) { | ||
const { | ||
valuePointer, | ||
keyPointer | ||
} = hashMapNodePointerToKeyValue(this.carrier.dataView, nodePointer); | ||
yield [entryToFinalJavaScriptValue(this.externalArgs, this.carrier, keyPointer), entryToFinalJavaScriptValue(this.externalArgs, this.carrier, this.carrier.dataView.getUint32(valuePointer))]; | ||
} = hashMapNodePointerToKeyValue(this.carrier, nodePointer); | ||
yield [entryToFinalJavaScriptValue(this.externalArgs, this.carrier, keyPointer), entryToFinalJavaScriptValue(this.externalArgs, this.carrier, this.carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT])]; | ||
} | ||
@@ -39,4 +39,4 @@ } | ||
*keys() { | ||
for (const nodePointer of hashmapNodesPointerIterator(this.carrier.dataView, this.entry.value)) { | ||
const t = hashMapNodePointerToKeyValue(this.carrier.dataView, nodePointer); | ||
for (const nodePointer of hashmapNodesPointerIterator(this.carrier, this.entry.value)) { | ||
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer); | ||
yield entryToFinalJavaScriptValue(this.externalArgs, this.carrier, t.keyPointer); | ||
@@ -47,7 +47,7 @@ } | ||
*values() { | ||
for (const nodePointer of hashmapNodesPointerIterator(this.carrier.dataView, this.entry.value)) { | ||
for (const nodePointer of hashmapNodesPointerIterator(this.carrier, this.entry.value)) { | ||
const { | ||
valuePointer | ||
} = hashMapNodePointerToKeyValue(this.carrier.dataView, nodePointer); | ||
yield entryToFinalJavaScriptValue(this.externalArgs, this.carrier, this.carrier.dataView.getUint32(valuePointer)); | ||
} = hashMapNodePointerToKeyValue(this.carrier, nodePointer); | ||
yield entryToFinalJavaScriptValue(this.externalArgs, this.carrier, this.carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT]); | ||
} | ||
@@ -104,4 +104,4 @@ } | ||
} | ||
export function createMapWrapper(externalArgs, dataViewCarrier, entryPointer) { | ||
return new MapWrapper(externalArgs, dataViewCarrier, entryPointer); | ||
export function createMapWrapper(externalArgs, globalCarrier, entryPointer) { | ||
return new MapWrapper(externalArgs, globalCarrier, entryPointer); | ||
} |
@@ -0,1 +1,2 @@ | ||
import { GlobalCarrier } from "./interfaces"; | ||
declare const ALLOWS_TYPED_ARRAYS_CTORS: readonly [Uint8ArrayConstructor, Uint32ArrayConstructor, Uint16ArrayConstructor]; | ||
@@ -19,7 +20,7 @@ declare type TypedArrayCtor = typeof ALLOWS_TYPED_ARRAYS_CTORS[number]; | ||
} | ||
export declare function createMemoryOperator<T extends string>(memoryMap: MemoryMap<T>, dataView: DataView, startAddress: number): MemoryOperator<T>; | ||
export declare function createMemoryOperator<T extends string>(memoryMap: MemoryMap<T>, carrier: GlobalCarrier, startAddress: number): MemoryOperator<T>; | ||
export declare function layoutDeclarationToMemoryMap<T extends string>(input: LayoutDeclaration<T>): MemoryMap<T>; | ||
export declare function createMemoryMachine<T extends string>(layoutDeclaration: LayoutDeclaration<T>): { | ||
map: MemoryMap<T>; | ||
createOperator: (dataView: DataView, address: number) => MemoryOperator<T>; | ||
createOperator: (carrier: GlobalCarrier, address: number) => MemoryOperator<T>; | ||
}; | ||
@@ -26,0 +27,0 @@ export declare function _buildMemoryLayout<T extends { |
const ALLOWS_TYPED_ARRAYS_CTORS = [Uint8Array, Uint32Array, // BigUint64Array, | ||
Uint16Array]; | ||
// DataView.prototype is any, ts thing. this is a workaround for better types. | ||
let dataViewInstance = new DataView(new ArrayBuffer(0)); | ||
const READ_WRITE_MAPS = [[Uint8Array, dataViewInstance.getUint8, dataViewInstance.setUint8], [Uint32Array, dataViewInstance.getUint32, dataViewInstance.setUint32], // [BigUint64Array, dataViewInstance.getBigUint64, dataViewInstance.setBigUint64], | ||
[Uint16Array, dataViewInstance.getUint16, dataViewInstance.setUint16]]; // eslint-disable-next-line @typescript-eslint/ban-ts-ignore | ||
// let dataViewInstance = new DataView(new ArrayBuffer(0)); | ||
// const READ_WRITE_MAPS = [ | ||
// [Uint8Array, dataViewInstance.getUint8, dataViewInstance.setUint8], | ||
// [Uint32Array, dataViewInstance.getUint32, dataViewInstance.setUint32], | ||
// // [BigUint64Array, dataViewInstance.getBigUint64, dataViewInstance.setBigUint64], | ||
// [Uint16Array, dataViewInstance.getUint16, dataViewInstance.setUint16] | ||
// ] as const; | ||
const READ_WRITE_MAPS_V2 = [[Uint8Array, "uint8"], [Uint32Array, "uint32"], // [BigUint64Array, dataViewInstance.getBigUint64, dataViewInstance.setBigUint64], | ||
[Uint16Array, "uint16"]]; // eslint-disable-next-line @typescript-eslint/ban-ts-ignore | ||
// @ts-ignore | ||
// dataViewInstance = undefined; | ||
// const READ_MAP = new Map(READ_WRITE_MAPS.map(e => [e[0], e[1]])); | ||
// const WRITE_MAP = new Map(READ_WRITE_MAPS.map(e => [e[0], e[2]])); | ||
dataViewInstance = undefined; | ||
const READ_MAP = new Map(READ_WRITE_MAPS.map(e => [e[0], e[1]])); | ||
const WRITE_MAP = new Map(READ_WRITE_MAPS.map(e => [e[0], e[2]])); | ||
export function createMemoryOperator(memoryMap, dataView, startAddress) { | ||
const READ_WRITE_MAP_V2 = new Map(READ_WRITE_MAPS_V2.map(e => [e[0], e[1]])); | ||
export function createMemoryOperator(memoryMap, carrier, startAddress) { | ||
return { | ||
set(key, value) { | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
const func = WRITE_MAP.get(memoryMap[key].type); | ||
return func.call(dataView, startAddress + memoryMap[key].bytesOffset, value); | ||
const func = READ_WRITE_MAP_V2.get(memoryMap[key].type); | ||
return carrier[func][(startAddress + memoryMap[key].bytesOffset) / memoryMap[key].type.BYTES_PER_ELEMENT] = value; | ||
}, | ||
@@ -22,4 +29,4 @@ | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
const func = READ_MAP.get(memoryMap[key].type); | ||
return func.call(dataView, startAddress + memoryMap[key].bytesOffset); | ||
const func = READ_WRITE_MAP_V2.get(memoryMap[key].type); | ||
return carrier[func][(startAddress + memoryMap[key].bytesOffset) / memoryMap[key].type.BYTES_PER_ELEMENT]; | ||
}, | ||
@@ -26,0 +33,0 @@ |
@@ -1,5 +0,5 @@ | ||
import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces"; | ||
export declare function objectSaver(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, referencedPointers: number[], objectToSave: any): number; | ||
export declare function mapSaver(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, referencedPointers: number[], mapToSave: Map<string | number, any>): number; | ||
export declare function setSaver(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, setToSave: Set<string | number>): number; | ||
import { ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
export declare function objectSaver(externalArgs: ExternalArgs, carrier: GlobalCarrier, referencedPointers: number[], objectToSave: any): number; | ||
export declare function mapSaver(externalArgs: ExternalArgs, carrier: GlobalCarrier, referencedPointers: number[], mapToSave: Map<string | number, any>): number; | ||
export declare function setSaver(externalArgs: ExternalArgs, carrier: GlobalCarrier, setToSave: Set<string | number>): number; | ||
//# sourceMappingURL=objectSaver.d.ts.map |
@@ -7,3 +7,3 @@ import { appendEntry } from "./store"; | ||
const objectEntries = Object.entries(objectToSave); | ||
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, objectEntries.length * 1.3)); | ||
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, Math.ceil(objectEntries.length * 1.3))); | ||
@@ -13,3 +13,3 @@ for (const [key, value] of objectEntries) { | ||
const pointerToValue = saveValue(externalArgs, carrier, referencedPointers, value); | ||
carrier.dataView.setUint32(ptrToPtr, pointerToValue); | ||
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = pointerToValue; | ||
} | ||
@@ -25,3 +25,3 @@ | ||
export function mapSaver(externalArgs, carrier, referencedPointers, mapToSave) { | ||
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, mapToSave.size * 1.3)); | ||
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, Math.ceil(mapToSave.size * 1.3))); | ||
@@ -31,3 +31,3 @@ for (const [key, value] of mapToSave.entries()) { | ||
const pointerToValue = saveValue(externalArgs, carrier, referencedPointers, value); | ||
carrier.dataView.setUint32(ptrToPtr, pointerToValue); | ||
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = pointerToValue; | ||
} | ||
@@ -43,7 +43,7 @@ | ||
export function setSaver(externalArgs, carrier, setToSave) { | ||
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, setToSave.size * 1.3)); | ||
const hashMapPointer = createHashMap(carrier, Math.max(externalArgs.hashMapMinInitialCapacity, Math.ceil(setToSave.size * 1.3))); | ||
for (const key of setToSave.keys()) { | ||
const ptrToPtr = hashMapInsertUpdate(externalArgs, carrier, hashMapPointer, key); | ||
carrier.dataView.setUint32(ptrToPtr, 1); | ||
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = 1; | ||
} | ||
@@ -50,0 +50,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { ObjectEntry, ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces"; | ||
import { ObjectEntry, ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
import { BaseProxyTrap } from "./BaseProxyTrap"; | ||
@@ -19,3 +19,3 @@ export declare class ObjectWrapper extends BaseProxyTrap<ObjectEntry> implements ProxyHandler<{}> { | ||
} | ||
export declare function createObjectWrapper<T = any>(externalArgs: ExternalArgs, dataViewCarrier: DataViewAndAllocatorCarrier, entryPointer: number): T; | ||
export declare function createObjectWrapper<T = any>(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, entryPointer: number): T; | ||
//# sourceMappingURL=objectWrapper.d.ts.map |
@@ -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)); | ||
} |
@@ -1,11 +0,10 @@ | ||
import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces"; | ||
export declare function deleteObjectPropertyEntryByKey(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, hashmapPointer: number, keyToDeleteBy: string | number): boolean; | ||
export declare function getObjectPropertiesEntries(carrier: DataViewAndAllocatorCarrier, hashmapPointer: number): Array<{ | ||
import { ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
export declare function deleteObjectPropertyEntryByKey(externalArgs: ExternalArgs, carrier: GlobalCarrier, hashmapPointer: number, keyToDeleteBy: string | number): boolean; | ||
export declare function getObjectPropertiesEntries(carrier: GlobalCarrier, hashmapPointer: number): Array<{ | ||
key: string | number; | ||
valuePointer: number; | ||
}>; | ||
export declare function objectSet(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, hashMapPointer: number, p: string | number, value: any): void; | ||
export declare function objectGet(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, entryPointer: number, key: string | number): any; | ||
export declare function hashmapClearFree(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, hashmapPointer: number): void; | ||
export declare function mapOrSetClear(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, mapOrSetPtr: number): void; | ||
export declare function objectSet(externalArgs: ExternalArgs, carrier: GlobalCarrier, hashMapPointer: number, p: string | number, value: any): void; | ||
export declare function objectGet(externalArgs: ExternalArgs, carrier: GlobalCarrier, entryPointer: number, key: string | number): any; | ||
export declare function mapOrSetClear(externalArgs: ExternalArgs, carrier: GlobalCarrier, mapOrSetPtr: number): void; | ||
//# sourceMappingURL=objectWrapperHelpers.d.ts.map |
@@ -1,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) { | ||
@@ -12,3 +12,3 @@ const deletedValuePointerToPointer = hashMapDelete(carrier, hashmapPointer, keyToDeleteBy); // no such key | ||
const deletedValuePointer = carrier.dataView.getUint32(deletedValuePointerToPointer); | ||
const deletedValuePointer = carrier.uint32[deletedValuePointerToPointer / Uint32Array.BYTES_PER_ELEMENT]; | ||
handleArcForDeletedValuePointer(externalArgs, carrier, deletedValuePointer); | ||
@@ -21,10 +21,10 @@ return true; | ||
while (iterator = hashMapLowLevelIterator(carrier.dataView, hashmapPointer, iterator)) { | ||
while (iterator = hashMapLowLevelIterator(carrier, hashmapPointer, iterator)) { | ||
const { | ||
valuePointer, | ||
keyPointer | ||
} = hashMapNodePointerToKeyValue(carrier.dataView, iterator); | ||
} = hashMapNodePointerToKeyValue(carrier, iterator); | ||
const keyEntry = readEntry(carrier, keyPointer); | ||
foundValues.push({ | ||
valuePointer: carrier.dataView.getUint32(valuePointer), | ||
valuePointer: carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT], | ||
key: keyEntry.value | ||
@@ -47,10 +47,39 @@ }); | ||
return entryToFinalJavaScriptValue(externalArgs, carrier, carrier.dataView.getUint32(valuePointer)); | ||
} | ||
export function hashmapClearFree(externalArgs, carrier, hashmapPointer) { | ||
const leafAddresses = []; | ||
const arcAddresses = []; | ||
getObjectOrMapOrSetAddresses(carrier, false, hashmapPointer, leafAddresses, arcAddresses); | ||
return entryToFinalJavaScriptValue(externalArgs, carrier, carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT]); | ||
} // export function hashmapClearFree( | ||
// externalArgs: ExternalArgs, | ||
// carrier: GlobalCarrier, | ||
// hashmapPointer: number | ||
// ) { | ||
// const leafAddresses = new Set<number>(); | ||
// const addressesToProcessQueue: number[] = []; | ||
// getObjectOrMapOrSetAddresses( | ||
// carrier, | ||
// hashmapPointer, | ||
// leafAddresses, | ||
// addressesToProcessQueue | ||
// ); | ||
// for (const address of leafAddresses) { | ||
// carrier.allocator.free(address); | ||
// } | ||
// for (const address of arcAddresses) { | ||
// decrementRefCount(externalArgs, carrier, address); | ||
// } | ||
// } | ||
export function mapOrSetClear(externalArgs, carrier, mapOrSetPtr) { | ||
const entry = readEntry(carrier, mapOrSetPtr); // we fake the entry refCount as zero so getAllLinkedAddresses will visit what's needed | ||
const prevCount = setRefCount(carrier, mapOrSetPtr, 0); | ||
const { | ||
leafAddresses, | ||
arcAddresses | ||
} = getAllLinkedAddresses(carrier, false, mapOrSetPtr); | ||
for (const address of leafAddresses) { | ||
// don't dispose the address we need to reuse | ||
if (address === mapOrSetPtr) { | ||
continue; | ||
} | ||
carrier.allocator.free(address); | ||
@@ -60,10 +89,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); | ||
} |
@@ -1,6 +0,6 @@ | ||
import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces"; | ||
import { ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
/** | ||
* Returns pointer for the value | ||
*/ | ||
export declare function saveValue(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, referencedPointers: number[], value: any): number; | ||
export declare function saveValue(externalArgs: ExternalArgs, carrier: GlobalCarrier, referencedPointers: number[], value: any): number; | ||
//# sourceMappingURL=saveValue.d.ts.map |
@@ -34,3 +34,3 @@ import { primitiveValueToEntry, isPrimitive, getOurPointerIfApplicable } from "./utils"; | ||
valuePointer = appendEntry(externalArgs, carrier, entry); | ||
} else if (maybeOurPointer = getOurPointerIfApplicable(value, carrier.dataView)) { | ||
} else if (maybeOurPointer = getOurPointerIfApplicable(value, carrier.allocator)) { | ||
valuePointer = maybeOurPointer; | ||
@@ -37,0 +37,0 @@ referencedPointers.push(valuePointer); |
@@ -1,2 +0,2 @@ | ||
import { ExternalArgs, DataViewAndAllocatorCarrier, MapEntry, InternalAPI } from "./interfaces"; | ||
import { ExternalArgs, GlobalCarrier, MapEntry, InternalAPI } from "./interfaces"; | ||
import { INTERNAL_API_SYMBOL } from "./symbols"; | ||
@@ -19,3 +19,3 @@ import { BaseProxyTrap } from "./BaseProxyTrap"; | ||
} | ||
export declare function createSetWrapper<K extends string | number>(externalArgs: ExternalArgs, dataViewCarrier: DataViewAndAllocatorCarrier, entryPointer: number): Set<K>; | ||
export declare function createSetWrapper<K extends string | number>(externalArgs: ExternalArgs, globalCarrier: GlobalCarrier, entryPointer: number): Set<K>; | ||
//# sourceMappingURL=setWrapper.d.ts.map |
@@ -19,3 +19,3 @@ import { deleteObjectPropertyEntryByKey, objectSet, mapOrSetClear } from "./objectWrapperHelpers"; | ||
get size() { | ||
return hashMapSize(this.carrier.dataView, this.entry.value); | ||
return hashMapSize(this.carrier, this.entry.value); | ||
} | ||
@@ -28,4 +28,4 @@ | ||
*entries() { | ||
for (const nodePointer of hashmapNodesPointerIterator(this.carrier.dataView, this.entry.value)) { | ||
const t = hashMapNodePointerToKeyValue(this.carrier.dataView, nodePointer); | ||
for (const nodePointer of hashmapNodesPointerIterator(this.carrier, this.entry.value)) { | ||
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer); | ||
const key = entryToFinalJavaScriptValue(this.externalArgs, this.carrier, t.keyPointer); | ||
@@ -37,4 +37,4 @@ yield [key, key]; | ||
*keys() { | ||
for (const nodePointer of hashmapNodesPointerIterator(this.carrier.dataView, this.entry.value)) { | ||
const t = hashMapNodePointerToKeyValue(this.carrier.dataView, nodePointer); | ||
for (const nodePointer of hashmapNodesPointerIterator(this.carrier, this.entry.value)) { | ||
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer); | ||
yield entryToFinalJavaScriptValue(this.externalArgs, this.carrier, t.keyPointer); | ||
@@ -45,4 +45,4 @@ } | ||
*values() { | ||
for (const nodePointer of hashmapNodesPointerIterator(this.carrier.dataView, this.entry.value)) { | ||
const t = hashMapNodePointerToKeyValue(this.carrier.dataView, nodePointer); | ||
for (const nodePointer of hashmapNodesPointerIterator(this.carrier, this.entry.value)) { | ||
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer); | ||
yield entryToFinalJavaScriptValue(this.externalArgs, this.carrier, t.keyPointer); | ||
@@ -92,4 +92,4 @@ } | ||
} | ||
export function createSetWrapper(externalArgs, dataViewCarrier, entryPointer) { | ||
return new SetWrapper(externalArgs, dataViewCarrier, entryPointer); | ||
export function createSetWrapper(externalArgs, globalCarrier, entryPointer) { | ||
return new SetWrapper(externalArgs, globalCarrier, entryPointer); | ||
} |
@@ -1,25 +0,23 @@ | ||
import { Entry, primitive, DataViewAndAllocatorCarrier } from "./interfaces"; | ||
import { Entry, primitive, GlobalCarrier } from "./interfaces"; | ||
import { ExternalArgs } from "./interfaces"; | ||
export declare function initializeArrayBuffer(arrayBuffer: ArrayBuffer): DataView; | ||
export declare function initializeArrayBuffer(arrayBuffer: ArrayBuffer): void; | ||
export declare function sizeOfEntry(entry: Entry): number; | ||
export declare function writeEntry({ dataView, uint8 }: DataViewAndAllocatorCarrier, startingCursor: number, entry: Entry): void; | ||
export declare function appendEntry(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, entry: Entry): number; | ||
export declare function readEntry(carrier: DataViewAndAllocatorCarrier, startingCursor: number): Entry; | ||
export declare function writeEntry(carrier: GlobalCarrier, startingCursor: number, entry: Entry): void; | ||
export declare function appendEntry(externalArgs: ExternalArgs, carrier: GlobalCarrier, entry: Entry): number; | ||
export declare function readEntry(carrier: GlobalCarrier, startingCursor: number): Entry; | ||
export declare function canReuseMemoryOfEntry(entryA: Entry, value: primitive): boolean; | ||
export declare function writeValueInPtrToPtr(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, ptrToPtr: number, value: any): { | ||
export declare function writeValueInPtrToPtr(externalArgs: ExternalArgs, carrier: GlobalCarrier, ptrToPtr: number, value: any): { | ||
referencedPointers: number[]; | ||
existingEntryPointer: number; | ||
existingValueEntry: Entry; | ||
existingValueEntry: import("./interfaces").StringEntry | import("./interfaces").NumberEntry | import("./interfaces").BigIntPositiveEntry | import("./interfaces").BigIntNegativeEntry | import("./interfaces").ObjectEntry | import("./interfaces").ArrayEntry | import("./interfaces").DateEntry | import("./interfaces").MapEntry | import("./interfaces").SetEntry | undefined; | ||
} | undefined; | ||
export declare function writeValueInPtrToPtrAndHandleMemory(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, ptrToPtr: number, value: any): void; | ||
export declare function handleArcForDeletedValuePointer(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, deletedValuePointer: number): void; | ||
export declare function incrementRefCount(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, entryPointer: number): number; | ||
export declare function decrementRefCount(externalArgs: ExternalArgs, carrier: DataViewAndAllocatorCarrier, entryPointer: number): number; | ||
export declare function getObjectPropPtrToPtr({ dataView }: DataViewAndAllocatorCarrier, pointerToEntry: number): { | ||
valuePtrToPtr: number; | ||
nextPtrToPtr: number; | ||
}; | ||
export declare function writeValueInPtrToPtrAndHandleMemory(externalArgs: ExternalArgs, carrier: GlobalCarrier, ptrToPtr: number, value: any): void; | ||
export declare function handleArcForDeletedValuePointer(externalArgs: ExternalArgs, carrier: GlobalCarrier, deletedValuePointer: number): void; | ||
export declare function incrementRefCount(externalArgs: ExternalArgs, carrier: GlobalCarrier, entryPointer: number): number; | ||
export declare function decrementRefCount(externalArgs: ExternalArgs, carrier: GlobalCarrier, entryPointer: number): number; | ||
export declare function getRefCount(carrier: GlobalCarrier, entryPointer: number): number; | ||
export declare function setRefCount(carrier: GlobalCarrier, entryPointer: number, newRefCount: number): number; | ||
export declare function getObjectValuePtrToPtr(pointerToEntry: number): number; | ||
export declare function memComp(dataView: DataView, aStart: number, bStart: number, length: number): boolean; | ||
export declare function compareStringOrNumberEntriesInPlace(dataView: DataView, entryAPointer: number, entryBPointer: number): boolean; | ||
export declare function memComp(uint8: Uint8Array, aStart: number, bStart: number, length: number): boolean; | ||
export declare function compareStringOrNumberEntriesInPlace(carrier: GlobalCarrier, entryAPointer: number, entryBPointer: number): boolean; | ||
//# sourceMappingURL=store.d.ts.map |
@@ -11,13 +11,11 @@ import { ENTRY_TYPE, isPrimitiveEntryType } from "./entry-types"; | ||
export function initializeArrayBuffer(arrayBuffer) { | ||
const dataView = new DataView(arrayBuffer); // global lock | ||
dataView.setInt32(0, 0); // first entry pointer | ||
dataView.setUint32(INITIAL_ENTRY_POINTER_TO_POINTER, INITIAL_ENTRY_POINTER_VALUE); | ||
return dataView; | ||
const uint32 = new Uint32Array(arrayBuffer); | ||
uint32[0] = 0; | ||
uint32[INITIAL_ENTRY_POINTER_TO_POINTER / Uint32Array.BYTES_PER_ELEMENT] = INITIAL_ENTRY_POINTER_VALUE; | ||
} | ||
export function sizeOfEntry(entry) { | ||
let cursor = 0; | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
let cursor = 0; // type | ||
cursor += Float64Array.BYTES_PER_ELEMENT; | ||
switch (entry.type) { | ||
@@ -29,4 +27,4 @@ case ENTRY_TYPE.NUMBER: | ||
case ENTRY_TYPE.STRING: | ||
cursor += Uint16Array.BYTES_PER_ELEMENT; | ||
cursor += Uint16Array.BYTES_PER_ELEMENT; | ||
// string length | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
cursor += entry.allocatedBytes; // oh boy. i don't want to change it now, but no choice | ||
@@ -50,3 +48,5 @@ // @todo: this is incorrect? should be Math.max | ||
case ENTRY_TYPE.SET: | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
// ref count | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; // pointer | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
@@ -56,11 +56,17 @@ break; | ||
case ENTRY_TYPE.ARRAY: | ||
// refsCount | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; // pointer | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; // length | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; // allocated length | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
break; | ||
case ENTRY_TYPE.DATE: | ||
cursor += Float64Array.BYTES_PER_ELEMENT; | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
// timestamp | ||
cursor += Float64Array.BYTES_PER_ELEMENT; // ref count | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
break; | ||
@@ -76,6 +82,3 @@ | ||
} | ||
export function writeEntry({ | ||
dataView, | ||
uint8 | ||
}, startingCursor, entry) { | ||
export function writeEntry(carrier, startingCursor, entry) { | ||
let cursor = startingCursor; // let writtenDataSizeInBytes = 0; | ||
@@ -85,8 +88,8 @@ // write type | ||
dataView.setUint8(cursor, entry.type); | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT] = entry.type; | ||
cursor += Float64Array.BYTES_PER_ELEMENT; | ||
switch (entry.type) { | ||
case ENTRY_TYPE.NUMBER: | ||
dataView.setFloat64(cursor, entry.value); | ||
carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT] = entry.value; | ||
cursor += Float64Array.BYTES_PER_ELEMENT; | ||
@@ -96,10 +99,6 @@ break; | ||
case ENTRY_TYPE.STRING: | ||
dataView.setUint16(cursor, entry.allocatedBytes); | ||
cursor += Uint16Array.BYTES_PER_ELEMENT; | ||
dataView.setUint16(cursor, entry.allocatedBytes); | ||
cursor += Uint16Array.BYTES_PER_ELEMENT; // const arr = new Uint8Array(entry.allocatedBytes); | ||
// const writtenBytes1 = stringEncodeInto(arr, 0, entry.value); | ||
// eslint-disable-next-line no-case-declarations | ||
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.allocatedBytes; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; // eslint-disable-next-line no-case-declarations | ||
const writtenBytes = stringEncodeInto(uint8, cursor, entry.value); | ||
const writtenBytes = stringEncodeInto(carrier.uint8, cursor, entry.value); | ||
@@ -112,3 +111,3 @@ if (writtenBytes !== entry.allocatedBytes) { | ||
allocatedBytes: entry.allocatedBytes | ||
}); | ||
}, true); | ||
throw new Error("WTF???"); | ||
@@ -126,3 +125,3 @@ } | ||
dataView.setBigUint64(cursor, entry.type === ENTRY_TYPE.BIGINT_NEGATIVE ? -entry.value : entry.value); | ||
carrier.bigUint64[cursor / BigUint64Array.BYTES_PER_ELEMENT] = entry.type === ENTRY_TYPE.BIGINT_NEGATIVE ? -entry.value : entry.value; | ||
cursor += BigUint64Array.BYTES_PER_ELEMENT; | ||
@@ -134,24 +133,24 @@ break; | ||
case ENTRY_TYPE.MAP: | ||
dataView.setUint8(cursor, entry.refsCount); | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
dataView.setUint32(cursor, entry.value); | ||
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.refsCount; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.value; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
break; | ||
case ENTRY_TYPE.ARRAY: | ||
dataView.setUint8(cursor, entry.refsCount); | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
dataView.setUint32(cursor, entry.value); | ||
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.refsCount; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
dataView.setUint32(cursor, entry.length); | ||
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.value; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
dataView.setUint32(cursor, entry.allocatedLength); | ||
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.length; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.allocatedLength; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
break; | ||
case ENTRY_TYPE.DATE: | ||
dataView.setUint8(cursor, entry.refsCount); | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
dataView.setFloat64(cursor, entry.value); | ||
carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT] = entry.value; | ||
cursor += Float64Array.BYTES_PER_ELEMENT; | ||
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.refsCount; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
break; | ||
@@ -173,4 +172,4 @@ | ||
let cursor = startingCursor; | ||
const entryType = carrier.dataView.getUint8(cursor); | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
const entryType = carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT]; | ||
cursor += Float64Array.BYTES_PER_ELEMENT; | ||
const entry = { | ||
@@ -182,15 +181,13 @@ type: entryType, | ||
switch (entryType) { | ||
case ENTRY_TYPE.UNDEFINED: | ||
break; | ||
case ENTRY_TYPE.NULL: | ||
break; | ||
case ENTRY_TYPE.BOOLEAN: | ||
entry.value = carrier.dataView.getUint8(cursor) !== 0; | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
break; | ||
// handled by well-known addresses | ||
// case ENTRY_TYPE.UNDEFINED: | ||
// break; | ||
// case ENTRY_TYPE.NULL: | ||
// break; | ||
// case ENTRY_TYPE.BOOLEAN: | ||
// entry.value = carrier.dataView.getUint8(cursor) !== 0; | ||
// cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
// break; | ||
case ENTRY_TYPE.NUMBER: | ||
entry.value = carrier.dataView.getFloat64(cursor); | ||
entry.value = carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT]; | ||
cursor += Float64Array.BYTES_PER_ELEMENT; | ||
@@ -201,6 +198,5 @@ break; | ||
// eslint-disable-next-line no-case-declarations | ||
const stringLength = carrier.dataView.getUint16(cursor); | ||
cursor += Uint16Array.BYTES_PER_ELEMENT; | ||
entry.allocatedBytes = carrier.dataView.getUint16(cursor); | ||
cursor += Uint16Array.BYTES_PER_ELEMENT; // decode fails with zero length array | ||
const stringLength = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT]; | ||
entry.allocatedBytes = stringLength; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; // decode fails with zero length array | ||
@@ -211,4 +207,4 @@ if (stringLength > 0) { | ||
// eslint-disable-next-line no-case-declarations | ||
// const tempAB = new ArrayBuffer(stringLength); | ||
// arrayBufferCopyTo(dataView.buffer, cursor, stringLength, tempAB, 0); | ||
// const tempAB = new ArrayBuffer(stringLength, true); | ||
// arrayBufferCopyTo(dataView.buffer, cursor, stringLength, tempAB, 0, true); | ||
entry.value = stringDecode(carrier.uint8, cursor, stringLength); | ||
@@ -223,3 +219,3 @@ } else { | ||
case ENTRY_TYPE.BIGINT_POSITIVE: | ||
entry.value = carrier.dataView.getBigUint64(cursor); | ||
entry.value = carrier.bigUint64[cursor / BigUint64Array.BYTES_PER_ELEMENT]; | ||
cursor += BigUint64Array.BYTES_PER_ELEMENT; | ||
@@ -229,3 +225,3 @@ break; | ||
case ENTRY_TYPE.BIGINT_NEGATIVE: | ||
entry.value = -carrier.dataView.getBigUint64(cursor); | ||
entry.value = -carrier.bigUint64[cursor / BigUint64Array.BYTES_PER_ELEMENT]; | ||
cursor += BigUint64Array.BYTES_PER_ELEMENT; | ||
@@ -237,24 +233,24 @@ break; | ||
case ENTRY_TYPE.SET: | ||
entry.refsCount = carrier.dataView.getUint8(cursor); | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
entry.value = carrier.dataView.getUint32(cursor); | ||
entry.refsCount = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT]; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
entry.value = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT]; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
break; | ||
case ENTRY_TYPE.ARRAY: | ||
entry.refsCount = carrier.dataView.getUint8(cursor); | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
entry.value = carrier.dataView.getUint32(cursor); | ||
entry.refsCount = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT]; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
entry.length = carrier.dataView.getUint32(cursor); | ||
entry.value = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT]; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
entry.allocatedLength = carrier.dataView.getUint32(cursor); | ||
entry.length = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT]; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
entry.allocatedLength = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT]; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
break; | ||
case ENTRY_TYPE.DATE: | ||
entry.refsCount = carrier.dataView.getUint8(cursor); | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
entry.value = carrier.dataView.getFloat64(cursor); | ||
entry.value = carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT]; | ||
cursor += Float64Array.BYTES_PER_ELEMENT; | ||
entry.refsCount = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT]; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
break; | ||
@@ -286,6 +282,13 @@ | ||
export function writeValueInPtrToPtr(externalArgs, carrier, ptrToPtr, value) { | ||
const existingEntryPointer = carrier.dataView.getUint32(ptrToPtr); | ||
const existingValueEntry = readEntry(carrier, existingEntryPointer); // try to re use memory | ||
const existingEntryPointer = carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT]; | ||
let reuse = false; | ||
let existingValueEntry; | ||
if (!isKnownAddressValuePointer(existingEntryPointer) && isPrimitive(value) && isPrimitiveEntryType(existingValueEntry.type) && canReuseMemoryOfEntry(existingValueEntry, value)) { | ||
if (!isKnownAddressValuePointer(existingEntryPointer)) { | ||
existingValueEntry = readEntry(carrier, existingEntryPointer); | ||
reuse = isPrimitive(value) && isPrimitiveEntryType(existingValueEntry.type) && canReuseMemoryOfEntry(existingValueEntry, value); | ||
} // try to re use memory | ||
if (reuse) { | ||
const newEntry = primitiveValueToEntry(value); | ||
@@ -296,3 +299,3 @@ writeEntry(carrier, existingEntryPointer, newEntry); | ||
const newEntryPointer = saveValue(externalArgs, carrier, referencedPointers, value); | ||
carrier.dataView.setUint32(ptrToPtr, newEntryPointer); | ||
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = newEntryPointer; | ||
return { | ||
@@ -384,18 +387,41 @@ referencedPointers, | ||
} | ||
export function getObjectPropPtrToPtr({ | ||
dataView | ||
}, pointerToEntry) { | ||
const keyStringLength = dataView.getUint16(pointerToEntry + 1); | ||
const valuePtrToPtr = Uint16Array.BYTES_PER_ELEMENT + pointerToEntry + 1 + keyStringLength; | ||
const nextPtrToPtr = valuePtrToPtr + Uint32Array.BYTES_PER_ELEMENT; | ||
return { | ||
valuePtrToPtr, | ||
nextPtrToPtr | ||
}; | ||
export function 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( | ||
// { dataView }: GlobalCarrier, | ||
// pointerToEntry: number | ||
// ) { | ||
// const keyStringLength = dataView.getUint16(pointerToEntry + 1); | ||
// const valuePtrToPtr = | ||
// Uint16Array.BYTES_PER_ELEMENT + pointerToEntry + 1 + keyStringLength; | ||
// const nextPtrToPtr = valuePtrToPtr + Uint32Array.BYTES_PER_ELEMENT; | ||
// return { | ||
// valuePtrToPtr, | ||
// nextPtrToPtr | ||
// }; | ||
// } | ||
export function getObjectValuePtrToPtr(pointerToEntry) { | ||
return pointerToEntry + 1 + 1; | ||
} | ||
export function memComp(dataView, aStart, bStart, length) { | ||
if (dataView.byteLength < aStart + length || dataView.byteLength < bStart + length) { | ||
export function memComp(uint8, aStart, bStart, length) { | ||
if (uint8.byteLength < aStart + length || uint8.byteLength < bStart + length) { | ||
return false; | ||
@@ -406,3 +432,3 @@ } | ||
// compare 8 using Float64Array? | ||
if (dataView.getUint8(aStart + i) !== dataView.getUint8(bStart + i)) { | ||
if (uint8[aStart + i] !== uint8[bStart + i]) { | ||
return false; | ||
@@ -414,7 +440,7 @@ } | ||
} | ||
export function compareStringOrNumberEntriesInPlace(dataView, entryAPointer, entryBPointer) { | ||
export function compareStringOrNumberEntriesInPlace(carrier, entryAPointer, entryBPointer) { | ||
let cursor = 0; | ||
const entryAType = dataView.getUint8(entryAPointer + cursor); | ||
const entryBType = dataView.getUint8(entryBPointer + cursor); | ||
cursor += 1; | ||
const entryAType = carrier.float64[(entryAPointer + cursor) / Float64Array.BYTES_PER_ELEMENT]; | ||
const entryBType = carrier.float64[(entryBPointer + cursor) / Float64Array.BYTES_PER_ELEMENT]; | ||
cursor += Float64Array.BYTES_PER_ELEMENT; | ||
@@ -426,4 +452,4 @@ if (entryAType !== entryBType) { | ||
if (entryAType === ENTRY_TYPE.STRING) { | ||
const aLength = dataView.getUint16(entryAPointer + cursor); | ||
const bLength = dataView.getUint16(entryBPointer + cursor); | ||
const aLength = carrier.uint32[(entryAPointer + cursor) / Uint32Array.BYTES_PER_ELEMENT]; | ||
const bLength = carrier.uint32[(entryBPointer + cursor) / Uint32Array.BYTES_PER_ELEMENT]; | ||
@@ -435,9 +461,7 @@ if (aLength !== bLength) { | ||
cursor += Uint16Array.BYTES_PER_ELEMENT; // allocated length, skip. | ||
cursor += Uint16Array.BYTES_PER_ELEMENT; | ||
return memComp(dataView, entryAPointer + cursor, entryBPointer + cursor, aLength); | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
return memComp(carrier.uint8, entryAPointer + cursor, entryBPointer + cursor, aLength); | ||
} | ||
return dataView.getFloat64(entryAPointer + cursor) === dataView.getFloat64(entryBPointer + cursor); | ||
return carrier.float64[(entryAPointer + cursor) / Float64Array.BYTES_PER_ELEMENT] === carrier.float64[(entryBPointer + cursor) / Float64Array.BYTES_PER_ELEMENT]; | ||
} |
@@ -90,3 +90,3 @@ export function arrayBuffer2HexArray(buffer, withByteNumber = false) { | ||
const carrier = { | ||
dataView: new DataView(arrayBuffer), | ||
// dataView: new DataView(arrayBuffer), | ||
allocator, | ||
@@ -93,0 +93,0 @@ uint8: new Uint8Array(arrayBuffer), |
import { primitive, Entry, ExternalArgs, InternalAPI, ExternalArgsApi } from "./interfaces"; | ||
import { IMemPool } from "@thi.ng/malloc"; | ||
export declare function isPrimitive(value: unknown): value is primitive; | ||
@@ -7,3 +8,3 @@ export declare function primitiveValueToEntry(value: primitive): Entry; | ||
export declare function arrayBufferCopyTo(origin: ArrayBuffer, startByte: number, length: number, target: ArrayBuffer, toTargetByte: number): void; | ||
export declare function getOurPointerIfApplicable(value: any, ourDateView: DataView): number | undefined; | ||
export declare function getOurPointerIfApplicable(value: any, ourAllocator: IMemPool): number | undefined; | ||
export declare function externalArgsApiToExternalArgsApi(p: ExternalArgsApi): ExternalArgs; | ||
@@ -10,0 +11,0 @@ export declare function getInternalAPI(value: any): InternalAPI; |
@@ -54,12 +54,9 @@ import { ENTRY_TYPE } from "./entry-types"; | ||
const copyTo = new Uint8Array(target); | ||
for (let i = 0; i < length; i += 1) { | ||
copyTo[toTargetByte + i] = copyFrom[startByte + i]; | ||
} | ||
copyTo.set(copyFrom.subarray(startByte, startByte + length), toTargetByte); | ||
} | ||
export function getOurPointerIfApplicable(value, ourDateView) { | ||
export function getOurPointerIfApplicable(value, ourAllocator) { | ||
if (INTERNAL_API_SYMBOL in value) { | ||
const api = getInternalAPI(value); | ||
if (api.getCarrier().dataView === ourDateView) { | ||
if (api.getCarrier().allocator === ourAllocator) { | ||
return api.getEntryPointer(); | ||
@@ -66,0 +63,0 @@ } |
@@ -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-738fce6", | ||
"version": "0.0.0-7d79fe6", | ||
"main": "dist/objectbuffer.cjs.js", | ||
@@ -39,36 +39,36 @@ "module": "dist/index.js", | ||
"devDependencies": { | ||
"@babel/cli": "^7.7.5", | ||
"@babel/core": "^7.7.5", | ||
"@babel/preset-env": "^7.7.6", | ||
"@babel/preset-typescript": "^7.7.4", | ||
"@babel/cli": "^7.8.4", | ||
"@babel/core": "^7.9.0", | ||
"@babel/preset-env": "^7.9.5", | ||
"@babel/preset-typescript": "^7.9.0", | ||
"@types/benchmark": "^1.0.31", | ||
"@types/jest": "^24.0.24", | ||
"@types/jest": "^25.2.1", | ||
"@types/node": "^12.12.21", | ||
"@typescript-eslint/eslint-plugin": "^2.12.0", | ||
"@typescript-eslint/parser": "^2.12.0", | ||
"babel-loader": "^8.0.6", | ||
"@typescript-eslint/eslint-plugin": "^2.27.0", | ||
"@typescript-eslint/parser": "^2.27.0", | ||
"babel-loader": "^8.1.0", | ||
"benchmark": "^2.1.4", | ||
"concurrently": "^5.0.2", | ||
"core-js": "^3.5.0", | ||
"eslint": "^6.7.2", | ||
"eslint-config-prettier": "^6.7.0", | ||
"concurrently": "^5.1.0", | ||
"core-js": "^3.6.5", | ||
"eslint": "^6.8.0", | ||
"eslint-config-prettier": "^6.10.1", | ||
"eslint-plugin-prettier": "^3.1.2", | ||
"gh-pages": "^2.1.1", | ||
"html-webpack-plugin": "^3.2.0", | ||
"husky": "^3.1.0", | ||
"jest": "^24.9.0", | ||
"prettier": "^1.19.1", | ||
"gh-pages": "^2.2.0", | ||
"html-webpack-plugin": "^4.2.0", | ||
"husky": "^4.2.5", | ||
"jest": "^25.3.0", | ||
"prettier": "^2.0.4", | ||
"prettier-eslint": "^9.0.1", | ||
"rimraf": "^3.0.0", | ||
"rollup": "^1.27.13", | ||
"rollup-plugin-babel": "^4.3.3", | ||
"rimraf": "^3.0.2", | ||
"rollup": "^2.4.0", | ||
"rollup-plugin-babel": "^4.4.0", | ||
"rollup-plugin-node-resolve": "^5.2.0", | ||
"typedoc": "npm:@gnd/typedoc", | ||
"typedoc-plugin-markdown": "^2.2.14", | ||
"typescript": "^3.7.3", | ||
"webpack": "^4.41.3", | ||
"webpack-cli": "^3.3.10", | ||
"webpack-dev-server": "^3.10.0", | ||
"typedoc": "^0.17.4", | ||
"typedoc-plugin-markdown": "^2.2.17", | ||
"typescript": "^3.8.3", | ||
"webpack": "^4.42.1", | ||
"webpack-cli": "^3.3.11", | ||
"webpack-dev-server": "^3.10.3", | ||
"worker-loader": "^2.0.0", | ||
"yarn-deduplicate": "^1.1.1" | ||
"yarn-deduplicate": "^2.0.0" | ||
}, | ||
@@ -87,8 +87,5 @@ "husky": { | ||
], | ||
"resolutions": { | ||
"typescript": "^3.7.2" | ||
}, | ||
"dependencies": { | ||
"@thi.ng/malloc": "^4.1.1" | ||
"@thi.ng/malloc": "^4.1.10" | ||
} | ||
} |
@@ -14,3 +14,3 @@ /* eslint-env jest */ | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -40,4 +40,4 @@ | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`624`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`592`); | ||
}); | ||
}); |
@@ -13,3 +13,3 @@ /* eslint-env jest */ | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -20,3 +20,3 @@ | ||
// 1/1 2000 | ||
myDate: new Date(946684800000) | ||
myDate: new Date(946684800000), | ||
}); | ||
@@ -50,4 +50,4 @@ | ||
expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`240`); | ||
expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`264`); | ||
}); | ||
}); |
@@ -13,3 +13,3 @@ /* eslint-env jest */ | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -57,4 +57,4 @@ | ||
expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`728`); | ||
expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`776`); | ||
}); | ||
}); |
@@ -12,3 +12,3 @@ /* eslint-env jest */ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder() | ||
textDecoder: new util.TextDecoder(), | ||
}); | ||
@@ -18,6 +18,6 @@ | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {}); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`); | ||
objectBuffer.foo = new Map([[1, "a"]]); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`624`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`592`); | ||
expect(objectBuffer.foo).toMatchInlineSnapshot(` | ||
@@ -32,7 +32,7 @@ Map { | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {}); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`); | ||
objectBuffer.foo = new Map([[1, "a"]]); | ||
objectBuffer.foo.set("2", "b"); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`504`); | ||
expect(objectBuffer.foo).toMatchInlineSnapshot(` | ||
@@ -56,11 +56,11 @@ Map { | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {}); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`); | ||
objectBuffer.foo = new Map([[1, "a"]]); | ||
objectBuffer.foo.set("2", "b"); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`504`); | ||
objectBuffer.foo.delete(1); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`632`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`592`); | ||
@@ -76,11 +76,14 @@ expect(objectBuffer.foo).toMatchInlineSnapshot(` | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {}); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`); | ||
objectBuffer.foo = new Map([[1, "a"]]); | ||
objectBuffer.foo = new Map(); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`680`); | ||
objectBuffer.foo.set(1, "a"); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`592`); | ||
objectBuffer.foo.set("2", "b"); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`504`); | ||
objectBuffer.foo.clear(); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`704`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`680`); | ||
@@ -92,3 +95,3 @@ expect(objectBuffer.foo).toMatchInlineSnapshot(`Map {}`); | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {}); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`); | ||
@@ -98,3 +101,3 @@ objectBuffer.foo = new Map([[1, "a"]]); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`504`); | ||
@@ -126,3 +129,3 @@ expect(objectBuffer.foo).toMatchInlineSnapshot(` | ||
[1, "a"], | ||
[2, "b"] | ||
[2, "b"], | ||
]); | ||
@@ -136,4 +139,4 @@ for (const [key] of nativeMap) { | ||
[1, "a"], | ||
[2, "b"] | ||
]) | ||
[2, "b"], | ||
]), | ||
}); | ||
@@ -149,3 +152,3 @@ for (const [key] of objectBuffer.foo) { | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {}); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`); | ||
@@ -163,3 +166,3 @@ objectBuffer.foo = new Map([[1, "a"]]); | ||
expect(thisArgs.every(v => v === objectBuffer.foo)).toBe(true); | ||
expect(thisArgs.every((v) => v === objectBuffer.foo)).toBe(true); | ||
@@ -166,0 +169,0 @@ expect(dump).toMatchInlineSnapshot(` |
@@ -13,3 +13,3 @@ /* eslint-env jest */ | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -20,3 +20,3 @@ | ||
arr: [1, 2, 3, 4], | ||
obj: { a: 1 } | ||
obj: { a: 1 }, | ||
}); | ||
@@ -26,4 +26,4 @@ | ||
Object { | ||
"available": 424, | ||
"used": 600, | ||
"available": 376, | ||
"used": 648, | ||
} | ||
@@ -36,3 +36,3 @@ `); | ||
arr: [1, 2, 3, 4], | ||
obj: { a: 1 } | ||
obj: { a: 1 }, | ||
}); | ||
@@ -42,4 +42,4 @@ | ||
Object { | ||
"available": 1448, | ||
"used": 600, | ||
"available": 1400, | ||
"used": 648, | ||
} | ||
@@ -51,4 +51,4 @@ `); | ||
Object { | ||
"available": 424, | ||
"used": 600, | ||
"available": 376, | ||
"used": 648, | ||
} | ||
@@ -60,4 +60,4 @@ `); | ||
Object { | ||
"available": 168, | ||
"used": 600, | ||
"available": 120, | ||
"used": 648, | ||
} | ||
@@ -68,8 +68,8 @@ `); | ||
expect(memoryStats(objectBuffer)).toMatchInlineSnapshot(` | ||
Object { | ||
"available": 1448, | ||
"used": 600, | ||
} | ||
`); | ||
Object { | ||
"available": 1400, | ||
"used": 648, | ||
} | ||
`); | ||
}); | ||
}); |
@@ -12,3 +12,3 @@ /* eslint-env jest */ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder() | ||
textDecoder: new util.TextDecoder(), | ||
}); | ||
@@ -18,10 +18,10 @@ | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {}); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`); | ||
objectBuffer.foo = "a"; | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`800`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`776`); | ||
delete objectBuffer.foo; | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`); | ||
expect(objectBuffer).toMatchInlineSnapshot(`Object {}`); | ||
@@ -37,7 +37,7 @@ }); | ||
e: undefined, | ||
foo: { a: 1, b: true, c: false, d: null, e: undefined } | ||
foo: { a: 1, b: true, c: false, d: null, e: undefined }, | ||
}; | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, input); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`96`); | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 2048, input); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`1016`); | ||
expect(input).toEqual(objectBuffer); | ||
@@ -44,0 +44,0 @@ expect(objectBuffer).toMatchInlineSnapshot(` |
@@ -9,7 +9,7 @@ /* eslint-env jest */ | ||
replaceUnderlyingArrayBuffer, | ||
memoryStats | ||
memoryStats, | ||
} from "../internal/api"; | ||
import { | ||
arrayBufferCopyTo, | ||
externalArgsApiToExternalArgsApi | ||
externalArgsApiToExternalArgsApi, | ||
} from "../internal/utils"; | ||
@@ -21,3 +21,3 @@ | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -27,3 +27,3 @@ | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 512, { | ||
a: 1 | ||
a: 1, | ||
}); | ||
@@ -42,3 +42,3 @@ | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`792`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`776`); | ||
expect(objectBuffer).toMatchInlineSnapshot(` | ||
@@ -53,3 +53,3 @@ Object { | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, { | ||
obj1: { a: 1 } | ||
obj1: { a: 1 }, | ||
}); | ||
@@ -56,0 +56,0 @@ |
@@ -14,3 +14,3 @@ /* eslint-env jest */ | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -25,4 +25,4 @@ | ||
test("Fail to set new data when enough memory", () => { | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 256, { | ||
value: "first value 123" | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 312, { | ||
value: "first value 123", | ||
}); | ||
@@ -36,3 +36,3 @@ const freeSpaceLeft = memoryStats(objectBuffer).available; | ||
expect(memoryStats(objectBuffer).available).toEqual(freeSpaceLeft); | ||
expect(freeSpaceLeft).toMatchInlineSnapshot(`8`); | ||
expect(freeSpaceLeft).toMatchInlineSnapshot(`40`); | ||
@@ -39,0 +39,0 @@ expect(objectBuffer).toMatchInlineSnapshot(` |
@@ -12,3 +12,3 @@ /* eslint-env jest */ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder() | ||
textDecoder: new util.TextDecoder(), | ||
}); | ||
@@ -18,6 +18,6 @@ | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {}); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`); | ||
objectBuffer.foo = new Set(["a"]); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`648`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`616`); | ||
expect(objectBuffer.foo).toMatchInlineSnapshot(` | ||
@@ -32,7 +32,7 @@ Set { | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {}); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`); | ||
objectBuffer.foo = new Set(["a"]); | ||
objectBuffer.foo.add("b"); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`592`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`); | ||
expect(objectBuffer.foo).toMatchInlineSnapshot(` | ||
@@ -56,11 +56,11 @@ Set { | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {}); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`); | ||
objectBuffer.foo = new Set(["a"]); | ||
objectBuffer.foo.add("b"); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`592`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`); | ||
objectBuffer.foo.delete(1); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`592`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`); | ||
@@ -77,11 +77,11 @@ expect(objectBuffer.foo).toMatchInlineSnapshot(` | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {}); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`); | ||
objectBuffer.foo = new Set(["a"]); | ||
objectBuffer.foo.add("b"); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`592`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`); | ||
objectBuffer.foo.clear(); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`704`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`680`); | ||
@@ -93,3 +93,3 @@ expect(objectBuffer.foo).toMatchInlineSnapshot(`Set {}`); | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {}); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`); | ||
@@ -99,3 +99,3 @@ objectBuffer.foo = new Set(["a"]); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`592`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`552`); | ||
@@ -131,3 +131,3 @@ expect(objectBuffer.foo).toMatchInlineSnapshot(` | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, { | ||
foo: new Set(["a", "b"]) | ||
foo: new Set(["a", "b"]), | ||
}); | ||
@@ -143,3 +143,3 @@ for (const [key] of objectBuffer.foo) { | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 1024, {}); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`872`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`864`); | ||
@@ -157,3 +157,3 @@ objectBuffer.foo = new Set(["a"]); | ||
expect(thisArgs.every(v => v === objectBuffer.foo)).toBe(true); | ||
expect(thisArgs.every((v) => v === objectBuffer.foo)).toBe(true); | ||
@@ -160,0 +160,0 @@ expect(dump).toMatchInlineSnapshot(` |
@@ -14,3 +14,3 @@ /* eslint-env jest */ | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -38,3 +38,3 @@ | ||
expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`440`); | ||
expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`480`); | ||
}); | ||
@@ -88,4 +88,4 @@ | ||
expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`608`); | ||
expect(memoryStats(objectBuffer).used).toMatchInlineSnapshot(`664`); | ||
}); | ||
}); |
@@ -12,3 +12,3 @@ import * as util from "util"; | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -18,3 +18,3 @@ | ||
const objectBuffer = createObjectBuffer<any>(externalArgs, 256, { | ||
foo: null | ||
foo: null, | ||
}); | ||
@@ -24,3 +24,3 @@ | ||
expect(initialFreeSpace).toMatchInlineSnapshot(`48`); | ||
expect(initialFreeSpace).toMatchInlineSnapshot(`32`); | ||
@@ -31,7 +31,7 @@ expect(() => { | ||
more: "than size", | ||
arr: [1, 2, 3] | ||
arr: [1, 2, 3], | ||
}; | ||
}).toThrowErrorMatchingInlineSnapshot(`"OutOfMemoryError"`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`48`); | ||
expect(memoryStats(objectBuffer).available).toMatchInlineSnapshot(`32`); | ||
@@ -38,0 +38,0 @@ expect(objectBuffer).toMatchInlineSnapshot(` |
@@ -12,3 +12,3 @@ import * as util from "util"; | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -18,3 +18,3 @@ | ||
const objectBuffer = createObjectBuffer(externalArgs, 128, { | ||
num: 1 as number | bigint | ||
num: 1 as number | bigint, | ||
}); | ||
@@ -54,3 +54,3 @@ | ||
const objectBuffer = createObjectBuffer(externalArgs, 128, { | ||
nullContainer: null as null | undefined | ||
nullContainer: null as null | undefined, | ||
}); | ||
@@ -83,3 +83,3 @@ | ||
const objectBuffer = createObjectBuffer(externalArgs, 128, { | ||
booleanContainer: false | ||
booleanContainer: false, | ||
}); | ||
@@ -86,0 +86,0 @@ |
@@ -7,3 +7,3 @@ /* eslint-env jest */ | ||
getUnderlyingArrayBuffer, | ||
loadObjectBuffer | ||
loadObjectBuffer, | ||
} from "."; | ||
@@ -17,3 +17,3 @@ import { arrayBuffer2HexArray } from "./internal/testUtils"; | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -25,3 +25,3 @@ | ||
b: null, | ||
c: { t: 5 } | ||
c: { t: 5 }, | ||
}); | ||
@@ -45,3 +45,3 @@ | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -51,3 +51,3 @@ test("getUnderlyingArrayBuffer simple", () => { | ||
b: null, | ||
c: { t: 5 } | ||
c: { t: 5 }, | ||
}); | ||
@@ -68,3 +68,3 @@ | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -76,3 +76,3 @@ | ||
b: null, | ||
c: { t: 5 } | ||
c: { t: 5 }, | ||
}); | ||
@@ -79,0 +79,0 @@ |
@@ -20,3 +20,3 @@ /** | ||
disposeWrapperObject, | ||
updateExternalArgs | ||
updateExternalArgs, | ||
} from "./internal/api"; | ||
@@ -23,0 +23,0 @@ export { acquireLock, acquireLockWait, releaseLock } from "./internal/locks"; |
import { initializeArrayBuffer } from "./store"; | ||
import { objectSaver } from "./objectSaver"; | ||
import { createObjectWrapper } from "./objectWrapper"; | ||
import { ExternalArgsApi, DataViewAndAllocatorCarrier } from "./interfaces"; | ||
import { ExternalArgsApi, GlobalCarrier } from "./interfaces"; | ||
import { | ||
arrayBufferCopyTo, | ||
externalArgsApiToExternalArgsApi, | ||
getInternalAPI | ||
getInternalAPI, | ||
isPrimitive, | ||
} from "./utils"; | ||
@@ -13,2 +14,3 @@ import { getCacheFor } from "./externalObjectsCache"; | ||
import { MemPool } from "@thi.ng/malloc"; | ||
import { UnsupportedOperationError } from "./exceptions"; | ||
@@ -36,14 +38,25 @@ export interface CreateObjectBufferOptions { | ||
): T { | ||
if ( | ||
Array.isArray(initialValue) || | ||
initialValue instanceof Date || | ||
initialValue instanceof Map || | ||
initialValue instanceof Set || | ||
isPrimitive(initialValue) | ||
) { | ||
throw new UnsupportedOperationError(); | ||
} | ||
const arrayBuffer = new (options.useSharedArrayBuffer | ||
? SharedArrayBuffer | ||
: ArrayBuffer)(size); | ||
const dataView = initializeArrayBuffer(arrayBuffer); | ||
initializeArrayBuffer(arrayBuffer); | ||
const allocator = new MemPool({ | ||
align: 8, | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
const carrier: DataViewAndAllocatorCarrier = { | ||
dataView, | ||
const carrier: GlobalCarrier = { | ||
// dataView, | ||
allocator, | ||
@@ -54,3 +67,3 @@ uint8: new Uint8Array(arrayBuffer), | ||
float64: new Float64Array(arrayBuffer), | ||
bigUint64: new BigUint64Array(arrayBuffer) | ||
bigUint64: new BigUint64Array(arrayBuffer), | ||
}; | ||
@@ -65,3 +78,5 @@ | ||
dataView.setUint32(INITIAL_ENTRY_POINTER_TO_POINTER, start); | ||
carrier.uint32[ | ||
INITIAL_ENTRY_POINTER_TO_POINTER / Uint32Array.BYTES_PER_ELEMENT | ||
] = start; | ||
@@ -101,3 +116,3 @@ return createObjectWrapper( | ||
): ArrayBuffer | SharedArrayBuffer { | ||
return getInternalAPI(objectBuffer).getCarrier().dataView.buffer; | ||
return getInternalAPI(objectBuffer).getCarrier().uint8.buffer; | ||
} | ||
@@ -118,11 +133,12 @@ | ||
): T { | ||
const dataView = new DataView(arrayBuffer); | ||
// const dataView = new DataView(arrayBuffer); | ||
const allocator = new MemPool({ | ||
align: 8, | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START, | ||
skipInitialization: true | ||
skipInitialization: true, | ||
}); | ||
const carrier: DataViewAndAllocatorCarrier = { | ||
dataView, | ||
const carrier: GlobalCarrier = { | ||
// dataView, | ||
allocator, | ||
@@ -133,3 +149,3 @@ uint8: new Uint8Array(arrayBuffer), | ||
float64: new Float64Array(arrayBuffer), | ||
bigUint64: new BigUint64Array(arrayBuffer) | ||
bigUint64: new BigUint64Array(arrayBuffer), | ||
}; | ||
@@ -140,3 +156,5 @@ | ||
carrier, | ||
dataView.getUint32(INITIAL_ENTRY_POINTER_TO_POINTER) | ||
carrier.uint32[ | ||
INITIAL_ENTRY_POINTER_TO_POINTER / Uint32Array.BYTES_PER_ELEMENT | ||
] | ||
); | ||
@@ -170,9 +188,10 @@ } | ||
const allocator = new MemPool({ | ||
align: 8, | ||
buf: newArrayBuffer, | ||
start: MEM_POOL_START, | ||
skipInitialization: true | ||
skipInitialization: true, | ||
}); | ||
const carrier: DataViewAndAllocatorCarrier = { | ||
dataView: new DataView(newArrayBuffer), | ||
const carrier: GlobalCarrier = { | ||
// dataView: new DataView(newArrayBuffer), | ||
allocator, | ||
@@ -183,3 +202,3 @@ uint8: new Uint8Array(newArrayBuffer), | ||
float64: new Float64Array(newArrayBuffer), | ||
bigUint64: new BigUint64Array(newArrayBuffer) | ||
bigUint64: new BigUint64Array(newArrayBuffer), | ||
}; | ||
@@ -203,5 +222,6 @@ | ||
const pool = new MemPool({ | ||
align: 8, | ||
buf, | ||
skipInitialization: true, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -208,0 +228,0 @@ |
@@ -9,3 +9,3 @@ /* eslint-env jest */ | ||
getFinalValueAtArrayIndex, | ||
setValueAtArrayIndex | ||
setValueAtArrayIndex, | ||
} from "./arrayHelpers"; | ||
@@ -21,3 +21,3 @@ import { ExternalArgs } from "./interfaces"; | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 0 | ||
arrayAdditionalAllocation: 0, | ||
}); | ||
@@ -47,3 +47,3 @@ | ||
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`128`); | ||
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`120`); | ||
}); | ||
@@ -59,3 +59,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -75,3 +75,3 @@ | ||
expect(finalValue).toMatchInlineSnapshot(`1`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`128`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`120`); | ||
}); | ||
@@ -86,3 +86,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -102,3 +102,3 @@ | ||
expect(finalValue).toMatchInlineSnapshot(`undefined`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`128`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`120`); | ||
}); | ||
@@ -113,3 +113,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -129,3 +129,3 @@ | ||
expect(finalValue).toMatchInlineSnapshot(`"b"`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`144`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`120`); | ||
}); | ||
@@ -141,3 +141,3 @@ }); | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -165,4 +165,4 @@ | ||
expect(finalValue).toMatchInlineSnapshot(`"im the new value"`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`120`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`104`); | ||
}); | ||
}); |
import { | ||
readEntry, | ||
writeEntry, | ||
writeValueInPtrToPtrAndHandleMemory | ||
writeValueInPtrToPtrAndHandleMemory, | ||
} from "./store"; | ||
import { | ||
ArrayEntry, | ||
ExternalArgs, | ||
DataViewAndAllocatorCarrier | ||
} from "./interfaces"; | ||
import { ArrayEntry, ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue"; | ||
@@ -16,3 +12,3 @@ import { ENTRY_TYPE } from "./entry-types"; | ||
export function arrayGetMetadata( | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
pointerToArrayEntry: number | ||
@@ -26,3 +22,3 @@ ) { | ||
export function arrayGetPointersToValueInIndex( | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
pointerToArrayEntry: number, | ||
@@ -41,7 +37,8 @@ indexToGet: number | ||
const pointer = carrier.dataView.getUint32(pointerToThePointer); | ||
const pointer = | ||
carrier.uint32[pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT]; | ||
return { | ||
pointer, | ||
pointerToThePointer | ||
pointerToThePointer, | ||
}; | ||
@@ -52,3 +49,3 @@ } | ||
externalArgs: ExternalArgs, | ||
dataViewCarrier: DataViewAndAllocatorCarrier, | ||
globalCarrier: GlobalCarrier, | ||
pointerToArrayEntry: number, | ||
@@ -58,3 +55,3 @@ indexToGet: number | ||
const pointers = arrayGetPointersToValueInIndex( | ||
dataViewCarrier, | ||
globalCarrier, | ||
pointerToArrayEntry, | ||
@@ -70,3 +67,3 @@ indexToGet | ||
externalArgs, | ||
dataViewCarrier, | ||
globalCarrier, | ||
pointers.pointer | ||
@@ -77,3 +74,3 @@ ); | ||
export function setValuePointerAtArrayIndex( | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
pointerToArrayEntry: number, | ||
@@ -90,4 +87,5 @@ indexToSet: number, | ||
assertNonNull(pointers); | ||
carrier.dataView.setUint32(pointers.pointerToThePointer, pointerToEntry); | ||
carrier.uint32[ | ||
pointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT | ||
] = pointerToEntry; | ||
} | ||
@@ -97,3 +95,3 @@ | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
pointerToArrayEntry: number, | ||
@@ -123,3 +121,3 @@ indexToSet: number, | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
pointerToArrayEntry: number, | ||
@@ -146,3 +144,3 @@ wishedLength: number | ||
allocatedLength: metadata.allocatedLength, | ||
length: wishedLength | ||
length: wishedLength, | ||
}); | ||
@@ -158,3 +156,3 @@ } | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
pointerToArrayEntry: number, | ||
@@ -170,3 +168,3 @@ wishedLength: number | ||
allocatedLength: metadata.allocatedLength, | ||
length: wishedLength | ||
length: wishedLength, | ||
}); | ||
@@ -177,3 +175,3 @@ } | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
pointerToArrayEntry: number, | ||
@@ -208,3 +206,3 @@ newAllocatedLength: number, | ||
allocatedLength: newAllocatedLength, | ||
length: newLength | ||
length: newLength, | ||
}); | ||
@@ -215,17 +213,18 @@ } | ||
externalArgs: ExternalArgs, | ||
dataViewCarrier: DataViewAndAllocatorCarrier, | ||
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(pointerToPointer => | ||
dataViewCarrier.dataView.getUint32(pointerToPointer) | ||
.map((index) => metadata.value + index * Uint32Array.BYTES_PER_ELEMENT) | ||
.map( | ||
(pointerToPointer) => | ||
globalCarrier.uint32[pointerToPointer / Uint32Array.BYTES_PER_ELEMENT] | ||
); | ||
const sortMe = pointersToValues.map(pointer => { | ||
const sortMe = pointersToValues.map((pointer) => { | ||
return [ | ||
pointer, | ||
entryToFinalJavaScriptValue(externalArgs, dataViewCarrier, pointer) | ||
entryToFinalJavaScriptValue(externalArgs, globalCarrier, pointer), | ||
] as const; | ||
@@ -239,6 +238,6 @@ }); | ||
for (let i = 0; i < sortMe.length; i += 1) { | ||
dataViewCarrier.dataView.setUint32( | ||
metadata.value + i * Uint32Array.BYTES_PER_ELEMENT, | ||
sortMe[i][0] | ||
); | ||
globalCarrier.uint32[ | ||
(metadata.value + i * Uint32Array.BYTES_PER_ELEMENT) / | ||
Uint32Array.BYTES_PER_ELEMENT | ||
] = sortMe[i][0]; | ||
} | ||
@@ -286,3 +285,3 @@ } | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
pointerToArrayEntry: number | ||
@@ -289,0 +288,0 @@ ) { |
@@ -13,3 +13,3 @@ /* eslint-env jest */ | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
@@ -16,0 +16,0 @@ |
import { appendEntry } from "./store"; | ||
import { ENTRY_TYPE } from "./entry-types"; | ||
import { | ||
ArrayEntry, | ||
ExternalArgs, | ||
DataViewAndAllocatorCarrier | ||
} from "./interfaces"; | ||
import { ArrayEntry, ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
import { saveValue } from "./saveValue"; | ||
@@ -12,3 +8,3 @@ | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
referencedPointers: number[], | ||
@@ -28,3 +24,3 @@ arrayToSave: Array<any> | ||
arrayToSave.length + externalArgs.arrayAdditionalAllocation, | ||
length: arrayToSave.length | ||
length: arrayToSave.length, | ||
}; | ||
@@ -35,3 +31,6 @@ | ||
carrier.dataView.setUint32(memoryForPointersCursor, rOfValue); | ||
carrier.uint32[ | ||
memoryForPointersCursor / Uint32Array.BYTES_PER_ELEMENT | ||
] = rOfValue; | ||
memoryForPointersCursor += Uint32Array.BYTES_PER_ELEMENT; | ||
@@ -38,0 +37,0 @@ } |
@@ -16,3 +16,3 @@ /* eslint-env jest */ | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
@@ -26,3 +26,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -91,3 +91,3 @@ | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`32`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`0`); | ||
}); | ||
@@ -101,3 +101,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -143,3 +143,3 @@ | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`80`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`72`); | ||
}); | ||
@@ -153,3 +153,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -204,7 +204,7 @@ | ||
expect(plainJSArray).toEqual([...arrayWrapper]); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`48`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`24`); | ||
}); | ||
test("arrayWrapper splice - add + delete - array will get longer", () => { | ||
const arrayBuffer = new ArrayBuffer(512); | ||
const arrayBuffer = new ArrayBuffer(1024); | ||
const carrier = makeCarrier(arrayBuffer); | ||
@@ -214,3 +214,3 @@ initializeArrayBuffer(arrayBuffer); | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -228,2 +228,4 @@ | ||
const availableCheckpoint = allocator.stats().available; | ||
const removed = arrayWrapper.splice(2, 2, "a", "b", "c", "d"); | ||
@@ -284,7 +286,9 @@ const removedFromPlain = plainJSArray.splice(2, 2, "a", "b", "c", "d"); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`16`); | ||
expect( | ||
availableCheckpoint - allocator.stats().available | ||
).toMatchInlineSnapshot(`96`); | ||
}); | ||
test("arrayWrapper splice - add + delete - array will get shorter", () => { | ||
const arrayBuffer = new ArrayBuffer(512); | ||
const arrayBuffer = new ArrayBuffer(1024); | ||
const carrier = makeCarrier(arrayBuffer); | ||
@@ -294,3 +298,3 @@ initializeArrayBuffer(arrayBuffer); | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -308,2 +312,4 @@ | ||
const availableCheckpoint = allocator.stats().available; | ||
const removed = arrayWrapper.splice(2, 6, "a", "b", "c", "d"); | ||
@@ -365,3 +371,5 @@ const removedFromPlain = plainJSArray.splice(2, 6, "a", "b", "c", "d"); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`16`); | ||
expect( | ||
availableCheckpoint - allocator.stats().available | ||
).toMatchInlineSnapshot(`96`); | ||
}); | ||
@@ -375,3 +383,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -435,3 +443,3 @@ | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`48`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`24`); | ||
}); | ||
@@ -445,3 +453,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -511,3 +519,3 @@ | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`48`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`24`); | ||
}); | ||
@@ -521,3 +529,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -587,3 +595,3 @@ | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`48`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`24`); | ||
}); | ||
@@ -597,3 +605,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -657,4 +665,4 @@ | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`32`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`24`); | ||
}); | ||
}); |
@@ -7,6 +7,6 @@ import { | ||
arrayGetPointersToValueInIndex, | ||
setValuePointerAtArrayIndex | ||
setValuePointerAtArrayIndex, | ||
} from "./arrayHelpers"; | ||
import { assertNonNull } from "./assertNonNull"; | ||
import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces"; | ||
import { ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
import { writeValueInPtrToPtr } from "./store"; | ||
@@ -17,3 +17,3 @@ | ||
externalArgs: ExternalArgs, | ||
dataViewCarrier: DataViewAndAllocatorCarrier, | ||
globalCarrier: GlobalCarrier, | ||
pointerToArrayEntry: number, | ||
@@ -24,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,6 +94,5 @@ writeValueToIndex, | ||
dataViewCarrier.dataView.setUint32( | ||
valueToCopyPointers.pointerToThePointer, | ||
0 | ||
); | ||
globalCarrier.uint32[ | ||
valueToCopyPointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT | ||
] = 0; | ||
} | ||
@@ -114,3 +113,3 @@ } | ||
const valueToCopyPointers = arrayGetPointersToValueInIndex( | ||
dataViewCarrier, | ||
globalCarrier, | ||
pointerToArrayEntry, | ||
@@ -123,3 +122,3 @@ writeValueToIndex - itemCountChange | ||
setValuePointerAtArrayIndex( | ||
dataViewCarrier, | ||
globalCarrier, | ||
pointerToArrayEntry, | ||
@@ -131,7 +130,7 @@ writeValueToIndex, | ||
// empty old array index, its still allocated! | ||
dataViewCarrier.dataView.setUint32( | ||
valueToCopyPointers.pointerToThePointer, | ||
0 | ||
); | ||
globalCarrier.uint32[ | ||
valueToCopyPointers.pointerToThePointer / Uint32Array.BYTES_PER_ELEMENT | ||
] = 0; | ||
// using that is wastefull | ||
@@ -152,3 +151,3 @@ // setValueAtArrayIndex( | ||
const valueToSetPointers = arrayGetPointersToValueInIndex( | ||
dataViewCarrier, | ||
globalCarrier, | ||
pointerToArrayEntry, | ||
@@ -162,3 +161,3 @@ calcedStart + i | ||
externalArgs, | ||
dataViewCarrier, | ||
globalCarrier, | ||
valueToSetPointers.pointerToThePointer, | ||
@@ -170,3 +169,3 @@ itemsToAddArg[i] | ||
if (newLength < metadata.length) { | ||
shrinkArray(externalArgs, dataViewCarrier, pointerToArrayEntry, newLength); | ||
shrinkArray(externalArgs, globalCarrier, pointerToArrayEntry, newLength); | ||
} | ||
@@ -173,0 +172,0 @@ |
@@ -16,3 +16,3 @@ /* eslint-env jest */ | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
@@ -22,3 +22,3 @@ | ||
test("arrayWrapper class 1", () => { | ||
const arrayBuffer = new ArrayBuffer(256); | ||
const arrayBuffer = new ArrayBuffer(512); | ||
const carrier = makeCarrier(arrayBuffer); | ||
@@ -28,3 +28,3 @@ initializeArrayBuffer(arrayBuffer); | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -50,7 +50,7 @@ | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`32`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`264`); | ||
}); | ||
test("arrayWrapper array.keys()", () => { | ||
const arrayBuffer = new ArrayBuffer(256); | ||
const arrayBuffer = new ArrayBuffer(512); | ||
const carrier = makeCarrier(arrayBuffer); | ||
@@ -60,3 +60,3 @@ initializeArrayBuffer(arrayBuffer); | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -75,7 +75,7 @@ const arrayToSave = ["a", "b", 1]; | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`32`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`264`); | ||
}); | ||
test("arrayWrapper array.entries()", () => { | ||
const arrayBuffer = new ArrayBuffer(256); | ||
const arrayBuffer = new ArrayBuffer(512); | ||
const carrier = makeCarrier(arrayBuffer); | ||
@@ -85,3 +85,3 @@ initializeArrayBuffer(arrayBuffer); | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -115,7 +115,7 @@ const arrayToSave = ["a", "b", 1]; | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`32`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`264`); | ||
}); | ||
test("arrayWrapper array.values() & iterator", () => { | ||
const arrayBuffer = new ArrayBuffer(256); | ||
const arrayBuffer = new ArrayBuffer(512); | ||
const carrier = makeCarrier(arrayBuffer); | ||
@@ -125,3 +125,3 @@ initializeArrayBuffer(arrayBuffer); | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -153,7 +153,7 @@ const arrayToSave = ["a", "b", 1]; | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`32`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`264`); | ||
}); | ||
test("arrayWrapper set value in bound", () => { | ||
const arrayBuffer = new ArrayBuffer(256); | ||
const arrayBuffer = new ArrayBuffer(512); | ||
const carrier = makeCarrier(arrayBuffer); | ||
@@ -183,3 +183,3 @@ initializeArrayBuffer(arrayBuffer); | ||
test("arrayWrapper set value out of bound, but inside allocated space", () => { | ||
const arrayBuffer = new ArrayBuffer(256); | ||
const arrayBuffer = new ArrayBuffer(512); | ||
const carrier = makeCarrier(arrayBuffer); | ||
@@ -222,3 +222,3 @@ initializeArrayBuffer(arrayBuffer); | ||
test("arrayWrapper set value out of bound, but outside allocated space", () => { | ||
const arrayBuffer = new ArrayBuffer(256); | ||
const arrayBuffer = new ArrayBuffer(512); | ||
const carrier = makeCarrier(arrayBuffer); | ||
@@ -228,3 +228,3 @@ initializeArrayBuffer(arrayBuffer); | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -258,3 +258,3 @@ const arrayToSave = ["a", "b", 1]; | ||
`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`8`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`232`); | ||
}); | ||
@@ -269,3 +269,3 @@ }); | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -298,3 +298,3 @@ | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`184`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`176`); | ||
}); | ||
@@ -308,7 +308,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 +357,3 @@ | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`672`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`568`); | ||
}); | ||
@@ -367,3 +367,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -399,3 +399,3 @@ | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`160`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`152`); | ||
}); | ||
@@ -409,3 +409,3 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
@@ -458,4 +458,4 @@ | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`160`); | ||
expect(allocator.stats().available).toMatchInlineSnapshot(`152`); | ||
}); | ||
}); |
@@ -7,14 +7,10 @@ import { | ||
extendArrayIfNeeded, | ||
arrayReverse | ||
arrayReverse, | ||
} from "./arrayHelpers"; | ||
import { INTERNAL_API_SYMBOL } from "./symbols"; | ||
import { arraySplice } from "./arraySplice"; | ||
import { ExternalArgs, GlobalCarrier, ArrayEntry } from "./interfaces"; | ||
import { | ||
ExternalArgs, | ||
DataViewAndAllocatorCarrier, | ||
ArrayEntry | ||
} from "./interfaces"; | ||
import { | ||
IllegalArrayIndexError, | ||
UnsupportedOperationError | ||
UnsupportedOperationError, | ||
} from "./exceptions"; | ||
@@ -176,3 +172,3 @@ import { allocationsTransaction } from "./allocationsTransaction"; | ||
index | ||
) | ||
), | ||
]; | ||
@@ -257,5 +253,5 @@ | ||
public getDataView() { | ||
return this.carrier.dataView; | ||
} | ||
// public getDataView() { | ||
// return this.carrier.dataView; | ||
// } | ||
@@ -298,3 +294,3 @@ public getEntryPointer() { | ||
externalArgs: ExternalArgs, | ||
dataViewCarrier: DataViewAndAllocatorCarrier, | ||
globalCarrier: GlobalCarrier, | ||
entryPointer: number | ||
@@ -304,4 +300,4 @@ ): Array<any> { | ||
[], | ||
new ArrayWrapper(externalArgs, dataViewCarrier, entryPointer) | ||
new ArrayWrapper(externalArgs, globalCarrier, entryPointer) | ||
) as any; | ||
} |
import { | ||
ExternalArgs, | ||
DataViewAndAllocatorCarrier, | ||
GlobalCarrier, | ||
InternalAPI, | ||
@@ -9,3 +9,3 @@ DateEntry, | ||
MapEntry, | ||
SetEntry | ||
SetEntry, | ||
} from "./interfaces"; | ||
@@ -20,3 +20,3 @@ import { incrementRefCount, decrementRefCount, readEntry } from "./store"; | ||
protected externalArgs: ExternalArgs, | ||
protected carrier: DataViewAndAllocatorCarrier, | ||
protected carrier: GlobalCarrier, | ||
protected _entryPointer: number | ||
@@ -42,3 +42,3 @@ ) { | ||
public replaceCarrierContent(newCarrierContent: DataViewAndAllocatorCarrier) { | ||
public replaceCarrierContent(newCarrierContent: GlobalCarrier) { | ||
Object.assign(this.carrier, newCarrierContent); | ||
@@ -45,0 +45,0 @@ } |
@@ -1,6 +0,2 @@ | ||
import { | ||
ExternalArgs, | ||
DataViewAndAllocatorCarrier, | ||
DateEntry | ||
} from "./interfaces"; | ||
import { ExternalArgs, GlobalCarrier, DateEntry } from "./interfaces"; | ||
@@ -42,3 +38,3 @@ import { readEntry, writeEntry } from "./store"; | ||
"toLocaleDateString", | ||
"toLocaleTimeString" | ||
"toLocaleTimeString", | ||
]; | ||
@@ -62,3 +58,3 @@ | ||
"setUTCMonth", | ||
"setUTCSeconds" | ||
"setUTCSeconds", | ||
// "setYear" | ||
@@ -74,3 +70,3 @@ ]; | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
entryPointer: number | ||
@@ -123,3 +119,3 @@ ) { | ||
refsCount: this.entry.refsCount, | ||
value: this.dateObjectForReuse.getTime() | ||
value: this.dateObjectForReuse.getTime(), | ||
}); | ||
@@ -143,3 +139,3 @@ } | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
entryPointer: number | ||
@@ -146,0 +142,0 @@ ): Date { |
@@ -11,3 +11,3 @@ import * as util from "util"; | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
@@ -19,3 +19,3 @@ | ||
array: [1], | ||
object: {} | ||
object: {}, | ||
}); | ||
@@ -35,3 +35,3 @@ | ||
Object.defineProperty(objectBuffer.date, "propy", { | ||
enumerable: true | ||
enumerable: true, | ||
}); | ||
@@ -59,3 +59,3 @@ }).toThrowErrorMatchingInlineSnapshot(`"UnsupportedOperationError"`); | ||
array: [1], | ||
object: {} | ||
object: {}, | ||
}); | ||
@@ -92,3 +92,3 @@ | ||
array: [1], | ||
object: {} | ||
object: {}, | ||
}); | ||
@@ -99,3 +99,3 @@ | ||
configurable: false, | ||
enumerable: false | ||
enumerable: false, | ||
}); | ||
@@ -102,0 +102,0 @@ }).toThrowErrorMatchingInlineSnapshot(`"UnsupportedOperationError"`); |
@@ -29,3 +29,3 @@ import { createKnownTypeGuard } from "./utils"; | ||
SET, | ||
DATE | ||
DATE, | ||
} | ||
@@ -37,5 +37,5 @@ | ||
ENTRY_TYPE.BIGINT_NEGATIVE, | ||
ENTRY_TYPE.STRING | ||
ENTRY_TYPE.STRING, | ||
] as const; | ||
export const isPrimitiveEntryType = createKnownTypeGuard(PRIMITIVE_TYPES); |
@@ -1,2 +0,2 @@ | ||
import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces"; | ||
import { ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
import { ENTRY_TYPE, isPrimitiveEntryType } from "./entry-types"; | ||
@@ -15,3 +15,3 @@ import { createObjectWrapper } from "./objectWrapper"; | ||
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; | ||
@@ -33,3 +33,3 @@ | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
pointerToEntry: number | ||
@@ -66,3 +66,3 @@ ) { | ||
) { | ||
const cache = getCacheFor(carrier, key => { | ||
const cache = getCacheFor(carrier, (key) => { | ||
finalizer(key, carrier, externalArgs); | ||
@@ -92,3 +92,3 @@ }); | ||
memoryAddress: number, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
externalArgs: ExternalArgs | ||
@@ -95,0 +95,0 @@ ) { |
@@ -13,7 +13,7 @@ /* eslint-env jest */ | ||
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 +30,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 +119,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(` | ||
@@ -59,7 +129,11 @@ Array [ | ||
1032, | ||
1048, | ||
1064, | ||
1080, | ||
1104, | ||
1056, | ||
1072, | ||
1096, | ||
112, | ||
1120, | ||
1144, | ||
1160, | ||
1184, | ||
1216, | ||
128, | ||
@@ -75,30 +149,26 @@ 144, | ||
336, | ||
352, | ||
368, | ||
392, | ||
416, | ||
432, | ||
360, | ||
376, | ||
400, | ||
424, | ||
448, | ||
472, | ||
464, | ||
48, | ||
488, | ||
504, | ||
512, | ||
528, | ||
552, | ||
576, | ||
592, | ||
560, | ||
584, | ||
616, | ||
632, | ||
656, | ||
672, | ||
688, | ||
680, | ||
704, | ||
72, | ||
792, | ||
816, | ||
840, | ||
864, | ||
904, | ||
920, | ||
728, | ||
744, | ||
848, | ||
880, | ||
912, | ||
936, | ||
960, | ||
976, | ||
@@ -125,11 +195,11 @@ 992, | ||
nestedObject: { a: 1, b: null, c: "string", bigint: BigInt("100") }, | ||
arr: [new Date(0), "somestring", { a: "6", h: null }] | ||
arr: [new Date(0), "somestring", { a: "6", h: null }], | ||
}); | ||
expect(memoryStats(objectBuffer)).toMatchInlineSnapshot(` | ||
Object { | ||
"available": 936, | ||
"used": 1112, | ||
} | ||
`); | ||
Object { | ||
"available": 816, | ||
"used": 1232, | ||
} | ||
`); | ||
@@ -146,3 +216,3 @@ const carrier = getInternalAPI(objectBuffer).getCarrier(); | ||
linkedAddresses.leafAddresses.forEach(address => { | ||
linkedAddresses.leafAddresses.forEach((address) => { | ||
pool.free(address); | ||
@@ -149,0 +219,0 @@ }); |
import { readEntry } from "./store"; | ||
import { DataViewAndAllocatorCarrier } from "./interfaces"; | ||
import { GlobalCarrier } from "./interfaces"; | ||
import { ENTRY_TYPE } from "./entry-types"; | ||
@@ -8,17 +8,35 @@ import { hashMapGetPointersToFree } from "./hashmap/hashmap"; | ||
export function getAllLinkedAddresses( | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
ignoreRefCount: boolean, | ||
entryPointer: number | ||
) { | ||
const leafAddresses: number[] = []; | ||
const arcAddresses: number[] = []; | ||
const leafAddresses: Set<number> = new Set<number>(); | ||
const arcAddresses: Set<number> = new Set<number>(); | ||
const addressesToProcessQueue: number[] = [entryPointer]; | ||
getAllLinkedAddressesStep( | ||
carrier, | ||
ignoreRefCount, | ||
entryPointer, | ||
leafAddresses, | ||
arcAddresses | ||
); | ||
let addressToProcess: number | undefined = undefined; | ||
// const diffs = []; | ||
while ((addressToProcess = addressesToProcessQueue.shift()) !== undefined) { | ||
// const before = addressesToProcessQueue.slice(); | ||
if (addressToProcess === 0) { | ||
continue; | ||
} | ||
getAllLinkedAddressesStep( | ||
carrier, | ||
ignoreRefCount, | ||
addressToProcess, | ||
leafAddresses, | ||
arcAddresses, | ||
addressesToProcessQueue | ||
); | ||
// diffs.push(addressesToProcessQueue.filter((p) => !before.includes(p))); | ||
} | ||
// console.log(diffs); | ||
return { leafAddresses, arcAddresses }; | ||
@@ -28,9 +46,14 @@ } | ||
function getAllLinkedAddressesStep( | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
ignoreRefCount: boolean, | ||
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,20 +93,16 @@ | ||
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.dataView.getUint32( | ||
entry.value + i * Uint32Array.BYTES_PER_ELEMENT | ||
); | ||
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); | ||
} | ||
@@ -95,5 +113,5 @@ break; | ||
if (entry.refsCount <= 1 || ignoreRefCount) { | ||
leafAddresses.push(entryPointer); | ||
leafAddresses.add(entryPointer); | ||
} else { | ||
arcAddresses.push(entryPointer); | ||
arcAddresses.add(entryPointer); | ||
} | ||
@@ -110,24 +128,21 @@ break; | ||
export function getObjectOrMapOrSetAddresses( | ||
carrier: DataViewAndAllocatorCarrier, | ||
ignoreRefCount: boolean, | ||
carrier: GlobalCarrier, | ||
internalHashmapPointer: number, | ||
leafAddresses: number[], | ||
arcAddresses: number[] | ||
leafAddresses: Set<number>, | ||
addressesToProcessQueue: number[] | ||
) { | ||
const { pointersToValuePointers, pointers } = hashMapGetPointersToFree( | ||
carrier.dataView, | ||
carrier, | ||
internalHashmapPointer | ||
); | ||
leafAddresses.push(...pointers); | ||
for (const leafPointer of pointers) { | ||
leafAddresses.add(leafPointer); | ||
} | ||
for (const pointer of pointersToValuePointers) { | ||
getAllLinkedAddressesStep( | ||
carrier, | ||
ignoreRefCount, | ||
carrier.dataView.getUint32(pointer), | ||
leafAddresses, | ||
arcAddresses | ||
addressesToProcessQueue.push( | ||
carrier.uint32[pointer / Uint32Array.BYTES_PER_ELEMENT] | ||
); | ||
} | ||
} |
@@ -6,3 +6,3 @@ /* eslint-env jest */ | ||
recordAllocations, | ||
makeCarrier | ||
makeCarrier, | ||
} from "../testUtils"; | ||
@@ -17,5 +17,5 @@ import { | ||
hashMapDelete, | ||
hashMapGetPointersToFree | ||
hashMapGetPointersToFree, | ||
} from "./hashmap"; | ||
import { DataViewAndAllocatorCarrier, StringEntry } from "../interfaces"; | ||
import { GlobalCarrier, StringEntry } from "../interfaces"; | ||
import { readEntry } from "../store"; | ||
@@ -28,7 +28,7 @@ import { externalArgsApiToExternalArgsApi } from "../utils"; | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
let ab = new ArrayBuffer(128); | ||
let carrier: DataViewAndAllocatorCarrier = makeCarrier(ab); | ||
let carrier: GlobalCarrier = makeCarrier(ab); | ||
@@ -62,3 +62,3 @@ function setABSize(size: number) { | ||
carrier.dataView.setUint32(valuePointer, 5); | ||
carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT] = 5; | ||
@@ -78,3 +78,3 @@ expect(arrayBuffer2HexArray(ab, true)).toMatchSnapshot("after insert"); | ||
carrier.dataView.setUint32(pointer, 6); | ||
carrier.uint32[pointer / Uint32Array.BYTES_PER_ELEMENT] = 6; | ||
@@ -159,3 +159,3 @@ expect(arrayBuffer2HexArray(ab, true)).toMatchSnapshot("after insert"); | ||
.map((i): number => i + "a".charCodeAt(0)) | ||
.map(n => String.fromCharCode(n)); | ||
.map((n) => String.fromCharCode(n)); | ||
@@ -168,3 +168,6 @@ const inserts: number[] = []; | ||
); | ||
carrier.dataView.setUint32(inserts[inserts.length - 1], index); | ||
carrier.uint32[ | ||
inserts[inserts.length - 1] / Uint32Array.BYTES_PER_ELEMENT | ||
] = index; | ||
} | ||
@@ -180,3 +183,3 @@ | ||
(iteratorToken = hashMapLowLevelIterator( | ||
carrier.dataView, | ||
carrier, | ||
mapPointer, | ||
@@ -186,8 +189,6 @@ iteratorToken | ||
) { | ||
values.push( | ||
hashMapNodePointerToKeyValue(carrier.dataView, iteratorToken) | ||
); | ||
values.push(hashMapNodePointerToKeyValue(carrier, iteratorToken)); | ||
} | ||
expect( | ||
values.map(v => (readEntry(carrier, v.keyPointer) as StringEntry).value) | ||
values.map((v) => (readEntry(carrier, v.keyPointer) as StringEntry).value) | ||
).toMatchInlineSnapshot(` | ||
@@ -229,5 +230,3 @@ Array [ | ||
expect(hashMapSize(carrier.dataView, mapPointer)).toMatchInlineSnapshot( | ||
`0` | ||
); | ||
expect(hashMapSize(carrier, mapPointer)).toMatchInlineSnapshot(`0`); | ||
const memAvailableAfterEachStep = [carrier.allocator.stats().available]; | ||
@@ -237,9 +236,9 @@ | ||
.map((i): number => i + "a".charCodeAt(0)) | ||
.map(n => String.fromCharCode(n)); | ||
.map((n) => String.fromCharCode(n)); | ||
for (const [index, useThatAsKey] of input.entries()) { | ||
carrier.dataView.setUint32( | ||
hashMapInsertUpdate(externalArgs, carrier, mapPointer, useThatAsKey), | ||
index | ||
); | ||
carrier.uint32[ | ||
hashMapInsertUpdate(externalArgs, carrier, mapPointer, useThatAsKey) / | ||
Uint32Array.BYTES_PER_ELEMENT | ||
] = index; | ||
@@ -249,5 +248,3 @@ memAvailableAfterEachStep.push(carrier.allocator.stats().available); | ||
expect(hashMapSize(carrier.dataView, mapPointer)).toMatchInlineSnapshot( | ||
`26` | ||
); | ||
expect(hashMapSize(carrier, mapPointer)).toMatchInlineSnapshot(`26`); | ||
@@ -257,39 +254,37 @@ hashMapDelete(carrier, mapPointer, "a"); | ||
hashMapDelete(carrier, mapPointer, "c"); | ||
expect(hashMapSize(carrier.dataView, mapPointer)).toMatchInlineSnapshot( | ||
`23` | ||
); | ||
expect(hashMapSize(carrier, mapPointer)).toMatchInlineSnapshot(`26`); | ||
memAvailableAfterEachStep.push(carrier.allocator.stats().available); | ||
expect(memAvailableAfterEachStep).toMatchInlineSnapshot(` | ||
Array [ | ||
1904, | ||
1848, | ||
1792, | ||
1736, | ||
1680, | ||
1624, | ||
1568, | ||
1512, | ||
1416, | ||
1352, | ||
1296, | ||
1240, | ||
1184, | ||
1128, | ||
1072, | ||
1016, | ||
880, | ||
824, | ||
760, | ||
704, | ||
648, | ||
592, | ||
536, | ||
480, | ||
424, | ||
368, | ||
312, | ||
480, | ||
] | ||
`); | ||
Array [ | ||
1904, | ||
1840, | ||
1776, | ||
1712, | ||
1648, | ||
1584, | ||
1520, | ||
1456, | ||
1352, | ||
1288, | ||
1224, | ||
1160, | ||
1096, | ||
1032, | ||
968, | ||
904, | ||
760, | ||
696, | ||
632, | ||
568, | ||
504, | ||
440, | ||
376, | ||
312, | ||
248, | ||
184, | ||
120, | ||
120, | ||
] | ||
`); | ||
}); | ||
@@ -304,3 +299,3 @@ | ||
.map((i): number => i + "a".charCodeAt(0)) | ||
.map(n => String.fromCharCode(n)); | ||
.map((n) => String.fromCharCode(n)); | ||
const inputCopy = input.slice(); | ||
@@ -316,63 +311,63 @@ | ||
while ((toAdd = inputCopy.pop()) !== undefined) { | ||
carrier.dataView.setUint32( | ||
hashMapInsertUpdate(externalArgs, carrier, hashmapPointer, toAdd), | ||
toAdd.charCodeAt(0) | ||
); | ||
carrier.uint32[ | ||
hashMapInsertUpdate(externalArgs, carrier, hashmapPointer, toAdd) / | ||
Uint32Array.BYTES_PER_ELEMENT | ||
] = toAdd.charCodeAt(0); | ||
} | ||
}, carrier.allocator); | ||
const r = hashMapGetPointersToFree(carrier.dataView, hashmapPointer); | ||
const r = hashMapGetPointersToFree(carrier, hashmapPointer); | ||
expect(r).toMatchInlineSnapshot(` | ||
Object { | ||
"pointers": Array [ | ||
48, | ||
600, | ||
120, | ||
136, | ||
192, | ||
248, | ||
304, | ||
360, | ||
416, | ||
472, | ||
528, | ||
584, | ||
688, | ||
744, | ||
152, | ||
176, | ||
208, | ||
232, | ||
264, | ||
288, | ||
320, | ||
344, | ||
376, | ||
400, | ||
432, | ||
456, | ||
488, | ||
512, | ||
544, | ||
568, | ||
72, | ||
96, | ||
704, | ||
728, | ||
], | ||
"pointersToValuePointers": Array [ | ||
152, | ||
208, | ||
264, | ||
320, | ||
376, | ||
432, | ||
488, | ||
544, | ||
72, | ||
704, | ||
], | ||
} | ||
`); | ||
Object { | ||
"pointers": Array [ | ||
48, | ||
664, | ||
120, | ||
136, | ||
200, | ||
264, | ||
328, | ||
392, | ||
456, | ||
520, | ||
584, | ||
648, | ||
752, | ||
816, | ||
152, | ||
176, | ||
216, | ||
240, | ||
280, | ||
304, | ||
344, | ||
368, | ||
408, | ||
432, | ||
472, | ||
496, | ||
536, | ||
560, | ||
600, | ||
624, | ||
72, | ||
96, | ||
768, | ||
792, | ||
], | ||
"pointersToValuePointers": Array [ | ||
152, | ||
216, | ||
280, | ||
344, | ||
408, | ||
472, | ||
536, | ||
600, | ||
72, | ||
768, | ||
], | ||
} | ||
`); | ||
@@ -382,3 +377,5 @@ expect(r.pointers.sort()).toEqual(allocations.sort()); | ||
r.pointersToValuePointers | ||
.map(v => String.fromCharCode(carrier.dataView.getUint32(v))) | ||
.map((v) => | ||
String.fromCharCode(carrier.uint32[v / Uint32Array.BYTES_PER_ELEMENT]) | ||
) | ||
.sort() | ||
@@ -385,0 +382,0 @@ ).toEqual(input.sort()); |
import { MAP_MACHINE, NODE_MACHINE } from "./memoryLayout"; | ||
import { | ||
DataViewAndAllocatorCarrier, | ||
GlobalCarrier, | ||
ExternalArgs, | ||
NumberEntry, | ||
StringEntry | ||
StringEntry, | ||
} from "../interfaces"; | ||
@@ -11,3 +11,3 @@ import { | ||
hashCodeExternalValue, | ||
getKeyStartLength | ||
getKeyStartLength, | ||
} from "./hashmapUtils"; | ||
@@ -19,3 +19,3 @@ import { primitiveValueToEntry } from "../utils"; | ||
readEntry, | ||
compareStringOrNumberEntriesInPlace | ||
compareStringOrNumberEntriesInPlace, | ||
} from "../store"; | ||
@@ -29,3 +29,3 @@ import { ENTRY_TYPE } from "../entry-types"; | ||
linkedListGetValue, | ||
linkedListGetPointersToFree | ||
linkedListGetPointersToFree, | ||
} from "../linkedList/linkedList"; | ||
@@ -36,3 +36,3 @@ | ||
export function createHashMap( | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
/** | ||
@@ -50,6 +50,3 @@ * number of buckets | ||
const mapMachine = MAP_MACHINE.createOperator( | ||
carrier.dataView, | ||
hashMapMemory | ||
); | ||
const mapMachine = MAP_MACHINE.createOperator(carrier, hashMapMemory); | ||
@@ -70,7 +67,7 @@ mapMachine.set("ARRAY_POINTER", arrayMemory); | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
mapPointer: number, | ||
externalKeyValue: number | string | ||
) { | ||
const mapOperator = MAP_MACHINE.createOperator(carrier.dataView, mapPointer); | ||
const mapOperator = MAP_MACHINE.createOperator(carrier, mapPointer); | ||
const keyEntry = primitiveValueToEntry(externalKeyValue) as | ||
@@ -88,5 +85,10 @@ | NumberEntry | ||
const keyHeaderOverhead = keyEntry.type === ENTRY_TYPE.STRING ? 5 : 1; | ||
const keyHeaderOverhead = | ||
keyEntry.type === ENTRY_TYPE.STRING | ||
? // type + string length | ||
8 + 4 | ||
: // type | ||
8; | ||
const keyHashCode = hashCodeInPlace( | ||
carrier.dataView, | ||
carrier.uint8, | ||
mapOperator.get("CAPACITY"), | ||
@@ -103,4 +105,4 @@ // + 1 for the type of key | ||
const commonNodeOperator = NODE_MACHINE.createOperator( | ||
carrier.dataView, | ||
carrier.dataView.getUint32(ptrToPtrToSaveTheNodeTo) | ||
carrier, | ||
carrier.uint32[ptrToPtrToSaveTheNodeTo / Uint32Array.BYTES_PER_ELEMENT] | ||
); | ||
@@ -112,3 +114,3 @@ | ||
!compareStringOrNumberEntriesInPlace( | ||
carrier.dataView, | ||
carrier, | ||
commonNodeOperator.get("KEY_POINTER"), | ||
@@ -152,3 +154,5 @@ keyEntryMemory | ||
carrier.dataView.setUint32(ptrToPtrToSaveTheNodeTo, memoryForNewNode); | ||
carrier.uint32[ | ||
ptrToPtrToSaveTheNodeTo / Uint32Array.BYTES_PER_ELEMENT | ||
] = memoryForNewNode; | ||
@@ -182,7 +186,7 @@ mapOperator.set( | ||
export function hashMapNodeLookup( | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
mapPointer: number, | ||
externalKeyValue: number | string | ||
) { | ||
const mapMachine = MAP_MACHINE.createOperator(carrier.dataView, mapPointer); | ||
const mapMachine = MAP_MACHINE.createOperator(carrier, mapPointer); | ||
@@ -199,4 +203,4 @@ const keyHashCode = hashCodeExternalValue( | ||
const node = NODE_MACHINE.createOperator( | ||
carrier.dataView, | ||
carrier.dataView.getUint32(ptrToPtr) | ||
carrier, | ||
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] | ||
); | ||
@@ -221,3 +225,3 @@ | ||
export function hashMapValueLookup( | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
mapPointer: number, | ||
@@ -233,4 +237,4 @@ externalKeyValue: number | string | ||
const node = NODE_MACHINE.createOperator( | ||
carrier.dataView, | ||
carrier.dataView.getUint32(nodePtrToPtr) | ||
carrier, | ||
carrier.uint32[nodePtrToPtr / Uint32Array.BYTES_PER_ELEMENT] | ||
); | ||
@@ -245,3 +249,3 @@ | ||
export function hashMapDelete( | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
mapPointer: number, | ||
@@ -260,6 +264,7 @@ externalKeyValue: number | string | ||
const nodeToDeletePointer = carrier.dataView.getUint32(foundNodePtrToPtr); | ||
const nodeToDeletePointer = | ||
carrier.uint32[foundNodePtrToPtr / Uint32Array.BYTES_PER_ELEMENT]; | ||
const nodeOperator = NODE_MACHINE.createOperator( | ||
carrier.dataView, | ||
carrier, | ||
nodeToDeletePointer | ||
@@ -273,6 +278,5 @@ ); | ||
// remove node from bucket | ||
carrier.dataView.setUint32( | ||
foundNodePtrToPtr, | ||
nodeOperator.get("NEXT_NODE_POINTER") | ||
); | ||
carrier.uint32[ | ||
foundNodePtrToPtr / Uint32Array.BYTES_PER_ELEMENT | ||
] = nodeOperator.get("NEXT_NODE_POINTER"); | ||
@@ -282,8 +286,6 @@ carrier.allocator.free(nodeOperator.get("KEY_POINTER")); | ||
carrier.dataView.setUint32( | ||
mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset, | ||
carrier.dataView.getUint32( | ||
mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset | ||
) - 1 | ||
); | ||
carrier.uint32[ | ||
(mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset) / | ||
Uint32Array.BYTES_PER_ELEMENT | ||
]--; | ||
@@ -298,7 +300,7 @@ return valuePointer; | ||
export function hashMapLowLevelIterator( | ||
dataView: DataView, | ||
carrier: GlobalCarrier, | ||
mapPointer: number, | ||
nodePointerIteratorToken: number | ||
) { | ||
const mapOperator = MAP_MACHINE.createOperator(dataView, mapPointer); | ||
const mapOperator = MAP_MACHINE.createOperator(carrier, mapPointer); | ||
let tokenToUseForLinkedListIterator = 0; | ||
@@ -308,3 +310,3 @@ | ||
tokenToUseForLinkedListIterator = NODE_MACHINE.createOperator( | ||
dataView, | ||
carrier, | ||
nodePointerIteratorToken | ||
@@ -315,3 +317,3 @@ ).get("LINKED_LIST_ITEM_POINTER"); | ||
const pointerToNextLinkedListItem = linkedListLowLevelIterator( | ||
dataView, | ||
carrier, | ||
mapOperator.get("LINKED_LIST_POINTER"), | ||
@@ -325,28 +327,29 @@ tokenToUseForLinkedListIterator | ||
return linkedListGetValue(dataView, pointerToNextLinkedListItem); | ||
return linkedListGetValue(carrier, pointerToNextLinkedListItem); | ||
} | ||
export function hashMapNodePointerToKeyValue( | ||
dataView: DataView, | ||
carrier: GlobalCarrier, | ||
nodePointer: number | ||
) { | ||
const operator = NODE_MACHINE.createOperator(dataView, nodePointer); | ||
const operator = NODE_MACHINE.createOperator(carrier, nodePointer); | ||
return { | ||
valuePointer: operator.pointerTo("VALUE_POINTER"), | ||
keyPointer: operator.get("KEY_POINTER") | ||
keyPointer: operator.get("KEY_POINTER"), | ||
}; | ||
} | ||
export function hashMapSize(dataView: DataView, mapPointer: number) { | ||
return dataView.getUint32( | ||
mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset | ||
); | ||
export function hashMapSize(carrier: GlobalCarrier, mapPointer: number) { | ||
return carrier.uint32[ | ||
(mapPointer + MAP_MACHINE.map.LINKED_LIST_SIZE.bytesOffset) / | ||
Uint32Array.BYTES_PER_ELEMENT | ||
]; | ||
} | ||
export function hashMapGetPointersToFree( | ||
dataView: DataView, | ||
carrier: GlobalCarrier, | ||
hashmapPointer: number | ||
) { | ||
const mapOperator = MAP_MACHINE.createOperator(dataView, hashmapPointer); | ||
const mapOperator = MAP_MACHINE.createOperator(carrier, hashmapPointer); | ||
const pointers: number[] = [hashmapPointer, mapOperator.get("ARRAY_POINTER")]; | ||
@@ -356,3 +359,3 @@ const pointersToValuePointers: number[] = []; | ||
const pointersOfLinkedList = linkedListGetPointersToFree( | ||
dataView, | ||
carrier, | ||
mapOperator.get("LINKED_LIST_POINTER") | ||
@@ -362,3 +365,3 @@ ); | ||
pointers.push(...pointersOfLinkedList.pointers); | ||
const nodeOperator = NODE_MACHINE.createOperator(dataView, 0); | ||
const nodeOperator = NODE_MACHINE.createOperator(carrier, 0); | ||
@@ -373,3 +376,3 @@ for (const nodePointer of pointersOfLinkedList.valuePointers) { | ||
pointers, | ||
pointersToValuePointers | ||
pointersToValuePointers, | ||
}; | ||
@@ -379,3 +382,3 @@ } | ||
function hashMapRehash( | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
mapOperator: MemoryOperator< | ||
@@ -419,3 +422,3 @@ | "CAPACITY" | ||
(pointerToNode = hashMapLowLevelIterator( | ||
carrier.dataView, | ||
carrier, | ||
mapOperator.startAddress, | ||
@@ -430,3 +433,3 @@ pointerToNode | ||
function hashMapRehashInsert( | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
bucketsArrayPointer: number, | ||
@@ -436,13 +439,7 @@ arraySize: number, | ||
) { | ||
const nodeOperator = NODE_MACHINE.createOperator( | ||
carrier.dataView, | ||
nodePointer | ||
); | ||
const keyInfo = getKeyStartLength( | ||
carrier.dataView, | ||
nodeOperator.get("KEY_POINTER") | ||
); | ||
const nodeOperator = NODE_MACHINE.createOperator(carrier, nodePointer); | ||
const keyInfo = getKeyStartLength(carrier, nodeOperator.get("KEY_POINTER")); | ||
const keyHashCode = hashCodeInPlace( | ||
carrier.dataView, | ||
carrier.uint8, | ||
arraySize, | ||
@@ -457,4 +454,9 @@ keyInfo.start, | ||
const prevFirstNodeInBucket = carrier.dataView.getUint32(bucketStartPointer); | ||
carrier.dataView.setUint32(bucketStartPointer, nodePointer); | ||
const prevFirstNodeInBucket = | ||
carrier.uint32[bucketStartPointer / Uint32Array.BYTES_PER_ELEMENT]; | ||
carrier.uint32[ | ||
bucketStartPointer / Uint32Array.BYTES_PER_ELEMENT | ||
] = nodePointer; | ||
nodeOperator.set("NEXT_NODE_POINTER", prevFirstNodeInBucket); | ||
@@ -488,3 +490,3 @@ | ||
export function* hashmapNodesPointerIterator( | ||
dataView: DataView, | ||
carrier: GlobalCarrier, | ||
mapPointer: number | ||
@@ -496,3 +498,3 @@ ) { | ||
(iteratorToken = hashMapLowLevelIterator( | ||
dataView, | ||
carrier, | ||
mapPointer, | ||
@@ -499,0 +501,0 @@ iteratorToken |
import { ENTRY_TYPE } from "../entry-types"; | ||
import { stringEncodeInto } from "../stringEncodeInto"; | ||
import { GlobalCarrier } from "../interfaces"; | ||
export function hashCodeInPlace( | ||
dataView: DataView, | ||
uint8: Uint8Array, | ||
capacity: number, | ||
@@ -15,4 +16,3 @@ keyStart: number, | ||
for (let i = 0; i < keyBytesLength; i++) { | ||
// hashed.push(dataView.getUint8(i + keyStart)); | ||
h = (Math.imul(31, h) + dataView.getUint8(i + keyStart)) | 0; | ||
h = (Math.imul(31, h) + uint8[i + keyStart]) | 0; | ||
} | ||
@@ -30,3 +30,3 @@ | ||
const ab = new ArrayBuffer(typeof value === "string" ? value.length * 3 : 8); | ||
const dv = new DataView(ab); | ||
const uint8 = new Uint8Array(ab); | ||
let keyBytesLength = ab.byteLength; | ||
@@ -37,25 +37,23 @@ | ||
} else { | ||
dv.setFloat64(0, value); | ||
new Float64Array(ab)[0] = value; | ||
} | ||
return hashCodeInPlace(dv, capacity, 0, keyBytesLength); | ||
return hashCodeInPlace(uint8, capacity, 0, keyBytesLength); | ||
} | ||
export function hashCodeEntry( | ||
dataView: DataView, | ||
carrier: GlobalCarrier, | ||
capacity: number, | ||
pointer: number | ||
): number { | ||
const type: ENTRY_TYPE.NUMBER | ENTRY_TYPE.STRING = dataView.getUint8( | ||
pointer | ||
); | ||
const type: ENTRY_TYPE.NUMBER | ENTRY_TYPE.STRING = carrier.uint8[pointer]; | ||
if (type === ENTRY_TYPE.NUMBER) { | ||
return hashCodeInPlace(dataView, capacity, pointer + 1, 8); | ||
return hashCodeInPlace(carrier.uint8, capacity, pointer + 1, 8); | ||
} else { | ||
return hashCodeInPlace( | ||
dataView, | ||
carrier.uint8, | ||
capacity, | ||
pointer + 1 + Uint16Array.BYTES_PER_ELEMENT, | ||
dataView.getUint16(pointer + 1) | ||
carrier.uint16[(pointer + 1) / Uint16Array.BYTES_PER_ELEMENT] | ||
); | ||
@@ -65,7 +63,10 @@ } | ||
export function getKeyStartLength(dataView: DataView, keyPointer: number) { | ||
if (dataView.getUint32(keyPointer) === ENTRY_TYPE.NUMBER) { | ||
export function getKeyStartLength(carrier: GlobalCarrier, keyPointer: number) { | ||
if ( | ||
carrier.uint32[keyPointer / Uint32Array.BYTES_PER_ELEMENT] === | ||
ENTRY_TYPE.NUMBER | ||
) { | ||
return { | ||
start: keyPointer + 1, | ||
length: Float64Array.BYTES_PER_ELEMENT | ||
length: Float64Array.BYTES_PER_ELEMENT, | ||
}; | ||
@@ -75,5 +76,5 @@ } else { | ||
start: keyPointer + 1 + 2 + 2, | ||
length: dataView.getUint16(keyPointer + 1) | ||
length: carrier.uint16[(keyPointer + 1) / Uint16Array.BYTES_PER_ELEMENT], | ||
}; | ||
} | ||
} |
import { createMemoryMachine } from "../memoryMachinery"; | ||
export const MAP_MACHINE = createMemoryMachine({ | ||
CAPACITY: Uint8Array, | ||
USED_CAPACITY: Uint8Array, | ||
ARRAY_POINTER: Uint32Array, | ||
LINKED_LIST_POINTER: Uint32Array, | ||
// maybe put save this value in the linked list? | ||
LINKED_LIST_SIZE: Uint32Array | ||
LINKED_LIST_SIZE: Uint32Array, | ||
CAPACITY: Uint8Array, | ||
USED_CAPACITY: Uint8Array, | ||
}); | ||
@@ -16,3 +16,3 @@ | ||
KEY_POINTER: Uint32Array, | ||
LINKED_LIST_ITEM_POINTER: Uint32Array | ||
LINKED_LIST_ITEM_POINTER: Uint32Array, | ||
}); | ||
@@ -19,0 +19,0 @@ |
@@ -84,4 +84,4 @@ import { ENTRY_TYPE } from "./entry-types"; | ||
*/ | ||
export interface DataViewAndAllocatorCarrier { | ||
dataView: DataView; | ||
export interface GlobalCarrier { | ||
// dataView: DataView; | ||
uint8: Uint8Array; | ||
@@ -113,6 +113,6 @@ uint16: Uint16Array; | ||
getExternalArgs(): ExternalArgs; | ||
getCarrier(): Readonly<DataViewAndAllocatorCarrier>; | ||
replaceCarrierContent(carrier: DataViewAndAllocatorCarrier): void; | ||
getCarrier(): Readonly<GlobalCarrier>; | ||
replaceCarrierContent(carrier: GlobalCarrier): void; | ||
getEntryPointer(): number; | ||
destroy(): number; | ||
} |
@@ -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), | ||
]; | ||
@@ -113,3 +113,3 @@ | ||
(iteratorPointer = linkedListLowLevelIterator( | ||
carrier.dataView, | ||
carrier, | ||
linkedListPointer, | ||
@@ -119,3 +119,3 @@ iteratorPointer | ||
) { | ||
values.push(linkedListGetValue(carrier.dataView, iteratorPointer)); | ||
values.push(linkedListGetValue(carrier, iteratorPointer)); | ||
} | ||
@@ -134,3 +134,3 @@ | ||
itemsPointers.forEach(p => linkedListItemRemove(carrier, p)); | ||
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p)); | ||
@@ -150,3 +150,3 @@ expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`); | ||
linkedListItemInsert(carrier, linkedListPointer, 5), | ||
linkedListItemInsert(carrier, linkedListPointer, 4) | ||
linkedListItemInsert(carrier, linkedListPointer, 4), | ||
]; | ||
@@ -159,3 +159,3 @@ | ||
(iteratorPointer = linkedListLowLevelIterator( | ||
carrier.dataView, | ||
carrier, | ||
linkedListPointer, | ||
@@ -165,3 +165,3 @@ iteratorPointer | ||
) { | ||
values.push(linkedListGetValue(carrier.dataView, iteratorPointer)); | ||
values.push(linkedListGetValue(carrier, iteratorPointer)); | ||
linkedListItemRemove(carrier, iteratorPointer); | ||
@@ -187,3 +187,3 @@ } | ||
itemsPointers.forEach(p => linkedListItemRemove(carrier, p)); | ||
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p)); | ||
@@ -204,3 +204,3 @@ expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`); | ||
linkedListItemInsert(carrier, linkedListPointer, 5), | ||
linkedListItemInsert(carrier, linkedListPointer, 4) | ||
linkedListItemInsert(carrier, linkedListPointer, 4), | ||
]; | ||
@@ -213,3 +213,3 @@ | ||
(iteratorPointer = linkedListLowLevelIterator( | ||
carrier.dataView, | ||
carrier, | ||
linkedListPointer, | ||
@@ -219,5 +219,3 @@ iteratorPointer | ||
) { | ||
linkedLintResults.push( | ||
linkedListGetValue(carrier.dataView, iteratorPointer) | ||
); | ||
linkedLintResults.push(linkedListGetValue(carrier, iteratorPointer)); | ||
linkedListItemRemove(carrier, iteratorPointer); | ||
@@ -250,3 +248,3 @@ } | ||
itemsPointers.forEach(p => linkedListItemRemove(carrier, p)); | ||
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p)); | ||
@@ -264,3 +262,3 @@ expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`184`); | ||
linkedListItemInsert(carrier, linkedListPointer, 7), | ||
linkedListItemInsert(carrier, linkedListPointer, 6) | ||
linkedListItemInsert(carrier, linkedListPointer, 6), | ||
]; | ||
@@ -276,3 +274,3 @@ | ||
(iteratorPointer = linkedListLowLevelIterator( | ||
carrier.dataView, | ||
carrier, | ||
linkedListPointer, | ||
@@ -282,3 +280,3 @@ iteratorPointer | ||
) { | ||
values.push(linkedListGetValue(carrier.dataView, iteratorPointer)); | ||
values.push(linkedListGetValue(carrier, iteratorPointer)); | ||
if (c < toAdd.length) { | ||
@@ -312,3 +310,3 @@ linkedListItemInsert(carrier, linkedListPointer, toAdd[c++]); | ||
itemsPointers.forEach(p => linkedListItemRemove(carrier, p)); | ||
itemsPointers.forEach((p) => linkedListItemRemove(carrier, p)); | ||
@@ -318,3 +316,3 @@ const iteratorPointerToFree = 0; | ||
(iteratorPointer = linkedListLowLevelIterator( | ||
carrier.dataView, | ||
carrier, | ||
linkedListPointer, | ||
@@ -348,3 +346,3 @@ iteratorPointerToFree | ||
const r = linkedListGetPointersToFree(carrier.dataView, linkedListPointer); | ||
const r = linkedListGetPointersToFree(carrier, linkedListPointer); | ||
@@ -351,0 +349,0 @@ expect(r).toMatchInlineSnapshot(` |
import { createMemoryMachine } from "../memoryMachinery"; | ||
import { DataViewAndAllocatorCarrier } from "../interfaces"; | ||
import { GlobalCarrier } from "../interfaces"; | ||
@@ -21,3 +21,3 @@ /* | ||
NEXT_POINTER: Uint32Array, | ||
VALUE: Uint32Array | ||
VALUE: Uint32Array, | ||
}); | ||
@@ -31,3 +31,3 @@ | ||
END_POINTER: Uint32Array, | ||
START_POINTER: Uint32Array | ||
START_POINTER: Uint32Array, | ||
}); | ||
@@ -38,6 +38,4 @@ export type LinkedListMachineType = ReturnType< | ||
export function initLinkedList({ | ||
dataView, | ||
allocator | ||
}: DataViewAndAllocatorCarrier) { | ||
export function initLinkedList(carrier: GlobalCarrier) { | ||
const { allocator } = carrier; | ||
const memoryForLinkedList = allocator.calloc(LINKED_LIST_MACHINE.map.SIZE_OF); | ||
@@ -49,3 +47,3 @@ const memoryForEndMarkerItem = allocator.calloc( | ||
const linkedListMachine = LINKED_LIST_MACHINE.createOperator( | ||
dataView, | ||
carrier, | ||
memoryForLinkedList | ||
@@ -61,7 +59,7 @@ ); | ||
export function linkedListItemInsert( | ||
{ dataView, allocator }: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
linkedListPointer: number, | ||
nodeValuePointer: number | ||
) { | ||
const newItemMemory: number = allocator.calloc( | ||
const newItemMemory: number = carrier.allocator.calloc( | ||
LINKED_LIST_ITEM_MACHINE.map.SIZE_OF | ||
@@ -71,3 +69,3 @@ ); | ||
const linkedListOperator = LINKED_LIST_MACHINE.createOperator( | ||
dataView, | ||
carrier, | ||
linkedListPointer | ||
@@ -77,3 +75,3 @@ ); | ||
const wasEndMarkerOperator = LINKED_LIST_ITEM_MACHINE.createOperator( | ||
dataView, | ||
carrier, | ||
linkedListOperator.get("END_POINTER") | ||
@@ -83,3 +81,3 @@ ); | ||
const toBeEndMarkerOperator = LINKED_LIST_ITEM_MACHINE.createOperator( | ||
dataView, | ||
carrier, | ||
newItemMemory | ||
@@ -101,7 +99,7 @@ ); | ||
export function linkedListItemRemove( | ||
{ dataView, allocator }: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
itemPointer: number | ||
) { | ||
const itemToOverwrite = LINKED_LIST_ITEM_MACHINE.createOperator( | ||
dataView, | ||
carrier, | ||
itemPointer | ||
@@ -111,3 +109,3 @@ ); | ||
const itemToOverwriteWith = LINKED_LIST_ITEM_MACHINE.createOperator( | ||
dataView, | ||
carrier, | ||
itemToOverwrite.get("NEXT_POINTER") | ||
@@ -122,7 +120,7 @@ ); | ||
allocator.free(memoryToFree); | ||
carrier.allocator.free(memoryToFree); | ||
} | ||
export function linkedListLowLevelIterator( | ||
dataView: DataView, | ||
carrier: GlobalCarrier, | ||
linkedListPointer: number, | ||
@@ -132,3 +130,3 @@ itemPointer: number | ||
const listItem = LINKED_LIST_ITEM_MACHINE.createOperator( | ||
dataView, | ||
carrier, | ||
itemPointer | ||
@@ -138,6 +136,3 @@ ); | ||
if (itemPointer === 0) { | ||
const list = LINKED_LIST_MACHINE.createOperator( | ||
dataView, | ||
linkedListPointer | ||
); | ||
const list = LINKED_LIST_MACHINE.createOperator(carrier, linkedListPointer); | ||
@@ -170,4 +165,7 @@ listItem.startAddress = list.get("START_POINTER"); | ||
export function linkedListGetValue(dataView: DataView, itemPointer: number) { | ||
return LINKED_LIST_ITEM_MACHINE.createOperator(dataView, itemPointer).get( | ||
export function linkedListGetValue( | ||
carrier: GlobalCarrier, | ||
itemPointer: number | ||
) { | ||
return LINKED_LIST_ITEM_MACHINE.createOperator(carrier, itemPointer).get( | ||
"VALUE" | ||
@@ -178,3 +176,3 @@ ); | ||
export function linkedListGetPointersToFree( | ||
dataView: DataView, | ||
carrier: GlobalCarrier, | ||
linkedListPointer: number | ||
@@ -186,3 +184,3 @@ ) { | ||
const operator = LINKED_LIST_MACHINE.createOperator( | ||
dataView, | ||
carrier, | ||
linkedListPointer | ||
@@ -200,4 +198,4 @@ ); | ||
const linkItemOperator = LINKED_LIST_ITEM_MACHINE.createOperator( | ||
dataView, | ||
linkedListLowLevelIterator(dataView, linkedListPointer, 0) | ||
carrier, | ||
linkedListLowLevelIterator(carrier, linkedListPointer, 0) | ||
); | ||
@@ -219,4 +217,4 @@ | ||
pointers, | ||
valuePointers | ||
valuePointers, | ||
}; | ||
} |
import { | ||
ExternalArgs, | ||
DataViewAndAllocatorCarrier, | ||
GlobalCarrier, | ||
MapEntry, | ||
InternalAPI | ||
InternalAPI, | ||
} from "./interfaces"; | ||
@@ -11,3 +11,3 @@ import { | ||
objectSet, | ||
mapOrSetClear | ||
mapOrSetClear, | ||
} from "./objectWrapperHelpers"; | ||
@@ -23,3 +23,3 @@ | ||
hashMapNodePointerToKeyValue, | ||
hashmapNodesPointerIterator | ||
hashmapNodesPointerIterator, | ||
} from "./hashmap/hashmap"; | ||
@@ -45,3 +45,3 @@ import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue"; | ||
get size(): number { | ||
return hashMapSize(this.carrier.dataView, this.entry.value); | ||
return hashMapSize(this.carrier, this.entry.value); | ||
} | ||
@@ -55,7 +55,7 @@ | ||
for (const nodePointer of hashmapNodesPointerIterator( | ||
this.carrier.dataView, | ||
this.carrier, | ||
this.entry.value | ||
)) { | ||
const { valuePointer, keyPointer } = hashMapNodePointerToKeyValue( | ||
this.carrier.dataView, | ||
this.carrier, | ||
nodePointer | ||
@@ -73,4 +73,4 @@ ); | ||
this.carrier, | ||
this.carrier.dataView.getUint32(valuePointer) | ||
) | ||
this.carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT] | ||
), | ||
]; | ||
@@ -82,9 +82,6 @@ } | ||
for (const nodePointer of hashmapNodesPointerIterator( | ||
this.carrier.dataView, | ||
this.carrier, | ||
this.entry.value | ||
)) { | ||
const t = hashMapNodePointerToKeyValue( | ||
this.carrier.dataView, | ||
nodePointer | ||
); | ||
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer); | ||
@@ -101,7 +98,7 @@ yield entryToFinalJavaScriptValue( | ||
for (const nodePointer of hashmapNodesPointerIterator( | ||
this.carrier.dataView, | ||
this.carrier, | ||
this.entry.value | ||
)) { | ||
const { valuePointer } = hashMapNodePointerToKeyValue( | ||
this.carrier.dataView, | ||
this.carrier, | ||
nodePointer | ||
@@ -113,3 +110,3 @@ ); | ||
this.carrier, | ||
this.carrier.dataView.getUint32(valuePointer) | ||
this.carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT] | ||
); | ||
@@ -175,6 +172,6 @@ } | ||
externalArgs: ExternalArgs, | ||
dataViewCarrier: DataViewAndAllocatorCarrier, | ||
globalCarrier: GlobalCarrier, | ||
entryPointer: number | ||
): Map<K, V> { | ||
return new MapWrapper<K, V>(externalArgs, dataViewCarrier, entryPointer); | ||
return new MapWrapper<K, V>(externalArgs, globalCarrier, entryPointer); | ||
} |
@@ -5,5 +5,5 @@ /* eslint-env jest */ | ||
createMemoryOperator, | ||
_buildMemoryLayout | ||
_buildMemoryLayout, | ||
} from "./memoryMachinery"; | ||
import { arrayBuffer2HexArray } from "./testUtils"; | ||
import { arrayBuffer2HexArray, makeCarrier } from "./testUtils"; | ||
@@ -15,3 +15,3 @@ describe("memory manifest", () => { | ||
Uint32: Uint32Array, | ||
Uint8: Uint8Array | ||
Uint8: Uint8Array, | ||
}; | ||
@@ -41,7 +41,7 @@ | ||
.filter(([key]) => key !== "SIZE_OF") | ||
.map(entry => [ | ||
.map((entry) => [ | ||
entry[0], | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore | ||
// @ts-ignore | ||
entry[1].type | ||
entry[1].type, | ||
]) | ||
@@ -54,9 +54,9 @@ ).toEqual(Object.entries(input)); | ||
POINTER_TO_NODE: Uint32Array, | ||
LENGTH_OF_KEY: Uint16Array | ||
LENGTH_OF_KEY: Uint32Array, | ||
}); | ||
const ab = new ArrayBuffer(memoryMap.SIZE_OF); | ||
const dataView = new DataView(ab); | ||
const ab = new ArrayBuffer(memoryMap.SIZE_OF + 48); | ||
const carrier = makeCarrier(ab); | ||
const operator = createMemoryOperator(memoryMap, dataView, 0); | ||
const operator = createMemoryOperator(memoryMap, carrier, 0); | ||
@@ -68,15 +68,7 @@ operator.set("POINTER_TO_NODE", 9); | ||
Array [ | ||
"0x09", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x09", | ||
"0x00", | ||
"0x05", | ||
] | ||
`); | ||
operator.set("POINTER_TO_NODE", 0); | ||
expect(arrayBuffer2HexArray(ab)).toMatchInlineSnapshot(` | ||
Array [ | ||
"0x00", | ||
@@ -87,5 +79,113 @@ "0x00", | ||
"0x00", | ||
"0x05", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x28", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x38", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x08", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x03", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x10", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
] | ||
`); | ||
operator.set("POINTER_TO_NODE", 0); | ||
expect(arrayBuffer2HexArray(ab)).toMatchInlineSnapshot(` | ||
Array [ | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x05", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x28", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x38", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x08", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x03", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x10", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
] | ||
`); | ||
}); | ||
@@ -96,9 +196,9 @@ | ||
POINTER_TO_NODE: Uint32Array, | ||
LENGTH_OF_KEY: Uint16Array | ||
LENGTH_OF_KEY: Uint32Array, | ||
}); | ||
const ab = new ArrayBuffer(memoryMap.SIZE_OF); | ||
const dataView = new DataView(ab); | ||
const ab = new ArrayBuffer(memoryMap.SIZE_OF + 48); | ||
const carrier = makeCarrier(ab); | ||
const operator = createMemoryOperator(memoryMap, dataView, 0); | ||
const operator = createMemoryOperator(memoryMap, carrier, 0); | ||
@@ -117,3 +217,3 @@ operator.set("POINTER_TO_NODE", 9); | ||
NODE_KEY_POINTER: Uint32Array.BYTES_PER_ELEMENT, | ||
NODE_KEY_LENGTH: Uint16Array.BYTES_PER_ELEMENT | ||
NODE_KEY_LENGTH: Uint16Array.BYTES_PER_ELEMENT, | ||
}); | ||
@@ -120,0 +220,0 @@ |
@@ -0,1 +1,3 @@ | ||
import { GlobalCarrier } from "./interfaces"; | ||
const ALLOWS_TYPED_ARRAYS_CTORS = [ | ||
@@ -5,3 +7,3 @@ Uint8Array, | ||
// BigUint64Array, | ||
Uint16Array | ||
Uint16Array, | ||
] as const; | ||
@@ -23,9 +25,16 @@ | ||
// DataView.prototype is any, ts thing. this is a workaround for better types. | ||
let dataViewInstance = new DataView(new ArrayBuffer(0)); | ||
// let dataViewInstance = new DataView(new ArrayBuffer(0)); | ||
const READ_WRITE_MAPS = [ | ||
[Uint8Array, dataViewInstance.getUint8, dataViewInstance.setUint8], | ||
[Uint32Array, dataViewInstance.getUint32, dataViewInstance.setUint32], | ||
// const READ_WRITE_MAPS = [ | ||
// [Uint8Array, dataViewInstance.getUint8, dataViewInstance.setUint8], | ||
// [Uint32Array, dataViewInstance.getUint32, dataViewInstance.setUint32], | ||
// // [BigUint64Array, dataViewInstance.getBigUint64, dataViewInstance.setBigUint64], | ||
// [Uint16Array, dataViewInstance.getUint16, dataViewInstance.setUint16] | ||
// ] as const; | ||
const READ_WRITE_MAPS_V2 = [ | ||
[Uint8Array, "uint8"], | ||
[Uint32Array, "uint32"], | ||
// [BigUint64Array, dataViewInstance.getBigUint64, dataViewInstance.setBigUint64], | ||
[Uint16Array, dataViewInstance.getUint16, dataViewInstance.setUint16] | ||
[Uint16Array, "uint16"], | ||
] as const; | ||
@@ -35,7 +44,9 @@ | ||
// @ts-ignore | ||
dataViewInstance = undefined; | ||
// dataViewInstance = undefined; | ||
const READ_MAP = new Map(READ_WRITE_MAPS.map(e => [e[0], e[1]])); | ||
const WRITE_MAP = new Map(READ_WRITE_MAPS.map(e => [e[0], e[2]])); | ||
// const READ_MAP = new Map(READ_WRITE_MAPS.map(e => [e[0], e[1]])); | ||
// const WRITE_MAP = new Map(READ_WRITE_MAPS.map(e => [e[0], e[2]])); | ||
const READ_WRITE_MAP_V2 = new Map(READ_WRITE_MAPS_V2.map((e) => [e[0], e[1]])); | ||
export interface MemoryOperator<T extends string> { | ||
@@ -51,3 +62,3 @@ set(key: T, value: number): void; | ||
memoryMap: MemoryMap<T>, | ||
dataView: DataView, | ||
carrier: GlobalCarrier, | ||
startAddress: number | ||
@@ -58,15 +69,17 @@ ): MemoryOperator<T> { | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
const func = WRITE_MAP.get(memoryMap[key].type)!; | ||
const func = READ_WRITE_MAP_V2.get(memoryMap[key].type)!; | ||
return func.call( | ||
dataView, | ||
startAddress + memoryMap[key].bytesOffset, | ||
value | ||
); | ||
return (carrier[func][ | ||
(startAddress + memoryMap[key].bytesOffset) / | ||
memoryMap[key].type.BYTES_PER_ELEMENT | ||
] = value); | ||
}, | ||
get(key: T): number { | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
const func = READ_MAP.get(memoryMap[key].type)!; | ||
const func = READ_WRITE_MAP_V2.get(memoryMap[key].type)!; | ||
return func.call(dataView, startAddress + memoryMap[key].bytesOffset); | ||
return carrier[func][ | ||
(startAddress + memoryMap[key].bytesOffset) / | ||
memoryMap[key].type.BYTES_PER_ELEMENT | ||
]; | ||
}, | ||
@@ -82,3 +95,3 @@ pointerTo(key: T): number { | ||
}, | ||
size: memoryMap.SIZE_OF | ||
size: memoryMap.SIZE_OF, | ||
}; | ||
@@ -106,4 +119,4 @@ } | ||
(oldEntries[index - 1][1] as any).BYTES_PER_ELEMENT, | ||
type: type as any | ||
} | ||
type: type as any, | ||
}, | ||
]); | ||
@@ -117,3 +130,3 @@ } | ||
(oldEntries[newObjectEntries.length - 1][1] as TypedArrayCtor) | ||
.BYTES_PER_ELEMENT | ||
.BYTES_PER_ELEMENT, | ||
]); | ||
@@ -132,5 +145,5 @@ | ||
createOperator: createMemoryOperator.bind(null, map) as ( | ||
dataView: DataView, | ||
carrier: GlobalCarrier, | ||
address: number | ||
) => MemoryOperator<T> | ||
) => MemoryOperator<T>, | ||
}; | ||
@@ -151,3 +164,3 @@ } | ||
key, | ||
newObjectEntries[index - 1][1] + oldEntries[index - 1][1] | ||
newObjectEntries[index - 1][1] + oldEntries[index - 1][1], | ||
]); | ||
@@ -160,3 +173,3 @@ } | ||
newObjectEntries[newObjectEntries.length - 1][1] + | ||
oldEntries[newObjectEntries.length - 1][1] | ||
oldEntries[newObjectEntries.length - 1][1], | ||
]); | ||
@@ -163,0 +176,0 @@ |
@@ -14,3 +14,3 @@ /* eslint-env jest */ | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
@@ -40,3 +40,2 @@ | ||
Array [ | ||
264, | ||
240, | ||
@@ -51,2 +50,3 @@ 216, | ||
48, | ||
24, | ||
] | ||
@@ -82,4 +82,4 @@ `); | ||
expect(arrayToCompare).toEqual(arrayWrapper); | ||
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`48`); | ||
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`24`); | ||
}); | ||
}); |
@@ -12,3 +12,3 @@ /* eslint-env jest */ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder() | ||
textDecoder: new util.TextDecoder(), | ||
}); | ||
@@ -31,4 +31,4 @@ | ||
nestedObject: { | ||
nestedProp: 7 | ||
} | ||
nestedProp: 7, | ||
}, | ||
}; | ||
@@ -38,8 +38,8 @@ | ||
expect(saverOutput).toMatchInlineSnapshot(`896`); | ||
expect(saverOutput).toMatchInlineSnapshot(`976`); | ||
expect(arrayBuffer2HexArray(arrayBuffer, true)).toMatchSnapshot(); | ||
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`120`); | ||
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`32`); | ||
}); | ||
}); | ||
}); |
@@ -6,5 +6,5 @@ import { appendEntry } from "./store"; | ||
ExternalArgs, | ||
DataViewAndAllocatorCarrier, | ||
GlobalCarrier, | ||
MapEntry, | ||
SetEntry | ||
SetEntry, | ||
} from "./interfaces"; | ||
@@ -16,3 +16,3 @@ import { saveValue } from "./saveValue"; | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
referencedPointers: number[], | ||
@@ -25,3 +25,6 @@ objectToSave: any | ||
carrier, | ||
Math.max(externalArgs.hashMapMinInitialCapacity, objectEntries.length * 1.3) | ||
Math.max( | ||
externalArgs.hashMapMinInitialCapacity, | ||
Math.ceil(objectEntries.length * 1.3) | ||
) | ||
); | ||
@@ -44,3 +47,3 @@ | ||
carrier.dataView.setUint32(ptrToPtr, pointerToValue); | ||
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = pointerToValue; | ||
} | ||
@@ -51,3 +54,3 @@ | ||
refsCount: 1, | ||
value: hashMapPointer | ||
value: hashMapPointer, | ||
}; | ||
@@ -60,3 +63,3 @@ | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
referencedPointers: number[], | ||
@@ -67,3 +70,6 @@ mapToSave: Map<string | number, any> | ||
carrier, | ||
Math.max(externalArgs.hashMapMinInitialCapacity, mapToSave.size * 1.3) | ||
Math.max( | ||
externalArgs.hashMapMinInitialCapacity, | ||
Math.ceil(mapToSave.size * 1.3) | ||
) | ||
); | ||
@@ -86,3 +92,3 @@ | ||
carrier.dataView.setUint32(ptrToPtr, pointerToValue); | ||
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = pointerToValue; | ||
} | ||
@@ -93,3 +99,3 @@ | ||
refsCount: 1, | ||
value: hashMapPointer | ||
value: hashMapPointer, | ||
}; | ||
@@ -102,3 +108,3 @@ | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
setToSave: Set<string | number> | ||
@@ -108,3 +114,6 @@ ) { | ||
carrier, | ||
Math.max(externalArgs.hashMapMinInitialCapacity, setToSave.size * 1.3) | ||
Math.max( | ||
externalArgs.hashMapMinInitialCapacity, | ||
Math.ceil(setToSave.size * 1.3) | ||
) | ||
); | ||
@@ -120,3 +129,3 @@ | ||
carrier.dataView.setUint32(ptrToPtr, 1); | ||
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = 1; | ||
} | ||
@@ -127,3 +136,3 @@ | ||
refsCount: 1, | ||
value: hashMapPointer | ||
value: hashMapPointer, | ||
}; | ||
@@ -130,0 +139,0 @@ |
@@ -13,3 +13,3 @@ /* eslint-env jest */ | ||
textEncoder: new util.TextEncoder(), | ||
textDecoder: new util.TextDecoder() | ||
textDecoder: new util.TextDecoder(), | ||
}); | ||
@@ -29,4 +29,4 @@ | ||
nestedObject: { | ||
nestedProp: 7 | ||
} | ||
nestedProp: 7, | ||
}, | ||
}; | ||
@@ -58,3 +58,3 @@ | ||
expect(carrier.allocator.stats().top).toMatchInlineSnapshot(`704`); | ||
expect(carrier.allocator.stats().top).toMatchInlineSnapshot(`768`); | ||
}); | ||
@@ -74,4 +74,4 @@ | ||
nestedObject: { | ||
nestedProp: 7 | ||
} | ||
nestedProp: 7, | ||
}, | ||
}; | ||
@@ -90,3 +90,3 @@ | ||
expect(carrier.allocator.stats().top).toMatchInlineSnapshot(`704`); | ||
expect(carrier.allocator.stats().top).toMatchInlineSnapshot(`768`); | ||
}); | ||
@@ -106,4 +106,4 @@ | ||
nestedObject: { | ||
nestedProp: 7 | ||
} | ||
nestedProp: 7, | ||
}, | ||
}; | ||
@@ -133,3 +133,3 @@ | ||
expect(carrier.allocator.stats().top).toMatchInlineSnapshot(`728`); | ||
expect(carrier.allocator.stats().top).toMatchInlineSnapshot(`800`); | ||
}); | ||
@@ -149,4 +149,4 @@ | ||
nestedObject: { | ||
nestedProp: 7 | ||
} | ||
nestedProp: 7, | ||
}, | ||
}; | ||
@@ -177,3 +177,3 @@ | ||
expect(carrier.allocator.stats().top).toMatchInlineSnapshot(`800`); | ||
expect(carrier.allocator.stats().top).toMatchInlineSnapshot(`880`); | ||
}); | ||
@@ -193,4 +193,4 @@ | ||
nestedObject: { | ||
nestedProp: 7 | ||
} | ||
nestedProp: 7, | ||
}, | ||
}; | ||
@@ -219,5 +219,5 @@ | ||
expect(carrier.allocator.stats().top).toMatchInlineSnapshot(`704`); | ||
expect(carrier.allocator.stats().top).toMatchInlineSnapshot(`768`); | ||
}); | ||
}); | ||
}); |
@@ -0,11 +1,7 @@ | ||
import { ObjectEntry, ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
import { | ||
ObjectEntry, | ||
ExternalArgs, | ||
DataViewAndAllocatorCarrier | ||
} from "./interfaces"; | ||
import { | ||
getObjectPropertiesEntries, | ||
deleteObjectPropertyEntryByKey, | ||
objectGet, | ||
objectSet | ||
objectSet, | ||
} from "./objectWrapperHelpers"; | ||
@@ -16,3 +12,3 @@ | ||
IllegalObjectPropConfigError, | ||
UnsupportedOperationError | ||
UnsupportedOperationError, | ||
} from "./exceptions"; | ||
@@ -56,3 +52,3 @@ import { allocationsTransaction } from "./allocationsTransaction"; | ||
return gotEntries.map(e => e.key); | ||
return gotEntries.map((e) => e.key); | ||
} | ||
@@ -66,3 +62,3 @@ | ||
return gotEntries.map(e => e.key); | ||
return gotEntries.map((e) => e.key); | ||
} | ||
@@ -134,3 +130,3 @@ | ||
externalArgs: ExternalArgs, | ||
dataViewCarrier: DataViewAndAllocatorCarrier, | ||
globalCarrier: GlobalCarrier, | ||
entryPointer: number | ||
@@ -140,4 +136,4 @@ ): T { | ||
{ objectBufferWrapper: "objectBufferWrapper" }, | ||
new ObjectWrapper(externalArgs, dataViewCarrier, entryPointer) | ||
new ObjectWrapper(externalArgs, globalCarrier, entryPointer) | ||
) as any; | ||
} |
@@ -8,3 +8,3 @@ /* eslint-env jest */ | ||
getObjectPropertiesEntries, | ||
deleteObjectPropertyEntryByKey | ||
deleteObjectPropertyEntryByKey, | ||
} from "./objectWrapperHelpers"; | ||
@@ -19,3 +19,3 @@ import { externalArgsApiToExternalArgsApi } from "./utils"; | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
@@ -34,4 +34,4 @@ | ||
nestedObject: { | ||
nestedProp: 7 | ||
} | ||
nestedProp: 7, | ||
}, | ||
}; | ||
@@ -54,3 +54,3 @@ | ||
"key": "a", | ||
"valuePointer": 256, | ||
"valuePointer": 272, | ||
}, | ||
@@ -63,7 +63,7 @@ Object { | ||
"key": "b", | ||
"valuePointer": 400, | ||
"valuePointer": 432, | ||
}, | ||
Object { | ||
"key": "nestedObject", | ||
"valuePointer": 680, | ||
"valuePointer": 728, | ||
}, | ||
@@ -83,3 +83,3 @@ ] | ||
c: undefined, | ||
d: null | ||
d: null, | ||
}; | ||
@@ -89,3 +89,3 @@ | ||
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`88`); | ||
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`40`); | ||
@@ -102,3 +102,3 @@ const hashmapPointer = (readEntry(carrier, saverOutput) as ObjectEntry) | ||
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`168`); | ||
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`128`); | ||
@@ -108,17 +108,17 @@ const gotEntries = getObjectPropertiesEntries(carrier, hashmapPointer); | ||
expect(gotEntries).toMatchInlineSnapshot(` | ||
Array [ | ||
Object { | ||
"key": "b", | ||
"valuePointer": 280, | ||
}, | ||
Object { | ||
"key": "c", | ||
"valuePointer": 0, | ||
}, | ||
Object { | ||
"key": "d", | ||
"valuePointer": 1, | ||
}, | ||
] | ||
`); | ||
Array [ | ||
Object { | ||
"key": "b", | ||
"valuePointer": 296, | ||
}, | ||
Object { | ||
"key": "c", | ||
"valuePointer": 0, | ||
}, | ||
Object { | ||
"key": "d", | ||
"valuePointer": 1, | ||
}, | ||
] | ||
`); | ||
}); | ||
@@ -136,3 +136,3 @@ | ||
c: undefined, | ||
d: null | ||
d: null, | ||
}; | ||
@@ -142,3 +142,3 @@ | ||
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`88`); | ||
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`40`); | ||
@@ -157,23 +157,23 @@ const hashmapPointer = (readEntry(carrier, saverOutput) as ObjectEntry) | ||
.toMatchInlineSnapshot(` | ||
Array [ | ||
Object { | ||
"key": "a", | ||
"valuePointer": 200, | ||
}, | ||
Object { | ||
"key": "b", | ||
"valuePointer": 280, | ||
}, | ||
Object { | ||
"key": "c", | ||
"valuePointer": 0, | ||
}, | ||
] | ||
`); | ||
Array [ | ||
Object { | ||
"key": "a", | ||
"valuePointer": 208, | ||
}, | ||
Object { | ||
"key": "b", | ||
"valuePointer": 296, | ||
}, | ||
Object { | ||
"key": "c", | ||
"valuePointer": 0, | ||
}, | ||
] | ||
`); | ||
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`144`); | ||
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`104`); | ||
}); | ||
test("deleteObjectPropertyEntryByKey - delete in the middle", () => { | ||
const arrayBuffer = new ArrayBuffer(512); | ||
const arrayBuffer = new ArrayBuffer(1024); | ||
initializeArrayBuffer(arrayBuffer); | ||
@@ -187,7 +187,7 @@ const carrier = makeCarrier(arrayBuffer); | ||
d: null, | ||
e: 66 | ||
e: 66, | ||
}; | ||
const saverOutput = objectSaver(externalArgs, carrier, [], objectToSave); | ||
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`8`); | ||
// expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`8`); | ||
@@ -205,25 +205,25 @@ const hashmapPointer = readEntry(carrier, saverOutput) as ObjectEntry; | ||
.toMatchInlineSnapshot(` | ||
Array [ | ||
Object { | ||
"key": "a", | ||
"valuePointer": 200, | ||
}, | ||
Object { | ||
"key": "b", | ||
"valuePointer": 280, | ||
}, | ||
Object { | ||
"key": "d", | ||
"valuePointer": 1, | ||
}, | ||
Object { | ||
"key": "e", | ||
"valuePointer": 472, | ||
}, | ||
] | ||
`); | ||
Array [ | ||
Object { | ||
"key": "a", | ||
"valuePointer": 208, | ||
}, | ||
Object { | ||
"key": "b", | ||
"valuePointer": 296, | ||
}, | ||
Object { | ||
"key": "d", | ||
"valuePointer": 1, | ||
}, | ||
Object { | ||
"key": "e", | ||
"valuePointer": 520, | ||
}, | ||
] | ||
`); | ||
expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`64`); | ||
// expect(carrier.allocator.stats().available).toMatchInlineSnapshot(`64`); | ||
}); | ||
}); | ||
}); |
import { | ||
ExternalArgs, | ||
DataViewAndAllocatorCarrier, | ||
GlobalCarrier, | ||
StringEntry, | ||
NumberEntry, | ||
MapEntry, | ||
SetEntry | ||
SetEntry, | ||
} from "./interfaces"; | ||
@@ -14,3 +14,4 @@ import { | ||
decrementRefCount, | ||
writeEntry | ||
writeEntry, | ||
setRefCount, | ||
} from "./store"; | ||
@@ -24,9 +25,9 @@ import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue"; | ||
hashMapValueLookup, | ||
createHashMap | ||
createHashMap, | ||
} from "./hashmap/hashmap"; | ||
import { getObjectOrMapOrSetAddresses } from "./getAllLinkedAddresses"; | ||
import { getAllLinkedAddresses } from "./getAllLinkedAddresses"; | ||
export function deleteObjectPropertyEntryByKey( | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
hashmapPointer: number, | ||
@@ -46,5 +47,6 @@ keyToDeleteBy: string | number | ||
const deletedValuePointer = carrier.dataView.getUint32( | ||
deletedValuePointerToPointer | ||
); | ||
const deletedValuePointer = | ||
carrier.uint32[ | ||
deletedValuePointerToPointer / Uint32Array.BYTES_PER_ELEMENT | ||
]; | ||
@@ -57,3 +59,3 @@ handleArcForDeletedValuePointer(externalArgs, carrier, deletedValuePointer); | ||
export function getObjectPropertiesEntries( | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
hashmapPointer: number | ||
@@ -65,10 +67,6 @@ ): Array<{ key: string | number; valuePointer: number }> { | ||
while ( | ||
(iterator = hashMapLowLevelIterator( | ||
carrier.dataView, | ||
hashmapPointer, | ||
iterator | ||
)) | ||
(iterator = hashMapLowLevelIterator(carrier, hashmapPointer, iterator)) | ||
) { | ||
const { valuePointer, keyPointer } = hashMapNodePointerToKeyValue( | ||
carrier.dataView, | ||
carrier, | ||
iterator | ||
@@ -82,4 +80,5 @@ ); | ||
foundValues.push({ | ||
valuePointer: carrier.dataView.getUint32(valuePointer), | ||
key: keyEntry.value | ||
valuePointer: | ||
carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT], | ||
key: keyEntry.value, | ||
}); | ||
@@ -93,3 +92,3 @@ } | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
hashMapPointer: number, | ||
@@ -111,3 +110,3 @@ p: string | number, | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
entryPointer: number, | ||
@@ -125,23 +124,53 @@ key: string | number | ||
carrier, | ||
carrier.dataView.getUint32(valuePointer) | ||
carrier.uint32[valuePointer / Uint32Array.BYTES_PER_ELEMENT] | ||
); | ||
} | ||
export function hashmapClearFree( | ||
// export function hashmapClearFree( | ||
// externalArgs: ExternalArgs, | ||
// carrier: GlobalCarrier, | ||
// hashmapPointer: number | ||
// ) { | ||
// const leafAddresses = new Set<number>(); | ||
// const addressesToProcessQueue: number[] = []; | ||
// getObjectOrMapOrSetAddresses( | ||
// carrier, | ||
// hashmapPointer, | ||
// leafAddresses, | ||
// addressesToProcessQueue | ||
// ); | ||
// for (const address of leafAddresses) { | ||
// carrier.allocator.free(address); | ||
// } | ||
// for (const address of arcAddresses) { | ||
// decrementRefCount(externalArgs, carrier, address); | ||
// } | ||
// } | ||
export function mapOrSetClear( | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
hashmapPointer: number | ||
carrier: GlobalCarrier, | ||
mapOrSetPtr: number | ||
) { | ||
const leafAddresses: number[] = []; | ||
const arcAddresses: number[] = []; | ||
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); | ||
@@ -151,14 +180,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: DataViewAndAllocatorCarrier, | ||
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); | ||
@@ -165,0 +194,0 @@ entry.value = createHashMap(carrier, externalArgs.hashMapMinInitialCapacity); |
import { | ||
primitiveValueToEntry, | ||
isPrimitive, | ||
getOurPointerIfApplicable | ||
getOurPointerIfApplicable, | ||
} from "./utils"; | ||
@@ -9,3 +9,3 @@ import { appendEntry } from "./store"; | ||
import { arraySaver } from "./arraySaver"; | ||
import { ExternalArgs, DataViewAndAllocatorCarrier } from "./interfaces"; | ||
import { ExternalArgs, GlobalCarrier } from "./interfaces"; | ||
import { ENTRY_TYPE } from "./entry-types"; | ||
@@ -16,3 +16,3 @@ import { | ||
TRUE_KNOWN_ADDRESS, | ||
FALSE_KNOWN_ADDRESS | ||
FALSE_KNOWN_ADDRESS, | ||
} from "./consts"; | ||
@@ -25,3 +25,3 @@ | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
referencedPointers: number[], | ||
@@ -53,3 +53,3 @@ value: any | ||
} else if ( | ||
(maybeOurPointer = getOurPointerIfApplicable(value, carrier.dataView)) | ||
(maybeOurPointer = getOurPointerIfApplicable(value, carrier.allocator)) | ||
) { | ||
@@ -64,3 +64,3 @@ valuePointer = maybeOurPointer; | ||
refsCount: 1, | ||
value: value.getTime() | ||
value: value.getTime(), | ||
}); | ||
@@ -67,0 +67,0 @@ } else if (value instanceof Map) { |
import { | ||
ExternalArgs, | ||
DataViewAndAllocatorCarrier, | ||
GlobalCarrier, | ||
MapEntry, | ||
InternalAPI | ||
InternalAPI, | ||
} from "./interfaces"; | ||
@@ -10,3 +10,3 @@ import { | ||
objectSet, | ||
mapOrSetClear | ||
mapOrSetClear, | ||
} from "./objectWrapperHelpers"; | ||
@@ -22,3 +22,3 @@ | ||
hashMapNodePointerToKeyValue, | ||
hashmapNodesPointerIterator | ||
hashmapNodesPointerIterator, | ||
} from "./hashmap/hashmap"; | ||
@@ -44,3 +44,3 @@ import { entryToFinalJavaScriptValue } from "./entryToFinalJavaScriptValue"; | ||
get size(): number { | ||
return hashMapSize(this.carrier.dataView, this.entry.value); | ||
return hashMapSize(this.carrier, this.entry.value); | ||
} | ||
@@ -54,9 +54,6 @@ | ||
for (const nodePointer of hashmapNodesPointerIterator( | ||
this.carrier.dataView, | ||
this.carrier, | ||
this.entry.value | ||
)) { | ||
const t = hashMapNodePointerToKeyValue( | ||
this.carrier.dataView, | ||
nodePointer | ||
); | ||
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer); | ||
@@ -75,9 +72,6 @@ const key = entryToFinalJavaScriptValue( | ||
for (const nodePointer of hashmapNodesPointerIterator( | ||
this.carrier.dataView, | ||
this.carrier, | ||
this.entry.value | ||
)) { | ||
const t = hashMapNodePointerToKeyValue( | ||
this.carrier.dataView, | ||
nodePointer | ||
); | ||
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer); | ||
@@ -93,9 +87,6 @@ yield entryToFinalJavaScriptValue( | ||
for (const nodePointer of hashmapNodesPointerIterator( | ||
this.carrier.dataView, | ||
this.carrier, | ||
this.entry.value | ||
)) { | ||
const t = hashMapNodePointerToKeyValue( | ||
this.carrier.dataView, | ||
nodePointer | ||
); | ||
const t = hashMapNodePointerToKeyValue(this.carrier, nodePointer); | ||
@@ -164,6 +155,6 @@ yield entryToFinalJavaScriptValue( | ||
externalArgs: ExternalArgs, | ||
dataViewCarrier: DataViewAndAllocatorCarrier, | ||
globalCarrier: GlobalCarrier, | ||
entryPointer: number | ||
): Set<K> { | ||
return new SetWrapper<K>(externalArgs, dataViewCarrier, entryPointer); | ||
return new SetWrapper<K>(externalArgs, globalCarrier, entryPointer); | ||
} |
@@ -12,3 +12,3 @@ /* eslint-env jest */ | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
@@ -28,3 +28,3 @@ | ||
calcedSize, | ||
realSize: beforeSave - afterSave | ||
realSize: beforeSave - afterSave, | ||
}; | ||
@@ -38,4 +38,4 @@ } | ||
Object { | ||
"calcedSize": 64, | ||
"realSize": 64, | ||
"calcedSize": 72, | ||
"realSize": 72, | ||
} | ||
@@ -52,3 +52,3 @@ `); | ||
test("string", () => { | ||
expect(sizeOf(externalArgs, "סלאם עליכום")).toMatchInlineSnapshot(`40`); | ||
expect(sizeOf(externalArgs, "סלאם עליכום")).toMatchInlineSnapshot(`48`); | ||
}); | ||
@@ -67,3 +67,3 @@ | ||
sizeOf(externalArgs, ["a", { a: "u" }, null, undefined, 1]) | ||
).toMatchInlineSnapshot(`356`); | ||
).toMatchInlineSnapshot(`396`); | ||
}); | ||
@@ -74,4 +74,4 @@ | ||
sizeOf(externalArgs, { a: 1, b: "some string" }) | ||
).toMatchInlineSnapshot(`256`); | ||
).toMatchInlineSnapshot(`296`); | ||
}); | ||
}); |
@@ -5,3 +5,3 @@ import { | ||
ArrayEntry, | ||
ObjectEntry | ||
ObjectEntry, | ||
} from "./interfaces"; | ||
@@ -12,3 +12,3 @@ import { | ||
primitiveValueToEntry, | ||
align | ||
align, | ||
} from "./utils"; | ||
@@ -18,3 +18,3 @@ import { ENTRY_TYPE } from "./entry-types"; | ||
LINKED_LIST_MACHINE, | ||
LINKED_LIST_ITEM_MACHINE | ||
LINKED_LIST_ITEM_MACHINE, | ||
} from "./linkedList/linkedList"; | ||
@@ -63,3 +63,3 @@ import { MAP_MACHINE, NODE_MACHINE } from "./hashmap/memoryLayout"; | ||
arrayToSave.length + externalArgs.arrayAdditionalAllocation, | ||
length: arrayToSave.length | ||
length: arrayToSave.length, | ||
}; | ||
@@ -79,3 +79,3 @@ | ||
memoryAllocated, | ||
numberOfAllocations | ||
numberOfAllocations, | ||
}; | ||
@@ -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,3 +7,3 @@ /* eslint-env jest */ | ||
readEntry, | ||
appendEntry | ||
appendEntry, | ||
} from "./store"; | ||
@@ -28,6 +28,6 @@ import { ENTRY_TYPE } from "./entry-types"; | ||
"3:0x00", | ||
"4:0x00", | ||
"4:0x08", | ||
"5:0x00", | ||
"6:0x00", | ||
"7:0x08", | ||
"7:0x00", | ||
"8:0x00", | ||
@@ -57,3 +57,3 @@ "9:0x00", | ||
type: ENTRY_TYPE.NUMBER, | ||
value: Number.MAX_VALUE | ||
value: Number.MAX_VALUE, | ||
}); | ||
@@ -72,11 +72,11 @@ | ||
"0x00", | ||
"0x02", | ||
"0x7f", | ||
"0xef", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x40", | ||
"0xff", | ||
"0xff", | ||
"0xff", | ||
"0xff", | ||
"0xff", | ||
"0xff", | ||
] | ||
@@ -91,3 +91,3 @@ `); | ||
type: ENTRY_TYPE.NUMBER, | ||
value: Number.MIN_VALUE | ||
value: Number.MIN_VALUE, | ||
}); | ||
@@ -97,22 +97,22 @@ | ||
.toMatchInlineSnapshot(` | ||
Array [ | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x02", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x01", | ||
] | ||
`); | ||
Array [ | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x40", | ||
"0x01", | ||
] | ||
`); | ||
}); | ||
@@ -127,3 +127,3 @@ | ||
value: "aא弟", | ||
allocatedBytes: 6 | ||
allocatedBytes: 6, | ||
}); | ||
@@ -133,24 +133,24 @@ | ||
.toMatchInlineSnapshot(` | ||
Array [ | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x05", | ||
"0x00", | ||
"0x06", | ||
"0x00", | ||
"0x06", | ||
"0x61", | ||
"0xd7", | ||
"0x90", | ||
"0xe5", | ||
"0xbc", | ||
"0x9f", | ||
] | ||
`); | ||
Array [ | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x00", | ||
"0x14", | ||
"0x40", | ||
"0x06", | ||
"0x00", | ||
"0x00", | ||
] | ||
`); | ||
}); | ||
@@ -163,3 +163,3 @@ }); | ||
textDecoder: new util.TextDecoder(), | ||
arrayAdditionalAllocation: 20 | ||
arrayAdditionalAllocation: 20, | ||
}); | ||
@@ -173,3 +173,3 @@ | ||
type: ENTRY_TYPE.NUMBER, | ||
value: Number.MAX_VALUE | ||
value: Number.MAX_VALUE, | ||
}); | ||
@@ -195,3 +195,3 @@ | ||
type: ENTRY_TYPE.NUMBER, | ||
value: Number.MIN_VALUE | ||
value: Number.MIN_VALUE, | ||
}); | ||
@@ -216,3 +216,3 @@ | ||
value: "aא弟", | ||
allocatedBytes: 6 | ||
allocatedBytes: 6, | ||
}); | ||
@@ -237,3 +237,3 @@ | ||
type: ENTRY_TYPE.BIGINT_POSITIVE, | ||
value: BigInt("0b0" + "1".repeat(63)) | ||
value: BigInt("0b0" + "1".repeat(63)), | ||
}); | ||
@@ -257,3 +257,3 @@ | ||
type: ENTRY_TYPE.BIGINT_POSITIVE, | ||
value: BigInt("0b" + "1".repeat(64)) | ||
value: BigInt("0b" + "1".repeat(64)), | ||
}); | ||
@@ -276,3 +276,3 @@ | ||
type: ENTRY_TYPE.BIGINT_POSITIVE, | ||
value: BigInt("0b" + "1".repeat(64)) | ||
value: BigInt("0b" + "1".repeat(64)), | ||
}); | ||
@@ -294,3 +294,3 @@ | ||
type: ENTRY_TYPE.BIGINT_NEGATIVE, | ||
value: -BigInt("0b" + "1".repeat(64)) | ||
value: -BigInt("0b" + "1".repeat(64)), | ||
}); | ||
@@ -313,3 +313,3 @@ | ||
type: ENTRY_TYPE.BIGINT_POSITIVE, | ||
value: BigInt("0b" + "1".repeat(65)) | ||
value: BigInt("0b" + "1".repeat(65)), | ||
}); | ||
@@ -327,3 +327,3 @@ }).toThrowErrorMatchingInlineSnapshot(`"BigInt64OverflowError"`); | ||
refsCount: 0, | ||
value: 10 | ||
value: 10, | ||
}; | ||
@@ -355,3 +355,3 @@ | ||
value: "im a string", | ||
allocatedBytes: 11 | ||
allocatedBytes: 11, | ||
}); | ||
@@ -362,204 +362,204 @@ | ||
expect(arrayBuffer2HexArray(arrayBuffer, true)).toMatchInlineSnapshot(` | ||
Array [ | ||
"0:0x00", | ||
"1:0x00", | ||
"2:0x00", | ||
"3:0x00", | ||
"4:0x00", | ||
"5:0x00", | ||
"6:0x00", | ||
"7:0x08", | ||
"8:0x00", | ||
"9:0x00", | ||
"10:0x00", | ||
"11:0x00", | ||
"12:0x00", | ||
"13:0x00", | ||
"14:0x00", | ||
"15:0x00", | ||
"16:0x28", | ||
"17:0x00", | ||
"18:0x00", | ||
"19:0x00", | ||
"20:0x40", | ||
"21:0x00", | ||
"22:0x00", | ||
"23:0x00", | ||
"24:0x60", | ||
"25:0x00", | ||
"26:0x00", | ||
"27:0x00", | ||
"28:0x08", | ||
"29:0x00", | ||
"30:0x00", | ||
"31:0x00", | ||
"32:0x03", | ||
"33:0x00", | ||
"34:0x00", | ||
"35:0x00", | ||
"36:0x10", | ||
"37:0x00", | ||
"38:0x00", | ||
"39:0x00", | ||
"40:0x18", | ||
"41:0x00", | ||
"42:0x00", | ||
"43:0x00", | ||
"44:0x00", | ||
"45:0x00", | ||
"46:0x00", | ||
"47:0x00", | ||
"48:0x05", | ||
"49:0x00", | ||
"50:0x0b", | ||
"51:0x00", | ||
"52:0x0b", | ||
"53:0x69", | ||
"54:0x6d", | ||
"55:0x20", | ||
"56:0x61", | ||
"57:0x20", | ||
"58:0x73", | ||
"59:0x74", | ||
"60:0x72", | ||
"61:0x69", | ||
"62:0x6e", | ||
"63:0x67", | ||
"64:0x00", | ||
"65:0x00", | ||
"66:0x00", | ||
"67:0x00", | ||
"68:0x00", | ||
"69:0x00", | ||
"70:0x00", | ||
"71:0x00", | ||
"72:0x00", | ||
"73:0x00", | ||
"74:0x00", | ||
"75:0x00", | ||
"76:0x00", | ||
"77:0x00", | ||
"78:0x00", | ||
"79:0x00", | ||
"80:0x00", | ||
"81:0x00", | ||
"82:0x00", | ||
"83:0x00", | ||
"84:0x00", | ||
"85:0x00", | ||
"86:0x00", | ||
"87:0x00", | ||
"88:0x00", | ||
"89:0x00", | ||
"90:0x00", | ||
"91:0x00", | ||
"92:0x00", | ||
"93:0x00", | ||
"94:0x00", | ||
"95:0x00", | ||
] | ||
`); | ||
Array [ | ||
"0:0x00", | ||
"1:0x00", | ||
"2:0x00", | ||
"3:0x00", | ||
"4:0x08", | ||
"5:0x00", | ||
"6:0x00", | ||
"7:0x00", | ||
"8:0x00", | ||
"9:0x00", | ||
"10:0x00", | ||
"11:0x00", | ||
"12:0x00", | ||
"13:0x00", | ||
"14:0x00", | ||
"15:0x00", | ||
"16:0x28", | ||
"17:0x00", | ||
"18:0x00", | ||
"19:0x00", | ||
"20:0x48", | ||
"21:0x00", | ||
"22:0x00", | ||
"23:0x00", | ||
"24:0x60", | ||
"25:0x00", | ||
"26:0x00", | ||
"27:0x00", | ||
"28:0x08", | ||
"29:0x00", | ||
"30:0x00", | ||
"31:0x00", | ||
"32:0x03", | ||
"33:0x00", | ||
"34:0x00", | ||
"35:0x00", | ||
"36:0x10", | ||
"37:0x00", | ||
"38:0x00", | ||
"39:0x00", | ||
"40:0x20", | ||
"41:0x00", | ||
"42:0x00", | ||
"43:0x00", | ||
"44:0x00", | ||
"45:0x00", | ||
"46:0x00", | ||
"47:0x00", | ||
"48:0x00", | ||
"49:0x00", | ||
"50:0x00", | ||
"51:0x00", | ||
"52:0x00", | ||
"53:0x00", | ||
"54:0x14", | ||
"55:0x40", | ||
"56:0x0b", | ||
"57:0x00", | ||
"58:0x00", | ||
"59:0x00", | ||
"60:0x69", | ||
"61:0x6d", | ||
"62:0x20", | ||
"63:0x61", | ||
"64:0x20", | ||
"65:0x73", | ||
"66:0x74", | ||
"67:0x72", | ||
"68:0x69", | ||
"69:0x6e", | ||
"70:0x67", | ||
"71:0x00", | ||
"72:0x00", | ||
"73:0x00", | ||
"74:0x00", | ||
"75:0x00", | ||
"76:0x00", | ||
"77:0x00", | ||
"78:0x00", | ||
"79:0x00", | ||
"80:0x00", | ||
"81:0x00", | ||
"82:0x00", | ||
"83:0x00", | ||
"84:0x00", | ||
"85:0x00", | ||
"86:0x00", | ||
"87:0x00", | ||
"88:0x00", | ||
"89:0x00", | ||
"90:0x00", | ||
"91:0x00", | ||
"92:0x00", | ||
"93:0x00", | ||
"94:0x00", | ||
"95:0x00", | ||
] | ||
`); | ||
expect(arrayBuffer2HexArray(arrayBuffer, true)).toMatchInlineSnapshot(` | ||
Array [ | ||
"0:0x00", | ||
"1:0x00", | ||
"2:0x00", | ||
"3:0x00", | ||
"4:0x00", | ||
"5:0x00", | ||
"6:0x00", | ||
"7:0x08", | ||
"8:0x00", | ||
"9:0x00", | ||
"10:0x00", | ||
"11:0x00", | ||
"12:0x00", | ||
"13:0x00", | ||
"14:0x00", | ||
"15:0x00", | ||
"16:0x28", | ||
"17:0x00", | ||
"18:0x00", | ||
"19:0x00", | ||
"20:0x40", | ||
"21:0x00", | ||
"22:0x00", | ||
"23:0x00", | ||
"24:0x60", | ||
"25:0x00", | ||
"26:0x00", | ||
"27:0x00", | ||
"28:0x08", | ||
"29:0x00", | ||
"30:0x00", | ||
"31:0x00", | ||
"32:0x03", | ||
"33:0x00", | ||
"34:0x00", | ||
"35:0x00", | ||
"36:0x10", | ||
"37:0x00", | ||
"38:0x00", | ||
"39:0x00", | ||
"40:0x18", | ||
"41:0x00", | ||
"42:0x00", | ||
"43:0x00", | ||
"44:0x00", | ||
"45:0x00", | ||
"46:0x00", | ||
"47:0x00", | ||
"48:0x05", | ||
"49:0x00", | ||
"50:0x0b", | ||
"51:0x00", | ||
"52:0x0b", | ||
"53:0x69", | ||
"54:0x6d", | ||
"55:0x20", | ||
"56:0x61", | ||
"57:0x20", | ||
"58:0x73", | ||
"59:0x74", | ||
"60:0x72", | ||
"61:0x69", | ||
"62:0x6e", | ||
"63:0x67", | ||
"64:0x00", | ||
"65:0x00", | ||
"66:0x00", | ||
"67:0x00", | ||
"68:0x00", | ||
"69:0x00", | ||
"70:0x00", | ||
"71:0x00", | ||
"72:0x00", | ||
"73:0x00", | ||
"74:0x00", | ||
"75:0x00", | ||
"76:0x00", | ||
"77:0x00", | ||
"78:0x00", | ||
"79:0x00", | ||
"80:0x00", | ||
"81:0x00", | ||
"82:0x00", | ||
"83:0x00", | ||
"84:0x00", | ||
"85:0x00", | ||
"86:0x00", | ||
"87:0x00", | ||
"88:0x00", | ||
"89:0x00", | ||
"90:0x00", | ||
"91:0x00", | ||
"92:0x00", | ||
"93:0x00", | ||
"94:0x00", | ||
"95:0x00", | ||
] | ||
`); | ||
Array [ | ||
"0:0x00", | ||
"1:0x00", | ||
"2:0x00", | ||
"3:0x00", | ||
"4:0x08", | ||
"5:0x00", | ||
"6:0x00", | ||
"7:0x00", | ||
"8:0x00", | ||
"9:0x00", | ||
"10:0x00", | ||
"11:0x00", | ||
"12:0x00", | ||
"13:0x00", | ||
"14:0x00", | ||
"15:0x00", | ||
"16:0x28", | ||
"17:0x00", | ||
"18:0x00", | ||
"19:0x00", | ||
"20:0x48", | ||
"21:0x00", | ||
"22:0x00", | ||
"23:0x00", | ||
"24:0x60", | ||
"25:0x00", | ||
"26:0x00", | ||
"27:0x00", | ||
"28:0x08", | ||
"29:0x00", | ||
"30:0x00", | ||
"31:0x00", | ||
"32:0x03", | ||
"33:0x00", | ||
"34:0x00", | ||
"35:0x00", | ||
"36:0x10", | ||
"37:0x00", | ||
"38:0x00", | ||
"39:0x00", | ||
"40:0x20", | ||
"41:0x00", | ||
"42:0x00", | ||
"43:0x00", | ||
"44:0x00", | ||
"45:0x00", | ||
"46:0x00", | ||
"47:0x00", | ||
"48:0x00", | ||
"49:0x00", | ||
"50:0x00", | ||
"51:0x00", | ||
"52:0x00", | ||
"53:0x00", | ||
"54:0x14", | ||
"55:0x40", | ||
"56:0x0b", | ||
"57:0x00", | ||
"58:0x00", | ||
"59:0x00", | ||
"60:0x69", | ||
"61:0x6d", | ||
"62:0x20", | ||
"63:0x61", | ||
"64:0x20", | ||
"65:0x73", | ||
"66:0x74", | ||
"67:0x72", | ||
"68:0x69", | ||
"69:0x6e", | ||
"70:0x67", | ||
"71:0x00", | ||
"72:0x00", | ||
"73:0x00", | ||
"74:0x00", | ||
"75:0x00", | ||
"76:0x00", | ||
"77:0x00", | ||
"78:0x00", | ||
"79:0x00", | ||
"80:0x00", | ||
"81:0x00", | ||
"82:0x00", | ||
"83:0x00", | ||
"84:0x00", | ||
"85:0x00", | ||
"86:0x00", | ||
"87:0x00", | ||
"88:0x00", | ||
"89:0x00", | ||
"90:0x00", | ||
"91:0x00", | ||
"92:0x00", | ||
"93:0x00", | ||
"94:0x00", | ||
"95:0x00", | ||
] | ||
`); | ||
}); | ||
}); | ||
}); |
import { ENTRY_TYPE, isPrimitiveEntryType } from "./entry-types"; | ||
import { Entry, primitive, DataViewAndAllocatorCarrier } from "./interfaces"; | ||
import { Entry, primitive, GlobalCarrier } from "./interfaces"; | ||
import { | ||
isPrimitive, | ||
primitiveValueToEntry, | ||
isKnownAddressValuePointer | ||
isKnownAddressValuePointer, | ||
} from "./utils"; | ||
@@ -12,3 +12,3 @@ import { ExternalArgs } from "./interfaces"; | ||
INITIAL_ENTRY_POINTER_TO_POINTER, | ||
INITIAL_ENTRY_POINTER_VALUE | ||
INITIAL_ENTRY_POINTER_VALUE, | ||
} from "./consts"; | ||
@@ -23,14 +23,8 @@ import { saveValue } from "./saveValue"; | ||
export function initializeArrayBuffer(arrayBuffer: ArrayBuffer) { | ||
const dataView = new DataView(arrayBuffer); | ||
const uint32 = new Uint32Array(arrayBuffer); | ||
// global lock | ||
dataView.setInt32(0, 0); | ||
// first entry pointer | ||
dataView.setUint32( | ||
INITIAL_ENTRY_POINTER_TO_POINTER, | ||
INITIAL_ENTRY_POINTER_VALUE | ||
); | ||
return dataView; | ||
uint32[0] = 0; | ||
uint32[ | ||
INITIAL_ENTRY_POINTER_TO_POINTER / Uint32Array.BYTES_PER_ELEMENT | ||
] = INITIAL_ENTRY_POINTER_VALUE; | ||
} | ||
@@ -41,3 +35,4 @@ | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
// type | ||
cursor += Float64Array.BYTES_PER_ELEMENT; | ||
@@ -50,6 +45,5 @@ switch (entry.type) { | ||
case ENTRY_TYPE.STRING: | ||
cursor += Uint16Array.BYTES_PER_ELEMENT; | ||
// string length | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
cursor += Uint16Array.BYTES_PER_ELEMENT; | ||
cursor += entry.allocatedBytes; | ||
@@ -75,16 +69,24 @@ | ||
case ENTRY_TYPE.SET: | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
// ref count | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
// pointer | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
break; | ||
case ENTRY_TYPE.ARRAY: | ||
// refsCount | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
// pointer | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
// length | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
// allocated length | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
break; | ||
case ENTRY_TYPE.DATE: | ||
// timestamp | ||
cursor += Float64Array.BYTES_PER_ELEMENT; | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
// ref count | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
break; | ||
@@ -102,3 +104,3 @@ | ||
export function writeEntry( | ||
{ dataView, uint8 }: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
startingCursor: number, | ||
@@ -113,8 +115,8 @@ entry: Entry | ||
// undo on throw ? | ||
dataView.setUint8(cursor, entry.type); | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT] = entry.type; | ||
cursor += Float64Array.BYTES_PER_ELEMENT; | ||
switch (entry.type) { | ||
case ENTRY_TYPE.NUMBER: | ||
dataView.setFloat64(cursor, entry.value); | ||
carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT] = entry.value; | ||
cursor += Float64Array.BYTES_PER_ELEMENT; | ||
@@ -124,20 +126,19 @@ break; | ||
case ENTRY_TYPE.STRING: | ||
dataView.setUint16(cursor, entry.allocatedBytes); | ||
cursor += Uint16Array.BYTES_PER_ELEMENT; | ||
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = | ||
entry.allocatedBytes; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
dataView.setUint16(cursor, entry.allocatedBytes); | ||
cursor += Uint16Array.BYTES_PER_ELEMENT; | ||
// const arr = new Uint8Array(entry.allocatedBytes); | ||
// const writtenBytes1 = stringEncodeInto(arr, 0, entry.value); | ||
// eslint-disable-next-line no-case-declarations | ||
const writtenBytes = stringEncodeInto(uint8, cursor, entry.value); | ||
const writtenBytes = stringEncodeInto(carrier.uint8, cursor, entry.value); | ||
if (writtenBytes !== entry.allocatedBytes) { | ||
// eslint-disable-next-line no-undef | ||
console.warn({ | ||
value: entry.value, | ||
writtenBytes, | ||
allocatedBytes: entry.allocatedBytes | ||
}); | ||
console.warn( | ||
{ | ||
value: entry.value, | ||
writtenBytes, | ||
allocatedBytes: entry.allocatedBytes, | ||
}, | ||
true | ||
); | ||
throw new Error("WTF???"); | ||
@@ -155,7 +156,5 @@ } | ||
} | ||
carrier.bigUint64[cursor / BigUint64Array.BYTES_PER_ELEMENT] = | ||
entry.type === ENTRY_TYPE.BIGINT_NEGATIVE ? -entry.value : entry.value; | ||
dataView.setBigUint64( | ||
cursor, | ||
entry.type === ENTRY_TYPE.BIGINT_NEGATIVE ? -entry.value : entry.value | ||
); | ||
cursor += BigUint64Array.BYTES_PER_ELEMENT; | ||
@@ -167,24 +166,25 @@ break; | ||
case ENTRY_TYPE.MAP: | ||
dataView.setUint8(cursor, entry.refsCount); | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
dataView.setUint32(cursor, entry.value); | ||
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.refsCount; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.value; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
break; | ||
case ENTRY_TYPE.ARRAY: | ||
dataView.setUint8(cursor, entry.refsCount); | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
dataView.setUint32(cursor, entry.value); | ||
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.refsCount; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
dataView.setUint32(cursor, entry.length); | ||
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.value; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
dataView.setUint32(cursor, entry.allocatedLength); | ||
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.length; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = | ||
entry.allocatedLength; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
break; | ||
case ENTRY_TYPE.DATE: | ||
dataView.setUint8(cursor, entry.refsCount); | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
dataView.setFloat64(cursor, entry.value); | ||
carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT] = entry.value; | ||
cursor += Float64Array.BYTES_PER_ELEMENT; | ||
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT] = entry.refsCount; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
break; | ||
@@ -201,3 +201,3 @@ | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
entry: Entry | ||
@@ -215,3 +215,3 @@ ) { | ||
export function readEntry( | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
startingCursor: number | ||
@@ -221,8 +221,9 @@ ): Entry { | ||
const entryType: ENTRY_TYPE = carrier.dataView.getUint8(cursor); | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
const entryType: ENTRY_TYPE = | ||
carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT]; | ||
cursor += Float64Array.BYTES_PER_ELEMENT; | ||
const entry: any = { | ||
type: entryType, | ||
value: undefined as any | ||
value: undefined as any, | ||
}; | ||
@@ -233,15 +234,16 @@ | ||
switch (entryType) { | ||
case ENTRY_TYPE.UNDEFINED: | ||
break; | ||
// handled by well-known addresses | ||
// case ENTRY_TYPE.UNDEFINED: | ||
// break; | ||
case ENTRY_TYPE.NULL: | ||
break; | ||
// case ENTRY_TYPE.NULL: | ||
// break; | ||
case ENTRY_TYPE.BOOLEAN: | ||
entry.value = carrier.dataView.getUint8(cursor) !== 0; | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
break; | ||
// case ENTRY_TYPE.BOOLEAN: | ||
// entry.value = carrier.dataView.getUint8(cursor) !== 0; | ||
// cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
// break; | ||
case ENTRY_TYPE.NUMBER: | ||
entry.value = carrier.dataView.getFloat64(cursor); | ||
entry.value = carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT]; | ||
cursor += Float64Array.BYTES_PER_ELEMENT; | ||
@@ -252,8 +254,7 @@ break; | ||
// eslint-disable-next-line no-case-declarations | ||
const stringLength = carrier.dataView.getUint16(cursor); | ||
cursor += Uint16Array.BYTES_PER_ELEMENT; | ||
const stringLength = | ||
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT]; | ||
entry.allocatedBytes = stringLength; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
entry.allocatedBytes = carrier.dataView.getUint16(cursor); | ||
cursor += Uint16Array.BYTES_PER_ELEMENT; | ||
// decode fails with zero length array | ||
@@ -264,4 +265,4 @@ if (stringLength > 0) { | ||
// eslint-disable-next-line no-case-declarations | ||
// const tempAB = new ArrayBuffer(stringLength); | ||
// arrayBufferCopyTo(dataView.buffer, cursor, stringLength, tempAB, 0); | ||
// const tempAB = new ArrayBuffer(stringLength, true); | ||
// arrayBufferCopyTo(dataView.buffer, cursor, stringLength, tempAB, 0, true); | ||
@@ -278,3 +279,4 @@ entry.value = stringDecode(carrier.uint8, cursor, stringLength); | ||
case ENTRY_TYPE.BIGINT_POSITIVE: | ||
entry.value = carrier.dataView.getBigUint64(cursor); | ||
entry.value = | ||
carrier.bigUint64[cursor / BigUint64Array.BYTES_PER_ELEMENT]; | ||
cursor += BigUint64Array.BYTES_PER_ELEMENT; | ||
@@ -284,3 +286,5 @@ break; | ||
case ENTRY_TYPE.BIGINT_NEGATIVE: | ||
entry.value = -carrier.dataView.getBigUint64(cursor); | ||
entry.value = -carrier.bigUint64[ | ||
cursor / BigUint64Array.BYTES_PER_ELEMENT | ||
]; | ||
cursor += BigUint64Array.BYTES_PER_ELEMENT; | ||
@@ -292,24 +296,25 @@ break; | ||
case ENTRY_TYPE.SET: | ||
entry.refsCount = carrier.dataView.getUint8(cursor); | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
entry.value = carrier.dataView.getUint32(cursor); | ||
entry.refsCount = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT]; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
entry.value = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT]; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
break; | ||
case ENTRY_TYPE.ARRAY: | ||
entry.refsCount = carrier.dataView.getUint8(cursor); | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
entry.value = carrier.dataView.getUint32(cursor); | ||
entry.refsCount = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT]; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
entry.length = carrier.dataView.getUint32(cursor); | ||
entry.value = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT]; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
entry.allocatedLength = carrier.dataView.getUint32(cursor); | ||
entry.length = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT]; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
entry.allocatedLength = | ||
carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT]; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
break; | ||
case ENTRY_TYPE.DATE: | ||
entry.refsCount = carrier.dataView.getUint8(cursor); | ||
cursor += Uint8Array.BYTES_PER_ELEMENT; | ||
entry.value = carrier.dataView.getFloat64(cursor); | ||
entry.value = carrier.float64[cursor / Float64Array.BYTES_PER_ELEMENT]; | ||
cursor += Float64Array.BYTES_PER_ELEMENT; | ||
entry.refsCount = carrier.uint32[cursor / Uint32Array.BYTES_PER_ELEMENT]; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
break; | ||
@@ -350,16 +355,22 @@ | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
ptrToPtr: number, | ||
value: any | ||
) { | ||
const existingEntryPointer = carrier.dataView.getUint32(ptrToPtr); | ||
const existingValueEntry = readEntry(carrier, existingEntryPointer); | ||
const existingEntryPointer = | ||
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT]; | ||
let reuse = false; | ||
let existingValueEntry: Entry | undefined; | ||
if (!isKnownAddressValuePointer(existingEntryPointer)) { | ||
existingValueEntry = readEntry(carrier, existingEntryPointer); | ||
reuse = | ||
isPrimitive(value) && | ||
isPrimitiveEntryType(existingValueEntry.type) && | ||
canReuseMemoryOfEntry(existingValueEntry, value); | ||
} | ||
// try to re use memory | ||
if ( | ||
!isKnownAddressValuePointer(existingEntryPointer) && | ||
isPrimitive(value) && | ||
isPrimitiveEntryType(existingValueEntry.type) && | ||
canReuseMemoryOfEntry(existingValueEntry, value) | ||
) { | ||
if (reuse) { | ||
const newEntry = primitiveValueToEntry(value); | ||
@@ -377,3 +388,3 @@ | ||
carrier.dataView.setUint32(ptrToPtr, newEntryPointer); | ||
carrier.uint32[ptrToPtr / Uint32Array.BYTES_PER_ELEMENT] = newEntryPointer; | ||
@@ -383,3 +394,3 @@ return { | ||
existingEntryPointer, | ||
existingValueEntry | ||
existingValueEntry, | ||
}; | ||
@@ -391,3 +402,3 @@ } | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
ptrToPtr: number, | ||
@@ -399,3 +410,3 @@ value: any | ||
existingEntryPointer = 0, | ||
referencedPointers = [] | ||
referencedPointers = [], | ||
} = writeValueInPtrToPtr(externalArgs, carrier, ptrToPtr, value) || {}; | ||
@@ -438,3 +449,3 @@ | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
deletedValuePointer: number | ||
@@ -477,3 +488,3 @@ ): void { | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
entryPointer: number | ||
@@ -495,3 +506,3 @@ ) { | ||
externalArgs: ExternalArgs, | ||
carrier: DataViewAndAllocatorCarrier, | ||
carrier: GlobalCarrier, | ||
entryPointer: number | ||
@@ -511,17 +522,44 @@ ) { | ||
export function getObjectPropPtrToPtr( | ||
{ dataView }: DataViewAndAllocatorCarrier, | ||
pointerToEntry: number | ||
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 keyStringLength = dataView.getUint16(pointerToEntry + 1); | ||
const valuePtrToPtr = | ||
Uint16Array.BYTES_PER_ELEMENT + pointerToEntry + 1 + keyStringLength; | ||
const nextPtrToPtr = valuePtrToPtr + Uint32Array.BYTES_PER_ELEMENT; | ||
const entry = readEntry(carrier, entryPointer); | ||
return { | ||
valuePtrToPtr, | ||
nextPtrToPtr | ||
}; | ||
if ("refsCount" in entry) { | ||
const prevCount = entry.refsCount; | ||
entry.refsCount = newRefCount; | ||
writeEntry(carrier, entryPointer, entry); | ||
return prevCount; | ||
} | ||
throw new Error("unexpected"); | ||
} | ||
// export function getObjectPropPtrToPtr( | ||
// { dataView }: GlobalCarrier, | ||
// pointerToEntry: number | ||
// ) { | ||
// const keyStringLength = dataView.getUint16(pointerToEntry + 1); | ||
// const valuePtrToPtr = | ||
// Uint16Array.BYTES_PER_ELEMENT + pointerToEntry + 1 + keyStringLength; | ||
// const nextPtrToPtr = valuePtrToPtr + Uint32Array.BYTES_PER_ELEMENT; | ||
// return { | ||
// valuePtrToPtr, | ||
// nextPtrToPtr | ||
// }; | ||
// } | ||
export function getObjectValuePtrToPtr(pointerToEntry: number) { | ||
@@ -532,3 +570,3 @@ return pointerToEntry + 1 + 1; | ||
export function memComp( | ||
dataView: DataView, | ||
uint8: Uint8Array, | ||
aStart: number, | ||
@@ -539,4 +577,4 @@ bStart: number, | ||
if ( | ||
dataView.byteLength < aStart + length || | ||
dataView.byteLength < bStart + length | ||
uint8.byteLength < aStart + length || | ||
uint8.byteLength < bStart + length | ||
) { | ||
@@ -547,3 +585,3 @@ return false; | ||
// compare 8 using Float64Array? | ||
if (dataView.getUint8(aStart + i) !== dataView.getUint8(bStart + i)) { | ||
if (uint8[aStart + i] !== uint8[bStart + i]) { | ||
return false; | ||
@@ -557,3 +595,3 @@ } | ||
export function compareStringOrNumberEntriesInPlace( | ||
dataView: DataView, | ||
carrier: GlobalCarrier, | ||
entryAPointer: number, | ||
@@ -563,5 +601,7 @@ entryBPointer: number | ||
let cursor = 0; | ||
const entryAType: ENTRY_TYPE = dataView.getUint8(entryAPointer + cursor); | ||
const entryBType: ENTRY_TYPE = dataView.getUint8(entryBPointer + cursor); | ||
cursor += 1; | ||
const entryAType: ENTRY_TYPE = | ||
carrier.float64[(entryAPointer + cursor) / Float64Array.BYTES_PER_ELEMENT]; | ||
const entryBType: ENTRY_TYPE = | ||
carrier.float64[(entryBPointer + cursor) / Float64Array.BYTES_PER_ELEMENT]; | ||
cursor += Float64Array.BYTES_PER_ELEMENT; | ||
@@ -573,4 +613,6 @@ if (entryAType !== entryBType) { | ||
if (entryAType === ENTRY_TYPE.STRING) { | ||
const aLength = dataView.getUint16(entryAPointer + cursor); | ||
const bLength = dataView.getUint16(entryBPointer + cursor); | ||
const aLength = | ||
carrier.uint32[(entryAPointer + cursor) / Uint32Array.BYTES_PER_ELEMENT]; | ||
const bLength = | ||
carrier.uint32[(entryBPointer + cursor) / Uint32Array.BYTES_PER_ELEMENT]; | ||
@@ -582,8 +624,6 @@ if (aLength !== bLength) { | ||
// string length | ||
cursor += Uint16Array.BYTES_PER_ELEMENT; | ||
// allocated length, skip. | ||
cursor += Uint16Array.BYTES_PER_ELEMENT; | ||
cursor += Uint32Array.BYTES_PER_ELEMENT; | ||
return memComp( | ||
dataView, | ||
carrier.uint8, | ||
entryAPointer + cursor, | ||
@@ -596,5 +636,7 @@ entryBPointer + cursor, | ||
return ( | ||
dataView.getFloat64(entryAPointer + cursor) === | ||
dataView.getFloat64(entryBPointer + cursor) | ||
carrier.float64[ | ||
(entryAPointer + cursor) / Float64Array.BYTES_PER_ELEMENT | ||
] === | ||
carrier.float64[(entryBPointer + cursor) / Float64Array.BYTES_PER_ELEMENT] | ||
); | ||
} |
@@ -19,4 +19,4 @@ /* eslint-env jest */ | ||
`請教「署」在文中的含義。 文句中「署」是什么意思?「使直言署」,及下文的「署帛宛然」a`, | ||
125 | ||
] | ||
125, | ||
], | ||
]; | ||
@@ -23,0 +23,0 @@ |
@@ -21,4 +21,4 @@ /* eslint-env jest */ | ||
`請教「署」在文中的含義。 文句中「署」是什么意思?「使直言署」,及下文的「署帛宛然」`, | ||
124 | ||
] | ||
124, | ||
], | ||
]; | ||
@@ -25,0 +25,0 @@ |
@@ -17,3 +17,3 @@ export function arrayBuffer2HexArray( | ||
export function wait(time: number) { | ||
return new Promise(res => { | ||
return new Promise((res) => { | ||
// eslint-disable-next-line no-undef | ||
@@ -26,3 +26,3 @@ setTimeout(res, time); | ||
import { OutOfMemoryError } from "./exceptions"; | ||
import { DataViewAndAllocatorCarrier } from "./interfaces"; | ||
import { GlobalCarrier } from "./interfaces"; | ||
import { MEM_POOL_START } from "./consts"; | ||
@@ -103,7 +103,7 @@ | ||
buf: arrayBuffer, | ||
start: MEM_POOL_START | ||
start: MEM_POOL_START, | ||
}); | ||
const carrier: DataViewAndAllocatorCarrier = { | ||
dataView: new DataView(arrayBuffer), | ||
const carrier: GlobalCarrier = { | ||
// dataView: new DataView(arrayBuffer), | ||
allocator, | ||
@@ -114,3 +114,3 @@ uint8: new Uint8Array(arrayBuffer), | ||
float64: new Float64Array(arrayBuffer), | ||
bigUint64: new BigUint64Array(arrayBuffer) | ||
bigUint64: new BigUint64Array(arrayBuffer), | ||
}; | ||
@@ -117,0 +117,0 @@ |
@@ -6,3 +6,3 @@ import { | ||
InternalAPI, | ||
ExternalArgsApi | ||
ExternalArgsApi, | ||
} from "./interfaces"; | ||
@@ -15,4 +15,5 @@ import { ENTRY_TYPE } from "./entry-types"; | ||
TRUE_KNOWN_ADDRESS, | ||
FALSE_KNOWN_ADDRESS | ||
FALSE_KNOWN_ADDRESS, | ||
} from "./consts"; | ||
import { IMemPool } from "@thi.ng/malloc"; | ||
@@ -24,3 +25,3 @@ const primitives = [ | ||
"boolean", | ||
"undefined" | ||
"undefined", | ||
] as const; | ||
@@ -45,3 +46,3 @@ | ||
value, | ||
allocatedBytes: strByteLength(value) | ||
allocatedBytes: strByteLength(value), | ||
}; | ||
@@ -53,3 +54,3 @@ } | ||
type: ENTRY_TYPE.NUMBER, | ||
value | ||
value, | ||
}; | ||
@@ -64,3 +65,3 @@ } | ||
: ENTRY_TYPE.BIGINT_NEGATIVE, | ||
value | ||
value, | ||
}; | ||
@@ -94,11 +95,9 @@ } | ||
for (let i = 0; i < length; i += 1) { | ||
copyTo[toTargetByte + i] = copyFrom[startByte + i]; | ||
} | ||
copyTo.set(copyFrom.subarray(startByte, startByte + length), toTargetByte); | ||
} | ||
export function getOurPointerIfApplicable(value: any, ourDateView: DataView) { | ||
export function getOurPointerIfApplicable(value: any, ourAllocator: IMemPool) { | ||
if (INTERNAL_API_SYMBOL in value) { | ||
const api = getInternalAPI(value); | ||
if (api.getCarrier().dataView === ourDateView) { | ||
if (api.getCarrier().allocator === ourAllocator) { | ||
return api.getEntryPointer(); | ||
@@ -120,3 +119,3 @@ } | ||
? p.arrayAdditionalAllocation | ||
: 0 | ||
: 0, | ||
}; | ||
@@ -123,0 +122,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
814921
21156
Updated@thi.ng/malloc@^4.1.10