Dump Buffer for TypedArrays (for compactness and efficiency)
SilentCicero opened this issue · 6 comments
Hi all,
Coming from the browser focused world, I see many of the Level libraries don't really use a ton of Buffer facility, and considering Buffer's can be easily fitted (and are just a view to) typed arrays, why not just dump the massive Buffer library altogether.
This would make Level a much leaner construction for browser based or p2p apps like mine, and may even make processing at a micro level faster.
Thoughts?
Some nuance: buffer is 147 bytes minified and gzipped. Calling it "massive" isn't fair, especially considering the interoperability that it enables. That said, I understand the need to shave off bytes wherever possible.
Unfortunately, the level ecosystem does use buffer heavily. The dozens of modules probably only use a small part of buffer's API, that's true, but switching to typed arrays (or restricting ourselves to UInt8Array's API) is nevertheless a huge breaking change and a huge effort.
I'd like to keep this open as a reminder. And to allow folks to chime in; I don't want to give the signal "it's never gonna happen".
I'm not even sure you'd save anything in the long run - Buffer gives extensive encoder support - that would have to be moved in level* if its not on the Buffer.
If its something you're passionate about, I'd recommend forking abstract-leveldown and try passing a Buffer prototype through to its constructor, which would be used in-place of require'ing the existing Buffer ponyfill. doing it this way is the least painful approach I can think of - but give the user the option to pass a custom cut-down prototype explicit for their needs and stack.
I'm more concerned with multiple Buffer ponyfills more than anything - I'm pretty sure current build (webpack) is bundling another Buffer polyfill. Also better support for Uint8Array would be nice: in my custom encoder I have to wrap a Uint8Array in a Buffer else its re-encoded, for some reason.
I'm not even sure you'd save anything in the long run - Buffer gives extensive encoder support - that would have to be moved in level* if its not on the Buffer.
The answer for that is to not use level
, which is a convenience module that is unlikely to drop buffer. Folks that don't want buffer should instead do something like:
const compose = require('level-compose')
const factory = compose(leveldown, levelup)
const db = factory('./db')
Which is to say, those folks won't get encodings, unless we write an alternative to encoding-down
(see below). Down the line, once abstract-leveldown
reaches feature parity with levelup
, folks can use leveldown
(or other) directly.
WIP list of tasks to make buffer optional (feel free to edit):
- Replace
Buffer.isBuffer
withis-buffer
(Level/abstract-leveldown@8f79234) - Determine what to do with
asBuffer
/keyAsBuffer
/valueAsBuffer
- Add
db.supports.buffer
(level-supports
) and use that in abstract tests - Write a new module that, like
level
, exports eitherleveldown
orlevel-js
depending on environment. To get the same convenience aslevel
but without buffer. - Write a new module similar to
encoding-down
but with bring-your-own codecs - Determine what to do in
memdown
, or write an alternative that is backed by typed arrays - Determine what to do in
level-js
, oh boy
Covered by #102 and https://github.com/Level/transcoder. It will be possible to use either Uint8Array, Buffer, or both, and to exclude the buffer
shim from browser bundles if you choose to use Uint8Array.