Created
November 11, 2018 12:52
-
-
Save AldoMX/c1f18730fbfab6067d8e21e9e5b00575 to your computer and use it in GitHub Desktop.
ES2018 wrapper for `rocksdb`, works without Babel with Node.js v10 and upwards
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const rocksdb = require('rocksdb'); | |
const valueCallback = resolve => (err, value) => err ? Promise.reject(err) : resolve(value); | |
class RocksDBIterator { | |
constructor(iterator) { | |
this.iterator = iterator; | |
} | |
async end() { | |
return await new Promise( | |
resolve => this.iterator.end(valueCallback(resolve)) | |
); | |
} | |
async next() { | |
return await new Promise( | |
resolve => this.iterator.next((err, key, value) => { | |
if (err) { | |
throw err; | |
} | |
if (typeof key !== 'undefined' || typeof value !== 'undefined') { | |
resolve({ value: [key, value], done: false }); | |
} | |
else { | |
resolve({ done: true }); | |
} | |
}) | |
); | |
} | |
seek(key) { | |
return this.iterator.seek(key); | |
} | |
[Symbol.asyncIterator]() { | |
return { | |
next: this.next.bind(this), | |
}; | |
} | |
} | |
class RocksDB { | |
/** | |
* @param {string} location | |
*/ | |
constructor(location) { | |
this.db = rocksdb(location); | |
} | |
/** | |
* @returns {Object} | |
*/ | |
static get defaultOpenOptions() { | |
return { | |
createIfMissing: true, | |
errorIfExists: false, | |
compression: true, | |
cacheSize: 8 * 1024 * 1024, | |
writeBufferSize: 4 * 1024 * 1024, | |
blockSize: 4 * 1024, | |
maxOpenFiles: 1000, | |
blockRestartInterval: 16, | |
maxFileSize: 2 * 1024 * 1024, | |
}; | |
} | |
/** | |
* @param {Object} options | |
*/ | |
async open(options = {}) { | |
const opts = { ...this.constructor.defaultOpenOptions, ...options }; | |
return await new Promise( | |
resolve => this.db.open(opts, valueCallback(resolve)) | |
); | |
} | |
async close() { | |
return await new Promise( | |
resolve => this.db.close(valueCallback(resolve)) | |
); | |
} | |
/** | |
* @returns {Object} | |
*/ | |
static get defaultPutOptions() { | |
return { | |
sync: false, | |
}; | |
} | |
/** | |
* @param {string|Buffer} key | |
* @param {string|Buffer} value | |
* @param {Object} options | |
*/ | |
async put(key, value, options = {}) { | |
const opts = { ...this.constructor.defaultPutOptions, ...options }; | |
return await new Promise( | |
resolve => this.db.put(key, value, opts, valueCallback(resolve)) | |
); | |
} | |
/** | |
* @returns {Object} | |
*/ | |
static get defaultGetOptions() { | |
return { | |
fillCache: true, | |
asBuffer: true, | |
}; | |
} | |
/** | |
* @param {string|Buffer} key | |
* @param {Object} options | |
* @returns {string|Buffer} | |
*/ | |
async get(key, options = {}) { | |
const opts = { ...this.constructor.defaultGetOptions, ...options }; | |
return await new Promise( | |
resolve => this.db.get(key, opts, valueCallback(resolve)) | |
); | |
} | |
/** | |
* @returns {Object} | |
*/ | |
static get defaultDelOptions() { | |
return { | |
sync: false, | |
}; | |
} | |
/** | |
* @param {string|Buffer} key | |
* @param {Object} options | |
*/ | |
async del(key, options = {}) { | |
const opts = { ...this.constructor.defaultDelOptions, ...options }; | |
return await new Promise( | |
resolve => this.db.del(key, opts, valueCallback(resolve)) | |
); | |
} | |
/** | |
* @typedef RocksDBBatchOperation | |
* @param {string} type | |
* @param {string|Buffer} key | |
* @param {string|Buffer|undefined} value | |
*/ | |
/** | |
* @returns {Object} | |
*/ | |
static get defaultBatchOptions() { | |
return { | |
sync: false, | |
}; | |
} | |
/** | |
* @param {RocksDBBatchOperation[]} operations | |
* @param {Object} options | |
*/ | |
async batch(operations, options = {}) { | |
const opts = { ...this.constructor.defaultBatchOptions, ...options }; | |
return await new Promise( | |
resolve => this.db.batch(operations, opts, valueCallback(resolve)) | |
); | |
} | |
/** | |
* @param {string|Buffer} start | |
* @param {string|Buffer} end | |
* @returns {Number} | |
*/ | |
async approximateSize(start, end) { | |
return await new Promise( | |
resolve => this.db.approximateSize(start, end, valueCallback(resolve)) | |
); | |
} | |
/** | |
* @param {string|Buffer} start | |
* @param {string|Buffer} end | |
*/ | |
async compactRange(start, end) { | |
return await new Promise( | |
resolve => this.db.compactRange(start, end, valueCallback(resolve)) | |
); | |
} | |
getProperty(property) { | |
return this.db.getProperty(property); | |
} | |
static get defaultIteratorOptions() { | |
return { | |
reverse: false, | |
keys: true, | |
values: true, | |
limit: -1, | |
fillCache: false, | |
keyAsBuffer: true, | |
valueAsBuffer: true, | |
}; | |
} | |
/** | |
* @param {Object} options | |
* @returns {RocksDBIterator} | |
*/ | |
iterator(options = {}) { | |
const iteratorOptions = { ...this.constructor.defaultIteratorOptions, ...options }; | |
const iterator = this.db.iterator(iteratorOptions); | |
return new RocksDBIterator(iterator); | |
} | |
/** | |
* @param {string} location | |
*/ | |
static async destroy(location) { | |
return await new Promise( | |
resolve => rocksdb.destroy(location, valueCallback(resolve)) | |
); | |
} | |
/** | |
* @param {string} location | |
*/ | |
static async repair(location) { | |
return await new Promise( | |
resolve => rocksdb.repair(location, valueCallback(resolve)) | |
); | |
} | |
} | |
RocksDB.RocksDBIterator = RocksDBIterator; | |
module.exports = RocksDB; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment