rocksdb-native 3.5.1 → 3.5.3

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/index.js CHANGED
@@ -101,11 +101,11 @@ class RocksDB {
101
101
  }
102
102
 
103
103
  isIdle() {
104
- return this._state.activity.isIdle()
104
+ return this._state.handles.isIdle()
105
105
  }
106
106
 
107
107
  idle() {
108
- return this._state.activity.idle()
108
+ return this._state.handles.idle()
109
109
  }
110
110
 
111
111
  iterator(range, opts) {
@@ -165,26 +165,14 @@ class RocksDB {
165
165
  await batch.flush()
166
166
  }
167
167
 
168
- // used by iterators/batches to ensure no gc/close when active
169
-
170
168
  _ref() {
171
169
  if (this._snapshot) this._snapshot.ref()
172
- this._state.activity.inc()
173
- }
174
-
175
- _refBatch() {
176
- this._ref()
177
- this._state.activeBatches.inc()
170
+ this._state.handles.inc()
178
171
  }
179
172
 
180
173
  _unref() {
181
174
  if (this._snapshot) this._snapshot.unref()
182
- this._state.activity.dec()
183
- }
184
-
185
- _unrefBatch() {
186
- this._unref()
187
- this._state.activeBatches.dec()
175
+ this._state.handles.dec()
188
176
  }
189
177
  }
190
178
 
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._refBatch()
11
+ db._ref()
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._refBatch()
35
+ db._ref()
36
36
 
37
37
  this._db = db
38
38
  this._destroyed = false
