@nxtedition/rocksdb 5.2.3 → 5.2.10

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/binding.gyp CHANGED
@@ -23,7 +23,8 @@
23
23
  }
24
24
  }
25
25
  }, { # OS != 'win'
26
- 'cflags!': [ '-fno-rtti' ]
26
+ 'cflags': [ '-std=c++20' ]
27
+ , 'cflags!': [ '-fno-rtti' ]
27
28
  , 'cflags_cc!': [ '-fno-rtti' ]
28
29
  , 'cflags_cc+': [ '-frtti' ]
29
30
  }]
@@ -38,7 +39,7 @@
38
39
  , '-Wno-ignored-qualifiers'
39
40
  ]
40
41
  , 'OTHER_CPLUSPLUSFLAGS': [
41
- '-mmacosx-version-min=10.8'
42
+ '-mmacosx-version-min=10.14'
42
43
  , '-std=c++20'
43
44
  , '-stdlib=libc++'
44
45
  , '-arch x86_64'
@@ -51,7 +52,7 @@
51
52
  ]
52
53
  , 'GCC_ENABLE_CPP_RTTI': 'YES'
53
54
  , 'GCC_ENABLE_CPP_EXCEPTIONS': 'YES'
54
- , 'MACOSX_DEPLOYMENT_TARGET': '10.8'
55
+ , 'MACOSX_DEPLOYMENT_TARGET': '10.14'
55
56
  }
56
57
  }]
57
58
  , ['OS == "linux"', {
package/chained-batch.js CHANGED
@@ -1,44 +1,39 @@
1
1
  'use strict'
2
2
 
3
- const { AbstractChainedBatch } = require('abstract-leveldown')
3
+ const { AbstractChainedBatch } = require('abstract-level')
4
4
  const binding = require('./binding')
5
5
 
6
6
  const kDbContext = Symbol('db')
7
7
  const kBatchContext = Symbol('context')
8
- const kHasData = Symbol('hasData')
9
8
 
10
9
  class ChainedBatch extends AbstractChainedBatch {
11
- constructor (db) {
10
+ constructor (db, context) {
12
11
  super(db)
13
- this[kDbContext] = db.context
14
- this[kBatchContext] = binding.batch_init(db.context)
15
- this[kHasData] = false
12
+
13
+ this[kDbContext] = context
14
+ this[kBatchContext] = binding.batch_init(context)
16
15
  }
17
16
 
18
17
  _put (key, value) {
19
18
  binding.batch_put(this[kBatchContext], key, value)
20
- this[kHasData] = true
21
19
  }
22
20
 
23
21
  _del (key) {
24
22
  binding.batch_del(this[kBatchContext], key)
25
- this[kHasData] = true
26
23
  }
27
24
 
28
25
  _clear () {
29
- if (this[kHasData]) {
30
- binding.batch_clear(this[kBatchContext])
31
- this[kHasData] = false
32
- }
26
+ binding.batch_clear(this[kBatchContext])
33
27
  }
34
28
 
35
29
  _write (options, callback) {
36
- if (this[kHasData]) {
37
- binding.batch_write(this[kDbContext], this[kBatchContext], options, callback)
38
- } else {
39
- process.nextTick(callback)
40
- }
30
+ binding.batch_write(this[kDbContext], this[kBatchContext], options, callback)
31
+ }
32
+
33
+ _close (callback) {
34
+ // TODO: close native batch (currently done on GC)
35
+ process.nextTick(callback)
41
36
  }
42
37
  }
43
38
 
44
- module.exports = ChainedBatch
39
+ exports.ChainedBatch = ChainedBatch
@@ -13,7 +13,10 @@
13
13
  ]
14
14
  }
15
15
  , 'defines': [
16
- 'SNAPPY=1'
16
+ 'SNAPPY=1',
17
+ 'ROCKSDB_BACKTRACE=1',
18
+ 'ROCKSDB_SUPPORT_THREAD_LOCAL=1',
19
+ 'USE_SSE=1'
17
20
  ]
18
21
  , 'include_dirs': [
19
22
  'rocksdb/'
@@ -73,16 +76,12 @@
73
76
  , 'defines': [
74
77
  'ROCKSDB_PLATFORM_POSIX=1'
75
78
  ]
76
- , 'ccflags': [
77
- '-fno-builtin-memcmp'
78
- , '-fPIC'
79
- ]
80
- , 'cflags': [ '-std=c++0x' ]
79
+ , 'ccflags': []
80
+ , 'cflags': [ '-std=c++20' ]
81
81
  , 'cflags!': [ '-fno-tree-vrp', '-fno-rtti' ]
82
82
  , 'cflags_cc!': [ '-fno-rtti' ]
83
- # , 'cflags_cc+': [ '-frtti' ]
84
83
  }]
