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/CMakeLists.txt +1 -1
- package/binding.c +514 -84
- package/index.js +102 -145
- package/lib/batch.js +76 -40
- package/lib/column-family.js +56 -0
- package/lib/iterator.js +14 -13
- package/lib/snapshot.js +14 -7
- package/lib/state.js +213 -0
- package/package.json +3 -3
- package/prebuilds/android-arm64/rocksdb-native.bare +0 -0
- package/prebuilds/android-ia32/rocksdb-native.bare +0 -0
- package/prebuilds/android-x64/rocksdb-native.bare +0 -0
- package/prebuilds/darwin-arm64/rocksdb-native.bare +0 -0
- package/prebuilds/darwin-arm64/rocksdb-native.node +0 -0
- package/prebuilds/darwin-x64/rocksdb-native.bare +0 -0
- package/prebuilds/darwin-x64/rocksdb-native.node +0 -0
- package/prebuilds/ios-arm64/rocksdb-native.bare +0 -0
- package/prebuilds/ios-arm64-simulator/rocksdb-native.bare +0 -0
- package/prebuilds/ios-x64-simulator/rocksdb-native.bare +0 -0
- package/prebuilds/linux-arm64/rocksdb-native.bare +0 -0
- package/prebuilds/linux-arm64/rocksdb-native.node +0 -0
- package/prebuilds/linux-x64/rocksdb-native.bare +0 -0
- package/prebuilds/linux-x64/rocksdb-native.node +0 -0
- package/prebuilds/win32-arm64/rocksdb-native.bare +0 -0
- package/prebuilds/win32-arm64/rocksdb-native.node +0 -0
- package/prebuilds/win32-x64/rocksdb-native.bare +0 -0
- package/prebuilds/win32-x64/rocksdb-native.node +0 -0
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 =
|
|
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.
|
|
25
|
+
db._state.ref()
|
|
27
26
|
|
|
28
|
-
this.
|
|
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 =
|
|
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 (
|
|
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(
|
|
71
|
-
value: this._decodeValue(
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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(
|
|
5
|
-
this.
|
|
6
|
-
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 (
|
|
11
|
+
if (state.opened === true) this._init()
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
_init() {
|
|
14
|
-
this._handle = binding.snapshotCreate(this.
|
|
15
|
+
this._handle = binding.snapshotCreate(this._state.handle)
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
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": "
|
|
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
|
},
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|