From 40e028f182fcfb697663ffdb43bf67efa17efeba Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 24 Aug 2016 20:11:13 -0700 Subject: [PATCH] db: use string keys for browser. --- lib/chain/chaindb.js | 74 +-------------- lib/chain/layout-browser.js | 91 ++++++++++++++++++ lib/utils/utils.js | 60 +++++++++++- lib/wallet/layout-browser.js | 173 +++++++++++++++++++++++++++++++++++ lib/wallet/txdb.js | 58 +----------- lib/wallet/walletdb.js | 44 +-------- 6 files changed, 331 insertions(+), 169 deletions(-) create mode 100644 lib/chain/layout-browser.js create mode 100644 lib/wallet/layout-browser.js diff --git a/lib/chain/chaindb.js b/lib/chain/chaindb.js index 22c8e325..ef691e38 100644 --- a/lib/chain/chaindb.js +++ b/lib/chain/chaindb.js @@ -34,75 +34,6 @@ var BufferReader = require('../utils/reader'); * q[height] -> block hash to be pruned */ -/* String keys -var layout = { - R: 'R', - e: function e(hash) { - return 'e' + hash; - }, - h: function h(hash) { - return 'h' + hash; - }, - H: function H(height) { - return 'H' + pad32(height); - }, - n: function n(hash) { - return 'n' + hash; - }, - b: function b(hash) { - return 'b' + hash; - }, - t: function t(hash) { - return 't' + hash; - }, - c: function c(hash) { - return 'c' + hash; - }, - u: function u(hash) { - return 'u' + hash; - }, - q: function q(height) { - return 'q' + pad32(height); - }, - T: function T(address, hash) { - var len = address.length; - var key; - - if (address.length === 64) - return 'W' + address + hash; - - return 'T' + address + hash; - }, - C: function C(address, hash, index) { - var len = address.length; - var key; - - if (address.length === 64) - return 'X' + address + hash + pad32(index); - - return 'C' + address + hash + pad32(index); - }, - Cc: function Cc(key) { - var hash, index; - - if (key.length === 139) { - hash = key.slice(65, 129); - index = +key.slice(129); - } else { - hash = key.slice(41, 105).toString('hex'); - index = +key.slice(105); - } - - return [hash, index]; - }, - Tt: function Tt(key) { - return key.length === 129 - ? key.slice(64) - : key.slice(41); - } -}; -*/ - var layout = { R: new Buffer([0x52]), e: function e(hash) { @@ -196,6 +127,9 @@ var layout = { } }; +if (utils.isBrowser) + layout = require('./layout-browser'); + /** * The database backend for the {@link Chain} object. * @exports ChainDB @@ -237,7 +171,7 @@ function ChainDB(chain, options) { compression: true, cacheSize: 16 << 20, writeBufferSize: 8 << 20, - bufferKeys: true + bufferKeys: !utils.isBrowser }); this.keepBlocks = options.keepBlocks || 288; diff --git a/lib/chain/layout-browser.js b/lib/chain/layout-browser.js new file mode 100644 index 00000000..79fca248 --- /dev/null +++ b/lib/chain/layout-browser.js @@ -0,0 +1,91 @@ +/*! + * layout-browser.js - chaindb layout for browser. + * Copyright (c) 2014-2016, Christopher Jeffrey (MIT License). + * https://github.com/bcoin-org/bcoin + */ + +'use strict'; + +var utils = require('../utils/utils'); +var pad32 = utils.pad32; + +var layout = { + R: 'R', + e: function e(hash) { + return 'e' + hex(hash); + }, + h: function h(hash) { + return 'h' + hex(hash); + }, + H: function H(height) { + return 'H' + pad32(height); + }, + n: function n(hash) { + return 'n' + hex(hash); + }, + b: function b(hash) { + return 'b' + hex(hash); + }, + t: function t(hash) { + return 't' + hex(hash); + }, + c: function c(hash) { + return 'c' + hex(hash); + }, + u: function u(hash) { + return 'u' + hex(hash); + }, + q: function q(height) { + return 'q' + pad32(height); + }, + T: function T(address, hash) { + address = hex(address); + + if (address.length === 64) + return 'W' + address + hex(hash); + + return 'T' + address + hex(hash); + }, + C: function C(address, hash, index) { + address = hex(address); + + if (address.length === 64) + return 'X' + address + hex(hash) + pad32(index); + + return 'C' + address + hex(hash) + pad32(index); + }, + Cc: function Cc(key) { + var hash, index; + + if (key.length === 139) { + hash = key.slice(65, 129); + index = +key.slice(129); + } else { + hash = key.slice(41, 105); + index = +key.slice(105); + } + + return [hash, index]; + }, + Tt: function Tt(key) { + return key.length === 129 + ? key.slice(64) + : key.slice(41); + } +}; + +/* + * Helpers + */ + +function hex(hash) { + if (typeof hash !== 'string') + hash = hash.toString('hex'); + return hash; +} + +/* + * Expose + */ + +module.exports = layout; diff --git a/lib/utils/utils.js b/lib/utils/utils.js index fb1de747..41454f4b 100644 --- a/lib/utils/utils.js +++ b/lib/utils/utils.js @@ -2065,10 +2065,62 @@ utils.indexOf = function indexOf(obj, data) { utils.pad32 = function pad32(num) { assert(num >= 0); num = num + ''; - while (num.length < 10) - num = '0' + num; - assert(num.length === 10); - return num; + switch (num.length) { + case 1: + return '000000000' + num; + case 2: + return '00000000' + num; + case 3: + return '0000000' + num; + case 4: + return '000000' + num; + case 5: + return '00000' + num; + case 6: + return '0000' + num; + case 7: + return '000' + num; + case 8: + return '00' + num; + case 9: + return '0' + num; + case 10: + return num; + default: + assert(false); + } +}; + +/** + * Convert a number to a padded uint32 + * string (8 digits in hex). + * @param {Number} num + * @returns {String} Padded number. + */ + +utils.hex32 = function hex32(num) { + assert(num >= 0); + num = num.toString(16); + switch (num.length) { + case 1: + return '0000000' + num; + case 2: + return '000000' + num; + case 3: + return '00000' + num; + case 4: + return '0000' + num; + case 5: + return '000' + num; + case 6: + return '00' + num; + case 7: + return '0' + num; + case 8: + return num; + default: + assert(false); + } }; /** diff --git a/lib/wallet/layout-browser.js b/lib/wallet/layout-browser.js new file mode 100644 index 00000000..afb7ffd7 --- /dev/null +++ b/lib/wallet/layout-browser.js @@ -0,0 +1,173 @@ +/*! + * layout-browser.js - walletdb and txdb layout for browser. + * Copyright (c) 2014-2016, Christopher Jeffrey (MIT License). + * https://github.com/bcoin-org/bcoin + */ + +'use strict'; + +var utils = require('../utils/utils'); +var pad32 = utils.pad32; +var layout = exports; + +layout.walletdb = { + p: function(hash) { + return 'p' + hash; + }, + pp: function(key) { + return key.slice(1); + }, + w: function(wid) { + return 'w' + pad32(wid); + }, + ww: function(key) { + return +key.slice(1); + }, + l: function(id) { + return 'l' + id; + }, + ll: function(key) { + return key.slice(1); + }, + a: function a(wid, index) { + return 'a' + pad32(wid) + pad32(index); + }, + i: function i(wid, name) { + return 'i' + pad32(wid) + name; + }, + ii: function ii(key) { + return [+key.slice(1, 11), key.slice(11)]; + }, + R: 'R', + b: function b(hash) { + return 'b' + hash; + }, + e: function e(hash) { + return 'e' + hash; + } +}; + +layout.txdb = { + prefix: function prefix(wid, key) { + return 't' + pad32(wid) + key; + }, + hi: function hi(ch, hash, index) { + return ch + hash + pad32(index); + }, + hii: function hii(key) { + key = key.slice(12); + return [key.slice(0, 64), +key.slice(64)]; + }, + ih: function ih(ch, index, hash) { + return ch + pad32(index) + hash; + }, + ihh: function ihh(key) { + key = key.slice(12); + return [+key.slice(0, 10), key.slice(10)]; + }, + iih: function iih(ch, index, num, hash) { + return ch + pad32(index) + pad32(num) + hash; + }, + iihh: function iihh(key) { + key = key.slice(12); + return [+key.slice(0, 10), +key.slice(10, 20), key.slice(20)]; + }, + ihi: function ihi(ch, index, hash, num) { + return ch + pad32(index) + hash + pad32(num); + }, + ihii: function ihii(key) { + key = key.slice(12); + return [+key.slice(0, 10), key.slice(10, 74), +key.slice(74)]; + }, + ha: function ha(ch, hash) { + return ch + hash; + }, + haa: function haa(key) { + key = key.slice(12); + return key; + }, + t: function t(hash) { + return this.ha('t', hash); + }, + tt: function tt(key) { + return this.haa(key); + }, + c: function c(hash, index) { + return this.hi('c', hash, index); + }, + cc: function cc(key) { + return this.hii(key); + }, + d: function d(hash, index) { + return this.hi('d', hash, index); + }, + dd: function dd(key) { + return this.hii(key); + }, + s: function s(hash, index) { + return this.hi('s', hash, index); + }, + ss: function ss(key) { + return this.hii(key); + }, + o: function o(hash, index) { + return this.hi('o', hash, index); + }, + oo: function oo(key) { + return this.hii(key); + }, + p: function p(hash) { + return this.ha('p', hash); + }, + pp: function pp(key) { + return this.haa(key); + }, + m: function m(time, hash) { + return this.ih('m', time, hash); + }, + mm: function mm(key) { + return this.ihh(key); + }, + h: function h(height, hash) { + return this.ih('h', height, hash); + }, + hh: function hh(key) { + return this.ihh(key); + }, + T: function T(account, hash) { + return this.ih('T', account, hash); + }, + Tt: function Tt(key) { + return this.ihh(key); + }, + P: function P(account, hash) { + return this.ih('P', account, hash); + }, + Pp: function Pp(key) { + return this.ihh(key); + }, + M: function M(account, time, hash) { + return this.iih('M', account, time, hash); + }, + Mm: function Mm(key) { + return this.iihh(key); + }, + H: function H(account, height, hash) { + return this.iih('H', account, height, hash); + }, + Hh: function Hh(key) { + return this.iihh(key); + }, + C: function C(account, hash, index) { + return this.ihi('C', account, hash, index); + }, + Cc: function Cc(key) { + return this.ihii(key); + } +}; + +/* + * Expose + */ + +module.exports = layout; diff --git a/lib/wallet/txdb.js b/lib/wallet/txdb.js index f5f71d43..43da6fec 100644 --- a/lib/wallet/txdb.js +++ b/lib/wallet/txdb.js @@ -32,61 +32,6 @@ var BufferWriter = require('../utils/writer'); * C[account][hash][index] -> dummy (coin by account) */ -/* String Keys -var layout = { - prefix: function prefix(wid, key) { - return 't' + pad32(wid) + key; - }, - - hi: function hi(ch, hash, index) { - return this.prefix(ch + hash + pad32(index)); - }, - - hii: function hii(key) { - key = key.slice(12); - return [key.slice(0, 64), +key.slice(64)]; - }, - - ih: function ih(ch, index, hash) { - return this.prefix(ch + pad32(index) + hash); - }, - - ihh: function ihh(key) { - key = key.slice(12); - return [+key.slice(0, 10), key.slice(10)]; - }, - - iih: function iih(ch, index, num, hash) { - return this.prefix(ch + pad32(index) + pad32(num) + hash); - }, - - iihh: function iihh(key) { - key = key.slice(12); - return [+key.slice(0, 10), +key.slice(10, 20), key.slice(20)]; - }, - - ihi: function ihi(ch, index, hash, num) { - return this.prefix(ch + pad32(index) + hash + pad32(num)); - }, - - ihii: function ihii(key) { - key = key.slice(12); - return [+key.slice(0, 10), key.slice(10, 74), +key.slice(74)]; - }, - - ha: function ha(ch, hash) { - return this.prefix(ch + hash); - }, - - haa: function haa(key) { - key = key.slice(12); - return key; - }, - - ... -}; -*/ - var layout = { prefix: function prefix(wid, key) { var out = new Buffer(5 + key.length); @@ -238,6 +183,9 @@ var layout = { } }; +if (utils.isBrowser) + layout = require('./layout-browser').txdb; + /** * TXDB * @exports TXDB diff --git a/lib/wallet/walletdb.js b/lib/wallet/walletdb.js index a6377b67..e7d282eb 100644 --- a/lib/wallet/walletdb.js +++ b/lib/wallet/walletdb.js @@ -30,45 +30,6 @@ var MAX_POINT = String.fromCharCode(0xdbff, 0xdfff); // U+10FFFF * e[hash] -> tx->wid map */ -/* String Keys -var layout = { - p: function(hash) { - return 'p' + hash; - }, - pp: function(key) { - return key.slice(1); - }, - w: function(wid) { - return 'w' + pad32(wid); - }, - ww: function(key) { - return +key.slice(1); - }, - l: function(id) { - return 'l' + id; - }, - ll: function(key) { - return key.slice(1); - }, - a: function a(wid, index) { - return 'a' + pad32(wid) + pad32(index); - }, - i: function i(wid, name) { - return 'i' + pad32(wid) + name; - }, - ii: function ii(key) { - return [+key.slice(1, 11), key.slice(11)]; - }, - R: 'R', - b: function b(hash) { - return 'b' + hash; - }, - e: function e(hash) { - return 'e' + hash; - } -}; -*/ - var layout = { p: function(hash) { var key = new Buffer(1 + (hash.length / 2)); @@ -133,6 +94,9 @@ var layout = { } }; +if (utils.isBrowser) + layout = require('./layout-browser').walletdb; + /** * WalletDB * @exports WalletDB @@ -193,7 +157,7 @@ function WalletDB(options) { maxOpenFiles: this.options.maxFiles, cacheSize: 8 << 20, writeBufferSize: 4 << 20, - bufferKeys: true + bufferKeys: !utils.isBrowser }); if (bcoin.useWorkers)