@@ -48,6 +48,7 @@ class RocksDBBatch {
48
48
  this._request = null
49
49
  this._resolve = null
50
50
  this._reject = null
51
+ this._db._state.io.dec()
51
52
 
52
53
  if (this._autoDestroy === true) this.destroy()
53
54
 
@@ -81,7 +82,7 @@ class RocksDBBatch {
81
82
 
82
83
  if (this._promises.length) this._abort()
83
84
 
84
- this._db._unrefBatch()
85
+ this._db._unref()
85
86
  this._onfree()
86
87
  }
87
88
 
@@ -101,12 +102,6 @@ class RocksDBBatch {
101
102
  if (this._request) throw new Error('Request in progress')
102
103
  if (this._destroyed) throw new Error('Batch is destroyed')
103
104
 
104
- const state = this._db._state
105
-
106
- if (state._suspending || state._suspended) {
107
- throw new Error('Database is suspended')
108
- }
109
-
110
105
  this._request = new Promise((resolve, reject) => {
111
106
  this._resolve = resolve
112
107
  this._reject = reject
@@ -121,12 +116,6 @@ class RocksDBBatch {
121
116
  if (this._request) throw new Error('Request in progress')
122
117
  if (this._destroyed) throw new Error('Batch is destroyed')
123
118
 
124
- const state = this._db._state
125
-
126
- if (state._suspending || state._suspended) {
127
- throw new Error('Database is suspended')
128
- }
129
-
130
119
  this._request = resolved
131
120
 
132
121
  this._flush()
@@ -134,6 +123,19 @@ class RocksDBBatch {
134
123
 
135
124
  async _flush() {
136
125
  if (this._handle === null) await this.ready()
126
+
127
+ this._db._state.io.inc()
128
+
129
+ if (this._db._state.resumed !== null) {
130
+ const resumed = await this._db._state.resumed.promise
131
+
132
+ if (!resumed && !this._destroyed) {
133
+ this._destroyed = true
134
+ this._abort()
135
+ this._db._state.io.dec()
136
+ this._db._unref()
137
+ }
138
+ }
137
139
  }
138
140
 
139
141
  _enqueuePromise(resolve, reject) {
@@ -174,14 +176,21 @@ exports.ReadBatch = class RocksDBReadBatch extends RocksDBBatch {
174
176
  async _flush() {
175
177
  await super._flush()
176
178
 
177
- binding.read(
178
- this._db._state._handle,
179
- this._handle,
180
- this._operations,
181
- this._db._snapshot ? this._db._snapshot._handle : null,
182
- this,
183
- this._onread
184
- )
179
+ if (this._destroyed) return
180
+
181
+ try {
182
+ binding.read(
183
+ this._db._state._handle,
184
+ this._handle,
185
+ this._operations,
186
+ this._db._snapshot ? this._db._snapshot._handle : null,
187
+ this,
188
+ this._onread
189
+ )
190
+ } catch (err) {
191
+ this._db._state.io.dec()
192
+ throw err
193
+ }
185
194
  }
186
195
 
187
196
  _onread(errs, values) {
@@ -241,13 +250,20 @@ exports.WriteBatch = class RocksDBWriteBatch extends RocksDBBatch {
241
250
  async _flush() {
242
251
  await super._flush()
243
252
 
244
- binding.write(
245
- this._db._state._handle,
246
- this._handle,
247
- this._operations,
248
- this,
249
- this._onwrite
250
- )
253
+ if (this._destroyed) return
254
+
255
+ try {
256
+ binding.write(
257
+ this._db._state._handle,
258
+ this._handle,
259
+ this._operations,
260
+ this,
261
+ this._onwrite
262
+ )
263
+ } catch (err) {
264
+ this._db._state.io.dec()
265
+ throw err
266
+ }
251
267
  }
252
268
 
253
269
  _onwrite(err) {
package/lib/iterator.js CHANGED
@@ -30,6 +30,7 @@ module.exports = class RocksDBIterator extends Readable {
30
30
  this._reverse = reverse
31
31
  this._limit = limit < 0 ? Infinity : limit
32
32
  this._capacity = capacity
33
+ this._opened = false
33
34
 
34
35
  this._pendingOpen = null
35
36
  this._pendingRead = null
@@ -44,12 +45,15 @@ module.exports = class RocksDBIterator extends Readable {
44
45
  _onopen(err) {
45
46
  const cb = this._pendingOpen
46
47
  this._pendingOpen = null
48
+ this._opened = true
49
+ this._db._state.io.dec()
47
50
  cb(err)
48
51
  }
49
52
 
50
53
  _onread(err, keys, values) {
51
54
  const cb = this._pendingRead
52
55
  this._pendingRead = null
56
+ this._db._state.io.dec()
53
57
  if (err) return cb(err)
54
58
 
55
59
  const n = keys.length
@@ -97,10 +101,8 @@ module.exports = class RocksDBIterator extends Readable {
97
101
  async _open(cb) {
98
102
  await this.ready()
99
103
 
100
- const state = this._db._state
101
-
102
- if (state._suspending || state._suspended) {
103
- return cb(new Error('Database is suspended'))
104
+ if (this._db._state.resumed !== null) {
105
+ await this._db._state.resumed.promise
104
106
  }
105
107
 
106
108
  this._pendingOpen = cb
@@ -120,18 +122,20 @@ module.exports = class RocksDBIterator extends Readable {
120
122
  this._onclose,
121
123
  this._onread
122
124
  )
123
- }
124
125
 
125
- _read(cb) {
126
- const state = this._db._state
126
+ this._db._state.io.inc()
127
+ }
127
128
 
128
- if (state._suspending || state._suspended) {
129
- return cb(new Error('Database is suspended'))
129
+ async _read(cb) {
130
+ if (this._db._state.resumed !== null) {
131
+ await this._db._state.resumed.promise
130
132
  }
131
133
 
132
134
  this._pendingRead = cb
133
135
 
134
136
  binding.iteratorRead(this._handle, Math.min(this._capacity, this._limit))
137
+
138
+ this._db._state.io.inc()
135
139
  }
136
140
 
137
141
  async _destroy(cb) {
@@ -139,6 +143,8 @@ module.exports = class RocksDBIterator extends Readable {
139
143
 
140
144
  this._pendingDestroy = cb
141
145
 
146
+ if (this._opened === false) return this._onclose(null)
147
+
142
148
  binding.iteratorClose(this._handle)
143
149
  }
144
150
 
package/lib/snapshot.js CHANGED
@@ -5,7 +5,7 @@ module.exports = class RocksDBSnapshot {
5
5
  this._state = state
6
6
 
7
7
  this._handle = null
8
- this._refs = 0 // starts unreffed, easier, must be reffed in first tick
8
+ this._refs = 0
9
9
 
10
10
  if (state.deferSnapshotInit === false) this._init()
11
11
  }
package/lib/state.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const ReadyResource = require('ready-resource')
2
2
  const RefCounter = require('refcounter')
3
+ const rrp = require('resolve-reject-promise')
3
4
  const { ReadBatch, WriteBatch } = require('./batch')
4
5
  const ColumnFamily = require('./column-family')
5
6
  const binding = require('../binding')
@@ -24,11 +25,12 @@ module.exports = class RocksDBState extends ReadyResource {
24
25
 
25
26
  this.path = path
26
27
  this.db = db
27
- this.activity = new RefCounter()
28
- this.activeBatches = new RefCounter()
28
+ this.handles = new RefCounter()
29
+ this.io = new RefCounter()
29
30
  this.sessions = []
30
31
  this.columnFamilies = [columnFamily]
31
32
  this.deferSnapshotInit = true
33
+ this.resumed = null
32
34
 
33
35
  this._suspended = false
34
36
  this._suspending = null
@@ -144,6 +146,7 @@ module.exports = class RocksDBState extends ReadyResource {
144
146
  await promise
145
147
 
146
148
  this.deferSnapshotInit = false
149
+
147
150
  for (const session of this.sessions) {
148
151
  if (session._snapshot) session._snapshot._init()
149
152
  }
@@ -155,10 +158,17 @@ module.exports = class RocksDBState extends ReadyResource {
155
158
  }
156
159
 
157
160
  async _close() {
158
- while (!this.activity.isIdle()) await this.activity.idle()
161
+ if (this.resumed) {
162
+ const resumed = this.resumed
163
+ this.resumed = null
164
+ resumed.resolve(false)
165
+ }
159
166
 
160
- while (this.sessions.length > 0)
167
+ while (!this.handles.isIdle()) await this.handles.idle()
168
+
169
+ while (this.sessions.length > 0) {
161
170
  await this.sessions[this.sessions.length - 1].close()
171
+ }
162
172
 
163
173
  for (const columnFamily of this.columnFamilies) columnFamily.destroy()
164
174
 
@@ -182,6 +192,20 @@ module.exports = class RocksDBState extends ReadyResource {
182
192
  async flush(db, opts) {
183
193
  if (this.opened === false) await this.ready()
184
194
 
195
+ this.handles.inc()
196
+ this.io.inc()
197
+
198
+ if (this.resumed !== null) {
199
+ const resumed = await this.resumed.promise
200
+
201
+ if (!resumed) {
202
+ this.handles.dec()
203
+ this.io.dec()
204
+
205
+ throw new Error('RocksDB session is closed')
206
+ }
207
+ }
208
+
185
209
  const req = { resolve: null, reject: null, handle: null }
186
210
 
187
211
  const promise = new Promise((resolve, reject) => {
@@ -189,14 +213,19 @@ module.exports = class RocksDBState extends ReadyResource {
189
213
  req.reject = reject
190
214
  })
191
215
 
192
- req.handle = binding.flush(
193
- this._handle,
194
- db._columnFamily._handle,
195
- req,
196
- onflush
197
- )
216
+ try {
217
+ req.handle = binding.flush(
218
+ this._handle,
219
+ db._columnFamily._handle,
220
+ req,
221
+ onflush
222
+ )
198
223
 
199
- await promise
224
+ await promise
225
+ } finally {
226
+ this.handles.dec()
227
+ this.io.dec()
228
+ }
200
229
 
201
230
  function onflush(err) {
202
231
  if (err) req.reject(new Error(err))
@@ -205,16 +234,18 @@ module.exports = class RocksDBState extends ReadyResource {
205
234
  }
206
235
 
207
236
  async suspend() {
208
- if (this._suspended === true) return
209
237
  if (this._suspending === null) this._suspending = this._suspend()
210
238
  return this._suspending
211
239
  }
212
240
 
213
241
  async _suspend() {
214
- if (this._resuming !== null) await this._resuming
215
242
  if (this.opened === false) await this.ready()
243
+ if (this._resuming !== null) await this._resuming
244
+ if (this._suspended === true) return
216
245
 
217
- while (!this.activeBatches.isIdle()) await this.activeBatches.idle()
246
+ while (!this.io.isIdle()) await this.io.idle()
247
+
248
+ this.resumed = rrp()
218
249
 
219
250
  const req = { resolve: null, reject: null, handle: null }
220
251
 
@@ -223,9 +254,9 @@ module.exports = class RocksDBState extends ReadyResource {
223
254
  req.reject = reject
224
255
  })
225
256
 
226
- req.handle = binding.suspend(this._handle, req, onsuspend)
227
-
228
257
  try {
258
+ req.handle = binding.suspend(this._handle, req, onsuspend)
259
+
229
260
  await promise
230
261
 
231
262
  this._suspended = true
@@ -240,14 +271,14 @@ module.exports = class RocksDBState extends ReadyResource {
240
271
  }
241
272
 
242
273
  resume() {
243
- if (this._suspended === false) return
244
274
  if (this._resuming === null) this._resuming = this._resume()
245
275
  return this._resuming
246
276
  }
247
277
 
248
278
  async _resume() {
249
- if (this._suspending !== null) await this._suspending
250
279
  if (this.opened === false) await this.ready()
280
+ if (this._suspending !== null) await this._suspending
281
+ if (this._suspended === false) return
251
282
 
252
283
  const req = { resolve: null, reject: null, handle: null }
253
284
 
@@ -256,9 +287,9 @@ module.exports = class RocksDBState extends ReadyResource {
256
287
  req.reject = reject
257
288
  })
258
289
 
259
- req.handle = binding.resume(this._handle, req, onresume)
260
-
261
290
  try {
291
+ req.handle = binding.resume(this._handle, req, onresume)
292
+
262
293
  await promise
263
294
 
264
295
  this._suspended = false
@@ -266,6 +297,10 @@ module.exports = class RocksDBState extends ReadyResource {
266
297
  this._resuming = null
267
298
  }
268
299
 
300
+ const resumed = this.resumed
301
+ this.resumed = null
302
+ resumed.resolve(true)
303
+
269
304
  function onresume(err) {
270
305
  if (err) req.reject(new Error(err))
271
306
  else req.resolve()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rocksdb-native",
3
- "version": "3.5.1",
3
+ "version": "3.5.3",
4
4
  "description": "librocksdb bindings for JavaScript",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -40,6 +40,7 @@
40
40
  "ready-resource": "^1.0.0",
41
41
  "refcounter": "^1.0.0",
42
42
  "require-addon": "^1.0.2",
43
+ "resolve-reject-promise": "^1.1.0",
43
44
  "streamx": "^2.16.1"
44
45
  },
45
46
  "devDependencies": {
@@ -49,7 +50,6 @@
49
50
  "cmake-fetch": "^1.0.1",
50
51
  "cmake-napi": "^1.0.6",
51
52
  "prettier": "^3.4.1",
52
- "prettier-config-standard": "^7.0.0",
53
- "test-tmp": "^1.2.0"
53
+ "prettier-config-standard": "^7.0.0"
54
54
  }
55
55
  }