Socket
Socket
Sign inDemoInstall

lmdb

Package Overview
Dependencies
19
Maintainers
3
Versions
164
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 3.0.4 to 3.0.5

60

native.js
import { dirname, join, default as pathModule } from 'path';
import { fileURLToPath } from 'url';
import loadNAPI from 'node-gyp-build-optional-packages';
export let Env, Txn, Dbi, Compression, Cursor, getAddress, getBufferAddress, createBufferForAddress, clearKeptObjects, globalBuffer, setGlobalBuffer, arch, fs, os, onExit, tmpdir, lmdbError, path, EventEmitter, orderedBinary, MsgpackrEncoder, WeakLRUCache, setEnvMap, getEnvMap, getByBinary, detachBuffer, startRead, setReadCallback, write, position, iterate, prefetch, resetTxn, getCurrentValue, getCurrentShared, getStringByBinary, getSharedByBinary, getSharedBuffer, compress, directWrite, attemptLock, unlock;
export let Env,
Txn,
Dbi,
Compression,
Cursor,
getAddress,
getBufferAddress,
createBufferForAddress,
clearKeptObjects,
globalBuffer,
setGlobalBuffer,
arch,
fs,
os,
onExit,
tmpdir,
lmdbError,
path,
EventEmitter,
orderedBinary,
MsgpackrEncoder,
WeakLRUCache,
setEnvMap,
getEnvMap,
getByBinary,
detachBuffer,
startRead,
setReadCallback,
write,
position,
iterate,
prefetch,
resetTxn,
getCurrentValue,
getCurrentShared,
getStringByBinary,
getSharedByBinary,
getSharedBuffer,
compress,
directWrite,
getIncrementer,
attemptLock,
unlock;
path = pathModule;

@@ -15,3 +57,3 @@ let dirName = dirname(fileURLToPath(import.meta.url)).replace(/dist$/, '');

returns: FFIType.u32,
ptr: nativeAddon.getByBinaryPtr
ptr: nativeAddon.getByBinaryPtr,
},

@@ -37,3 +79,3 @@ iterate: {

ptr: nativeAddon.resetTxnPtr,
}
},
});

@@ -45,3 +87,3 @@ for (let key in lmdbLib.symbols) {

setNativeFunctions(nativeAddon);
export function setNativeFunctions(externals) {

@@ -55,5 +97,5 @@ Env = externals.Env;

createBufferForAddress = externals.createBufferForAddress;
clearKeptObjects = externals.clearKeptObjects || function() {};
clearKeptObjects = externals.clearKeptObjects || function () {};
getByBinary = externals.getByBinary;
detachBuffer = externals.detachBuffer;
detachBuffer = externals.detachBuffer;
startRead = externals.startRead;

@@ -69,2 +111,3 @@ setReadCallback = externals.setReadCallback;

directWrite = externals.directWrite;
getIncrementer = externals.getIncrementer;
attemptLock = externals.attemptLock;

@@ -80,4 +123,3 @@ unlock = externals.unlock;

lmdbError = externals.lmdbError;
if (externals.tmpdir)
tmpdir = externals.tmpdir
if (externals.tmpdir) tmpdir = externals.tmpdir;
}

@@ -92,4 +134,4 @@ export function setExternals(externals) {

tmpdir = externals.tmpdir;
os = externals.os;
os = externals.os;
onExit = externals.onExit;
}

14

package.json
{
"name": "lmdb",
"author": "Kris Zyp",
"version": "3.0.4",
"version": "3.0.5",
"description": "Simple, efficient, scalable, high-performance LMDB interface",

@@ -113,9 +113,9 @@ "license": "MIT",

"optionalDependencies": {
"@lmdb/lmdb-darwin-arm64": "3.0.4",
"@lmdb/lmdb-darwin-x64": "3.0.4",
"@lmdb/lmdb-linux-arm": "3.0.4",
"@lmdb/lmdb-linux-arm64": "3.0.4",
"@lmdb/lmdb-linux-x64": "3.0.4",
"@lmdb/lmdb-win32-x64": "3.0.4"
"@lmdb/lmdb-darwin-arm64": "3.0.5",
"@lmdb/lmdb-darwin-x64": "3.0.5",
"@lmdb/lmdb-linux-arm": "3.0.5",
"@lmdb/lmdb-linux-arm64": "3.0.5",
"@lmdb/lmdb-linux-x64": "3.0.5",
"@lmdb/lmdb-win32-x64": "3.0.5"
}
}

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

import { RangeIterable } from './util/RangeIterable.js';
import { RangeIterable } from './util/RangeIterable.js';
import {

@@ -23,5 +23,5 @@ getAddress,

attemptLock,
unlock
unlock,
} from './native.js';
import { saveKey } from './keys.js';
import { saveKey } from './keys.js';
const IF_EXISTS = 3.542694326329068e-103;

@@ -35,3 +35,7 @@ const DEFAULT_BEGINNING_KEY = Buffer.from([5]); // the default starting key for iteration, which excludes symbols/metadata

getValueBytes.isGlobal = true;
Object.defineProperty(getValueBytes, 'length', { value: getValueBytes.length, writable: true, configurable: true });
Object.defineProperty(getValueBytes, 'length', {
value: getValueBytes.length,
writable: true,
configurable: true,
});
}

