Skip to content

Instantly share code, notes, and snippets.

@AldoMX
Created November 11, 2018 12:52
Show Gist options
  • Save AldoMX/c1f18730fbfab6067d8e21e9e5b00575 to your computer and use it in GitHub Desktop.
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
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