Skip to content

Instantly share code, notes, and snippets.

@ralphtheninja
Created December 29, 2012 02:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ralphtheninja/4404231 to your computer and use it in GitHub Desktop.
Save ralphtheninja/4404231 to your computer and use it in GitHub Desktop.
refactoring idea of lib/read-stream.js
/* Copyright (c) 2012 Rod Vagg <@rvagg> */
var Stream = require('stream').Stream
, BufferStream = require('bufferstream')
, toEncoding = require('./util').toEncoding
, toSlice = require('./util').toSlice
, extend = require('./util').extend
module.exports.create = function (options, db, iteratorFactory) {
var defaultOptions = { keys: true, values: true }
options = extend(extend({}, defaultOptions), options)
return new ReadStream(options, db, iteratorFactory)
function ReadStream (options, db, iteratorFactory) {
this.__proto__.__proto__ = Stream.prototype
Stream.call(this)
// use self so we can get data from this in local functions
var self = this
function someHelper() {
// code that can use self to reference this
}
if (typeof options.start != 'undefined')
options.start = toSlice[getKeyEncoding()](options.start)
if (typeof options.end != 'undefined')
options.end = toSlice[getKeyEncoding()](options.end)
if (typeof options.limit != 'number')
options.limit = -1
self._makeData = options.keys && options.values
? makeKeyValueData : options.keys
? makeKeyData : options.values
? makeValueData : makeNoData
}
// 1. these functions are only related to the options object, so we can lift
// out all methods accessing that state
// 2. much better to abstract into functions rather than caching values, V8 is very good at optimising
// function calls, Felix Geisendörfer talk about that in Dublin when he presented his work on mysql
// parser written in pure js
function getKeyEncoding () { return options.keyEncoding || options.encoding }
function getValueEncoding () { return options.valueEncoding || options.encoding }
function makeKeyValueData (key, value) {
return { key: toEncoding[getKeyEncoding()](key), value: toEncoding[getValueEncoding()](value) }
}
function makeKeyData (key) { return toEncoding[getKeyEncoding()](key) }
function makeValueData (key, value) { return toEncoding[getValueEncoding()](value) }
function makeNoData () { return null }
ReadStream.prototype = {
, pipe: function (dest) {
if (typeof dest.add == 'function' && isFStream()) {
this._dataEvent = 'entry'
this.on('entry', function (data) {
var entry = new BufferStream()
entry.path = data.key.toString()
entry.type = 'File'
entry.props = {
type: 'File'
, path: data.key.toString()
}
entry.once('data', process.nextTick.bind(null, entry.end.bind(entry)))
entry.pause()
if (dest.add(entry) === false) {
this.pause()
}
entry.write(data.value)
}.bind(this))
}
return Stream.prototype.pipe.apply(this, arguments)
}
}
// The isFStream() call is much clearer what it does than having to read the comparision
function isFStream () { return options.type == 'fstream' }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment