rocksdb-native 3.1.0 → 3.1.2

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
@@ -18,7 +18,9 @@ class RocksDB {
18
18
  this._columnFamily = state.getColumnFamily(columnFamily)
19
19
  this._keyEncoding = keyEncoding
20
20
  this._valueEncoding = valueEncoding
21
- this._index = this._state.addSession(this)
21
+ this._index = -1
22
+
23
+ this._state.addSession(this)
22
24
  }
23
25
 
24
26
  get opened() {
@@ -33,6 +35,10 @@ class RocksDB {
33
35
  return this._state.path
34
36
  }
35
37
 
38
+ get snapshotted() {
39
+ return this._snapshot !== null
40
+ }
41
+
36
42
  get defaultColumnFamily() {
37
43
  return this._columnFamily
38
44
  }
@@ -43,18 +49,12 @@ class RocksDB {
43
49
  keyEncoding = this._keyEncoding,
44
50
  valueEncoding = this._valueEncoding
45
51
  } = {}) {
46
- let snap = null
47
-
48
- if (snapshot) {
49
- snap = this._snapshot
50
- if (snap === null) snap = new Snapshot(this._state)
51
- else snap.ref()
52
- }
52
+ maybeClosed(this)
53
53
 
54
54
  return new RocksDB(null, {
55
55
  state: this._state,
56
56
  columnFamily,
57
- snapshot: snap,
57
+ snapshot: snapshot ? this._snapshot || new Snapshot(this._state) : null,
58
58
  keyEncoding,
59
59
  valueEncoding
60
60
  })
@@ -77,11 +77,7 @@ class RocksDB {
77
77
  }
78
78
 
79
79
  async close({ force } = {}) {
80
- if (this._index !== -1) {
81
- this._state.removeSession(this)
82
- this._index = -1
83
- if (this._snapshot) this._snapshot.unref()
84
- }
80
+ if (this._index !== -1) this._state.removeSession(this)
85
81
 
86
82
  if (force) {
87
83
  for (let i = this._state.sessions.length - 1; i >= 0; i--) {
@@ -93,22 +89,28 @@ class RocksDB {
93
89
  }
94
90
 
95
91
  suspend() {
92
+ maybeClosed(this)
93
+
96
94
  return this._state.suspend()
97
95
  }
98
96
 
99
97
  resume() {
98
+ maybeClosed(this)
99
+
100
100
  return this._state.resume()
101
101
  }
102
102
 
103
103
  isIdle() {
104
- return this._state.refs.isIdle()
104
+ return this._state.activity.isIdle()
105
105
  }
106
106
 
107
107
  idle() {
108
- return this._state.refs.idle()
108
+ return this._state.activity.idle()
109
109
  }
110
110
 
111
111
  iterator(range, opts) {
112
+ maybeClosed(this)
113
+
112
114
  return new Iterator(this, { ...range, ...opts })
113
115
  }
114
116
 
@@ -121,10 +123,14 @@ class RocksDB {
121
123
  }
122
124
 
123
125
  read(opts) {
126
+ maybeClosed(this)
127
+
124
128
  return this._state.createReadBatch(this, opts)
125
129
  }
126
130
 
127
131
  write(opts) {
132
+ maybeClosed(this)
133
+
128
134
  return this._state.createWriteBatch(this, opts)
129
135
  }
130
136
 
@@ -152,7 +158,24 @@ class RocksDB {
152
158
  batch.tryDeleteRange(start, end)
153
159
  await batch.flush()
154
160
  }
161
+
162
+ // used by iterators/batches to ensure no gc/close when active
163
+
164
+ _ref() {
165
+ if (this._snapshot) this._snapshot.ref()
166
+ this._state.activity.inc()
167
+ }
168
+
169
+ _unref() {
170
+ if (this._snapshot) this._snapshot.unref()
171
+ this._state.activity.dec()
172
+ }
155
173
  }
156
174
 
157
175
  module.exports = exports = RocksDB
158
176
  exports.ColumnFamily = ColumnFamily
177
+
178
+ function maybeClosed(db) {
179
+ if (db._state.closing || db._destroyed)
180
+ throw new Error('RocksDB session is closed')
181
+ }
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._state.ref()
11
+ db._ref()
12
12
 
13
13
  this._db = db
14
14
  this._destroyed = false
@@ -31,7 +31,7 @@ class RocksDBBatch {
31
31
  _reuse(db, opts = {}) {
32
32
  const { autoDestroy = false } = opts
33
33
 
34
- db._state.ref()
34
+ db._ref()
35
35
 
36
36
  this._db = db
37
37
  this._destroyed = false
@@ -76,7 +76,7 @@ class RocksDBBatch {
76
76
 
77
77
  if (this._promises.length) this._abort()
78
78
 
79
- this._db._state.unref()
79
+ this._db._unref()
80
80
  this._onfree()
81
81
  }
82
82
 
package/lib/iterator.js CHANGED
@@ -18,7 +18,7 @@ module.exports = class RocksDBIterator extends Readable {
18
18
 
19
19
  super()
20
20
 
21
- db._state.ref()
21
+ db._ref()
22
22
 
23
23
  this._db = db
24
24
 
@@ -71,7 +71,7 @@ module.exports = class RocksDBIterator extends Readable {
71
71
  _onclose(err) {
72
72
  const cb = this._pendingDestroy
73
73
  this._pendingDestroy = null
74
- this._db._state.unref()
74
+ this._db._unref()
75
75
  cb(err)
76
76
  }
77
77
 
package/lib/snapshot.js CHANGED
@@ -3,12 +3,11 @@ const binding = require('../binding')
3
3
  module.exports = class RocksDBSnapshot {
4
4
  constructor(state) {
5
5
  this._state = state
6
- this._state.snapshots.add(this)
7
6
 
8
7
  this._handle = null
9
- this._refs = 1
8
+ this._refs = 0 // starts unreffed, easier, must be reffed in first tick
10
9
 
11
- if (state.opened === true) this._init()
10
+ if (state.deferSnapshotInit === false) this._init()
12
11
  }
13
12
 
14
13
  _init() {
@@ -22,8 +21,6 @@ module.exports = class RocksDBSnapshot {
22
21
  unref() {
23
22
  if (--this._refs > 0) return
24
23
 
25
- this._state.snapshots.delete(this)
26
-
27
24
  if (this._handle === null) return
28
25
 
29
26
  binding.snapshotDestroy(this._handle)
package/lib/state.js CHANGED
@@ -22,11 +22,10 @@ module.exports = class DBState extends ReadyResource {
22
22
 
23
23
  this.path = path
24
24
  this.db = db
25
- this.refs = new RefCounter()
26
- this.sessionRefs = new RefCounter()
25
+ this.activity = new RefCounter()
27
26
  this.sessions = []
28
27
  this.columnFamilies = [columnFamily]
29
- this.snapshots = new Set()
28
+ this.deferSnapshotInit = true
30
29
 
31
30
  this._suspending = null
32
31
  this._resuming = null
@@ -73,23 +72,15 @@ module.exports = class DBState extends ReadyResource {
73
72
  }
74
73
 
75
74
  addSession(db) {
76
- this.sessionRefs.inc()
77
- return this.sessions.push(db) - 1
75
+ db._index = this.sessions.push(db) - 1
76
+ if (db._snapshot) db._snapshot.ref()
78
77
  }
79
78
 
80
79
  removeSession(db) {
81
- this.sessionRefs.dec()
82
80
  const head = this.sessions.pop()
83
81
  if (head !== db) this.sessions[(head._index = db._index)] = head
84
- }
85
-
86
- ref() {
87
- if (this.closing) throw new Error('Database closed')
88
- this.refs.inc()
89
- }
90
-
91
- unref() {
92
- this.refs.dec()
82
+ db._index = -1
83
+ if (db._snapshot) db._snapshot.unref()
93
84
  }
94
85
 
95
86
  upsertColumnFamily(c) {
@@ -146,7 +137,10 @@ module.exports = class DBState extends ReadyResource {
146
137
 
147
138
  await promise
148
139
 
149
- for (const snapshot of this.snapshots) snapshot._init()
140
+ this.deferSnapshotInit = false
141
+ for (const session of this.sessions) {
142
+ if (session._snapshot) session._snapshot._init()
143
+ }
150
144
 
151
145
  function onopen(err) {
152
146
  if (err) req.reject(new Error(err))
@@ -155,13 +149,11 @@ module.exports = class DBState extends ReadyResource {
155
149
  }
156
150
 
157
151
  async _close() {
158
- while (!this.refs.isIdle() || !this.sessionRefs.isIdle()) {
159
- await this.refs.idle()
160
- await this.sessionRefs.idle()
161
- }
152
+ while (!this.activity.isIdle()) await this.activity.idle()
153
+ for (let i = this.sessions.length - 1; i >= 0; i--)
154
+ await this.sessions[i].close()
162
155
 
163
156
  for (const columnFamily of this.columnFamilies) columnFamily.destroy()
164
- for (const snapshot of this.snapshots) snapshot.destroy()
165
157
 
166
158
  const req = { resolve: null, reject: null, handle: null }
167
159
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rocksdb-native",
3
- "version": "3.1.0",
3
+ "version": "3.1.2",
4
4
  "description": "librocksdb bindings for JavaScript",
5
5
  "exports": {
6
6
  ".": "./index.js",