85
- , ['OS != "win"' and 'OS != "freebsd"', {
84
+ , ['OS != "win"', {
86
85
  'cflags': [
87
86
  '-Wno-sign-compare'
88
87
  , '-Wno-unused-but-set-variable'
@@ -91,66 +90,50 @@
91
90
  , ['OS == "linux"', {
92
91
  'defines': [
93
92
  'OS_LINUX=1',
94
- 'ROCKSDB_LIB_IO_POSIX=1'
95
- ]
96
- , 'libraries': [
97
- '-lpthread'
93
+ 'ROCKSDB_LIB_IO_POSIX=1',
94
+ 'ROCKSDB_FALLOCATE_PRESENT=1',
95
+ 'ROCKSDB_MALLOC_USABLE_SIZE=1',
96
+ 'ROCKSDB_PTHREAD_ADAPTIVE_MUTEX=1',
97
+ 'ROCKSDB_RANGESYNC_PRESENT=1',
98
+ 'ROCKSDB_SCHED_GETCPU_PRESENT=1',
99
+ # 'ROCKSDB_IOURING_PRESENT=1',
100
+ # 'HAVE_SSE42=1',
101
+ 'HAVE_BMI=1',
102
+ 'HAVE_LZCNT=1'
103
+ 'HAVE_AVX2=1',
104
+ 'HAVE_PCLMUL=1',
105
+ 'HAVE_UINT128_EXTENSION=1',
106
+ 'HAVE_ALIGNED_NEW=1',
107
+ # 'LIBURING=1'
108
+ # 'NUMA=1'
109
+ 'ROCKSDB_PLATFORM_POSIX=1',
110
+ 'ROCKSDB_LIB_IO_POSIX=1',
111
+ # "-TBB=1",
98
112
  ]
99
113
  , 'ccflags': [
100
- '-pthread'
101
- '-fexceptions'
114
+ '-flto'
115
+ , '-pthread'
116
+ , '-msse4.2'
117
+ , '-mpclmul'
118
+ , '-mavx2'
119
+ , '-mbmi'
120
+ , '-mlzcnt'
121
+ , '-fexceptions'
122
+ , '-faligned-new'
123
+ , '-latomic'
102
124
  ]
103
125
  , 'cflags!': [ '-fno-exceptions' ]
104
126
  , 'cflags_cc!': [ '-fno-exceptions' ]
105
- }]
106
- , ['OS == "freebsd"', {
107
- 'defines': [
108
- 'OS_FREEBSD=1'
109
- , '_REENTRANT=1'
110
- ]
111
- , 'libraries': [
112
- '-lpthread'
113
- ]
114
- , 'ccflags': [
115
- '-pthread'
116
- ]
117
- , 'cflags': [
118
- '-Wno-sign-compare'
119
- ]
120
- }]
121
- , ['OS == "openbsd"', {
122
- 'defines': [
123
- 'OS_OPENBSD=1'
124
- , '_REENTRANT=1'
125
- ]
126
- , 'libraries': [
127
- '-lpthread'
128
- ]
129
- , 'ccflags': [
130
- '-pthread'
131
- ]
132
- , 'cflags': [
133
- '-Wno-sign-compare'
134
- ]
135
- }]
136
- , ['OS == "solaris"', {
137
- 'defines': [
138
- 'OS_SOLARIS=1'
139
- , '_REENTRANT=1'
140
- ]
141
- , 'libraries': [
142
- '-lrt'
143
- , '-lpthread'
144
- ]
145
- , 'ccflags': [
146
- '-pthread'
127
+ , 'ldflags': [
128
+ '-flto'
129
+ , '-fuse-linker-plugin'
147
130
  ]
148
131
  }]
149
132
  , ['OS == "mac"', {
150
133
  'defines': [
151
134
  'OS_MACOSX=1',
152
- 'ROCKSDB_LIB_IO_POSIX=1',
153
- 'ROCKSDB_BACKTRACE=1'
135
+ 'DROCKSDB_PLATFORM_POSIX=1',
136
+ 'ROCKSDB_LIB_IO_POSIX=1'
154
137
  ]
155
138
  , 'libraries': []
156
139
  , 'ccflags': []
@@ -161,18 +144,17 @@
161
144
  , '-Wno-unused-function'
162
145
  ]
163
146
  , 'OTHER_CPLUSPLUSFLAGS': [
164
- '-mmacosx-version-min=10.8'
165
- , '-std=c++11'
147
+ '-mmacosx-version-min=10.14'
148
+ , '-std=c++20'
166
149
  , '-stdlib=libc++'
167
150
  , '-fno-omit-frame-pointer'
168
151
  , '-momit-leaf-frame-pointer'
169
152
  , '-arch x86_64'
170
153
  , '-arch arm64'
171
154
  ]
172
- # , 'OTHER_LDFLAGS': ['-stdlib=libc++']
173
155
  , 'GCC_ENABLE_CPP_RTTI': 'YES'
174
156
  , 'GCC_ENABLE_CPP_EXCEPTIONS': 'YES'
175
- , 'MACOSX_DEPLOYMENT_TARGET': '10.8'
157
+ , 'MACOSX_DEPLOYMENT_TARGET': '10.14'
176
158
  }
177
159
  }]
178
160
  ]
package/index.js ADDED
@@ -0,0 +1,92 @@
1
+ 'use strict'
2
+
3
+ const { AbstractLevel } = require('abstract-level')
4
+ const ModuleError = require('module-error')
5
+ const fs = require('fs')
6
+ const binding = require('./binding')
7
+ const { ChainedBatch } = require('./chained-batch')
8
+ const { Iterator } = require('./iterator')
9
+
10
+ const kContext = Symbol('context')
11
+ const kLocation = Symbol('location')
12
+
13
+ class ClassicLevel extends AbstractLevel {
14
+ constructor (location, options, _) {
15
+ // To help migrating to abstract-level
16
+ if (typeof options === 'function' || typeof _ === 'function') {
17
+ throw new ModuleError('The levelup-style callback argument has been removed', {
18
+ code: 'LEVEL_LEGACY'
19
+ })
20
+ }
21
+
22
+ if (typeof location !== 'string' || location === '') {
23
+ throw new TypeError("The first argument 'location' must be a non-empty string")
24
+ }
25
+
26
+ super({
27
+ encodings: {
28
+ buffer: true,
29
+ utf8: true
30
+ },
31
+ seek: true,
32
+ createIfMissing: true,
33
+ errorIfExists: true
34
+ }, options)
35
+
36
+ this[kLocation] = location
37
+ this[kContext] = binding.db_init()
38
+ }
39
+
40
+ get location () {
41
+ return this[kLocation]
42
+ }
43
+
44
+ _open (options, callback) {
45
+ if (options.createIfMissing) {
46
+ fs.mkdir(this[kLocation], { recursive: true }, (err) => {
47
+ if (err) return callback(err)
48
+ binding.db_open(this[kContext], this[kLocation], options, callback)
49
+ })
50
+ } else {
51
+ binding.db_open(this[kContext], this[kLocation], options, callback)
52
+ }
53
+ }
54
+
55
+ _close (callback) {
56
+ binding.db_close(this[kContext], callback)
57
+ }
58
+
59
+ _put (key, value, options, callback) {
60
+ binding.db_put(this[kContext], key, value, options, callback)
61
+ }
62
+
63
+ _get (key, options, callback) {
64
+ binding.db_get(this[kContext], key, options, callback)
65
+ }
66
+
67
+ _getMany (keys, options, callback) {
68
+ binding.db_get_many(this[kContext], keys, options, callback)
69
+ }
70
+
71
+ _del (key, options, callback) {
72
+ binding.db_del(this[kContext], key, options, callback)
73
+ }
74
+
75
+ _clear (options, callback) {
76
+ binding.db_clear(this[kContext], options, callback)
77
+ }
78
+
79
+ _chainedBatch () {
80
+ return new ChainedBatch(this, this[kContext])
81
+ }
82
+
83
+ _batch (operations, options, callback) {
84
+ binding.batch_do(this[kContext], operations, options, callback)
85
+ }
86
+
87
+ _iterator (options) {
88
+ return new Iterator(this, this[kContext], options)
89
+ }
90
+ }
91
+
92
+ exports.ClassicLevel = ClassicLevel
package/iterator.js CHANGED
@@ -1,19 +1,31 @@
1
1
  'use strict'
2
2
 
3
- const { AbstractIterator } = require('abstract-leveldown')
3
+ const { AbstractIterator } = require('abstract-level')
4
4
  const binding = require('./binding')
5
5
 
6
6
  const kContext = Symbol('context')
7
- const kFinalized = Symbol('finalized')
7
+ const kCache = Symbol('cache')
8
+ const kFinished = Symbol('finished')
9
+ const kFirst = Symbol('first')
10
+ const kPosition = Symbol('position')
11
+ const kHandleNext = Symbol('handleNext')
12
+ const kHandleNextv = Symbol('handleNextv')
13
+ const kCallback = Symbol('callback')
14
+ const empty = []
8
15
 
9
16
  class Iterator extends AbstractIterator {
10
- constructor (db, options) {
11
- super(db)
17
+ constructor (db, context, options) {
18
+ super(db, options)
12
19
 
13
- this[kContext] = binding.iterator_init(db.context, options)
14
- this[kFinalized] = false
20
+ this[kContext] = binding.iterator_init(context, options)
15
21
 
16
- this.cache = null
22
+ this[kHandleNext] = this[kHandleNext].bind(this)
23
+ this[kHandleNextv] = this[kHandleNextv].bind(this)
24
+ this[kCallback] = null
25
+ this[kFirst] = true
26
+ this[kCache] = empty
27
+ this[kFinished] = false
28
+ this[kPosition] = 0
17
29
  }
18
30
 
19
31
  _seek (target) {
@@ -21,35 +33,87 @@ class Iterator extends AbstractIterator {
21
33
  throw new Error('cannot seek() to an empty target')
22
34
  }
23
35
 
24
- this.cache = null
36
+ this[kFirst] = true
37
+ this[kCache] = empty
38
+ this[kFinished] = false
39
+ this[kPosition] = 0
40
+
25
41
  binding.iterator_seek(this[kContext], target)
26
- this[kFinalized] = false
27
42
  }
28
43
 
29
44
  _next (callback) {
30
- if (this.cache && this.cache.length) {
31
- process.nextTick(callback, null, this.cache.pop(), this.cache.pop())
32
- } else if (this[kFinalized]) {
45
+ if (this[kPosition] < this[kCache].length) {
46
+ const key = this[kCache][this[kPosition]++]
47
+ const val = this[kCache][this[kPosition]++]
48
+ process.nextTick(callback, null, key, val)
49
+ } else if (this[kFinished]) {
33
50
  process.nextTick(callback)
34
51
  } else {
35
- binding.iterator_nextv(this[kContext], 1000, (err, array, finished) => {
36
- if (err) {
37
- callback(err)
38
- } else {
39
- this.cache = array
40
- this[kFinalized] = finished
41
- this._next(callback)
42
- }
43
- })
52
+ this[kCallback] = callback
53
+
54
+ if (this[kFirst]) {
55
+ // It's common to only want one entry initially or after a seek()
56
+ this[kFirst] = false
57
+ binding.iterator_nextv(this[kContext], 1, this[kHandleNext])
58
+ } else {
59
+ // Limit the size of the cache to prevent starving the event loop
60
+ // while we're recursively calling process.nextTick().
61
+ binding.iterator_nextv(this[kContext], 1000, this[kHandleNext])
62
+ }
44
63
  }
45
64
 
46
65
  return this
47
66
  }
48
67
 
49
- _end (callback) {
50
- this.cache = null
68
+ [kHandleNext] (err, items, finished) {
69
+ const callback = this[kCallback]
70
+ if (err) return callback(err)
71
+
72
+ this[kCache] = items
73
+ this[kFinished] = finished
74
+ this[kPosition] = 0
75
+
76
+ this._next(callback)
77
+ }
78
+
79
+ _nextv (size, options, callback) {
80
+ if (this[kFinished]) {
81
+ process.nextTick(callback, null, [])
82
+ } else {
83
+ this[kCallback] = callback
84
+ this[kFirst] = false
85
+ binding.iterator_nextv(this[kContext], size, this[kHandleNextv])
86
+ }
87
+ }
88
+
89
+ [kHandleNextv] (err, items, finished) {
90
+ const callback = this[kCallback]
91
+ if (err) return callback(err)
92
+ this[kFinished] = finished
93
+
94
+ const entries = []
95
+ for (let n = 0; n < items.length; n += 2) {
96
+ entries.push([items[n + 0], items[n + 1]])
97
+ }
98
+
99
+ callback(null, entries)
100
+ }
101
+
102
+ _close (callback) {
103
+ this[kCache] = empty
104
+ this[kCallback] = null
105
+
51
106
  binding.iterator_close(this[kContext], callback)
52
107
  }
108
+
109
+ _end (callback) {
110
+ this._close(callback)
111
+ }
112
+
113
+ // Undocumented, exposed for tests only
114
+ get cached () {
115
+ return (this[kCache].length - this[kPosition]) / 2
116
+ }
53
117
  }
54
118
 
55
- module.exports = Iterator
119
+ exports.Iterator = Iterator
package/package.json CHANGED
@@ -1,32 +1,38 @@
1
1
  {
2
2
  "name": "@nxtedition/rocksdb",
3
- "version": "5.2.3",
3
+ "version": "5.2.10",
4
4
  "description": "A low-level Node.js RocksDB binding",
5
5
  "license": "MIT",
6
- "main": "leveldown.js",
6
+ "main": "index.js",
7
7
  "scripts": {
8
8
  "install": "node-gyp-build",
9
- "test": "npx standard && npx hallmark && (nyc -s tape test/*-test.js | faucet) && nyc report",
9
+ "test": "standard && (nyc -s tape test/*-test.js | faucet) && nyc report",
10
10
  "test-gc": "node --expose-gc test/gc.js",
11
11
  "test-electron": "electron test/electron.js",
12
12
  "test-prebuild": "cross-env PREBUILDS_ONLY=1 npm t",
13
13
  "coverage": "nyc report -r lcovonly",
14
14
  "rebuild": "npm run install --build-from-source",
15
15
  "prebuild": "prebuildify -t 8.14.0 --napi --strip",
16
+ "download-prebuilds": "prebuildify-ci download",
17
+ "hallmark": "hallmark --fix",
18
+ "dependency-check": "dependency-check --no-dev -i napi-macros . test/*.js",
19
+ "prepublishOnly": "npm run dependency-check",
20
+ "prebuild-linux-arm": "prebuildify-cross -i linux-armv6 -i linux-armv7 -i linux-arm64 -t 8.14.0 --napi --strip",
21
+ "prebuild-android-arm": "prebuildify-cross -i android-armv7 -i android-arm64 -t 8.14.0 --napi --strip",
16
22
  "prebuild-linux-x64": "prebuildify-cross -i centos7-devtoolset7 -i alpine -t 8.14.0 --napi --strip",
17
23
  "prebuild-darwin-x64+arm64": "prebuildify -t 8.14.0 --napi --strip --arch x64+arm64",
18
- "prebuild-win32-x64": "prebuildify -t 8.14.0 --napi --strip",
19
- "download-prebuilds": "prebuildify-ci download",
20
- "hallmark": "hallmark fix",
21
- "dependency-check": "npx dependency-check --no-dev -i napi-macros . test/*.js",
22
- "prepublishOnly": "npm run dependency-check"
24
+ "prebuild-win32-x86": "prebuildify -t 8.14.0 --napi --strip",
25
+ "prebuild-win32-x64": "prebuildify -t 8.14.0 --napi --strip"
23
26
  },
24
27
  "dependencies": {
25
- "abstract-leveldown": "^7.2.0",
26
- "napi-macros": "^2.0.0",
28
+ "abstract-level": "^1.0.2",
29
+ "module-error": "^1.0.1",
30
+ "napi-macros": "~2.0.0",
27
31
  "node-gyp-build": "^4.3.0"
28
32
  },
29
33
  "devDependencies": {
34
+ "@types/node": "^17.0.16",
35
+ "@voxpelli/tsconfig": "^3.1.0",
30
36
  "async-each": "^1.0.3",
31
37
  "cross-env": "^7.0.3",
32
38
  "delayed": "^2.0.0",
@@ -34,9 +40,8 @@
34
40
  "du": "^1.0.0",
35
41
  "electron": "^18.0.1",
36
42
  "faucet": "^0.0.1",
37
- "glob": "^8.0.1",
38
- "hallmark": "^4.0.0",
39
- "level-concat-iterator": "^3.0.0",
43
+ "glob": "^7.2.0",
44
+ "hallmark": "^4.1.0",
40
45
  "mkfiletree": "^2.0.0",
41
46
  "node-gyp": "^9.0.0",
42
47
  "nyc": "^15.0.0",
@@ -45,9 +50,9 @@
45
50
  "prebuildify-cross": "^5.0.0",
46
51
  "readfiletree": "^1.0.0",
47
52
  "rimraf": "^3.0.0",
48
- "standard": "^16.0.3",
49
- "tape": "^5.0.1",
50
- "tempy": "^3.0.0"
53
+ "standard": "^16.0.4",
54
+ "tape": "^5.5.0",
55
+ "tempy": "^1.0.1"
51
56
  },
52
57
  "standard": {
53
58
  "ignore": [
package/leveldown.js DELETED
@@ -1,113 +0,0 @@
1
- 'use strict'
2
-
3
- const util = require('util')
4
- const { AbstractLevelDOWN } = require('abstract-leveldown')
5
- const binding = require('./binding')
6
- const ChainedBatch = require('./chained-batch')
7
- const Iterator = require('./iterator')
8
-
9
- function LevelDOWN (location) {
10
- if (!(this instanceof LevelDOWN)) {
11
- return new LevelDOWN(location)
12
- }
13
-
14
- if (typeof location !== 'string') {
15
- throw new Error('constructor requires a location string argument')
16
- }
17
-
18
- AbstractLevelDOWN.call(this, {
19
- bufferKeys: true,
20
- snapshots: true,
21
- permanence: true,
22
- seek: true,
23
- clear: true,
24
- getMany: true,
25
- createIfMissing: true,
26
- errorIfExists: true
27
- })
28
-
29
- this.location = location
30
- this.context = binding.db_init()
31
- }
32
-
33
- util.inherits(LevelDOWN, AbstractLevelDOWN)
34
-
35
- LevelDOWN.prototype._open = function (options, callback) {
36
- binding.db_open(this.context, this.location, options, callback)
37
- }
38
-
39
- LevelDOWN.prototype._close = function (callback) {
40
- binding.db_close(this.context, callback)
41
- }
42
-
43
- LevelDOWN.prototype._serializeKey = function (key) {
44
- return Buffer.isBuffer(key) ? key : String(key)
45
- }
46
-
47
- LevelDOWN.prototype._serializeValue = function (value) {
48
- return Buffer.isBuffer(value) ? value : String(value)
49
- }
50
-
51
- LevelDOWN.prototype._put = function (key, value, options, callback) {
52
- const batch = new ChainedBatch(this)
53
- batch.put(key, value)
54
- batch.write(options, callback)
55
- }
56
-
57
- LevelDOWN.prototype._get = function (key, options, callback) {
58
- binding.db_get_many(this.context, [key], options, (err, val) => {
59
- if (err) {
60
- callback(err)
61
- } else if (!val[0]) {
62
- callback(new Error('NotFound'))
63
- } else {
64
- callback(null, val[0])
65
- }
66
- })
67
- }
68
-
69
- LevelDOWN.prototype._getMany = function (keys, options, callback) {
70
- binding.db_get_many(this.context, keys, options, callback)
71
- }
72
-
73
- LevelDOWN.prototype._del = function (key, options, callback) {
74
- const batch = new ChainedBatch(this)
75
- batch.del(key)
76
- batch.write(options, callback)
77
- }
78
-
79
- LevelDOWN.prototype._chainedBatch = function () {
80
- return new ChainedBatch(this)
81
- }
82
-
83
- LevelDOWN.prototype._batch = function (operations, options, callback) {
84
- let batch = null
85
- for (const op of operations) {
86
- if (op.type === 'del') {
87
- if (!('key' in op)) continue
88
- batch = batch || this.batch()
89
- batch.del(op.key)
90
- } else if (op.type === 'put') {
91
- if (!('key' in op)) continue
92
- if (!('value' in op)) continue
93
- batch = batch || this.batch()
94
- batch.put(op.key, op.value)
95
- }
96
- }
97
- if (batch) {
98
- batch.write(options, callback)
99
- } else {
100
- process.nextTick(callback)
101
- }
102
- }
103
-
104
- LevelDOWN.prototype._iterator = function (options) {
105
- if (this.status !== 'open') {
106
- // Prevent segfault
107
- throw new Error('cannot call iterator() before open()')
108
- }
109
-
110
- return new Iterator(this, options)
111
- }
112
-
113
- module.exports = LevelDOWN