@@ -44,6 +48,9 @@ const START_ADDRESS_POSITION = 4064;

export function addReadMethods(LMDBStore, {
maxKeySize, env, keyBytes, keyBytesView, getLastVersion, getLastTxnId
}) {
let readTxn, readTxnRenewed, asSafeBuffer = false;
export function addReadMethods(
LMDBStore,
{ maxKeySize, env, keyBytes, keyBytesView, getLastVersion, getLastTxnId },
) {
let readTxn,
readTxnRenewed,
asSafeBuffer = false;
let renewId = 1;

@@ -53,11 +60,22 @@ let outstandingReads = 0;

getString(id, options) {
let txn = env.writeTxn || (options && options.transaction) || (readTxnRenewed ? readTxn : renewReadTxn(this));
let string = getStringByBinary(this.dbAddress, this.writeKey(id, keyBytes, 0), txn.address || 0);
if (typeof string === 'number') { // indicates the buffer wasn't large enough
let txn =
env.writeTxn ||
(options && options.transaction) ||
(readTxnRenewed ? readTxn : renewReadTxn(this));
let string = getStringByBinary(
this.dbAddress,
this.writeKey(id, keyBytes, 0),
txn.address || 0,
);
if (typeof string === 'number') {
// indicates the buffer wasn't large enough
this._allocateGetBuffer(string);
// and then try again
string = getStringByBinary(this.dbAddress, this.writeKey(id, keyBytes, 0), txn.address || 0);
string = getStringByBinary(
this.dbAddress,
this.writeKey(id, keyBytes, 0),
txn.address || 0,
);
}
if (string)
this.lastSize = string.length;
if (string) this.lastSize = string.length;
return string;

@@ -67,16 +85,33 @@ },

let rc;
let txn = env.writeTxn || (options && options.transaction) || (readTxnRenewed ? readTxn : renewReadTxn(this));
rc = this.lastSize = getByBinary(this.dbAddress, this.writeKey(id, keyBytes, 0), (options && options.ifNotTxnId) || 0, txn.address || 0);
let txn =
env.writeTxn ||
(options && options.transaction) ||
(readTxnRenewed ? readTxn : renewReadTxn(this));
rc = this.lastSize = getByBinary(
this.dbAddress,
this.writeKey(id, keyBytes, 0),
(options && options.ifNotTxnId) || 0,
txn.address || 0,
);
if (rc < 0) {
if (rc == -30798) // MDB_NOTFOUND
if (rc == -30798)
// MDB_NOTFOUND
return; // undefined
if (rc == -30004) // txn id matched
if (rc == -30004)
// txn id matched
return UNMODIFIED;
if (rc == -30781 /*MDB_BAD_VALSIZE*/ && this.writeKey(id, keyBytes, 0) == 0)
throw new Error(id === undefined ?
'A key is required for get, but is undefined' :
'Zero length key is not allowed in LMDB');
if (rc == -30000) // int32 overflow, read uint32
if (
rc == -30781 /*MDB_BAD_VALSIZE*/ &&
this.writeKey(id, keyBytes, 0) == 0
)
throw new Error(
id === undefined
? 'A key is required for get, but is undefined'
: 'Zero length key is not allowed in LMDB',
);
if (rc == -30000)
// int32 overflow, read uint32
rc = this.lastSize = keyBytesView.getUint32(0, true);
else if (rc == -30001) {// shared buffer
else if (rc == -30001) {
// shared buffer
this.lastSize = keyBytesView.getUint32(0, true);

@@ -86,4 +121,3 @@ let bufferId = keyBytesView.getUint32(4, true);

return asSafeBuffer ? Buffer.from(bytes) : bytes;
} else
throw lmdbError(rc);
} else throw lmdbError(rc);
}

@@ -94,4 +128,10 @@ let compression = this.compression;

// this means the target buffer wasn't big enough, so the get failed to copy all the data from the database, need to either grow or use special buffer
return this._returnLargeBuffer(
() => getByBinary(this.dbAddress, this.writeKey(id, keyBytes, 0), 0, txn.address || 0));
return this._returnLargeBuffer(() =>
getByBinary(
this.dbAddress,
this.writeKey(id, keyBytes, 0),
0,
txn.address || 0,
),
);
}

@@ -102,3 +142,6 @@ bytes.length = this.lastSize;

getBFAsync(id, options, callback) {
let txn = env.writeTxn || (options && options.transaction) || (readTxnRenewed ? readTxn : renewReadTxn(this));
let txn =
env.writeTxn ||
(options && options.transaction) ||
(readTxnRenewed ? readTxn : renewReadTxn(this));
txn.refCount = (txn.refCount || 0) + 1;

@@ -109,24 +152,30 @@ outstandingReads++;

}
let address = recordReadInstruction(txn.address, this.db.dbi, id, this.writeKey, maxKeySize, ( rc, bufferId, offset, size ) => {
if (rc && rc !== 1)
callback(lmdbError(rc));
outstandingReads--;
let buffer = mmaps[bufferId];
if (!buffer) {
buffer = mmaps[bufferId] = getSharedBuffer(bufferId, env.address);
}
//console.log({bufferId, offset, size})
if (buffer.isSharedMap) {
// using LMDB shared memory
// TODO: We may want explicit support for clearing aborting the transaction on the next event turn,
// but for now we are relying on the GC to cleanup transaction for larger blocks of memory
let bytes = new Uint8Array(buffer, offset, size);
bytes.txn = txn;
callback(bytes, 0, size);
} else {
// using copied memory
txn.done(); // decrement and possibly abort
callback(buffer, offset, size);
}
});
let address = recordReadInstruction(
txn.address,
this.db.dbi,
id,
this.writeKey,
maxKeySize,
(rc, bufferId, offset, size) => {
if (rc && rc !== 1) callback(lmdbError(rc));
outstandingReads--;
let buffer = mmaps[bufferId];
if (!buffer) {
buffer = mmaps[bufferId] = getSharedBuffer(bufferId, env.address);
}
//console.log({bufferId, offset, size})
if (buffer.isSharedMap) {
// using LMDB shared memory
// TODO: We may want explicit support for clearing aborting the transaction on the next event turn,
// but for now we are relying on the GC to cleanup transaction for larger blocks of memory
let bytes = new Uint8Array(buffer, offset, size);
bytes.txn = txn;
callback(bytes, 0, size);
} else {
// using copied memory
txn.done(); // decrement and possibly abort
callback(buffer, offset, size);
}
},
);
if (address) {

@@ -140,4 +189,3 @@ startRead(address, () => {

let promise;
if (!callback)
promise = new Promise(resolve => callback = resolve);
if (!callback) promise = new Promise((resolve) => (callback = resolve));
this.getBFAsync(id, options, (buffer, offset, size) => {

@@ -158,4 +206,3 @@ if (this.useVersions) {

value = Buffer.prototype.utf8Slice.call(bytes, 0, size);
if (this.encoding == 'json' && value)
value = JSON.parse(value);
if (this.encoding == 'json' && value) value = JSON.parse(value);
}

@@ -167,8 +214,9 @@ callback(value);

retain(data, options) {
if (!data)
return
if (!data) return;
let source = data[SOURCE_SYMBOL];
let buffer = source ? source.bytes : data;
if (!buffer.isGlobal && !env.writeTxn) {
let txn = options?.transaction || (readTxnRenewed ? readTxn : renewReadTxn(this));
let txn =
options?.transaction ||
(readTxnRenewed ? readTxn : renewReadTxn(this));
buffer.txn = txn;

@@ -183,4 +231,3 @@

return data;
} else
return buffer;
} else return buffer;
}

@@ -193,3 +240,3 @@ },

// used by getBinary to indicate it should create a dedicated buffer to receive this
let bytesToRestore
let bytesToRestore;
try {

@@ -199,9 +246,17 @@ if (compression) {

let dictionary = compression.dictionary || [];
let dictLength = (dictionary.length >> 3) << 3;// make sure it is word-aligned
let dictLength = (dictionary.length >> 3) << 3; // make sure it is word-aligned
bytes = makeReusableBuffer(this.lastSize);
compression.setBuffer(bytes.buffer, bytes.byteOffset, this.lastSize, dictionary, dictLength);
compression.setBuffer(
bytes.buffer,
bytes.byteOffset,
this.lastSize,
dictionary,
dictLength,
);
compression.getValueBytes = bytes;
} else {
bytesToRestore = getValueBytes;
setGlobalBuffer(bytes = getValueBytes = makeReusableBuffer(this.lastSize));
setGlobalBuffer(
(bytes = getValueBytes = makeReusableBuffer(this.lastSize)),
);
}

@@ -212,3 +267,9 @@ getFast();

let dictLength = (compression.dictionary.length >> 3) << 3;
compression.setBuffer(bytesToRestore.buffer, bytesToRestore.byteOffset, bytesToRestore.maxLength, compression.dictionary, dictLength);
compression.setBuffer(
bytesToRestore.buffer,
bytesToRestore.byteOffset,
bytesToRestore.maxLength,
compression.dictionary,
dictLength,
);
compression.getValueBytes = bytesToRestore;

@@ -233,15 +294,26 @@ } else {

if (this.compression) {
let dictionary = this.compression.dictionary || Buffer.allocUnsafeSlow(0);
let dictLength = (dictionary.length >> 3) << 3;// make sure it is word-aligned
let dictionary =
this.compression.dictionary || Buffer.allocUnsafeSlow(0);
let dictLength = (dictionary.length >> 3) << 3; // make sure it is word-aligned
bytes = Buffer.allocUnsafeSlow(newLength + dictLength);
bytes.set(dictionary) // copy dictionary into start
bytes.set(dictionary); // copy dictionary into start
// the section after the dictionary is the target area for get values
bytes = bytes.subarray(dictLength);
this.compression.setBuffer(bytes.buffer, bytes.byteOffset, newLength, dictionary, dictLength);
this.compression.setBuffer(
bytes.buffer,
bytes.byteOffset,
newLength,
dictionary,
dictLength,
);
bytes.maxLength = newLength;
Object.defineProperty(bytes, 'length', { value: newLength, writable: true, configurable: true });
Object.defineProperty(bytes, 'length', {
value: newLength,
writable: true,
configurable: true,
});
this.compression.getValueBytes = bytes;
} else {
bytes = makeReusableBuffer(newLength);
setGlobalBuffer(getValueBytes = bytes);
setGlobalBuffer((getValueBytes = bytes));
}

@@ -255,3 +327,8 @@ bytes.isGlobal = true;

let fastBuffer = this.getBinaryFast(id, options);
return fastBuffer && (fastBuffer.isGlobal ? Uint8ArraySlice.call(fastBuffer, 0, this.lastSize) : fastBuffer);
return (
fastBuffer &&
(fastBuffer.isGlobal
? Uint8ArraySlice.call(fastBuffer, 0, this.lastSize)
: fastBuffer)
);
} finally {

@@ -265,4 +342,4 @@ asSafeBuffer = false;

if (fastBuffer.isGlobal || writeTxn)
return Uint8ArraySlice.call(fastBuffer, 0, this.lastSize)
fastBuffer.txn = (options && options.transaction);
return Uint8ArraySlice.call(fastBuffer, 0, this.lastSize);
fastBuffer.txn = options && options.transaction;
options.transaction.refCount = (options.transaction.refCount || 0) + 1;

@@ -276,10 +353,17 @@ return fastBuffer;

let bytes = this.getBinaryFast(id, options);
return bytes && (bytes == UNMODIFIED ? UNMODIFIED : this.decoder.decode(bytes, options));
return (
bytes &&
(bytes == UNMODIFIED
? UNMODIFIED
: this.decoder.decode(bytes, options))
);
}
if (this.encoding == 'binary')
return this.getBinary(id, options);
if (this.encoding == 'binary') return this.getBinary(id, options);
if (this.decoder) {
// the decoder potentially uses the data from the buffer in the future and needs a stable buffer
let bytes = this.getBinary(id, options);
return bytes && (bytes == UNMODIFIED ? UNMODIFIED : this.decoder.decode(bytes));
return (
bytes &&
(bytes == UNMODIFIED ? UNMODIFIED : this.decoder.decode(bytes))
);
}

@@ -289,4 +373,3 @@

if (result) {
if (this.encoding == 'json')
return JSON.parse(result);
if (this.encoding == 'json') return JSON.parse(result);
}

@@ -314,10 +397,25 @@ return result;

let rc;
let txn = env.writeTxn || (options && options.transaction) || (readTxnRenewed ? readTxn : renewReadTxn(this));
let txn =
env.writeTxn ||
(options && options.transaction) ||
(readTxnRenewed ? readTxn : renewReadTxn(this));
let keySize = this.writeKey(id, keyBytes, 0);
let dataOffset = (((keySize >> 3) + 1) << 3);
keyBytes.set(options.bytes, dataOffset)
rc = directWrite(this.dbAddress, keySize, options.offset, options.bytes.length, txn.address || 0);
let dataOffset = ((keySize >> 3) + 1) << 3;
keyBytes.set(options.bytes, dataOffset);
rc = directWrite(
this.dbAddress,
keySize,
options.offset,
options.bytes.length,
txn.address || 0,
);
if (rc < 0) lmdbError(rc);
},
getIncrementer(id, startingValue) {
keyBytes.dataView.setUint32(0, this.db.dbi);
let keySize = this.writeKey(id, keyBytes, 4);
return getIncrementer(env.address, keySize, startingValue);
},
attemptLock(id, version, callback) {

@@ -345,3 +443,3 @@ keyBytes.dataView.setUint32(0, this.db.dbi);

if (readTxn) {
readTxn.isCommitted = true
readTxn.isCommitted = true;
readTxn.commit();

@@ -354,4 +452,3 @@ }

ensureReadTxn() {
if (!env.writeTxn && !readTxnRenewed)
renewReadTxn(this);
if (!env.writeTxn && !readTxnRenewed) renewReadTxn(this);
},

@@ -361,8 +458,12 @@ doesExist(key, versionOrValue, options) {

// undefined means the entry exists, null is used specifically to check for the entry *not* existing
return (this.getBinaryFast(key, options) === undefined) == (versionOrValue === null);
}
else if (this.useVersions) {
return this.getBinaryFast(key, options) !== undefined && (versionOrValue === IF_EXISTS || getLastVersion() === versionOrValue);
}
else {
return (
(this.getBinaryFast(key, options) === undefined) ==
(versionOrValue === null)
);
} else if (this.useVersions) {
return (
this.getBinaryFast(key, options) !== undefined &&
(versionOrValue === IF_EXISTS || getLastVersion() === versionOrValue)
);
} else {
if (versionOrValue && versionOrValue['\x10binary-data\x02'])

@@ -375,3 +476,8 @@ versionOrValue = versionOrValue['\x10binary-data\x02'];

let defaultOptions = { start: versionOrValue, exactMatch: true };
return this.getValuesCount(key, options ? Object.assign(defaultOptions, options) : defaultOptions) > 0;
return (
this.getValuesCount(
key,
options ? Object.assign(defaultOptions, options) : defaultOptions,
) > 0
);
}

@@ -382,11 +488,12 @@ },

key,
valuesForKey: true
valuesForKey: true,
};
if (options && options.snapshot === false)
throw new Error('Can not disable snapshots for getValues');
return this.getRange(options ? Object.assign(defaultOptions, options) : defaultOptions);
return this.getRange(
options ? Object.assign(defaultOptions, options) : defaultOptions,
);
},
getKeys(options) {
if (!options)
options = {};
if (!options) options = {};
options.values = false;

@@ -396,4 +503,3 @@ return this.getRange(options);

getCount(options) {
if (!options)
options = {};
if (!options) options = {};
options.onlyCount = true;

@@ -403,4 +509,3 @@ return this.getRange(options).iterate();

getKeysCount(options) {
if (!options)
options = {};
if (!options) options = {};
options.onlyCount = true;

@@ -411,4 +516,3 @@ options.values = false;

getValuesCount(key, options) {
if (!options)
options = {};
if (!options) options = {};
options.key = key;

@@ -421,4 +525,3 @@ options.valuesForKey = true;

let iterable = new RangeIterable();
if (!options)
options = {};
if (!options) options = {};
let includeValues = options.values !== false;

@@ -430,13 +533,22 @@ let includeVersions = options.versions;

let snapshot = options.snapshot;
if (snapshot === false && this.dupSort && includeValues) throw new Error('Can not disable snapshot on a' +
' dupSort data store');
if (snapshot === false && this.dupSort && includeValues)
throw new Error(
'Can not disable snapshot on a' + ' dupSort data store',
);
let compression = this.compression;
iterable.iterate = () => {
const reverse = options.reverse;
let currentKey = valuesForKey ? options.key : (reverse || 'start' in options) ? options.start : DEFAULT_BEGINNING_KEY;
let currentKey = valuesForKey
? options.key
: reverse || 'start' in options
? options.start
: DEFAULT_BEGINNING_KEY;
let count = 0;
let cursor, cursorRenewId, cursorAddress;
let txn;
let flags = (includeValues ? 0x100 : 0) | (reverse ? 0x400 : 0) |
(valuesForKey ? 0x800 : 0) | (options.exactMatch ? 0x4000 : 0) |
let flags =
(includeValues ? 0x100 : 0) |
(reverse ? 0x400 : 0) |
(valuesForKey ? 0x800 : 0) |
(options.exactMatch ? 0x4000 : 0) |
(options.inclusiveEnd ? 0x8000 : 0) |

@@ -447,9 +559,11 @@ (options.exclusiveStart ? 0x10000 : 0);

try {
if (cursor)
finishCursor();
if (cursor) finishCursor();
let txnAddress;
txn = options.transaction
txn = options.transaction;
if (txn) {
if (txn.isDone) throw new Error('Can not iterate on range with transaction that is already' +
' done');
if (txn.isDone)
throw new Error(
'Can not iterate on range with transaction that is already' +
' done',
);
txnAddress = txn.address;

@@ -462,5 +576,7 @@ if (!txnAddress) {

let writeTxn = env.writeTxn;
if (writeTxn)
snapshot = false;
txn = env.writeTxn || options.transaction || (readTxnRenewed ? readTxn : renewReadTxn(store));
if (writeTxn) snapshot = false;
txn =
env.writeTxn ||
options.transaction ||
(readTxnRenewed ? readTxn : renewReadTxn(store));
cursor = !writeTxn && db.availableCursor;

@@ -475,3 +591,4 @@ }

cursorAddress = cursor.address;
if (txn.use) txn.use(); // track transaction so we always use the same one
if (txn.use)
txn.use(); // track transaction so we always use the same one
else txn.refCount = (txn.refCount || 0) + 1;

@@ -482,7 +599,7 @@ if (snapshot === false) {

}
} catch(error) {
} catch (error) {
if (cursor) {
try {
cursor.close();
} catch(error) { }
} catch (error) {}
}

@@ -496,4 +613,3 @@ throw error;

let count = position(options.offset);
if (count < 0)
lmdbError(count);
if (count < 0) lmdbError(count);
finishCursor();

@@ -506,3 +622,6 @@ return count;

}
let keySize = currentKey === undefined ? 0 : store.writeKey(currentKey, keyBytes, 0);
let keySize =
currentKey === undefined
? 0
: store.writeKey(currentKey, keyBytes, 0);
let endAddress;

@@ -515,13 +634,49 @@ if (valuesForKey) {

if (store.encoder.writeKey) {
startAddress = saveKey(options.start, store.encoder.writeKey, iterable, maxKeySize);
keyBytesView.setFloat64(START_ADDRESS_POSITION, startAddress, true);
endAddress = saveKey(options.end, store.encoder.writeKey, iterable, maxKeySize);
} else if ((!options.start || options.start instanceof Uint8Array) && (!options.end || options.end instanceof Uint8Array)) {
startAddress = saveKey(options.start, orderedBinary.writeKey, iterable, maxKeySize);
keyBytesView.setFloat64(START_ADDRESS_POSITION, startAddress, true);
endAddress = saveKey(options.end, orderedBinary.writeKey, iterable, maxKeySize);
startAddress = saveKey(
options.start,
store.encoder.writeKey,
iterable,
maxKeySize,
);
keyBytesView.setFloat64(
START_ADDRESS_POSITION,
startAddress,
true,
);
endAddress = saveKey(
options.end,
store.encoder.writeKey,
iterable,
maxKeySize,
);
} else if (
(!options.start || options.start instanceof Uint8Array) &&
(!options.end || options.end instanceof Uint8Array)
) {
startAddress = saveKey(
options.start,
orderedBinary.writeKey,
iterable,
maxKeySize,
);
keyBytesView.setFloat64(
START_ADDRESS_POSITION,
startAddress,
true,
);
endAddress = saveKey(
options.end,
orderedBinary.writeKey,
iterable,
maxKeySize,
);
} else {
throw new Error('Only key-based encoding is supported for start/end values');
throw new Error(
'Only key-based encoding is supported for start/end values',
);
let encoded = store.encoder.encode(options.start);
let bufferAddress = encoded.buffer.address || (encoded.buffer.address = getAddress(encoded.buffer) - encoded.byteOffset);
let bufferAddress =
encoded.buffer.address ||
(encoded.buffer.address =
getAddress(encoded.buffer) - encoded.byteOffset);
startAddress = bufferAddress + encoded.byteOffset;

@@ -531,13 +686,23 @@ }

} else
endAddress = saveKey((reverse && !('end' in options)) ? DEFAULT_BEGINNING_KEY : options.end, store.writeKey, iterable, maxKeySize);
return doPosition(cursorAddress, flags, offset || 0, keySize, endAddress);
endAddress = saveKey(
reverse && !('end' in options)
? DEFAULT_BEGINNING_KEY
: options.end,
store.writeKey,
iterable,
maxKeySize,
);
return doPosition(
cursorAddress,
flags,
offset || 0,
keySize,
endAddress,
);
}
function finishCursor() {
if (!cursor || txn.isDone)
return;
if (iterable.onDone)
iterable.onDone()
if (cursorRenewId)
txn.renewingRefCount--;
if (!cursor || txn.isDone) return;
if (iterable.onDone) iterable.onDone();
if (cursorRenewId) txn.renewingRefCount--;
if (txn.refCount <= 1 && txn.notCurrent) {

@@ -555,3 +720,4 @@ cursor.close(); // this must be closed before the transaction is aborted or it can cause a

cursor.close();
} else { // try to reuse it
} else {
// try to reuse it
db.availableCursor = cursor;

@@ -573,10 +739,8 @@ db.cursorTxn = txn;

}
if (count === 0) { // && includeValues) // on first entry, get current value if we need to
if (count === 0) {
// && includeValues) // on first entry, get current value if we need to
keySize = position(options.offset);
} else
keySize = iterate(cursorAddress);
if (keySize <= 0 ||
(count++ >= limit)) {
if (keySize < -30700 && keySize !== -30798)
lmdbError(keySize);
} else keySize = iterate(cursorAddress);
if (keySize <= 0 || count++ >= limit) {
if (keySize < -30700 && keySize !== -30798) lmdbError(keySize);
finishCursor();

@@ -587,5 +751,4 @@ return ITERATOR_DONE;

if (keySize > 20000) {
if (keySize > 0x1000000)
lmdbError(keySize - 0x100000000)
throw new Error('Invalid key size ' + keySize.toString(16))
if (keySize > 0x1000000) lmdbError(keySize - 0x100000000);
throw new Error('Invalid key size ' + keySize.toString(16));
}

@@ -608,8 +771,9 @@ currentKey = store.readKey(keyBytes, 32, keySize + 32);

try {
bytes = store._returnLargeBuffer(() => getCurrentValue(cursorAddress));
bytes = store._returnLargeBuffer(() =>
getCurrentValue(cursorAddress),
);
} finally {
asSafeBuffer = false;
}
} else
bytes.length = lastSize;
} else bytes.length = lastSize;
}

@@ -619,3 +783,5 @@ if (store.decoder) {

} else if (store.encoding == 'binary')
value = bytes.isGlobal ? Uint8ArraySlice.call(bytes, 0, lastSize) : bytes;
value = bytes.isGlobal
? Uint8ArraySlice.call(bytes, 0, lastSize)
: bytes;
else {

@@ -631,8 +797,8 @@ value = bytes.toString('utf8', 0, lastSize);

value,
version: getLastVersion()
}
version: getLastVersion(),
},
};
else if (valuesForKey)
else if (valuesForKey)
return {
value
value,
};

@@ -644,3 +810,3 @@ else

value,
}
},
};

@@ -651,8 +817,8 @@ } else if (includeVersions) {

key: currentKey,
version: getLastVersion()
}
version: getLastVersion(),
},
};
} else {
return {
value: currentKey
value: currentKey,
};

@@ -668,3 +834,3 @@ }

