rocksdb-native 3.3.1 → 3.4.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#2adf4ff")
16
+ fetch_package("github:holepunchto/librocksdb#4f197ed")
17
17
 
18
18
  add_bare_module(rocksdb_native_bare)
19
19
 
package/binding.c CHANGED
@@ -6,32 +6,6 @@
6
6
  #include <string.h>
7
7
  #include <utf.h>
8
8
 
9
- typedef struct {
10
- uint32_t low;
11
- uint32_t high;
12
- } rocksdb_native_uint64_t;
13
-
14
- typedef struct {
15
- uint32_t read_only;
16
- uint32_t create_if_missing;
17
- uint32_t create_missing_column_families;
18
- uint32_t max_background_jobs;
19
- rocksdb_native_uint64_t bytes_per_sync;
20
- } rocksdb_native_options_t;
21
-
22
- typedef struct {
23
- uint32_t compation_style;
24
- uint32_t enable_blob_files;
25
- rocksdb_native_uint64_t min_blob_size;
26
- rocksdb_native_uint64_t blob_file_size;
27
- uint32_t enable_blob_garbage_collection;
28
- rocksdb_native_uint64_t table_block_size;
29
- uint32_t table_cache_index_and_filter_blocks;
30
- uint32_t table_format_version;
31
- uint32_t optimize_filters_for_memory;
32
- uint32_t no_block_cache;
33
- } rocksdb_native_column_family_options_t;
34
-
35
9
  typedef struct {
36
10
  rocksdb_column_family_t *handle;
37
11
  rocksdb_column_family_descriptor_t descriptor;
@@ -137,11 +111,6 @@ typedef struct {
137
111
  rocksdb_snapshot_t handle;
138
112
  } rocksdb_native_snapshot_t;
139
113
 
140
- static inline uint64_t
141
- rocksdb_native__to_uint64(rocksdb_native_uint64_t n) {
142
- return n.high * 0x100000000 + n.low;
143
- }
144
-
145
114
  static void
146
115
  rocksdb_native__on_free(js_env_t *env, void *data, void *finalize_hint) {
147
116
  free(data);
@@ -325,18 +294,33 @@ static js_value_t *
325
294
  rocksdb_native_init(js_env_t *env, js_callback_info_t *info) {
326
295
  int err;
327
296
 
328
- size_t argc = 1;
329
- js_value_t *argv[1];
297
+ size_t argc = 7;
298
+ js_value_t *argv[7];
330
299
 
331
300
  err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
332
301
  assert(err == 0);
333
302
 
334
- assert(argc == 1);
303
+ assert(argc == 7);
335
304
 
336
- rocksdb_native_options_t *options;
337
- err = js_get_typedarray_info(env, argv[0], NULL, (void **) &options, NULL, NULL, NULL);
305
+ typedef bool bool_t;
306
+
307
+ #define V(name, type) \
308
+ assert(i < argc); \
309
+ type##_t name; \
310
+ err = js_get_value_##type(env, argv[i++], &name); \
338
311
  assert(err == 0);
339
312
 
313
+ int i = 0;
314
+
315
+ V(read_only, bool)
316
+ V(create_if_missing, bool)
317
+ V(create_missing_column_families, bool)
318
+ V(max_background_jobs, int32)
319
+ V(bytes_per_sync, int64)
320
+ V(max_open_files, int32)
321
+ V(use_direct_reads, bool)
322
+ #undef V
323
+
340
324
  uv_loop_t *loop;
341
325
  err = js_get_env_loop(env, &loop);
342
326
  assert(err == 0);
@@ -352,12 +336,14 @@ rocksdb_native_init(js_env_t *env, js_callback_info_t *info) {
352
336
  db->exiting = false;
353
337
 
354
338
  db->options = (rocksdb_options_t) {
355
- 0,
356
- options->read_only,
357
- options->create_if_missing,
358
- options->create_missing_column_families,
359
- options->max_background_jobs,
360
- rocksdb_native__to_uint64(options->bytes_per_sync),
339
+ 1,
340
+ read_only,
341
+ create_if_missing,
342
+ create_missing_column_families,
343
+ max_background_jobs,
344
+ bytes_per_sync,
345
+ max_open_files,
346
+ use_direct_reads
361
347
  };
362
348
 
363
349
  err = rocksdb_init(loop, &db->handle);
@@ -682,13 +668,13 @@ static js_value_t *
682
668
  rocksdb_native_column_family_init(js_env_t *env, js_callback_info_t *info) {
683
669
  int err;
684
670
 
685
- size_t argc = 2;
686
- js_value_t *argv[2];
671
+ size_t argc = 13;
672
+ js_value_t *argv[13];
687
673
 
688
674
  err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
689
675
  assert(err == 0);
690
676
 
691
- assert(argc == 2);
677
+ assert(argc >= 11 && argc <= 13);
692
678
 
693
679
  size_t name_len;
694
680
  err = js_get_value_string_utf8(env, argv[0], NULL, 0, &name_len);
@@ -700,10 +686,56 @@ rocksdb_native_column_family_init(js_env_t *env, js_callback_info_t *info) {
700
686
  err = js_get_value_string_utf8(env, argv[0], name, name_len, NULL);
701
687
  assert(err == 0);
702
688
 
703
- rocksdb_native_column_family_options_t *options;
704
- err = js_get_typedarray_info(env, argv[1], NULL, (void **) &options, NULL, NULL, NULL);
689
+ typedef bool bool_t;
690
+ typedef double double_t;
691
+
692
+ #define V(name, type) \
693
+ assert(i < argc); \
694
+ type##_t name; \
695
+ err = js_get_value_##type(env, argv[i++], &name); \
705
696
  assert(err == 0);
706
697
 
698
+ int i = 1;
699
+
700
+ V(enable_blob_files, bool)
701
+ V(min_blob_size, int64)
702
+ V(blob_file_size, int64)
703
+ V(enable_blob_garbage_collection, bool)
704
+ V(table_block_size, int64)
705
+ V(table_cache_index_and_filter_blocks, bool)
706
+ V(table_format_version, uint32)
707
+ V(optimize_filters_for_memory, bool)
708
+ V(no_block_cache, bool)
709
+ V(filter_policy_type, uint32)
710
+
711
+ rocksdb_filter_policy_t filter_policy = {filter_policy_type};
712
+
713
+ switch (filter_policy_type) {
714
+ case rocksdb_bloom_filter_policy: {
715
+ V(bits_per_key, double)
716
+
717
+ filter_policy.bloom = (rocksdb_bloom_filter_options_t) {
718
+ 0,
719
+ bits_per_key
720
+ };
721
+
722
+ break;
723
+ }
724
+ case rocksdb_ribbon_filter_policy: {
725
+ V(bloom_equivalent_bits_per_key, double)
726
+ V(bloom_before_level, int32)
727
+
728
+ filter_policy.ribbon = (rocksdb_ribbon_filter_options_t) {
729
+ 0,
730
+ bloom_equivalent_bits_per_key,
731
+ bloom_before_level,
732
+ };
733
+
734
+ break;
735
+ }
736
+ }
737
+ #undef V
738
+
707
739
  uv_loop_t *loop;
708
740
  err = js_get_env_loop(env, &loop);
709
741
  assert(err == 0);
@@ -721,17 +753,18 @@ rocksdb_native_column_family_init(js_env_t *env, js_callback_info_t *info) {
721
753
  column_family->descriptor = (rocksdb_column_family_descriptor_t) {
722
754
  (const char *) name,
723
755
  {
724
- 1,
725
- options->compation_style,
726
- options->enable_blob_files,
727
- rocksdb_native__to_uint64(options->min_blob_size),
728
- rocksdb_native__to_uint64(options->blob_file_size),
729
- options->enable_blob_garbage_collection,
730
- rocksdb_native__to_uint64(options->table_block_size),
731
- options->table_cache_index_and_filter_blocks,
732
- options->table_format_version,
733
- options->optimize_filters_for_memory,
734
- options->no_block_cache,
756
+ 2,
757
+ rocksdb_level_compaction,
758
+ enable_blob_files,
759
+ min_blob_size,
760
+ blob_file_size,
761
+ enable_blob_garbage_collection,
762
+ table_block_size,
763
+ table_cache_index_and_filter_blocks,
764
+ table_format_version,
765
+ optimize_filters_for_memory,
766
+ no_block_cache,
767
+ filter_policy,
735
768
  }
736
769
  };
737
770
 
package/index.js CHANGED
@@ -1,13 +1,14 @@
1
1
  const ColumnFamily = require('./lib/column-family')
2
2
  const Iterator = require('./lib/iterator')
3
3
  const Snapshot = require('./lib/snapshot')
4
- const DBState = require('./lib/state')
4
+ const State = require('./lib/state')
5
+ const { BloomFilterPolicy, RibbonFilterPolicy } = require('./lib/filter-policy')
5
6
 
6
7
  class RocksDB {
7
8
  constructor(path, opts = {}) {
8
9
  const {
9
10
  columnFamily,
10
- state = new DBState(this, path, opts),
11
+ state = new State(this, path, opts),
11
12
  snapshot = null,
12
13
  keyEncoding = null,
13
14
  valueEncoding = null
@@ -174,6 +175,8 @@ class RocksDB {
174
175
  module.exports = exports = RocksDB
175
176
 
176
177
  exports.ColumnFamily = ColumnFamily
178
+ exports.BloomFilterPolicy = BloomFilterPolicy
179
+ exports.RibbonFilterPolicy = RibbonFilterPolicy
177
180
 
178
181
  function maybeClosed(db) {
179
182
  if (db._state.closing || db._index === -1)
package/lib/batch.js CHANGED
@@ -97,10 +97,16 @@ class RocksDBBatch {
97
97
  }
98
98
  }
99
99
 
100
- flush() {
100
+ async flush() {
101
101
  if (this._request) throw new Error('Request in progress')
102
102
  if (this._destroyed) throw new Error('Batch is destroyed')
103
103
 
104
+ const state = this._db._state
105
+
106
+ if (state._suspending || state._suspended) {
107
+ throw new Error('Database is suspended')
108
+ }
109
+
104
110
  this._request = new Promise((resolve, reject) => {
105
111
  this._resolve = resolve
106
112
  this._reject = reject
@@ -113,6 +119,13 @@ class RocksDBBatch {
113
119
 
114
120
  tryFlush() {
115
121
  if (this._request) throw new Error('Request in progress')
122
+ if (this._destroyed) throw new Error('Batch is destroyed')
123
+
124
+ const state = this._db._state
125
+
126
+ if (state._suspending || state._suspended) {
127
+ throw new Error('Database is suspended')
128
+ }
116
129
 
117
130
  this._request = resolved
118
131
 
@@ -1,4 +1,5 @@
1
1
  const binding = require('../binding')
2
+ const { BloomFilterPolicy } = require('./filter-policy')
2
3
 
3
4
  class RocksDBColumnFamily {
4
5
  constructor(name, opts = {}) {
@@ -14,34 +15,59 @@ class RocksDBColumnFamily {
14
15
  tableFormatVersion = 6,
15
16
  optimizeFiltersForMemory = false,
16
17
  blockCache = true,
17
- // In case we are cloning
18
- settings = null
18
+ filterPolicy = new BloomFilterPolicy(10)
19
19
  } = opts
20
20
 
21
21
  this._name = name
22
- this._settings =
23
- settings ||
24
- Uint32Array.from([
25
- 0,
26
- enableBlobFiles ? 1 : 0,
27
- minBlobSize & 0xffffffff,
28
- Math.floor(minBlobSize / 0x100000000),
29
- blobFileSize & 0xffffffff,
30
- Math.floor(blobFileSize / 0x100000000),
31
- enableBlobGarbageCollection ? 1 : 0,
32
- tableBlockSize & 0xffffffff,
33
- Math.floor(tableBlockSize / 0x100000000),
34
- tableCacheIndexAndFilterBlocks ? 1 : 0,
35
- tableFormatVersion,
36
- optimizeFiltersForMemory ? 1 : 0,
37
- blockCache ? 0 : 1
38
- ])
39
-
40
- this._handle = binding.columnFamilyInit(name, this._settings)
22
+ this._options = {
23
+ enableBlobFiles,
24
+ minBlobSize,
25
+ blobFileSize,
26
+ enableBlobGarbageCollection,
27
+ tableBlockSize,
28
+ tableCacheIndexAndFilterBlocks,
29
+ tableFormatVersion,
30
+ optimizeFiltersForMemory,
31
+ blockCache,
32
+ filterPolicy
33
+ }
34
+
35
+ const filterPolicyArguments = []
36
+
37
+ if (filterPolicy === null) filterPolicyArguments.push(0)
38
+ else {
39
+ filterPolicyArguments.push(filterPolicy.type)
40
+
41
+ switch (filterPolicy.type) {
42
+ case 1: // Bloom filter policy
43
+ filterPolicyArguments.push(filterPolicy.bitsPerKey)
44
+ break
45
+ case 2: // Ribbon filter policy
46
+ filterPolicyArguments.push(
47
+ filterPolicy.bloomEquivalentBitsPerKey,
48
+ filterPolicy.bloomBeforeLevel
49
+ )
50
+ break
51
+ }
52
+ }
53
+
54
+ this._handle = binding.columnFamilyInit(
55
+ name,
56
+ enableBlobFiles,
57
+ minBlobSize,
58
+ blobFileSize,
59
+ enableBlobGarbageCollection,
60
+ tableBlockSize,
61
+ tableCacheIndexAndFilterBlocks,
62
+ tableFormatVersion,
63
+ optimizeFiltersForMemory,
64
+ blockCache === false,
65
+ ...filterPolicyArguments
66
+ )
41
67
  }
42
68
 
43
69
  cloneSettings(name) {
44
- return new RocksDBColumnFamily(name, { settings: this._settings })
70
+ return new RocksDBColumnFamily(name, this._options)
45
71
  }
46
72
 
47
73
  get name() {
@@ -0,0 +1,20 @@
1
+ exports.BloomFilterPolicy = class RocksDBBloomFilterPolicy {
2
+ get type() {
3
+ return 1
4
+ }
5
+
6
+ constructor(bitsPerKey) {
7
+ this.bitsPerKey = bitsPerKey
8
+ }
9
+ }
10
+
11
+ exports.RibbonFilterPolicy = class RocksDBRibbonFilterPolicy {
12
+ get type() {
13
+ return 2
14
+ }
15
+
16
+ constructor(bloomEquivalentBitsPerKey, bloomBeforeLevel = 0) {
17
+ this.bloomEquivalentBitsPerKey = bloomEquivalentBitsPerKey
18
+ this.bloomBeforeLevel = bloomBeforeLevel
19
+ }
20
+ }
package/lib/iterator.js CHANGED
@@ -97,6 +97,12 @@ module.exports = class RocksDBIterator extends Readable {
97
97
  async _open(cb) {
98
98
  await this.ready()
99
99
 
100
+ const state = this._db._state
101
+
102
+ if (state._suspending || state._suspended) {
103
+ return cb(new Error('Database is suspended'))
104
+ }
105
+
100
106
  this._pendingOpen = cb
101
107
 
102
108
  binding.iteratorOpen(
@@ -117,6 +123,12 @@ module.exports = class RocksDBIterator extends Readable {
117
123
  }
118
124
 
119
125
  _read(cb) {
126
+ const state = this._db._state
127
+
128
+ if (state._suspending || state._suspended) {
129
+ return cb(new Error('Database is suspended'))
130
+ }
131
+
120
132
  this._pendingRead = cb
121
133
 
122
134
  binding.iteratorRead(this._handle, Math.min(this._capacity, this._limit))
package/lib/state.js CHANGED
@@ -6,7 +6,7 @@ const binding = require('../binding')
6
6
 
7
7
  const MAX_BATCH_REUSE = 64
8
8
 
9
- module.exports = class DBState extends ReadyResource {
9
+ module.exports = class RocksDBState extends ReadyResource {
10
10
  constructor(db, path, opts) {
11
11
  super()
12
12
 
@@ -17,7 +17,9 @@ module.exports = class DBState extends ReadyResource {
17
17
  createIfMissing = true,
18
18
  createMissingColumnFamilies = true,
19
19
  maxBackgroundJobs = 6,
20
- bytesPerSync = 1048576
20
+ bytesPerSync = 1048576,
21
+ maxOpenFiles = -1,
22
+ useDirectReads = false
21
23
  } = opts
22
24
 
23
25
  this.path = path
@@ -27,6 +29,7 @@ module.exports = class DBState extends ReadyResource {
27
29
  this.columnFamilies = [columnFamily]
28
30
  this.deferSnapshotInit = true
29
31
 
32
+ this._suspended = false
30
33
  this._suspending = null
31
34
  this._resuming = null
32
35
  this._columnsFlushed = false
@@ -40,14 +43,13 @@ module.exports = class DBState extends ReadyResource {
40
43
  }
41
44
 
42
45
  this.handle = binding.init(
43
- Uint32Array.from([
44
- readOnly ? 1 : 0,
45
- createIfMissing ? 1 : 0,
46
- createMissingColumnFamilies ? 1 : 0,
47
- maxBackgroundJobs,
48
- bytesPerSync & 0xffffffff,
49
- Math.floor(bytesPerSync / 0x100000000)
50
- ])
46
+ readOnly,
47
+ createIfMissing,
48
+ createMissingColumnFamilies,
49
+ maxBackgroundJobs,
50
+ bytesPerSync,
51
+ maxOpenFiles,
52
+ useDirectReads
51
53
  )
52
54
  }
53
55
 
@@ -126,6 +128,7 @@ module.exports = class DBState extends ReadyResource {
126
128
  })
127
129
 
128
130
  this._columnsFlushed = true
131
+
129
132
  req.handle = binding.open(
130
133
  this.handle,
131
134
  this,
@@ -191,9 +194,13 @@ module.exports = class DBState extends ReadyResource {
191
194
 
192
195
  req.handle = binding.suspend(this.handle, req, onsuspend)
193
196
 
194
- await promise
197
+ try {
198
+ await promise
195
199
 
196
- this._suspending = null
200
+ this._suspended = true
201
+ } finally {
202
+ this._suspending = null
203
+ }
197
204
 
198
205
  function onsuspend(err) {
199
206
  if (err) req.reject(new Error(err))
@@ -219,9 +226,13 @@ module.exports = class DBState extends ReadyResource {
219
226
 
220
227
  req.handle = binding.resume(this.handle, req, onresume)
221
228
 
222
- await promise
229
+ try {
230
+ await promise
223
231
 
224
- this._resuming = null
232
+ this._suspended = false
233
+ } finally {
234
+ this._resuming = null
235
+ }
225
236
 
226
237
  function onresume(err) {
227
238
  if (err) req.reject(new Error(err))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rocksdb-native",
3
- "version": "3.3.1",
3
+ "version": "3.4.1",
4
4
  "description": "librocksdb bindings for JavaScript",
5
5
  "exports": {
6
6
  ".": "./index.js",