Comparing version 2.0.0 to 2.0.1
@@ -406,2 +406,20 @@ /** | ||
/** | ||
* Get the Pnodes in the hash. | ||
* | ||
* @param {function} callback The optional callback of f(err, pnodes[]) | ||
* @return {Array} pnodes The pnodes in the hash. | ||
*/ | ||
ConsistentHash.prototype.getPnodes = function getPnodes(cb) { | ||
var self = this; | ||
var log = self.log; | ||
assert.optionalFunc(cb, 'callback'); | ||
log.info('ConsistentHash.getPnodes: entering'); | ||
if (cb) { | ||
cb(null, self.pnodes_); | ||
} | ||
return self.pnodes_; | ||
}; | ||
/** | ||
* Get the array of vnodes that belong to a particular pnode | ||
@@ -408,0 +426,0 @@ * |
@@ -23,2 +23,3 @@ /** | ||
var LKEY_VNODE_V = '/VNODE/%d'; | ||
var LKEY_PNODE = '/PNODE'; | ||
var LKEY_PNODE_P = '/PNODE/%s'; | ||
@@ -90,3 +91,4 @@ var LKEY_PNODE_P_V = '/PNODE/%s/%d'; | ||
* 4) create /PNODE/<PNODE> keys for all pnodes. The value is the set of | ||
* all vnodes that belong to this pnode. | ||
* all vnodes that belong to this pnode. create /PNODE key which is an | ||
* array of all the pnodes. | ||
* 5) create algorithm key which contains the algorithm. | ||
@@ -210,2 +212,3 @@ * 6) create version key which contains the version. | ||
} | ||
_.bach = _.batch.put(LKEY_PNODE, Object.keys(pnodeMap)); | ||
return _cb(); | ||
@@ -227,3 +230,9 @@ }, | ||
function commit(_, _cb) { | ||
_.batch.write(_cb); | ||
_.batch.write(function(err) { | ||
if (err) { | ||
err = new verror.VError(err); | ||
} | ||
return _cb(err); | ||
}); | ||
} | ||
@@ -280,4 +289,6 @@ ]; | ||
var pvMap = topology.pnodeToVnodeMap; | ||
// /vnode/n, /pnode/pnode, /p/p/v | ||
// /PNODE | ||
var pnodes = Object.keys(pvMap); | ||
_.batch = _.batch.put(LKEY_PNODE, pnodes); | ||
// /VNODE/V, /PNODE/P, /P/P/V | ||
var pcount = pnodes.length; | ||
@@ -287,3 +298,3 @@ pnodes.forEach(function(pnode) { | ||
var vcount = vnodes.length; | ||
// write /p/p and /v/v. and /p/p/v | ||
// write /P/P and /V/V. and /P/P/V | ||
vnodes.forEach(function(vnode, index) { | ||
@@ -293,6 +304,6 @@ // json serializes vnode into a string, we need to | ||
vnodes[index] = parseInt(vnode, 10); | ||
// write /v/v | ||
// write /V/V | ||
_.batch = _.batch.put(sprintf(LKEY_VNODE_V, vnode), | ||
pnode); | ||
// write /p/p/v | ||
// write /P/P/V | ||
_.batch = _.batch.put( | ||
@@ -302,3 +313,3 @@ sprintf(LKEY_PNODE_P_V, pnode, vnode), | ||
); | ||
// write /p/p once all the vnodes have been parsed back | ||
// write /P/P once all the vnodes have been parsed back | ||
// into ints. | ||
@@ -642,2 +653,16 @@ vcount--; | ||
}, | ||
function addPnodeToPnodeArray(_, _cb) { | ||
db.get(LKEY_PNODE, function(err, pnodes) { | ||
if (err) { | ||
return _cb(new verror.VError(err)); | ||
} | ||
// add the new pnode to the pnode array if it doesn't exist. | ||
if (pnodes.indexOf(newPnode) === -1) { | ||
pnodes.push(newPnode); | ||
_.batch = _.batch.put(LKEY_PNODE, pnodes); | ||
} | ||
return _cb(); | ||
}); | ||
}, | ||
function commit(_, _cb) { | ||
@@ -687,2 +712,24 @@ _.batch.write(function(err) { | ||
/** | ||
* Get the map of pnodes that's in this hash. | ||
* | ||
* @param {function} cb The callback f(err, map). | ||
*/ | ||
ConsistentHash.prototype.getPnodes = function getPnodes(cb) { | ||
var self = this; | ||
var log = self.log; | ||
var db = self.db_; | ||
log.info('ConsistentHash.getPnodes: entering'); | ||
assert.func(cb, 'callback'); | ||
db.get(LKEY_PNODE, function(err, pnodes) { | ||
if (err) { | ||
err = new verror.VError(err, 'unable to get Pnodes'); | ||
} | ||
return cb(err, pnodes); | ||
}); | ||
}; | ||
/** | ||
* Removes a pnode from the hash ring. Note the pnode must not map to any | ||
@@ -727,11 +774,26 @@ * vnodes. Remove the vnodes first by re-assigning them to other pnodes before | ||
// remove /pnode/%s | ||
db.del(sprintf(LKEY_PNODE_P, pnode), function(err) { | ||
var batch = db.batch().del(sprintf(LKEY_PNODE_P, pnode)); | ||
// get the pnode array | ||
db.get(LKEY_PNODE, function(err, pnodes) { | ||
if (err) { | ||
err = new verror.VError(err, 'unable to remove pnode'); | ||
return _cb(new verror.VError(err)); | ||
} | ||
log.info({ | ||
err: err, | ||
pnode: pnode | ||
}, 'ConsistentHash.removePnode: exiting'); | ||
return _cb(err); | ||
// remove the pnode to the pnode array if it doesn't exist. | ||
var pnodeIndex = pnodes.indexOf(pnode); | ||
if (pnodeIndex === -1) { | ||
return _cb(new verror.VError('pnode does not exist')); | ||
} | ||
pnodes.splice(pnodeIndex, 1); | ||
batch.put(LKEY_PNODE, pnodes).write(function(_err) { | ||
if (_err) { | ||
_err = new verror.VError(_err); | ||
} | ||
log.info({ | ||
err: _err, | ||
pnode: pnode | ||
}, 'ConsistentHash.removePnode: exiting'); | ||
return _cb(_err); | ||
}); | ||
return (undefined); | ||
}); | ||
@@ -738,0 +800,0 @@ } |
@@ -18,3 +18,3 @@ { | ||
], | ||
"version": "2.0.0", | ||
"version": "2.0.1", | ||
"repository": { | ||
@@ -21,0 +21,0 @@ "type": "git", |
@@ -153,3 +153,3 @@ var bignum = require('bignum'); | ||
chash.removePnode(PNODES[0], function(ring, pnodes) { | ||
t.ok(chash.pnodes_.indexOf(PNODES[0]) === -1, | ||
t.ok(chash.getPnodes().indexOf(PNODES[0]) === -1, | ||
'A should not exist in pnode array'); | ||
@@ -156,0 +156,0 @@ t.ok(!chash.pnodeToVnodeMap_[PNODES[0]], |
@@ -21,2 +21,3 @@ var bignum = require('bignum'); | ||
}); | ||
var TEST_ITERATIONS = process.env.TEST_ITERATIONS || 1; | ||
var FASH_CLI_PATH = process.env.FASH_CLI_PATH || './bin/fash.js'; | ||
@@ -166,2 +167,11 @@ var NUMBER_OF_KEYS = parseInt(process.env.NUMBER_OF_KEYS || 1000, 10); | ||
_testAllConstructors(function removePnode(algo, constructor, t) { | ||
var rmPnodeIdx = ((PNODES.length - 1) * Math.random()).toFixed(); | ||
var rmPnode = PNODES[rmPnodeIdx]; | ||
var remapIdx; | ||
if (rmPnodeIdx == 0) { | ||
remapIdx = 1; | ||
} else { | ||
remapIdx = rmPnodeIdx - 1; | ||
} | ||
var remapPnode = PNODES[remapIdx]; | ||
vasync.pipeline({funcs: [ | ||
@@ -176,3 +186,3 @@ function newRing(_, cb) { | ||
function getVnodes(_, cb) { | ||
_.hLevel.getVnodes(PNODES[0], function(err, vnodes) { | ||
_.hLevel.getVnodes(rmPnode, function(err, vnodes) { | ||
_.vnodes = vnodes; | ||
@@ -183,6 +193,6 @@ return cb(err); | ||
function remap(_, cb) { | ||
_.hInMem.remapVnode(PNODES[1], _.vnodes); | ||
_.hInMem.remapVnode(remapPnode, _.vnodes); | ||
var count = 0; | ||
// remap to the second pnode | ||
_.hLevel.remapVnode(PNODES[1], _.vnodes[count++], remapCb); | ||
_.hLevel.remapVnode(remapPnode, _.vnodes[count++], remapCb); | ||
@@ -197,11 +207,11 @@ // ensure serial invocations of remap | ||
} | ||
_.hLevel.remapVnode(PNODES[1], _.vnodes[count++], remapCb); | ||
_.hLevel.remapVnode(remapPnode, _.vnodes[count++], remapCb); | ||
}; | ||
}, | ||
function assertVnodes(_, cb) { | ||
_.hLevel.getVnodes(PNODES[1], function(err, vnodes) { | ||
_.hLevel.getVnodes(remapPnode, function(err, vnodes) { | ||
if (err) { | ||
return cb(err); | ||
} | ||
var inMemVnodes = _.hInMem.getVnodes(PNODES[1]); | ||
var inMemVnodes = _.hInMem.getVnodes(remapPnode); | ||
t.ok(lodash.isEqual(vnodes.sort(), inMemVnodes.sort()), | ||
@@ -213,7 +223,7 @@ 'level vnodes should equal in mem vnodes'); | ||
function removePnode(_, cb) { | ||
_.hLevel.removePnode(PNODES[0], function(err) { | ||
_.hLevel.removePnode(rmPnode, function(err) { | ||
if (err) { | ||
return cb(err); | ||
} | ||
_.hInMem.removePnode(PNODES[0]); | ||
_.hInMem.removePnode(rmPnode); | ||
return cb(); | ||
@@ -227,3 +237,3 @@ }); | ||
function removePnodeAgain(_, cb) { | ||
_.hLevel.removePnode(PNODES[0], function(err) { | ||
_.hLevel.removePnode(rmPnode, function(err) { | ||
if (!err) { | ||
@@ -235,2 +245,16 @@ return cb(new Error('removing pnode again should throw')); | ||
}); | ||
}, | ||
function checkPnodes(_, cb) { | ||
_.hLevel.getPnodes(function(err, pnodes) { | ||
if (err) { | ||
return cb(err); | ||
} | ||
if (pnodes.indexOf(rmPnode) !== -1) { | ||
return cb( | ||
new Error('removed pnode still exists pnode array')); | ||
} | ||
return cb(); | ||
}); | ||
} | ||
@@ -844,6 +868,3 @@ ], arg: {}}, function(err) { | ||
], arg: {}}, function(err) { | ||
if (err) { | ||
t.fail(err); | ||
} | ||
t.done(); | ||
return cb(err); | ||
}); | ||
@@ -868,3 +889,3 @@ } | ||
src: true, | ||
level: 'fatal' | ||
level: process.env.LOG_LEVEL_MEM || 'fatal' | ||
}), | ||
@@ -961,15 +982,20 @@ algorithm: algo, | ||
function _testAllAlgorithms(test) { | ||
ALGORITHM.forEach(function(algo) { | ||
exports[test.name + algo] = test.bind(null, algo); | ||
}); | ||
for (var i = 0; i < TEST_ITERATIONS; i++) { | ||
ALGORITHM.forEach(function(algo) { | ||
exports[test.name + algo + i] = test.bind(null, algo); | ||
}); | ||
} | ||
} | ||
function _testAllConstructors(test) { | ||
ALGORITHM.forEach(function(algo) { | ||
exports[test.name + algo + 'new'] = test.bind(null, algo, _newRing); | ||
exports[test.name + algo + 'fromDb'] = | ||
test.bind(null, algo, _newRingFromDb); | ||
exports[test.name + algo + 'fromTopology'] = | ||
test.bind(null, algo, _newRingFromTopology); | ||
}); | ||
for (var i = 0; i < TEST_ITERATIONS; i++) { | ||
ALGORITHM.forEach(function(algo) { | ||
exports[test.name + algo + 'new' + i] = | ||
test.bind(null, algo, _newRing); | ||
exports[test.name + algo + 'fromDb' + i] = | ||
test.bind(null, algo, _newRingFromDb); | ||
exports[test.name + algo + 'fromTopology' + i] = | ||
test.bind(null, algo, _newRingFromTopology); | ||
}); | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
4397163
187
3760
1
18