return ITERATOR_DONE;
}
},
};

@@ -680,3 +846,7 @@ };

// once the prefetch occurs
let promise = callback ? undefined : new Promise(resolve => callback = (error, results) => resolve(results));
let promise = callback
? undefined
: new Promise(
(resolve) => (callback = (error, results) => resolve(results)),
);
this.prefetch(keys, () => {

@@ -692,5 +862,11 @@ let results = new Array(keys.length);

getSharedBufferForGet(id, options) {
let txn = env.writeTxn || (options && options.transaction) || (readTxnRenewed ? readTxn : renewReadTxn(this));
this.lastSize = this.keyIsCompatibility ? txn.getBinaryShared(id) : this.db.get(this.writeKey(id, keyBytes, 0));
if (this.lastSize === -30798) { // not found code
let txn =
env.writeTxn ||
(options && options.transaction) ||
(readTxnRenewed ? readTxn : renewReadTxn(this));
this.lastSize = this.keyIsCompatibility
? txn.getBinaryShared(id)
: this.db.get(this.writeKey(id, keyBytes, 0));
if (this.lastSize === -30798) {
// not found code
return; //undefined

@@ -704,8 +880,16 @@ }

let startOffset;
if (!buffer || lastOffset < (startOffset = buffer.startOffset) || (lastOffset + this.lastSize > startOffset + 0x100000000)) {
if (buffer)
env.detachBuffer(buffer.buffer);
if (
!buffer ||
lastOffset < (startOffset = buffer.startOffset) ||
lastOffset + this.lastSize > startOffset + 0x100000000
) {
if (buffer) env.detachBuffer(buffer.buffer);
startOffset = (lastOffset >>> 16) * 0x10000;
console.log('make buffer for address', bufferIndex * 0x100000000 + startOffset);
buffer = buffers[bufferIndex] = Buffer.from(getBufferForAddress(bufferIndex * 0x100000000 + startOffset));
console.log(
'make buffer for address',
bufferIndex * 0x100000000 + startOffset,
);
buffer = buffers[bufferIndex] = Buffer.from(
getBufferForAddress(bufferIndex * 0x100000000 + startOffset),
);
buffer.startOffset = startOffset;

@@ -715,7 +899,9 @@ }

return buffer;
return buffer.slice(lastOffset, lastOffset + this.lastSize);/*Uint8ArraySlice.call(buffer, lastOffset, lastOffset + this.lastSize)*/
return buffer.slice(
lastOffset,
lastOffset + this.lastSize,
); /*Uint8ArraySlice.call(buffer, lastOffset, lastOffset + this.lastSize)*/
},
prefetch(keys, callback) {
if (!keys)
throw new Error('An array of keys must be provided');
if (!keys) throw new Error('An array of keys must be provided');
if (!keys.length) {

@@ -725,4 +911,3 @@ if (callback) {

return;
} else
return Promise.resolve();
} else return Promise.resolve();
}

@@ -734,5 +919,11 @@ let buffers = [];

for (let key of keys) {
let position
let position;
if (key && key.key !== undefined && key.value !== undefined) {
position = saveKey(key.value, this.writeKey, bufferHolder, maxKeySize, 0x80000000);
position = saveKey(
key.value,
this.writeKey,
bufferHolder,
maxKeySize,
0x80000000,
);
saveReferenceToBuffer();

@@ -743,4 +934,3 @@ saveKey(key.key, this.writeKey, bufferHolder, maxKeySize);

}
if (!startPosition)
startPosition = position;
if (!startPosition) startPosition = position;
saveReferenceToBuffer();

@@ -761,7 +951,5 @@ }

console.error('Error with prefetch', buffers); // partly exists to keep the buffers pinned in memory
else
callback(null);
else callback(null);
});
if (!callback)
return new Promise(resolve => callback = resolve);
if (!callback) return new Promise((resolve) => (callback = resolve));
},

@@ -789,11 +977,13 @@ useReadTransaction() {

readTxn.isDone = true;
Object.defineProperty(readTxn,'renew', {
Object.defineProperty(readTxn, 'renew', {
value: () => {
throw new Error('Can not read from a closed database');
}, configurable: true
},
configurable: true,
});
Object.defineProperty(readTxn,'use', {
Object.defineProperty(readTxn, 'use', {
value: () => {
throw new Error('Can not read from a closed database');
}, configurable: true
},
configurable: true,
});

@@ -806,14 +996,13 @@ readTxnRenewed = null;

if (outstandingReads > 0) {
return new Promise(resolve => setTimeout(() => resolve(doClose()), 1));
return new Promise((resolve) =>
setTimeout(() => resolve(doClose()), 1),
);
}
env.address = 0;
env.close();
} else
this.db.close();
} else this.db.close();
this.status = 'closed';
if (callback)
callback();
}
if (txnPromise)
return txnPromise.then(doClose);
if (callback) callback();
};
if (txnPromise) return txnPromise.then(doClose);
else {

@@ -853,7 +1042,10 @@ doClose();

let lastReadTxn = lastReadTxnRef && lastReadTxnRef.deref();
readTxn = new Txn(env, 0x20000, lastReadTxn && !lastReadTxn.isDone && lastReadTxn);
readTxn = new Txn(
env,
0x20000,
lastReadTxn && !lastReadTxn.isDone && lastReadTxn,
);
if (readTxn.address == 0) {
readTxn = lastReadTxn;
if (readTxn.notCurrent)
readTxn.notCurrent = false;
if (readTxn.notCurrent) readTxn.notCurrent = false;
}

@@ -866,4 +1058,3 @@ break;

Atomics.wait(waitArray, 0, 0, retries * 2);
} else
throw error;
} else throw error;
}

