|
1 | 1 | 'use strict'
|
2 | 2 |
|
3 |
| -const ModuleError = require('module-error') |
4 | 3 | const { Buffer } = require('buffer') || {}
|
5 | 4 | const {
|
6 | 5 | AbstractSublevelIterator,
|
@@ -38,18 +37,11 @@ module.exports = function ({ AbstractLevel }) {
|
38 | 37 | const { separator, manifest, ...forward } = AbstractSublevel.defaults(options)
|
39 | 38 | const names = [].concat(name).map(name => trim(name, separator))
|
40 | 39 |
|
41 |
| - // Reserve one character between separator and name to give us an upper bound |
| 40 | + // Reserve one character between separator and name to give us an upper bound, by |
| 41 | + // default '"'. Keys should sort like ['!a!', '!a!!a!', '!a"', '!aa!', '!b!'] |
42 | 42 | const reserved = separator.charCodeAt(0) + 1
|
43 | 43 | const root = db[kRoot] || db
|
44 | 44 |
|
45 |
| - // Keys should sort like ['!a!', '!a!!a!', '!a"', '!aa!', '!b!']. |
46 |
| - // Use ASCII for consistent length between string, Buffer and Uint8Array |
47 |
| - if (!names.every(name => textEncoder.encode(name).every(x => x > reserved && x < 127))) { |
48 |
| - throw new ModuleError(`Sublevel name must use bytes > ${reserved} < ${127}`, { |
49 |
| - code: 'LEVEL_INVALID_PREFIX' |
50 |
| - }) |
51 |
| - } |
52 |
| - |
53 | 45 | super(mergeManifests(db, manifest), forward)
|
54 | 46 |
|
55 | 47 | const localPrefix = names.map(name => separator + name + separator).join('')
|
@@ -179,14 +171,22 @@ module.exports = function ({ AbstractLevel }) {
|
179 | 171 | // TODO (refactor): move to AbstractLevel
|
180 | 172 | this.#prefixRange(options, options.keyEncoding)
|
181 | 173 | const iterator = this[kRoot].iterator(options)
|
182 |
| - const unfix = this.#unfix.get(this.#globalPrefix.utf8.length, options.keyEncoding) |
| 174 | + const unfix = this.#unfix.get( |
| 175 | + this.#globalPrefix.utf8.length, |
| 176 | + this.#globalPrefix.view.byteLength, |
| 177 | + options.keyEncoding |
| 178 | + ) |
183 | 179 | return new AbstractSublevelIterator(this, options, iterator, unfix)
|
184 | 180 | }
|
185 | 181 |
|
186 | 182 | _keys (options) {
|
187 | 183 | this.#prefixRange(options, options.keyEncoding)
|
188 | 184 | const iterator = this[kRoot].keys(options)
|
189 |
| - const unfix = this.#unfix.get(this.#globalPrefix.utf8.length, options.keyEncoding) |
| 185 | + const unfix = this.#unfix.get( |
| 186 | + this.#globalPrefix.utf8.length, |
| 187 | + this.#globalPrefix.view.byteLength, |
| 188 | + options.keyEncoding |
| 189 | + ) |
190 | 190 | return new AbstractSublevelKeyIterator(this, options, iterator, unfix)
|
191 | 191 | }
|
192 | 192 |
|
@@ -252,20 +252,24 @@ class Unfixer {
|
252 | 252 | this.cache = new Map()
|
253 | 253 | }
|
254 | 254 |
|
255 |
| - get (prefixLength, keyFormat) { |
| 255 | + get (stringLength, byteLength, keyFormat) { |
256 | 256 | let unfix = this.cache.get(keyFormat)
|
257 | 257 |
|
258 | 258 | if (unfix === undefined) {
|
259 | 259 | if (keyFormat === 'view') {
|
260 |
| - unfix = function (prefixLength, key) { |
| 260 | + unfix = function (byteLength, key) { |
261 | 261 | // Avoid Uint8Array#slice() because it copies
|
262 |
| - return key.subarray(prefixLength) |
263 |
| - }.bind(null, prefixLength) |
| 262 | + return key.subarray(byteLength) |
| 263 | + }.bind(null, byteLength) |
| 264 | + } else if (keyFormat === 'utf8') { |
| 265 | + unfix = function (stringLength, key) { |
| 266 | + return key.slice(stringLength) |
| 267 | + }.bind(null, stringLength) |
264 | 268 | } else {
|
265 |
| - unfix = function (prefixLength, key) { |
| 269 | + unfix = function (byteLength, key) { |
266 | 270 | // Avoid Buffer#subarray() because it's slow
|
267 |
| - return key.slice(prefixLength) |
268 |
| - }.bind(null, prefixLength) |
| 271 | + return key.slice(byteLength) |
| 272 | + }.bind(null, byteLength) |
269 | 273 | }
|
270 | 274 |
|
271 | 275 | this.cache.set(keyFormat, unfix)
|
|
0 commit comments