@ohos-ports/lmdb 2.5.3 → 2.8.5-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -20
- package/README.md +72 -28
- package/SECURITY.md +12 -12
- package/bin/download-prebuilds.js +15 -0
- package/binding.gyp +115 -111
- package/build/Release/lmdb.node +0 -0
- package/caching.js +212 -156
- package/dependencies/lmdb/libraries/liblmdb/COPYRIGHT +20 -20
- package/dependencies/lmdb/libraries/liblmdb/Doxyfile +1631 -1631
- package/dependencies/lmdb/libraries/liblmdb/LICENSE +47 -47
- package/dependencies/lmdb/libraries/liblmdb/Makefile +136 -136
- package/dependencies/lmdb/libraries/liblmdb/chacha8.c +183 -183
- package/dependencies/lmdb/libraries/liblmdb/chacha8.h +14 -14
- package/dependencies/lmdb/libraries/liblmdb/crypto.c +121 -121
- package/dependencies/lmdb/libraries/liblmdb/intro.doc +192 -192
- package/dependencies/lmdb/libraries/liblmdb/lmdb.h +28 -3
- package/dependencies/lmdb/libraries/liblmdb/mdb.c +157 -31
- package/dependencies/lmdb/libraries/liblmdb/mdb_copy.1 +74 -74
- package/dependencies/lmdb/libraries/liblmdb/mdb_copy.c +106 -106
- package/dependencies/lmdb/libraries/liblmdb/mdb_drop.1 +53 -53
- package/dependencies/lmdb/libraries/liblmdb/mdb_drop.c +154 -154
- package/dependencies/lmdb/libraries/liblmdb/mdb_dump.1 +94 -94
- package/dependencies/lmdb/libraries/liblmdb/mdb_dump.c +333 -333
- package/dependencies/lmdb/libraries/liblmdb/mdb_load.1 +97 -97
- package/dependencies/lmdb/libraries/liblmdb/mdb_load.c +530 -530
- package/dependencies/lmdb/libraries/liblmdb/mdb_stat.1 +83 -83
- package/dependencies/lmdb/libraries/liblmdb/mdb_stat.c +276 -276
- package/dependencies/lmdb/libraries/liblmdb/midl-sparse.c +452 -0
- package/dependencies/lmdb/libraries/liblmdb/midl.c +452 -452
- package/dependencies/lmdb/libraries/liblmdb/midl.h +208 -208
- package/dependencies/lmdb/libraries/liblmdb/module.c +101 -101
- package/dependencies/lmdb/libraries/liblmdb/module.h +16 -16
- package/dependencies/lmdb/libraries/liblmdb/mtest.c +178 -178
- package/dependencies/lmdb/libraries/liblmdb/mtest2.c +124 -124
- package/dependencies/lmdb/libraries/liblmdb/mtest3.c +133 -133
- package/dependencies/lmdb/libraries/liblmdb/mtest4.c +168 -168
- package/dependencies/lmdb/libraries/liblmdb/mtest5.c +135 -135
- package/dependencies/lmdb/libraries/liblmdb/mtest6.c +141 -141
- package/dependencies/lmdb/libraries/liblmdb/mtest_enc.c +190 -190
- package/dependencies/lmdb/libraries/liblmdb/mtest_enc2.c +189 -189
- package/dependencies/lmdb/libraries/liblmdb/mtest_remap.c +177 -177
- package/dependencies/lmdb/libraries/liblmdb/sample-bdb.txt +73 -73
- package/dependencies/lmdb/libraries/liblmdb/sample-mdb.txt +62 -62
- package/dependencies/lmdb/libraries/liblmdb/tooltag +27 -27
- package/dependencies/lmdb-data-v1/libraries/liblmdb/CHANGES +266 -0
- package/dependencies/lmdb-data-v1/libraries/liblmdb/COPYRIGHT +20 -20
- package/dependencies/lmdb-data-v1/libraries/liblmdb/Doxyfile +1631 -1631
- package/dependencies/lmdb-data-v1/libraries/liblmdb/LICENSE +47 -47
- package/dependencies/lmdb-data-v1/libraries/liblmdb/intro.doc +192 -192
- package/dependencies/lmdb-data-v1/libraries/liblmdb/lmdb.h +1608 -1653
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb.c +10320 -11359
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_copy.1 +55 -61
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_copy.c +82 -84
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_dump.1 +75 -81
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_dump.c +319 -319
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_load.1 +84 -84
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_load.c +496 -492
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_stat.1 +64 -70
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_stat.c +263 -264
- package/dependencies/lmdb-data-v1/libraries/liblmdb/midl.c +359 -421
- package/dependencies/lmdb-data-v1/libraries/liblmdb/midl.h +186 -200
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mtest.c +177 -177
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mtest2.c +124 -124
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mtest3.c +133 -133
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mtest4.c +168 -168
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mtest5.c +135 -135
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mtest6.c +141 -141
- package/dependencies/lmdb-data-v1/libraries/liblmdb/sample-bdb.txt +73 -73
- package/dependencies/lmdb-data-v1/libraries/liblmdb/sample-mdb.txt +62 -62
- package/dependencies/lmdb-data-v1/libraries/liblmdb/tooltag +22 -27
- package/dependencies/lz4/LICENSE +11 -11
- package/dependencies/lz4/lib/LICENSE +24 -24
- package/dependencies/lz4/lib/Makefile +225 -0
- package/dependencies/lz4/lib/README.md +169 -137
- package/dependencies/lz4/lib/dll/example/Makefile +63 -0
- package/dependencies/lz4/lib/dll/example/README.md +69 -69
- package/dependencies/lz4/lib/dll/liblz4.def +62 -62
- package/dependencies/lz4/lib/liblz4-dll.rc.in +35 -35
- package/dependencies/lz4/lib/liblz4.pc.in +14 -14
- package/dependencies/lz4/lib/lz4.c +2722 -2495
- package/dependencies/lz4/lib/lz4.h +842 -774
- package/dependencies/lz4/lib/lz4file.c +311 -0
- package/dependencies/lz4/lib/lz4file.h +93 -0
- package/dependencies/lz4/lib/lz4frame.c +2078 -1899
- package/dependencies/lz4/lib/lz4frame.h +692 -623
- package/dependencies/lz4/lib/lz4frame_static.h +47 -47
- package/dependencies/lz4/lib/lz4hc.c +1631 -1615
- package/dependencies/lz4/lib/lz4hc.h +413 -413
- package/dependencies/lz4/lib/xxhash.c +1030 -1030
- package/dependencies/lz4/lib/xxhash.h +328 -328
- package/dependencies/v8/v8-fast-api-calls-v16.h +790 -790
- package/dependencies/v8/v8-fast-api-calls.h +784 -888
- package/dist/index.cjs +1050 -584
- package/dist/index.cjs.map +1 -1
- package/index.d.cts +420 -0
- package/index.d.ts +450 -385
- package/index.js +38 -37
- package/keys.js +116 -102
- package/level.js +26 -26
- package/native.js +8 -5
- package/node-index.js +21 -17
- package/open.js +51 -17
- package/package.json +63 -21
- package/read.js +338 -95
- package/src/compression.cpp +12 -9
- package/src/cursor.cpp +82 -31
- package/src/dbi.cpp +78 -40
- package/src/env.cpp +336 -68
- package/src/lmdb-js.cpp +64 -64
- package/src/lmdb-js.h +83 -49
- package/src/misc.cpp +297 -28
- package/src/ordered-binary.cpp +46 -46
- package/src/txn.cpp +210 -257
- package/src/v8-functions.cpp +170 -166
- package/src/windows.c +34 -34
- package/src/writer.cpp +169 -84
- package/util/RangeIterable.js +112 -17
- package/util/set-optional-deps.cjs +14 -10
- package/util/when.js +8 -8
- package/write.js +145 -121
- package/dependencies/lmdb-data-v1/libraries/liblmdb/Makefile +0 -118
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_drop.1 +0 -40
- package/dependencies/lmdb-data-v1/libraries/liblmdb/mdb_drop.c +0 -135
- package/rollup.config.js +0 -12
package/src/env.cpp
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
#include "lmdb-js.h"
|
|
1
|
+
#include "lmdb-js.h"
|
|
2
|
+
#include <atomic>
|
|
2
3
|
#ifndef _WIN32
|
|
3
4
|
#include <sys/types.h>
|
|
4
5
|
#include <sys/stat.h>
|
|
@@ -9,14 +10,22 @@ using namespace Napi;
|
|
|
9
10
|
#define IGNORE_NOTFOUND (1)
|
|
10
11
|
|
|
11
12
|
env_tracking_t* EnvWrap::envTracking = EnvWrap::initTracking();
|
|
13
|
+
thread_local std::vector<EnvWrap*>* EnvWrap::openEnvWraps = nullptr;
|
|
14
|
+
thread_local js_buffers_t* EnvWrap::sharedBuffers = nullptr;
|
|
15
|
+
//thread_local std::unordered_map<void*, buffer_info_t>* EnvWrap::sharedBuffers = nullptr;
|
|
16
|
+
void* getSharedBuffers() {
|
|
17
|
+
return (void*) EnvWrap::sharedBuffers;
|
|
18
|
+
}
|
|
12
19
|
|
|
13
20
|
env_tracking_t* EnvWrap::initTracking() {
|
|
14
21
|
env_tracking_t* tracking = new env_tracking_t;
|
|
15
22
|
tracking->envsLock = new pthread_mutex_t;
|
|
16
23
|
pthread_mutex_init(tracking->envsLock, nullptr);
|
|
24
|
+
tracking->getSharedBuffers = getSharedBuffers;
|
|
17
25
|
return tracking;
|
|
18
26
|
}
|
|
19
|
-
|
|
27
|
+
static napi_ref testRef;
|
|
28
|
+
static napi_env testRefEnv;
|
|
20
29
|
void EnvWrap::cleanupEnvWraps(void* data) {
|
|
21
30
|
if (openEnvWraps)
|
|
22
31
|
free(openEnvWraps);
|
|
@@ -39,11 +48,12 @@ EnvWrap::EnvWrap(const CallbackInfo& info) : ObjectWrap<EnvWrap>(info) {
|
|
|
39
48
|
this->writeTxn = nullptr;
|
|
40
49
|
this->writeWorker = nullptr;
|
|
41
50
|
this->readTxnRenewed = false;
|
|
51
|
+
this->hasWrites = false;
|
|
42
52
|
this->writingLock = new pthread_mutex_t;
|
|
43
53
|
this->writingCond = new pthread_cond_t;
|
|
44
54
|
info.This().As<Object>().Set("address", Number::New(info.Env(), (size_t) this));
|
|
45
55
|
pthread_mutex_init(this->writingLock, nullptr);
|
|
46
|
-
|
|
56
|
+
cond_init(this->writingCond);
|
|
47
57
|
}
|
|
48
58
|
MDB_env* foundEnv;
|
|
49
59
|
const int EXISTING_ENV_FOUND = 10;
|
|
@@ -77,6 +87,7 @@ int checkExistingEnvs(mdb_filehandle_t fd, MDB_env* env) {
|
|
|
77
87
|
envRef.inode = inode;
|
|
78
88
|
envRef.env = env;
|
|
79
89
|
envRef.count = 1;
|
|
90
|
+
envRef.hasWrites = false;
|
|
80
91
|
EnvWrap::envTracking->envs.push_back(envRef);
|
|
81
92
|
return 0;
|
|
82
93
|
}
|
|
@@ -105,6 +116,10 @@ void EnvWrap::cleanupStrayTxns() {
|
|
|
105
116
|
tw->removeFromEnvWrap();
|
|
106
117
|
}
|
|
107
118
|
}
|
|
119
|
+
void EnvWrap::consolidateTxns() {
|
|
120
|
+
// sort read txns by txn id, and then abort newer ones that we can just reference older ones with.
|
|
121
|
+
|
|
122
|
+
}
|
|
108
123
|
|
|
109
124
|
class SyncWorker : public AsyncWorker {
|
|
110
125
|
public:
|
|
@@ -123,22 +138,28 @@ class SyncWorker : public AsyncWorker {
|
|
|
123
138
|
napi_value result; // we use direct napi call here because node-addon-api interface with throw a fatal error if a worker thread is terminating
|
|
124
139
|
napi_call_function(Env(), Env().Undefined(), Callback().Value(), 0, {}, &result);
|
|
125
140
|
}
|
|
141
|
+
void OnError(const Error& e) {
|
|
142
|
+
napi_value result; // we use direct napi call here because node-addon-api interface with throw a fatal error if a worker thread is terminating
|
|
143
|
+
napi_value arg = e.Value();
|
|
144
|
+
napi_call_function(Env(), Env().Undefined(), Callback().Value(), 1, &arg, &result);
|
|
145
|
+
}
|
|
126
146
|
|
|
127
147
|
void Execute() {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
148
|
+
#ifdef _WIN32
|
|
149
|
+
int rc = mdb_env_sync(env->env, 1);
|
|
150
|
+
#else
|
|
151
|
+
int retries = 0;
|
|
152
|
+
retry:
|
|
153
|
+
int rc = mdb_env_sync(env->env, 1);
|
|
154
|
+
#ifdef MDB_LOCK_FAILURE
|
|
155
|
+
if (rc == MDB_LOCK_FAILURE) {
|
|
156
|
+
if (retries++ < 4) {
|
|
157
|
+
sleep(1);
|
|
158
|
+
goto retry;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
#endif
|
|
162
|
+
#endif
|
|
142
163
|
if (rc != 0) {
|
|
143
164
|
SetError(mdb_strerror(rc));
|
|
144
165
|
}
|
|
@@ -160,8 +181,7 @@ class CopyWorker : public AsyncWorker {
|
|
|
160
181
|
void Execute() {
|
|
161
182
|
int rc = mdb_env_copy2(env, path.c_str(), flags);
|
|
162
183
|
if (rc != 0) {
|
|
163
|
-
|
|
164
|
-
SetError("Error on copy");
|
|
184
|
+
SetError(mdb_strerror(rc));
|
|
165
185
|
}
|
|
166
186
|
}
|
|
167
187
|
|
|
@@ -170,21 +190,22 @@ class CopyWorker : public AsyncWorker {
|
|
|
170
190
|
std::string path;
|
|
171
191
|
int flags;
|
|
172
192
|
};
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if (
|
|
179
|
-
return txn;
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
193
|
+
|
|
194
|
+
MDB_txn* EnvWrap::getReadTxn(int64_t tw_address) {
|
|
195
|
+
MDB_txn* txn;
|
|
196
|
+
if (tw_address) // explicit txn
|
|
197
|
+
txn = ((TxnWrap*)tw_address)->txn;
|
|
198
|
+
else if (writeTxn && (txn = writeTxn->txn)) {
|
|
199
|
+
return txn; // no need to renew write txn
|
|
200
|
+
} else // default to current read txn
|
|
201
|
+
txn = currentReadTxn;
|
|
202
|
+
int rc = mdb_txn_renew(txn); // always try to renew
|
|
203
|
+
if (rc) {
|
|
204
|
+
if (!txn)
|
|
205
|
+
fprintf(stderr, "No current read transaction available");
|
|
206
|
+
if (rc != EINVAL)
|
|
207
|
+
return nullptr; // if there was a real error, signal with nullptr and let error propagate with last_error
|
|
186
208
|
}
|
|
187
|
-
readTxnRenewed = true;
|
|
188
209
|
return txn;
|
|
189
210
|
}
|
|
190
211
|
|
|
@@ -221,8 +242,7 @@ Napi::Value EnvWrap::open(const CallbackInfo& info) {
|
|
|
221
242
|
if (!keyBytesValue.IsTypedArray())
|
|
222
243
|
fprintf(stderr, "Invalid key buffer\n");
|
|
223
244
|
size_t keyBufferLength;
|
|
224
|
-
|
|
225
|
-
setFlagFromValue(&jsFlags, SEPARATE_FLUSHED, "separateFlushed", false, options);
|
|
245
|
+
napi_get_buffer_info(info.Env(), keyBytesValue, &keyBuffer, &keyBufferLength);
|
|
226
246
|
String path = options.Get("path").As<String>();
|
|
227
247
|
std::string pathString = path.Utf8Value();
|
|
228
248
|
// Parse the maxDbs option
|
|
@@ -236,7 +256,7 @@ Napi::Value EnvWrap::open(const CallbackInfo& info) {
|
|
|
236
256
|
option = options.Get("mapSize");
|
|
237
257
|
if (option.IsNumber())
|
|
238
258
|
mapSize = option.As<Number>().Int64Value();
|
|
239
|
-
int pageSize =
|
|
259
|
+
int pageSize = 0;
|
|
240
260
|
// Parse the mapSize option
|
|
241
261
|
option = options.Get("pageSize");
|
|
242
262
|
if (option.IsNumber())
|
|
@@ -262,7 +282,7 @@ Napi::Value EnvWrap::open(const CallbackInfo& info) {
|
|
|
262
282
|
napiEnv = info.Env();
|
|
263
283
|
rc = openEnv(flags, jsFlags, (const char*)pathString.c_str(), (char*) keyBuffer, compression, maxDbs, maxReaders, mapSize, pageSize, encryptKey.empty() ? nullptr : (char*)encryptKey.c_str());
|
|
264
284
|
//delete[] pathBytes;
|
|
265
|
-
if (rc
|
|
285
|
+
if (rc != 0)
|
|
266
286
|
return throwLmdbError(info.Env(), rc);
|
|
267
287
|
napi_add_env_cleanup_hook(napiEnv, cleanup, this);
|
|
268
288
|
return info.Env().Undefined();
|
|
@@ -272,7 +292,9 @@ int EnvWrap::openEnv(int flags, int jsFlags, const char* path, char* keyBuffer,
|
|
|
272
292
|
this->keyBuffer = keyBuffer;
|
|
273
293
|
this->compression = compression;
|
|
274
294
|
this->jsFlags = jsFlags;
|
|
275
|
-
|
|
295
|
+
#ifdef MDB_OVERLAPPINGSYNC
|
|
296
|
+
MDB_metrics* metrics;
|
|
297
|
+
#endif
|
|
276
298
|
int rc;
|
|
277
299
|
rc = mdb_env_set_maxdbs(env, maxDbs);
|
|
278
300
|
if (rc) goto fail;
|
|
@@ -281,7 +303,8 @@ int EnvWrap::openEnv(int flags, int jsFlags, const char* path, char* keyBuffer,
|
|
|
281
303
|
rc = mdb_env_set_mapsize(env, mapSize);
|
|
282
304
|
if (rc) goto fail;
|
|
283
305
|
#ifdef MDB_RPAGE_CACHE
|
|
284
|
-
|
|
306
|
+
if (pageSize)
|
|
307
|
+
rc = mdb_env_set_pagesize(env, pageSize);
|
|
285
308
|
if (rc) goto fail;
|
|
286
309
|
#endif
|
|
287
310
|
if ((size_t) encryptionKey > 100) {
|
|
@@ -296,15 +319,24 @@ int EnvWrap::openEnv(int flags, int jsFlags, const char* path, char* keyBuffer,
|
|
|
296
319
|
if (rc != 0) goto fail;
|
|
297
320
|
}
|
|
298
321
|
|
|
322
|
+
if (flags & MDB_NOLOCK) {
|
|
323
|
+
fprintf(stderr, "You chose to use MDB_NOLOCK which is not officially supported by node-lmdb. You have been warned!\n");
|
|
324
|
+
}
|
|
325
|
+
#ifdef MDB_OVERLAPPINGSYNC
|
|
299
326
|
if (flags & MDB_OVERLAPPINGSYNC) {
|
|
300
327
|
flags |= MDB_PREVSNAPSHOT;
|
|
301
328
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
329
|
+
mdb_env_set_callback(env, checkExistingEnvs);
|
|
330
|
+
trackMetrics = !!(flags & MDB_TRACK_METRICS);
|
|
331
|
+
if (trackMetrics) {
|
|
332
|
+
metrics = new MDB_metrics;
|
|
333
|
+
memset(metrics, 0, sizeof(MDB_metrics));
|
|
334
|
+
rc = mdb_env_set_userctx(env, (void*) metrics);
|
|
335
|
+
if (rc) goto fail;
|
|
305
336
|
}
|
|
306
|
-
|
|
337
|
+
#endif
|
|
307
338
|
|
|
339
|
+
timeTxnWaiting = 0;
|
|
308
340
|
// Set MDB_NOTLS to enable multiple read-only transactions on the same thread (in this case, the nodejs main thread)
|
|
309
341
|
flags |= MDB_NOTLS;
|
|
310
342
|
// TODO: make file attributes configurable
|
|
@@ -313,14 +345,27 @@ int EnvWrap::openEnv(int flags, int jsFlags, const char* path, char* keyBuffer,
|
|
|
313
345
|
rc = mdb_env_open(env, path, flags, 0664);
|
|
314
346
|
|
|
315
347
|
if (rc != 0) {
|
|
316
|
-
|
|
348
|
+
#ifdef MDB_OVERLAPPINGSYNC
|
|
349
|
+
if (trackMetrics) {
|
|
350
|
+
delete metrics;
|
|
351
|
+
}
|
|
352
|
+
#endif
|
|
317
353
|
if (rc == EXISTING_ENV_FOUND) {
|
|
354
|
+
mdb_env_close(env);
|
|
318
355
|
env = foundEnv;
|
|
319
|
-
} else
|
|
356
|
+
} else {
|
|
357
|
+
this->jsFlags |= OPEN_FAILED;
|
|
358
|
+
closeEnv(true);
|
|
359
|
+
pthread_mutex_unlock(envTracking->envsLock);
|
|
320
360
|
goto fail;
|
|
361
|
+
}
|
|
321
362
|
}
|
|
322
363
|
mdb_env_get_flags(env, (unsigned int*) &flags);
|
|
323
|
-
if ((jsFlags & DELETE_ON_CLOSE)
|
|
364
|
+
if ((jsFlags & DELETE_ON_CLOSE)
|
|
365
|
+
#ifdef MDB_OVERLAPPINGSYNC
|
|
366
|
+
|| (flags & MDB_OVERLAPPINGSYNC)
|
|
367
|
+
#endif
|
|
368
|
+
) {
|
|
324
369
|
if (!openEnvWraps) {
|
|
325
370
|
openEnvWraps = new std::vector<EnvWrap*>;
|
|
326
371
|
napi_add_env_cleanup_hook(napiEnv, cleanupEnvWraps, nullptr);
|
|
@@ -331,13 +376,13 @@ int EnvWrap::openEnv(int flags, int jsFlags, const char* path, char* keyBuffer,
|
|
|
331
376
|
return 0;
|
|
332
377
|
|
|
333
378
|
fail:
|
|
334
|
-
pthread_mutex_unlock(envTracking->envsLock);
|
|
335
379
|
env = nullptr;
|
|
336
380
|
return rc;
|
|
337
381
|
}
|
|
338
382
|
Napi::Value EnvWrap::getMaxKeySize(const CallbackInfo& info) {
|
|
339
383
|
return Number::New(info.Env(), mdb_env_get_maxkeysize(this->env));
|
|
340
384
|
}
|
|
385
|
+
|
|
341
386
|
NAPI_FUNCTION(getEnvFlags) {
|
|
342
387
|
ARGS(1)
|
|
343
388
|
GET_INT64_ARG(0);
|
|
@@ -350,9 +395,9 @@ NAPI_FUNCTION(getEnvFlags) {
|
|
|
350
395
|
NAPI_FUNCTION(setJSFlags) {
|
|
351
396
|
ARGS(2)
|
|
352
397
|
GET_INT64_ARG(0);
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
398
|
+
EnvWrap* ew = (EnvWrap*) i64;
|
|
399
|
+
int64_t jsFlags;
|
|
400
|
+
napi_get_value_int64(env, args[1], &jsFlags);
|
|
356
401
|
ew->jsFlags = jsFlags;
|
|
357
402
|
RETURN_UNDEFINED;
|
|
358
403
|
}
|
|
@@ -377,21 +422,200 @@ NAPI_FUNCTION(EnvWrap::onExit) {
|
|
|
377
422
|
NAPI_FUNCTION(getEnvsPointer) {
|
|
378
423
|
napi_value returnValue;
|
|
379
424
|
napi_create_double(env, (double) (size_t) EnvWrap::envTracking, &returnValue);
|
|
425
|
+
if (!EnvWrap::sharedBuffers) {
|
|
426
|
+
EnvWrap::sharedBuffers = new js_buffers_t;
|
|
427
|
+
EnvWrap::sharedBuffers->nextId = 0;
|
|
428
|
+
pthread_mutex_init(&EnvWrap::sharedBuffers->modification_lock, nullptr);
|
|
429
|
+
}
|
|
380
430
|
return returnValue;
|
|
381
431
|
}
|
|
382
432
|
|
|
383
433
|
NAPI_FUNCTION(setEnvsPointer) {
|
|
384
434
|
// If another version of lmdb-js is running, switch to using its list of envs
|
|
385
|
-
ARGS(
|
|
435
|
+
ARGS(2)
|
|
386
436
|
GET_INT64_ARG(0);
|
|
387
|
-
|
|
437
|
+
env_tracking_t* adoptedTracking = (env_tracking_t*) i64;
|
|
388
438
|
// copy any existing ones over to the central one
|
|
389
439
|
adoptedTracking->envs.assign(EnvWrap::envTracking->envs.begin(), EnvWrap::envTracking->envs.end());
|
|
390
440
|
EnvWrap::envTracking = adoptedTracking;
|
|
441
|
+
js_buffers_t* adoptedBuffers = (js_buffers_t*) adoptedTracking->getSharedBuffers();
|
|
442
|
+
if (EnvWrap::sharedBuffers && adoptedBuffers != EnvWrap::sharedBuffers) {
|
|
443
|
+
free(EnvWrap::sharedBuffers);
|
|
444
|
+
}
|
|
445
|
+
EnvWrap::sharedBuffers = adoptedBuffers;
|
|
446
|
+
RETURN_UNDEFINED;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
napi_finalize cleanupSharedExternal = [](napi_env env, void* data, void* buffer_info) {
|
|
450
|
+
// Data belongs to LMDB, we shouldn't free it here
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
napi_finalize cleanupAllocatedExternal = [](napi_env env, void* data, void* buffer_info) {
|
|
454
|
+
int32_t id = ((buffer_info_t*) buffer_info)->id;
|
|
455
|
+
pthread_mutex_lock(&EnvWrap::sharedBuffers->modification_lock);
|
|
456
|
+
for (auto bufferRef = EnvWrap::sharedBuffers->buffers.begin(); bufferRef != EnvWrap::sharedBuffers->buffers.end();) {
|
|
457
|
+
if (bufferRef->second.id == id) {
|
|
458
|
+
// fprintf(stderr, "erasing buffer on cleanpu %p\n", bufferRef->first);
|
|
459
|
+
bufferRef = EnvWrap::sharedBuffers->buffers.erase(bufferRef);
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
bufferRef++;
|
|
463
|
+
}
|
|
464
|
+
pthread_mutex_unlock(&EnvWrap::sharedBuffers->modification_lock);
|
|
465
|
+
// We malloc'ed this data so free it
|
|
466
|
+
free(data);
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
NAPI_FUNCTION(getSharedBuffer) {
|
|
471
|
+
ARGS(2)
|
|
472
|
+
int32_t bufferId;
|
|
473
|
+
GET_UINT32_ARG(bufferId, 0);
|
|
474
|
+
GET_INT64_ARG(1);
|
|
475
|
+
EnvWrap* ew = (EnvWrap*) i64;
|
|
476
|
+
pthread_mutex_lock(&EnvWrap::sharedBuffers->modification_lock);
|
|
477
|
+
for (auto bufferRef = EnvWrap::sharedBuffers->buffers.begin(); bufferRef != EnvWrap::sharedBuffers->buffers.end(); bufferRef++) {
|
|
478
|
+
if (bufferRef->second.id == bufferId) {
|
|
479
|
+
char* start = bufferRef->first;
|
|
480
|
+
buffer_info_t* buffer = &bufferRef->second;
|
|
481
|
+
if (buffer->env == ew->env) {
|
|
482
|
+
//fprintf(stderr, "found exiting buffer for %u\n", bufferId);
|
|
483
|
+
napi_get_reference_value(env, buffer->ref, &returnValue);
|
|
484
|
+
pthread_mutex_unlock(&EnvWrap::sharedBuffers->modification_lock);
|
|
485
|
+
return returnValue;
|
|
486
|
+
}
|
|
487
|
+
if (buffer->env) {
|
|
488
|
+
// if for some reason it is different env that didn't get cleaned up
|
|
489
|
+
napi_value arrayBuffer;
|
|
490
|
+
napi_get_reference_value(env, buffer->ref, &arrayBuffer);
|
|
491
|
+
napi_detach_arraybuffer(env, arrayBuffer);
|
|
492
|
+
napi_delete_reference(env, buffer->ref);
|
|
493
|
+
}
|
|
494
|
+
char* end = buffer->end;
|
|
495
|
+
if (buffer->isSharedMap) // only memory mapped buffers are tied to envs
|
|
496
|
+
buffer->env = ew->env;
|
|
497
|
+
size_t size = end - start;
|
|
498
|
+
if (size > 0x100000000)
|
|
499
|
+
fprintf(stderr, "Getting invalid shared buffer size %llu from start: %llu to %end: %llu", size, start, end);
|
|
500
|
+
napi_create_external_arraybuffer(env, start, size,
|
|
501
|
+
buffer->isSharedMap ? cleanupSharedExternal : cleanupAllocatedExternal, (void*) buffer, &returnValue);
|
|
502
|
+
int64_t result;
|
|
503
|
+
napi_create_reference(env, returnValue, 1, &buffer->ref);
|
|
504
|
+
if (buffer->isSharedMap) {
|
|
505
|
+
napi_adjust_external_memory(env, -(int64_t) size, &result);
|
|
506
|
+
napi_value true_value;
|
|
507
|
+
napi_get_boolean(env, true, &true_value);
|
|
508
|
+
napi_set_named_property(env, returnValue, "isSharedMap", true_value);
|
|
509
|
+
}
|
|
510
|
+
pthread_mutex_unlock(&EnvWrap::sharedBuffers->modification_lock);
|
|
511
|
+
return returnValue;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
pthread_mutex_unlock(&EnvWrap::sharedBuffers->modification_lock);
|
|
515
|
+
RETURN_UNDEFINED;
|
|
516
|
+
}
|
|
517
|
+
NAPI_FUNCTION(setTestRef) {
|
|
518
|
+
ARGS(1)
|
|
519
|
+
napi_create_reference(env, args[0], 1, &testRef);
|
|
520
|
+
testRefEnv = env;
|
|
521
|
+
RETURN_UNDEFINED
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
NAPI_FUNCTION(getTestRef) {
|
|
525
|
+
napi_value returnValue;
|
|
526
|
+
fprintf(stderr,"trying to get refernec\n");
|
|
527
|
+
napi_get_reference_value(env, testRef, &returnValue);
|
|
528
|
+
fprintf(stderr,"got refernec\n");
|
|
529
|
+
return returnValue;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
NAPI_FUNCTION(directWrite) {
|
|
533
|
+
ARGS(4)
|
|
534
|
+
GET_INT64_ARG(0);
|
|
535
|
+
EnvWrap* ew = (EnvWrap*) i64;
|
|
536
|
+
napi_get_value_int64(env, args[1], &i64);
|
|
537
|
+
char* target = (char*) i64;
|
|
538
|
+
napi_get_value_int64(env, args[2], &i64);
|
|
539
|
+
void* source = (void*) i64;
|
|
540
|
+
uint32_t length;
|
|
541
|
+
GET_UINT32_ARG(length, 3);
|
|
542
|
+
mdb_filehandle_t fd;
|
|
543
|
+
mdb_env_get_fd(ew->env, &fd);
|
|
544
|
+
MDB_envinfo stat;
|
|
545
|
+
mdb_env_info(ew->env, &stat);
|
|
546
|
+
int64_t offset = target - (char*) stat.me_mapaddr;
|
|
547
|
+
if (offset > 0 && offset < (int64_t) stat.me_mapsize) {
|
|
548
|
+
#ifdef _WIN32
|
|
549
|
+
OVERLAPPED ov;
|
|
550
|
+
ov.Offset = offset;
|
|
551
|
+
ov.OffsetHigh = 0;
|
|
552
|
+
WriteFile(fd, source, length, nullptr, &ov);
|
|
553
|
+
#else
|
|
554
|
+
pwrite(fd, source, length, offset);
|
|
555
|
+
#endif
|
|
556
|
+
}
|
|
391
557
|
RETURN_UNDEFINED;
|
|
392
558
|
}
|
|
393
559
|
|
|
394
|
-
|
|
560
|
+
int32_t EnvWrap::toSharedBuffer(MDB_env* env, uint32_t* keyBuffer, MDB_val data) {
|
|
561
|
+
unsigned int flags;
|
|
562
|
+
mdb_env_get_flags(env, (unsigned int*) &flags);
|
|
563
|
+
#ifdef MDB_RPAGE_CACHE
|
|
564
|
+
if (flags & MDB_REMAP_CHUNKS) {
|
|
565
|
+
*((uint32_t*)keyBuffer) = data.mv_size;
|
|
566
|
+
*((uint32_t*) (keyBuffer + 4)) = 0;
|
|
567
|
+
return -30000;
|
|
568
|
+
}
|
|
569
|
+
#endif
|
|
570
|
+
MDB_envinfo stat;
|
|
571
|
+
mdb_env_info(env, &stat);
|
|
572
|
+
size_t mapAddress = (size_t) (char*) stat.me_mapaddr;
|
|
573
|
+
size_t dataAddress = (size_t) (char*) data.mv_data;
|
|
574
|
+
size_t bufferStart;
|
|
575
|
+
uint64_t end;
|
|
576
|
+
if (dataAddress > mapAddress && (dataAddress + data.mv_size) <= (mapAddress + stat.me_mapsize)) {
|
|
577
|
+
// an address within the memory map
|
|
578
|
+
int64_t mapOffset = dataAddress - mapAddress;
|
|
579
|
+
size_t bufferPosition = (mapOffset + (mapOffset >> 4)) >> 32;
|
|
580
|
+
bufferStart = bufferPosition << 32;
|
|
581
|
+
bufferStart += mapAddress - (bufferStart >> 4);
|
|
582
|
+
end = bufferStart + 0xffffffffll;
|
|
583
|
+
if (end > mapAddress + stat.me_mapsize)
|
|
584
|
+
end = mapAddress + stat.me_mapsize;
|
|
585
|
+
} else {
|
|
586
|
+
// outside the memory map, usually because this is from the heap during a write txn or the mmap has been reallocated
|
|
587
|
+
bufferStart = (dataAddress >> 32) << 32;
|
|
588
|
+
if (!bufferStart) // can't use a memory address of 0 because it is considered a nullptr
|
|
589
|
+
bufferStart = 8;
|
|
590
|
+
end = bufferStart + 0xffffffffll;
|
|
591
|
+
}
|
|
592
|
+
if ((dataAddress + data.mv_size) > end) {
|
|
593
|
+
// crosses boundaries, create one-off for this address
|
|
594
|
+
bufferStart = dataAddress;
|
|
595
|
+
end = bufferStart + 0xffffffffll;
|
|
596
|
+
}
|
|
597
|
+
//fprintf(stderr, "mapAddress %p bufferStart %p", mapAddress, bufferStart);
|
|
598
|
+
pthread_mutex_lock(&sharedBuffers->modification_lock);
|
|
599
|
+
auto bufferSearch = sharedBuffers->buffers.find((char*)bufferStart);
|
|
600
|
+
size_t offset = dataAddress - bufferStart;
|
|
601
|
+
buffer_info_t bufferInfo;
|
|
602
|
+
if (bufferSearch == sharedBuffers->buffers.end()) {
|
|
603
|
+
bufferInfo.end = (char*) end;
|
|
604
|
+
bufferInfo.env = nullptr;
|
|
605
|
+
bufferInfo.isSharedMap = true;
|
|
606
|
+
bufferInfo.id = sharedBuffers->nextId++;
|
|
607
|
+
sharedBuffers->buffers.emplace((char*)bufferStart, bufferInfo);
|
|
608
|
+
} else {
|
|
609
|
+
bufferInfo = bufferSearch->second;
|
|
610
|
+
}
|
|
611
|
+
pthread_mutex_unlock(&sharedBuffers->modification_lock);
|
|
612
|
+
*keyBuffer = data.mv_size;
|
|
613
|
+
*(keyBuffer + 1) = bufferInfo.id;
|
|
614
|
+
*(keyBuffer + 2) = offset;
|
|
615
|
+
return -30001;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
void EnvWrap::closeEnv(bool hasLock) {
|
|
395
619
|
if (!env)
|
|
396
620
|
return;
|
|
397
621
|
if (openEnvWraps) {
|
|
@@ -405,21 +629,44 @@ void EnvWrap::closeEnv() {
|
|
|
405
629
|
}
|
|
406
630
|
napi_remove_env_cleanup_hook(napiEnv, cleanup, this);
|
|
407
631
|
cleanupStrayTxns();
|
|
408
|
-
|
|
632
|
+
if (!hasLock)
|
|
633
|
+
pthread_mutex_lock(envTracking->envsLock);
|
|
409
634
|
for (auto envPath = envTracking->envs.begin(); envPath != envTracking->envs.end(); ) {
|
|
410
635
|
if (envPath->env == env) {
|
|
411
636
|
envPath->count--;
|
|
637
|
+
if (hasWrites)
|
|
638
|
+
envPath->hasWrites = true;
|
|
412
639
|
if (envPath->count <= 0) {
|
|
413
640
|
// last thread using it, we can really close it now
|
|
414
641
|
unsigned int envFlags; // This is primarily useful for detecting termination of threads and sync'ing on their termination
|
|
415
642
|
mdb_env_get_flags(env, &envFlags);
|
|
416
|
-
|
|
643
|
+
#ifdef MDB_OVERLAPPINGSYNC
|
|
644
|
+
if ((envFlags & MDB_OVERLAPPINGSYNC) && envPath->hasWrites) {
|
|
417
645
|
mdb_env_sync(env, 1);
|
|
418
646
|
}
|
|
647
|
+
if (envFlags & MDB_TRACK_METRICS) {
|
|
648
|
+
delete (MDB_metrics*) mdb_env_get_userctx(env);
|
|
649
|
+
}
|
|
650
|
+
#endif
|
|
419
651
|
char* path;
|
|
420
652
|
mdb_env_get_path(env, (const char**)&path);
|
|
421
653
|
path = strdup(path);
|
|
422
654
|
mdb_env_close(env);
|
|
655
|
+
pthread_mutex_lock(&sharedBuffers->modification_lock);
|
|
656
|
+
for (auto bufferRef = EnvWrap::sharedBuffers->buffers.begin(); bufferRef != EnvWrap::sharedBuffers->buffers.end();) {
|
|
657
|
+
if (bufferRef->second.env == env) {
|
|
658
|
+
napi_value arrayBuffer;
|
|
659
|
+
napi_get_reference_value(napiEnv, bufferRef->second.ref, &arrayBuffer);
|
|
660
|
+
napi_detach_arraybuffer(napiEnv, arrayBuffer);
|
|
661
|
+
napi_delete_reference(napiEnv, bufferRef->second.ref);
|
|
662
|
+
int64_t result;
|
|
663
|
+
if (bufferRef->second.id >= 0)
|
|
664
|
+
napi_adjust_external_memory(napiEnv, bufferRef->second.end - bufferRef->first, &result);
|
|
665
|
+
bufferRef = EnvWrap::sharedBuffers->buffers.erase(bufferRef);
|
|
666
|
+
} else
|
|
667
|
+
bufferRef++;
|
|
668
|
+
}
|
|
669
|
+
pthread_mutex_unlock(&sharedBuffers->modification_lock);
|
|
423
670
|
if (jsFlags & DELETE_ON_CLOSE) {
|
|
424
671
|
unlink(path);
|
|
425
672
|
//unlink(strcat(envPath->path, "-lock"));
|
|
@@ -430,7 +677,8 @@ void EnvWrap::closeEnv() {
|
|
|
430
677
|
}
|
|
431
678
|
++envPath;
|
|
432
679
|
}
|
|
433
|
-
|
|
680
|
+
if (!hasLock)
|
|
681
|
+
pthread_mutex_unlock(envTracking->envsLock);
|
|
434
682
|
env = nullptr;
|
|
435
683
|
}
|
|
436
684
|
|
|
@@ -469,9 +717,8 @@ Napi::Value EnvWrap::freeStat(const CallbackInfo& info) {
|
|
|
469
717
|
}
|
|
470
718
|
int rc;
|
|
471
719
|
MDB_stat stat;
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
rc = mdb_stat(txn->txn, 0, &stat);
|
|
720
|
+
MDB_txn *txn = getReadTxn();
|
|
721
|
+
rc = mdb_stat(txn, 0, &stat);
|
|
475
722
|
if (rc != 0) {
|
|
476
723
|
return throwLmdbError(info.Env(), rc);
|
|
477
724
|
}
|
|
@@ -502,6 +749,22 @@ Napi::Value EnvWrap::info(const CallbackInfo& info) {
|
|
|
502
749
|
stats.Set("lastTxnId", Number::New(info.Env(), envinfo.me_last_txnid));
|
|
503
750
|
stats.Set("maxReaders", Number::New(info.Env(), envinfo.me_maxreaders));
|
|
504
751
|
stats.Set("numReaders", Number::New(info.Env(), envinfo.me_numreaders));
|
|
752
|
+
#ifdef MDB_OVERLAPPINGSYNC
|
|
753
|
+
if (this->trackMetrics) {
|
|
754
|
+
MDB_metrics* metrics = (MDB_metrics*) mdb_env_get_userctx(this->env);
|
|
755
|
+
stats.Set("timeStartTxns", Number::New(info.Env(), (double) metrics->time_start_txns / TICKS_PER_SECOND));
|
|
756
|
+
stats.Set("timeDuringTxns", Number::New(info.Env(), (double) metrics->time_during_txns / TICKS_PER_SECOND));
|
|
757
|
+
stats.Set("timePageFlushes", Number::New(info.Env(), (double) metrics->time_page_flushes / TICKS_PER_SECOND));
|
|
758
|
+
stats.Set("timeSync", Number::New(info.Env(), (double) metrics->time_sync / TICKS_PER_SECOND));
|
|
759
|
+
stats.Set("timeTxnWaiting", Number::New(info.Env(), (double) timeTxnWaiting / TICKS_PER_SECOND));
|
|
760
|
+
stats.Set("txns", Number::New(info.Env(), metrics->txns));
|
|
761
|
+
stats.Set("pageFlushes", Number::New(info.Env(), metrics->page_flushes));
|
|
762
|
+
stats.Set("pagesWritten", Number::New(info.Env(), metrics->pages_written));
|
|
763
|
+
stats.Set("writes", Number::New(info.Env(), metrics->writes));
|
|
764
|
+
stats.Set("puts", Number::New(info.Env(), metrics->puts));
|
|
765
|
+
stats.Set("deletes", Number::New(info.Env(), metrics->deletes));
|
|
766
|
+
}
|
|
767
|
+
#endif
|
|
505
768
|
return stats;
|
|
506
769
|
}
|
|
507
770
|
|
|
@@ -627,9 +890,16 @@ Napi::Value EnvWrap::commitTxn(const CallbackInfo& info) {
|
|
|
627
890
|
pthread_mutex_unlock(this->writingLock);
|
|
628
891
|
}
|
|
629
892
|
delete currentTxn;
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
893
|
+
if (rc == 0) {
|
|
894
|
+
hasWrites = true;
|
|
895
|
+
return Napi::Boolean::New(info.Env(), true);
|
|
896
|
+
}
|
|
897
|
+
#ifdef MDB_EMPTY_TXN
|
|
898
|
+
else if (rc == MDB_EMPTY_TXN)
|
|
899
|
+
return Napi::Boolean::New(info.Env(), false);
|
|
900
|
+
#endif
|
|
901
|
+
else
|
|
902
|
+
return throwLmdbError(info.Env(), rc);
|
|
633
903
|
}
|
|
634
904
|
Napi::Value EnvWrap::abortTxn(const CallbackInfo& info) {
|
|
635
905
|
TxnTracked *currentTxn = this->writeTxn;
|
|
@@ -687,11 +957,6 @@ Napi::Value EnvWrap::sync(const CallbackInfo& info) {
|
|
|
687
957
|
return info.Env().Undefined();
|
|
688
958
|
}
|
|
689
959
|
|
|
690
|
-
Napi::Value EnvWrap::resetCurrentReadTxn(const CallbackInfo& info) {
|
|
691
|
-
mdb_txn_reset(this->currentReadTxn);
|
|
692
|
-
this->readTxnRenewed = false;
|
|
693
|
-
return info.Env().Undefined();
|
|
694
|
-
}
|
|
695
960
|
int32_t writeFFI(double ewPointer, uint64_t instructionAddress) {
|
|
696
961
|
EnvWrap* ew = (EnvWrap*) (size_t) ewPointer;
|
|
697
962
|
int rc;
|
|
@@ -715,6 +980,7 @@ void EnvWrap::setupExports(Napi::Env env, Object exports) {
|
|
|
715
980
|
EnvWrap::InstanceMethod("commitTxn", &EnvWrap::commitTxn),
|
|
716
981
|
EnvWrap::InstanceMethod("abortTxn", &EnvWrap::abortTxn),
|
|
717
982
|
EnvWrap::InstanceMethod("sync", &EnvWrap::sync),
|
|
983
|
+
EnvWrap::InstanceMethod("resumeWriting", &EnvWrap::resumeWriting),
|
|
718
984
|
EnvWrap::InstanceMethod("startWriting", &EnvWrap::startWriting),
|
|
719
985
|
EnvWrap::InstanceMethod("stat", &EnvWrap::stat),
|
|
720
986
|
EnvWrap::InstanceMethod("freeStat", &EnvWrap::freeStat),
|
|
@@ -723,7 +989,6 @@ void EnvWrap::setupExports(Napi::Env env, Object exports) {
|
|
|
723
989
|
EnvWrap::InstanceMethod("readerList", &EnvWrap::readerList),
|
|
724
990
|
EnvWrap::InstanceMethod("copy", &EnvWrap::copy),
|
|
725
991
|
//EnvWrap::InstanceMethod("detachBuffer", &EnvWrap::detachBuffer),
|
|
726
|
-
EnvWrap::InstanceMethod("resetCurrentReadTxn", &EnvWrap::resetCurrentReadTxn),
|
|
727
992
|
});
|
|
728
993
|
EXPORT_NAPI_FUNCTION("compress", compress);
|
|
729
994
|
EXPORT_NAPI_FUNCTION("write", write);
|
|
@@ -732,6 +997,9 @@ void EnvWrap::setupExports(Napi::Env env, Object exports) {
|
|
|
732
997
|
EXPORT_NAPI_FUNCTION("setEnvsPointer", setEnvsPointer);
|
|
733
998
|
EXPORT_NAPI_FUNCTION("getEnvFlags", getEnvFlags);
|
|
734
999
|
EXPORT_NAPI_FUNCTION("setJSFlags", setJSFlags);
|
|
1000
|
+
EXPORT_NAPI_FUNCTION("getSharedBuffer", getSharedBuffer);
|
|
1001
|
+
EXPORT_NAPI_FUNCTION("setTestRef", setTestRef);
|
|
1002
|
+
EXPORT_NAPI_FUNCTION("getTestRef", getTestRef);
|
|
735
1003
|
EXPORT_FUNCTION_ADDRESS("writePtr", writeFFI);
|
|
736
1004
|
//envTpl->InstanceTemplate()->SetInternalFieldCount(1);
|
|
737
1005
|
exports.Set("Env", EnvClass);
|