@@ -896,9 +1087,14 @@ } while (retries++ < 100);

export function makeReusableBuffer(size) {
let bytes = typeof Buffer != 'undefined' ? Buffer.alloc(size) : new Uint8Array(size);
let bytes =
typeof Buffer != 'undefined' ? Buffer.alloc(size) : new Uint8Array(size);
bytes.maxLength = size;
Object.defineProperty(bytes, 'length', { value: size, writable: true, configurable: true });
Object.defineProperty(bytes, 'length', {
value: size,
writable: true,
configurable: true,
});
return bytes;
}
Txn.prototype.done = function() {
Txn.prototype.done = function () {
this.refCount--;

@@ -910,20 +1106,43 @@ if (this.refCount === 0 && this.notCurrent) {

throw new Error('Can not finish a transaction more times than it was used');
}
Txn.prototype.use = function() {
};
Txn.prototype.use = function () {
this.refCount = (this.refCount || 0) + 1;
}
};
let readInstructions, readCallbacks = new Map(), uint32Instructions, instructionsDataView = { setFloat64() {}, setUint32() {} }, instructionsAddress;
let readInstructions,
readCallbacks = new Map(),
uint32Instructions,
instructionsDataView = { setFloat64() {}, setUint32() {} },
instructionsAddress;
let savePosition = 8000;
let DYNAMIC_KEY_BUFFER_SIZE = 8192;
function allocateInstructionsBuffer() {
readInstructions = typeof Buffer != 'undefined' ? Buffer.alloc(DYNAMIC_KEY_BUFFER_SIZE) : new Uint8Array(DYNAMIC_KEY_BUFFER_SIZE);
uint32Instructions = new Int32Array(readInstructions.buffer, 0, readInstructions.buffer.byteLength >> 2);
readInstructions =
typeof Buffer != 'undefined'
? Buffer.alloc(DYNAMIC_KEY_BUFFER_SIZE)
: new Uint8Array(DYNAMIC_KEY_BUFFER_SIZE);
uint32Instructions = new Int32Array(
readInstructions.buffer,
0,
readInstructions.buffer.byteLength >> 2,
);
uint32Instructions[2] = 0xf0000000; // indicates a new read task must be started
instructionsAddress = readInstructions.buffer.address = getAddress(readInstructions.buffer);
readInstructions.dataView = instructionsDataView = new DataView(readInstructions.buffer, readInstructions.byteOffset, readInstructions.byteLength);
instructionsAddress = readInstructions.buffer.address = getAddress(
readInstructions.buffer,
);
readInstructions.dataView = instructionsDataView = new DataView(
readInstructions.buffer,
readInstructions.byteOffset,
readInstructions.byteLength,
);
savePosition = 0;
}
export function recordReadInstruction(txnAddress, dbi, key, writeKey, maxKeySize, callback) {
export function recordReadInstruction(
txnAddress,
dbi,
key,
writeKey,
maxKeySize,
callback,
) {
if (savePosition > 7800) {

@@ -935,4 +1154,6 @@ allocateInstructionsBuffer();

try {
savePosition = key === undefined ? keyPosition :
writeKey(key, readInstructions, keyPosition);
savePosition =
key === undefined
? keyPosition
: writeKey(key, readInstructions, keyPosition);
} catch (error) {

@@ -942,7 +1163,13 @@ if (error.name == 'RangeError') {

allocateInstructionsBuffer(); // try again:
return recordReadInstruction(txnAddress, dbi, key, writeKey, maxKeySize, callback);
return recordReadInstruction(
txnAddress,
dbi,
key,
writeKey,
maxKeySize,
callback,
);
}
throw new Error('Key was too large, max key size is ' + maxKeySize);
} else
throw error;
} else throw error;
}

@@ -952,3 +1179,5 @@ let length = savePosition - keyPosition;

savePosition = start;
throw new Error('Key of size ' + length + ' was too large, max key size is ' + maxKeySize);
throw new Error(
'Key of size ' + length + ' was too large, max key size is ' + maxKeySize,
);
}

@@ -962,9 +1191,14 @@ uint32Instructions[(start >> 2) + 3] = length; // save the length

let rc = thisInstructions[position];
callback(rc, thisInstructions[position + 1], thisInstructions[position + 2], thisInstructions[position + 3]);
callback(
rc,
thisInstructions[position + 1],
thisInstructions[position + 2],
thisInstructions[position + 3],
);
});
let thisInstructions = uint32Instructions;
//if (start === 0)
return startRead(instructionsAddress + start, callbackId, {}, 'read');
return startRead(instructionsAddress + start, callbackId, {}, 'read');
//else
//nextRead(start);
//nextRead(start);
}

@@ -974,3 +1208,3 @@ let nextCallbackId = 0;

if (!addReadCallback) {
addReadCallback = globalThis.__lmdb_read_callback = function(callback) {
addReadCallback = globalThis.__lmdb_read_callback = function (callback) {
let callbackId = nextCallbackId++;

@@ -980,6 +1214,6 @@ readCallbacks.set(callbackId, callback);

};
setReadCallback(function(callbackId) {
setReadCallback(function (callbackId) {
readCallbacks.get(callbackId)();
readCallbacks.delete(callbackId);
})
});
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc