rocksdb-native 2.6.8 → 3.0.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/lib/iterator.js CHANGED
@@ -1,13 +1,13 @@
1
1
  const { Readable } = require('streamx')
2
2
  const c = require('compact-encoding')
3
- const b4a = require('b4a')
4
3
  const binding = require('../binding')
5
4
 
6
- const empty = b4a.alloc(0)
5
+ const empty = Buffer.alloc(0)
7
6
 
8
7
  module.exports = class RocksDBIterator extends Readable {
9
8
  constructor(db, opts = {}) {
10
9
  const {
10
+ columnFamily = db.defaultColumnFamily,
11
11
  gt = null,
12
12
  gte = null,
13
13
  lt = null,
@@ -15,7 +15,6 @@ module.exports = class RocksDBIterator extends Readable {
15
15
  reverse = false,
16
16
  limit = Infinity,
17
17
  capacity = 8,
18
- snapshot = null,
19
18
  encoding = null,
20
19
  keyEncoding = encoding,
21
20
  valueEncoding = encoding
@@ -23,9 +22,10 @@ module.exports = class RocksDBIterator extends Readable {
23
22
 
24
23
  super()
25
24
 
26
- db._incRef()
25
+ db._state.ref()
27
26
 
28
- this._db = db
27
+ this._state = db._state
28
+ this._columnFamily = columnFamily
29
29
 
30
30
  this._keyEncoding = keyEncoding
31
31
  this._valueEncoding = valueEncoding
@@ -38,7 +38,7 @@ module.exports = class RocksDBIterator extends Readable {
38
38
  this._reverse = reverse
39
39
  this._limit = limit < 0 ? Infinity : limit
40
40
  this._capacity = capacity
41
- this._snapshot = snapshot
41
+ this._snapshot = db._snapshot
42
42
 
43
43
  this._pendingOpen = null
44
44
  this._pendingRead = null
@@ -47,7 +47,7 @@ module.exports = class RocksDBIterator extends Readable {
47
47
  this._buffer = null
48
48
  this._handle = null
49
49
 
50
- if (db.opened === true) this.ready()
50
+ if (this._state.opened === true) this.ready()
51
51
  }
52
52
 
53
53
  _onopen(err) {
@@ -67,8 +67,8 @@ module.exports = class RocksDBIterator extends Readable {
67
67
 
68
68
  for (let i = 0; i < n; i++) {
69
69
  this.push({
70
- key: this._decodeKey(b4a.from(keys[i])),
71
- value: this._decodeValue(b4a.from(values[i]))
70
+ key: this._decodeKey(Buffer.from(keys[i])),
71
+ value: this._decodeValue(Buffer.from(values[i]))
72
72
  })
73
73
  }
74
74
 
@@ -80,7 +80,7 @@ module.exports = class RocksDBIterator extends Readable {
80
80
  _onclose(err) {
81
81
  const cb = this._pendingDestroy
82
82
  this._pendingDestroy = null
83
- this._db._decRef()
83
+ this._state.unref()
84
84
  cb(err)
85
85
  }
86
86
 
@@ -93,7 +93,7 @@ module.exports = class RocksDBIterator extends Readable {
93
93
  async ready() {
94
94
  if (this._handle !== null) return
95
95
 
96
- if (this._db.opened === false) await this._db.ready()
96
+ if (this._state.opened === false) await this._state.ready()
97
97
 
98
98
  this._init()
99
99
  }
@@ -109,8 +109,9 @@ module.exports = class RocksDBIterator extends Readable {
109
109
  this._pendingOpen = cb
110
110
 
111
111
  binding.iteratorOpen(
112
- this._db._handle,
112
+ this._state.handle,
113
113
  this._handle,
114
+ this._columnFamily._handle,
114
115
  this._gt,
115
116
  this._gte,
116
117
  this._lt,
@@ -140,7 +141,7 @@ module.exports = class RocksDBIterator extends Readable {
140
141
 
141
142
  _encodeKey(k) {
142
143
  if (this._keyEncoding) return c.encode(this._keyEncoding, k)
143
- if (typeof k === 'string') return b4a.from(k)
144
+ if (typeof k === 'string') return Buffer.from(k)
144
145
  return k
145
146
  }
146
147
 
package/lib/snapshot.js CHANGED
@@ -1,21 +1,28 @@
1
1
  const binding = require('../binding')
2
2
 
3
3
  module.exports = class RocksDBSnapshot {
4
- constructor(db) {
5
- this._db = db
6
- this._db._snapshots.add(this)
4
+ constructor(state) {
5
+ this._state = state
6
+ this._state.snapshots.add(this)
7
7
 
8
8
  this._handle = null
9
+ this._refs = 1
9
10
 
10
- if (db.opened === true) this._init()
11
+ if (state.opened === true) this._init()
11
12
  }
12
13
 
13
14
  _init() {
14
- this._handle = binding.snapshotCreate(this._db._handle)
15
+ this._handle = binding.snapshotCreate(this._state.handle)
15
16
  }
16
17
 
17
- destroy() {
18
- this._db._snapshots.delete(this)
18
+ ref() {
19
+ this._refs++
20
+ }
21
+
22
+ unref() {
23
+ if (--this._refs > 0) return
24
+
25
+ this._state.snapshots.delete(this)
19
26
 
20
27
  if (this._handle === null) return
21
28
 
package/lib/state.js ADDED
@@ -0,0 +1,213 @@
1
+ const ReadyResource = require('ready-resource')
2
+ const RefCounter = require('refcounter')
3
+ const ColumnFamily = require('./column-family')
4
+ const binding = require('../binding')
5
+
6
+ module.exports = class DBState extends ReadyResource {
7
+ constructor(db, path, opts) {
8
+ super()
9
+
10
+ const {
11
+ columnFamily = new ColumnFamily('default', opts),
12
+ columnFamilies = [],
13
+ readOnly = false,
14
+ createIfMissing = true,
15
+ createMissingColumnFamilies = true,
16
+ maxBackgroundJobs = 6,
17
+ bytesPerSync = 1048576
18
+ } = opts
19
+
20
+ this.path = path
21
+ this.db = db
22
+ this.refs = new RefCounter()
23
+ this.sessionRefs = new RefCounter()
24
+ this.sessions = []
25
+ this.columnFamilies = [columnFamily]
26
+ this.snapshots = new Set()
27
+
28
+ this._suspending = null
29
+ this._resuming = null
30
+ this._columnsFlushed = false
31
+
32
+ for (const col of columnFamilies) {
33
+ this.columnFamilies.push(
34
+ typeof col === 'string' ? new ColumnFamily(col, opts) : col
35
+ )
36
+ }
37
+
38
+ this.handle = binding.init(
39
+ Uint32Array.from([
40
+ readOnly ? 1 : 0,
41
+ createIfMissing ? 1 : 0,
42
+ createMissingColumnFamilies ? 1 : 0,
43
+ maxBackgroundJobs,
44
+ bytesPerSync & 0xffffffff,
45
+ Math.floor(bytesPerSync / 0x100000000)
46
+ ])
47
+ )
48
+ }
49
+
50
+ addSession(db) {
51
+ this.sessionRefs.inc()
52
+ db._index = this.sessions.push(db) - 1
53
+ }
54
+
55
+ removeSession(db) {
56
+ this.sessionRefs.dec()
57
+ const head = this.sessions.pop()
58
+ if (head !== db) this.sessions[(head._index = db._index)] = head
59
+ }
60
+
61
+ ref() {
62
+ if (this.closing) throw new Error('Database closed')
63
+ this.refs.inc()
64
+ }
65
+
66
+ unref() {
67
+ this.refs.dec()
68
+ }
69
+
70
+ upsertColumnFamily(c) {
71
+ if (typeof c === 'string') {
72
+ let col = this.getColumnFamilyByName(c)
73
+ if (col) return col
74
+ col = this.columnFamilies[0].cloneSettings(c)
75
+ this.columnFamilies.push(col)
76
+ return col
77
+ }
78
+
79
+ if (this.columnFamilies.includes(c)) return c
80
+ this.columnFamilies.push(c)
81
+ return c
82
+ }
83
+
84
+ getColumnFamily(c) {
85
+ if (!c) return this.columnFamilies[0]
86
+ if (!this._columnsFlushed) return this.upsertColumnFamily(c)
87
+
88
+ if (typeof c !== 'string') return c
89
+
90
+ const col = this.getColumnFamilyByName(c)
91
+ if (col === null) throw new Error('Unknown column family')
92
+ return col
93
+ }
94
+
95
+ getColumnFamilyByName(name) {
96
+ for (const col of this.columnFamilies) {
97
+ if (col.name === name) return col
98
+ }
99
+ return null
100
+ }
101
+
102
+ async _open() {
103
+ await Promise.resolve() // allow column families to populate if ondemand
104
+
105
+ const req = { resolve: null, reject: null, handle: null }
106
+
107
+ const promise = new Promise((resolve, reject) => {
108
+ req.resolve = resolve
109
+ req.reject = reject
110
+ })
111
+
112
+ this._columnsFlushed = true
113
+ req.handle = binding.open(
114
+ this.handle,
115
+ this,
116
+ this.path,
117
+ this.columnFamilies.map((c) => c._handle),
118
+ req,
119
+ onopen
120
+ )
121
+
122
+ await promise
123
+
124
+ for (const snapshot of this.snapshots) snapshot._init()
125
+
126
+ function onopen(err) {
127
+ if (err) req.reject(new Error(err))
128
+ else req.resolve()
129
+ }
130
+ }
131
+
132
+ async _close() {
133
+ while (!this.refs.isIdle() || !this.sessionRefs.isIdle()) {
134
+ await this.refs.idle()
135
+ await this.sessionRefs.idle()
136
+ }
137
+
138
+ for (const columnFamily of this.columnFamilies) columnFamily.destroy()
139
+ for (const snapshot of this.snapshots) snapshot.destroy()
140
+
141
+ const req = { resolve: null, reject: null, handle: null }
142
+
143
+ const promise = new Promise((resolve, reject) => {
144
+ req.resolve = resolve
145
+ req.reject = reject
146
+ })
147
+
148
+ req.handle = binding.close(this.handle, req, onclose)
149
+
150
+ await promise
151
+
152
+ function onclose(err) {
153
+ if (err) req.reject(new Error(err))
154
+ else req.resolve()
155
+ }
156
+ }
157
+
158
+ async suspend() {
159
+ if (this._suspending === null) this._suspending = this._suspend()
160
+ return this._suspending
161
+ }
162
+
163
+ async _suspend() {
164
+ if (this._resuming) await this._resuming
165
+ if (this.opened === false) await this.ready()
166
+
167
+ const req = { resolve: null, reject: null, handle: null }
168
+
169
+ const promise = new Promise((resolve, reject) => {
170
+ req.resolve = resolve
171
+ req.reject = reject
172
+ })
173
+
174
+ req.handle = binding.suspend(this.handle, req, onsuspend)
175
+
176
+ await promise
177
+
178
+ this._suspending = null
179
+
180
+ function onsuspend(err) {
181
+ if (err) req.reject(new Error(err))
182
+ else req.resolve()
183
+ }
184
+ }
185
+
186
+ resume() {
187
+ if (this._resuming === null) this._resuming = this._resume()
188
+ return this._resuming
189
+ }
190
+
191
+ async _resume() {
192
+ if (this._suspending) await this._suspending
193
+ if (this.opened === false) await this.ready()
194
+
195
+ const req = { resolve: null, reject: null, handle: null }
196
+
197
+ const promise = new Promise((resolve, reject) => {
198
+ req.resolve = resolve
199
+ req.reject = reject
200
+ })
201
+
202
+ req.handle = binding.resume(this.handle, req, onresume)
203
+
204
+ await promise
205
+
206
+ this._resuming = null
207
+
208
+ function onresume(err) {
209
+ if (err) req.reject(new Error(err))
210
+ else req.resolve()
211
+ }
212
+ }
213
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rocksdb-native",
3
- "version": "2.6.8",
3
+ "version": "3.0.0",
4
4
  "description": "librocksdb bindings for JavaScript",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "repository": {
26
26
  "type": "git",
27
- "url": "https://github.com/holepunchto/rocksdb-native.git"
27
+ "url": "git+https://github.com/holepunchto/rocksdb-native.git"
28
28
  },
29
29
  "author": "Holepunch Inc",
30
30
  "license": "Apache-2.0",
@@ -36,9 +36,9 @@
36
36
  "bare": ">=1.7.0"
37
37
  },
38
38
  "dependencies": {
39
- "b4a": "^1.6.6",
40
39
  "compact-encoding": "^2.15.0",
41
40
  "ready-resource": "^1.0.0",
41
+ "refcounter": "^1.0.0",
42
42
  "require-addon": "^1.0.2",
43
43
  "streamx": "^2.16.1"
44
44
  },