rocksdb-native 3.4.1 → 3.5.1

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/CMakeLists.txt CHANGED
@@ -13,7 +13,7 @@ if(target MATCHES "win32")
13
13
  add_compile_options(/MT$<$<CONFIG:Debug>:d>)
14
14
  endif()
15
15
 
16
- fetch_package("github:holepunchto/librocksdb#4f197ed")
16
+ fetch_package("github:holepunchto/librocksdb#d2b6760")
17
17
 
18
18
  add_bare_module(rocksdb_native_bare)
19
19
 
package/binding.c CHANGED
@@ -107,6 +107,16 @@ typedef struct {
107
107
  js_ref_t *on_status;
108
108
  } rocksdb_native_write_batch_t;
109
109
 
110
+ typedef struct {
111
+ rocksdb_flush_t handle;
112
+
113
+ js_env_t *env;
114
+ js_ref_t *ctx;
115
+ js_ref_t *on_flush;
116
+
117
+ js_ref_t *column_family;
118
+ } rocksdb_native_flush_t;
119
+
110
120
  typedef struct {
111
121
  rocksdb_snapshot_t handle;
112
122
  } rocksdb_native_snapshot_t;
@@ -180,10 +190,15 @@ rocksdb_native__on_open(rocksdb_open_t *handle, int status) {
180
190
  err = js_get_array_length(env, column_families, &len);
181
191
  assert(err == 0);
182
192
 
193
+ js_value_t **elements = malloc(len * sizeof(js_value_t *));
194
+
195
+ uint32_t fetched;
196
+ err = js_get_array_elements(env, column_families, elements, len, 0, &fetched);
197
+ assert(err == 0);
198
+ assert(fetched == len);
199
+
183
200
  for (uint32_t i = 0; i < len; i++) {
184
- js_value_t *handle;
185
- err = js_get_element(env, column_families, i, &handle);
186
- assert(err == 0);
201
+ js_value_t *handle = elements[i];
187
202
 
188
203
  rocksdb_native_column_family_t *column_family;
189
204
  err = js_get_arraybuffer_info(env, handle, (void **) &column_family, NULL);
@@ -197,6 +212,8 @@ rocksdb_native__on_open(rocksdb_open_t *handle, int status) {
197
212
  err = js_add_teardown_callback(env, rocksdb_native__on_column_family_teardown, (void *) column_family);
198
213
  assert(err == 0);
199
214
  }
215
+
216
+ free(elements);
200
217
  }
201
218
 
202
219
  js_call_function_with_checkpoint(env, ctx, cb, 1, (js_value_t *[]) {error}, NULL);
@@ -378,10 +395,15 @@ rocksdb_native_open(js_env_t *env, js_callback_info_t *info) {
378
395
 
379
396
  rocksdb_column_family_descriptor_t *column_families = calloc(len, sizeof(rocksdb_column_family_descriptor_t));
380
397
 
398
+ js_value_t **elements = malloc(len * sizeof(js_value_t *));
399
+
400
+ uint32_t fetched;
401
+ err = js_get_array_elements(env, argv[3], elements, len, 0, &fetched);
402
+ assert(err == 0);
403
+ assert(fetched == len);
404
+
381
405
  for (uint32_t i = 0; i < len; i++) {
382
- js_value_t *handle;
383
- err = js_get_element(env, argv[3], i, &handle);
384
- assert(err == 0);
406
+ js_value_t *handle = elements[i];
385
407
 
386
408
  rocksdb_native_column_family_t *column_family;
387
409
  err = js_get_arraybuffer_info(env, handle, (void **) &column_family, NULL);
@@ -392,6 +414,8 @@ rocksdb_native_open(js_env_t *env, js_callback_info_t *info) {
392
414
  column_family->db = &db->handle;
393
415
  }
394
416
 
417
+ free(elements);
418
+
395
419
  rocksdb_column_family_t **handles = calloc(len, sizeof(rocksdb_column_family_t *));
396
420
 
397
421
  js_value_t *handle;
@@ -1384,10 +1408,15 @@ rocksdb_native_read(js_env_t *env, js_callback_info_t *info) {
1384
1408
  err = js_create_reference(env, argv[5], 1, &req->on_status);
1385
1409
  assert(err == 0);
1386
1410
 
1411
+ js_value_t **elements = malloc(len * sizeof(js_value_t *));
1412
+
1413
+ uint32_t fetched;
1414
+ err = js_get_array_elements(env, argv[2], elements, len, 0, &fetched);
1415
+ assert(err == 0);
1416
+ assert(fetched == len);
1417
+
1387
1418
  for (uint32_t i = 0; i < len; i++) {
1388
- js_value_t *read;
1389
- err = js_get_element(env, argv[2], i, &read);
1390
- assert(err == 0);
1419
+ js_value_t *read = elements[i];
1391
1420
 
1392
1421
  js_value_t *property;
1393
1422
 
@@ -1423,6 +1452,8 @@ rocksdb_native_read(js_env_t *env, js_callback_info_t *info) {
1423
1452
  }
1424
1453
  }
1425
1454
 
1455
+ free(elements);
1456
+
1426
1457
  rocksdb_read_options_t options = {
1427
1458
  .version = 0,
1428
1459
  };
@@ -1581,10 +1612,15 @@ rocksdb_native_write(js_env_t *env, js_callback_info_t *info) {
1581
1612
  err = js_create_reference(env, argv[4], 1, &req->on_status);
1582
1613
  assert(err == 0);
1583
1614
 
1615
+ js_value_t **elements = malloc(len * sizeof(js_value_t *));
1616
+
1617
+ uint32_t fetched;
1618
+ err = js_get_array_elements(env, argv[2], elements, len, 0, &fetched);
1619
+ assert(err == 0);
1620
+ assert(fetched == len);
1621
+
1584
1622
  for (uint32_t i = 0; i < len; i++) {
1585
- js_value_t *write;
1586
- err = js_get_element(env, argv[2], i, &write);
1587
- assert(err == 0);
1623
+ js_value_t *write = elements[i];
1588
1624
 
1589
1625
  js_value_t *property;
1590
1626
 
@@ -1658,12 +1694,109 @@ rocksdb_native_write(js_env_t *env, js_callback_info_t *info) {
1658
1694
  }
1659
1695
  }
1660
1696
 
1697
+ free(elements);
1698
+
1661
1699
  err = rocksdb_write(&db->handle, &req->handle, req->writes, len, NULL, rocksdb_native__on_write);
1662
1700
  assert(err == 0);
1663
1701
 
1664
1702
  return NULL;
1665
1703
  }
1666
1704
 
1705
+ static void
1706
+ rocksdb_native__on_flush(rocksdb_flush_t *handle, int status) {
1707
+ int err;
1708
+
1709
+ assert(status == 0);
1710
+
1711
+ rocksdb_native_flush_t *req = (rocksdb_native_flush_t *) handle->data;
1712
+
1713
+ rocksdb_native_t *db = (rocksdb_native_t *) req->handle.req.db;
1714
+
1715
+ js_env_t *env = req->env;
1716
+
1717
+ if (db->exiting) {
1718
+ err = js_delete_reference(env, req->on_flush);
1719
+ assert(err == 0);
1720
+
1721
+ err = js_delete_reference(env, req->ctx);
1722
+ assert(err == 0);
1723
+ } else {
1724
+ js_handle_scope_t *scope;
1725
+ err = js_open_handle_scope(env, &scope);
1726
+ assert(err == 0);
1727
+
1728
+ js_value_t *error;
1729
+
1730
+ if (req->handle.error) {
1731
+ err = js_create_string_utf8(env, (utf8_t *) req->handle.error, -1, &error);
1732
+ assert(err == 0);
1733
+ } else {
1734
+ err = js_get_null(env, &error);
1735
+ assert(err == 0);
1736
+ }
1737
+
1738
+ js_value_t *ctx;
1739
+ err = js_get_reference_value(env, req->ctx, &ctx);
1740
+ assert(err == 0);
1741
+
1742
+ js_value_t *cb;
1743
+ err = js_get_reference_value(env, req->on_flush, &cb);
1744
+ assert(err == 0);
1745
+
1746
+ err = js_delete_reference(env, req->on_flush);
1747
+ assert(err == 0);
1748
+
1749
+ err = js_delete_reference(env, req->ctx);
1750
+ assert(err == 0);
1751
+
1752
+ js_call_function_with_checkpoint(env, ctx, cb, 1, (js_value_t *[]) {error}, NULL);
1753
+
1754
+ err = js_close_handle_scope(env, scope);
1755
+ assert(err == 0);
1756
+ }
1757
+ }
1758
+
1759
+ static js_value_t *
1760
+ rocksdb_native_flush(js_env_t *env, js_callback_info_t *info) {
1761
+ int err;
1762
+
1763
+ size_t argc = 4;
1764
+ js_value_t *argv[4];
1765
+
1766
+ err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
1767
+ assert(err == 0);
1768
+
1769
+ assert(argc == 4);
1770
+
1771
+ rocksdb_native_t *db;
1772
+ err = js_get_arraybuffer_info(env, argv[0], (void **) &db, NULL);
1773
+ assert(err == 0);
1774
+
1775
+ rocksdb_native_column_family_t *column_family;
1776
+ err = js_get_arraybuffer_info(env, argv[1], (void **) &column_family, NULL);
1777
+ assert(err == 0);
1778
+
1779
+ js_value_t *handle;
1780
+
1781
+ rocksdb_native_flush_t *req;
1782
+ err = js_create_arraybuffer(env, sizeof(rocksdb_native_flush_t), (void **) &req, &handle);
1783
+ assert(err == 0);
1784
+
1785
+ req->env = env;
1786
+ req->handle.data = (void *) req;
1787
+
1788
+ err = js_create_reference(env, argv[2], 1, &req->ctx);
1789
+ assert(err == 0);
1790
+
1791
+ err = js_create_reference(env, argv[3], 1, &req->on_flush);
1792
+ assert(err == 0);
1793
+
1794
+ err = rocksdb_flush(&db->handle, &req->handle, column_family->handle, NULL, rocksdb_native__on_flush);
1795
+ assert(err == 0);
1796
+
1797
+ return NULL;
1798
+ }
1799
+
1667
1800
  static js_value_t *
1668
1801
  rocksdb_native_snapshot_create(js_env_t *env, js_callback_info_t *info) {
1669
1802
  int err;
@@ -1749,6 +1882,8 @@ rocksdb_native_exports(js_env_t *env, js_value_t *exports) {
1749
1882
  V("writeBuffer", rocksdb_native_write_buffer)
1750
1883
  V("write", rocksdb_native_write)
1751
1884
 
1885
+ V("flush", rocksdb_native_flush)
1886
+
1752
1887
  V("snapshotCreate", rocksdb_native_snapshot_create)
1753
1888
  V("snapshotDestroy", rocksdb_native_snapshot_destroy)
1754
1889
  #undef V
package/index.js CHANGED
@@ -134,6 +134,12 @@ class RocksDB {
134
134
  return this._state.createWriteBatch(this, opts)
135
135
  }
136
136
 
137
+ flush(opts) {
138
+ maybeClosed(this)
139
+
140
+ return this._state.flush(this, opts)
141
+ }
142
+
137
143
  async get(key, opts) {
138
144
  const batch = this.read({ ...opts, capacity: 1, autoDestroy: true })
139
145
  const value = batch.get(key)
@@ -166,10 +172,20 @@ class RocksDB {
166
172
  this._state.activity.inc()
167
173
  }
168
174
 
175
+ _refBatch() {
176
+ this._ref()
177
+ this._state.activeBatches.inc()
178
+ }
179
+
169
180
  _unref() {
170
181
  if (this._snapshot) this._snapshot.unref()
171
182
  this._state.activity.dec()
172
183
  }
184
+
185
+ _unrefBatch() {
186
+ this._unref()
187
+ this._state.activeBatches.dec()
188
+ }
173
189
  }
174
190
 
175
191
  module.exports = exports = RocksDB
package/lib/batch.js CHANGED
@@ -8,7 +8,7 @@ class RocksDBBatch {
8
8
  constructor(db, opts = {}) {
9
9
  const { capacity = 8, autoDestroy = false } = opts
10
10
 
11
- db._ref()
11
+ db._refBatch()
12
12
 
13
13
  this._db = db
14
14
  this._destroyed = false
@@ -32,7 +32,7 @@ class RocksDBBatch {
32
32
  _reuse(db, opts = {}) {
33
33
  const { autoDestroy = false } = opts
34
34
 
35
- db._ref()
35
+ db._refBatch()
36
36
 
37
37
  this._db = db
38
38
  this._destroyed = false
@@ -81,7 +81,7 @@ class RocksDBBatch {
81
81
 
82
82
  if (this._promises.length) this._abort()
83
83
 
84
- this._db._unref()
84
+ this._db._unrefBatch()
85
85
  this._onfree()
86
86
  }
87
87
 
@@ -175,7 +175,7 @@ exports.ReadBatch = class RocksDBReadBatch extends RocksDBBatch {
175
175
  await super._flush()
176
176
 
177
177
  binding.read(
178
- this._db._state.handle,
178
+ this._db._state._handle,
179
179
  this._handle,
180
180
  this._operations,
181
181
  this._db._snapshot ? this._db._snapshot._handle : null,
@@ -242,7 +242,7 @@ exports.WriteBatch = class RocksDBWriteBatch extends RocksDBBatch {
242
242
  await super._flush()
243
243
 
244
244
  binding.write(
245
- this._db._state.handle,
245
+ this._db._state._handle,
246
246
  this._handle,
247
247
  this._operations,
248
248
  this,
@@ -19,6 +19,7 @@ class RocksDBColumnFamily {
19
19
  } = opts
20
20
 
21
21
  this._name = name
22
+ this._flushing = null
22
23
  this._options = {
23
24
  enableBlobFiles,
24
25
  minBlobSize,
package/lib/iterator.js CHANGED
@@ -106,7 +106,7 @@ module.exports = class RocksDBIterator extends Readable {
106
106
  this._pendingOpen = cb
107
107
 
108
108
  binding.iteratorOpen(
109
- this._db._state.handle,
109
+ this._db._state._handle,
110
110
  this._handle,
111
111
  this._db._columnFamily._handle,
112
112
  this._gt,
package/lib/snapshot.js CHANGED
@@ -11,7 +11,7 @@ module.exports = class RocksDBSnapshot {
11
11
  }
12
12
 
13
13
  _init() {
14
- this._handle = binding.snapshotCreate(this._state.handle)
14
+ this._handle = binding.snapshotCreate(this._state._handle)
15
15
  }
16
16
 
17
17
  ref() {
package/lib/state.js CHANGED
@@ -25,6 +25,7 @@ module.exports = class RocksDBState extends ReadyResource {
25
25
  this.path = path
26
26
  this.db = db
27
27
  this.activity = new RefCounter()
28
+ this.activeBatches = new RefCounter()
28
29
  this.sessions = []
29
30
  this.columnFamilies = [columnFamily]
30
31
  this.deferSnapshotInit = true
@@ -36,13 +37,15 @@ module.exports = class RocksDBState extends ReadyResource {
36
37
  this._readBatches = []
37
38
  this._writeBatches = []
38
39
 
39
- for (const col of columnFamilies) {
40
+ for (const columnFamily of columnFamilies) {
40
41
  this.columnFamilies.push(
41
- typeof col === 'string' ? new ColumnFamily(col, opts) : col
42
+ typeof columnFamily === 'string'
43
+ ? new ColumnFamily(columnFamily, opts)
44
+ : columnFamily
42
45
  )
43
46
  }
44
47
 
45
- this.handle = binding.init(
48
+ this._handle = binding.init(
46
49
  readOnly,
47
50
  createIfMissing,
48
51
  createMissingColumnFamilies,
@@ -130,7 +133,7 @@ module.exports = class RocksDBState extends ReadyResource {
130
133
  this._columnsFlushed = true
131
134
 
132
135
  req.handle = binding.open(
133
- this.handle,
136
+ this._handle,
134
137
  this,
135
138
  this.path,
136
139
  this.columnFamilies.map((c) => c._handle),
@@ -166,7 +169,7 @@ module.exports = class RocksDBState extends ReadyResource {
166
169
  req.reject = reject
167
170
  })
168
171
 
169
- req.handle = binding.close(this.handle, req, onclose)
172
+ req.handle = binding.close(this._handle, req, onclose)
170
173
 
171
174
  await promise
172
175
 
@@ -176,15 +179,43 @@ module.exports = class RocksDBState extends ReadyResource {
176
179
  }
177
180
  }
178
181
 
182
+ async flush(db, opts) {
183
+ if (this.opened === false) await this.ready()
184
+
185
+ const req = { resolve: null, reject: null, handle: null }
186
+
187
+ const promise = new Promise((resolve, reject) => {
188
+ req.resolve = resolve
189
+ req.reject = reject
190
+ })
191
+
192
+ req.handle = binding.flush(
193
+ this._handle,
194
+ db._columnFamily._handle,
195
+ req,
196
+ onflush
197
+ )
198
+
199
+ await promise
200
+
201
+ function onflush(err) {
202
+ if (err) req.reject(new Error(err))
203
+ else req.resolve()
204
+ }
205
+ }
206
+
179
207
  async suspend() {
208
+ if (this._suspended === true) return
180
209
  if (this._suspending === null) this._suspending = this._suspend()
181
210
  return this._suspending
182
211
  }
183
212
 
184
213
  async _suspend() {
185
- if (this._resuming) await this._resuming
214
+ if (this._resuming !== null) await this._resuming
186
215
  if (this.opened === false) await this.ready()
187
216
 
217
+ while (!this.activeBatches.isIdle()) await this.activeBatches.idle()
218
+
188
219
  const req = { resolve: null, reject: null, handle: null }
189
220
 
190
221
  const promise = new Promise((resolve, reject) => {
@@ -192,7 +223,7 @@ module.exports = class RocksDBState extends ReadyResource {
192
223
  req.reject = reject
193
224
  })
194
225
 
195
- req.handle = binding.suspend(this.handle, req, onsuspend)
226
+ req.handle = binding.suspend(this._handle, req, onsuspend)
196
227
 
197
228
  try {
198
229
  await promise
@@ -209,12 +240,13 @@ module.exports = class RocksDBState extends ReadyResource {
209
240
  }
210
241
 
211
242
  resume() {
243
+ if (this._suspended === false) return
212
244
  if (this._resuming === null) this._resuming = this._resume()
213
245
  return this._resuming
214
246
  }
215
247
 
216
248
  async _resume() {
217
- if (this._suspending) await this._suspending
249
+ if (this._suspending !== null) await this._suspending
218
250
  if (this.opened === false) await this.ready()
219
251
 
220
252
  const req = { resolve: null, reject: null, handle: null }
@@ -224,7 +256,7 @@ module.exports = class RocksDBState extends ReadyResource {
224
256
  req.reject = reject
225
257
  })
226
258
 
227
- req.handle = binding.resume(this.handle, req, onresume)
259
+ req.handle = binding.resume(this._handle, req, onresume)
228
260
 
229
261
  try {
230
262
  await promise
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rocksdb-native",
3
- "version": "3.4.1",
3
+ "version": "3.5.1",
4
4
  "description": "librocksdb bindings for JavaScript",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "homepage": "https://github.com/holepunchto/rocksdb-native",
35
35
  "engines": {
36
- "bare": ">=1.7.0"
36
+ "bare": ">=1.16.0"
37
37
  },
38
38
  "dependencies": {
39
39
  "compact-encoding": "^2.15.0",
@@ -43,7 +43,7 @@
43
43
  "streamx": "^2.16.1"
44
44
  },
45
45
  "devDependencies": {
46
- "bare-compat-napi": "^1.1.0",
46
+ "bare-compat-napi": "^1.3.0",
47
47
  "brittle": "^3.5.0",
48
48
  "cmake-bare": "^1.1.14",
49
49
  "cmake-fetch": "^1.0.1",