pax_global_header00006660000000000000000000000064143302234240014507gustar00rootroot0000000000000052 comment=992ae4c2599dd8ff985930df1013af4ab94fe7e1 cluster-key-slot-1.1.2/000077500000000000000000000000001433022342400147365ustar00rootroot00000000000000cluster-key-slot-1.1.2/.editorconfig000066400000000000000000000002341433022342400174120ustar00rootroot00000000000000# http://editorconfig.org root = true [*] indent_style = space indent_size = 2 charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true cluster-key-slot-1.1.2/.eslintrc000066400000000000000000000004241433022342400165620ustar00rootroot00000000000000{ "extends": "airbnb-base/legacy", "parserOptions":{ "ecmaFeatures": { "experimentalObjectRestSpread": true } }, "rules": { "max-len": 0, "no-plusplus": 0, "no-bitwise": 0, "no-param-reassign": 0, "no-undef": 0 }, "globals": {} } cluster-key-slot-1.1.2/.gitignore000066400000000000000000000000471433022342400167270ustar00rootroot00000000000000logs *.log coverage node_modules .idea cluster-key-slot-1.1.2/.npmignore000066400000000000000000000002261433022342400167350ustar00rootroot00000000000000# IntelliJ project files .idea *.iml out gen # Irrelevant files and folders .editorconfig .travis.yml benchmark coverage test .travis.yml .gitignore cluster-key-slot-1.1.2/.travis.yml000066400000000000000000000003341433022342400170470ustar00rootroot00000000000000language: node_js sudo: false env: - CXX=g++-4.8 addons: apt: sources: - ubuntu-toolchain-r-test packages: - g++-4.8 node_js: - "4" - "6" - "7" - "8" - "9" - "10" install: - npm install cluster-key-slot-1.1.2/LICENSE000066400000000000000000000011231433022342400157400ustar00rootroot00000000000000Copyright (c) 2018 Mike Diarmid (Salakar) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this library except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. cluster-key-slot-1.1.2/README.md000066400000000000000000000052311433022342400162160ustar00rootroot00000000000000[![Coverage Status](https://coveralls.io/repos/github/Salakar/cluster-key-slot/badge.svg?branch=master)](https://coveralls.io/github/Salakar/cluster-key-slot?branch=master) ![Downloads](https://img.shields.io/npm/dt/cluster-key-slot.svg) [![npm version](https://img.shields.io/npm/v/cluster-key-slot.svg)](https://www.npmjs.com/package/cluster-key-slot) [![dependencies](https://img.shields.io/david/Salakar/cluster-key-slot.svg)](https://david-dm.org/Salakar/cluster-key-slot) [![License](https://img.shields.io/npm/l/cluster-key-slot.svg)](/LICENSE) Follow on Twitter # Redis Key Slot Calculator A high performance redis cluster key slot calculator for node redis clients e.g. [node_redis](https://github.com/NodeRedis/node_redis), [ioredis](https://github.com/luin/ioredis) and [redis-clustr](https://github.com/gosquared/redis-clustr/). This also handles key tags such as `somekey{actualTag}`. ## Install Install with [NPM](https://npmjs.org/): ``` npm install cluster-key-slot --save ``` ## Usage ```js const calculateSlot = require('cluster-key-slot'); const calculateMultipleSlots = require('cluster-key-slot').generateMulti; // ... // a single slot number const slot = calculateSlot('test:key:{butOnlyThis}redis'); // Buffer is also supported const anotherSlot = calculateSlot(Buffer.from([0x7b, 0x7d, 0x2a])); // multiple keys - multi returns a single key slot number, returns -1 if any // of the keys does not match the base slot number (base is defaulted to first keys slot) // This is useful to quickly determine a singe slot for multi keys operations. const slotForRedisMulti = calculateMultipleSlots([ 'test:key:{butOnlyThis}redis', 'something:key45:{butOnlyThis}hello', 'example:key46:{butOnlyThis}foobar', ]); ``` ## Benchmarks `OLD` in these benchmarks refers to the `ioredis` crc calc and many of the other calculators that use `Buffer`. ```text node -v  ✔  16.38G RAM  10:29:07 v10.15.3 NEW tags x 721,445 ops/sec ±0.44% (90 runs sampled) OLD tags x 566,777 ops/sec ±0.97% (96 runs sampled) NEW without tags x 2,054,845 ops/sec ±1.77% (92 runs sampled) OLD without tags x 865,839 ops/sec ±0.43% (96 runs sampled) NEW without tags singular x 6,354,097 ops/sec ±1.25% (94 runs sampled) OLD without tags singular x 4,012,250 ops/sec ±0.96% (94 runs sampled) NEW tags (Buffer) x 552,346 ops/sec ±1.35% (92 runs sampled) ``` cluster-key-slot-1.1.2/benchmark/000077500000000000000000000000001433022342400166705ustar00rootroot00000000000000cluster-key-slot-1.1.2/benchmark/index.js000066400000000000000000000025701433022342400203410ustar00rootroot00000000000000var Benchmark = require('benchmark'); var suite = new Benchmark.Suite(); var oldGenerate = require('./old'); var newGenerate = require('../lib'); var elems = ['123465', 'foobar', 'abcdefghijklmnopqrstuvwxyz', 'gsdfhan$%^&*(sdgsdnhshcs', 'foobar{foobar']; /* eslint func-names: 0 */ // add listeners suite.add('NEW tags', function () { var i = 0; for (; i < elems.length; i++) { newGenerate('abc{' + elems[i] + '}}{yeahh}'); } }); suite.add('OLD tags', function () { var i = 0; for (; i < elems.length; i++) { oldGenerate('abc{' + elems[i] + '}}{yeahh}'); } }); suite.add('NEW without tags', function () { var i = 0; for (; i < elems.length; i++) { newGenerate(elems[i]); } }); suite.add('OLD without tags', function () { var i = 0; for (; i < elems.length; i++) { oldGenerate(elems[i]); } }); suite.add('NEW without tags singular', function () { newGenerate(elems[2]); }); suite.add('OLD without tags singular', function () { oldGenerate(elems[2]); }); suite.add('NEW tags (Buffer)', function () { var i = 0; for (; i < elems.length; i++) { newGenerate(Buffer.from('abc{' + elems[i] + '}}{yeahh}')); } }); suite.on('cycle', function (event) { console.log(String(event.target)); }); suite.on('complete', function () { console.log('\n\nFastest is ' + this.filter('fastest').map('name')); }); suite.run({ delay: 1, minSamples: 150 }); cluster-key-slot-1.1.2/benchmark/old/000077500000000000000000000000001433022342400174465ustar00rootroot00000000000000cluster-key-slot-1.1.2/benchmark/old/index.js000066400000000000000000000114111433022342400211110ustar00rootroot00000000000000/* * Copyright 2001-2010 Georges Menie (www.menie.org) * Copyright 2010 Salvatore Sanfilippo (adapted to Redis coding style) * Copyright 2015 Zihua Li (http://zihua.li) (ported to JavaScript) * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the University of California, Berkeley nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* CRC16 implementation according to CCITT standards. * * Note by @antirez: this is actually the XMODEM CRC 16 algorithm, using the * following parameters: * * Name : "XMODEM", also known as "ZMODEM", "CRC-16/ACORN" * Width : 16 bit * Poly : 1021 (That is actually x^16 + x^12 + x^5 + 1) * Initialization : 0000 * Reflect Input byte : False * Reflect Output CRC : False * Xor constant to output CRC : 0000 * Output for "123456789" : 31C3 */ var crc16tab = [ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 ]; function crc16(str) { var buf = new Buffer(str); var crc = 0; for (var i = 0, len = buf.length; i < len; i++) { crc = (crc << 8) ^ crc16tab[((crc >> 8) ^ buf[i]) & 0x00ff]; } return crc; } function calcSlot(key) { var s = key.indexOf('{'); if (s !== -1) { var e = key.indexOf('}', s + 2); if (e !== -1) { key = key.slice(s + 1, e); } } return crc16(key) & 16383; } module.exports = calcSlot; cluster-key-slot-1.1.2/index.d.ts000066400000000000000000000006151433022342400166410ustar00rootroot00000000000000declare module 'cluster-key-slot' { // Convert a string or Buffer into a redis slot hash. function calculate(value: string | Buffer): number; // Convert an array of multiple strings or Buffers into a redis slot hash. // Returns -1 if one of the keys is not for the same slot as the others export function generateMulti(values: Array): number; export = calculate; }cluster-key-slot-1.1.2/lib/000077500000000000000000000000001433022342400155045ustar00rootroot00000000000000cluster-key-slot-1.1.2/lib/index.js000066400000000000000000000147721433022342400171640ustar00rootroot00000000000000/* * Copyright 2001-2010 Georges Menie (www.menie.org) * Copyright 2010 Salvatore Sanfilippo (adapted to Redis coding style) * Copyright 2015 Zihua Li (http://zihua.li) (ported to JavaScript) * Copyright 2016 Mike Diarmid (http://github.com/salakar) (re-write for performance, ~700% perf inc) * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the University of California, Berkeley nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* CRC16 implementation according to CCITT standards. * * Note by @antirez: this is actually the XMODEM CRC 16 algorithm, using the * following parameters: * * Name : "XMODEM", also known as "ZMODEM", "CRC-16/ACORN" * Width : 16 bit * Poly : 1021 (That is actually x^16 + x^12 + x^5 + 1) * Initialization : 0000 * Reflect Input byte : False * Reflect Output CRC : False * Xor constant to output CRC : 0000 * Output for "123456789" : 31C3 */ var lookup = [ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 ]; /** * Convert a string to a UTF8 array - faster than via buffer * @param str * @returns {Array} */ var toUTF8Array = function toUTF8Array(str) { var char; var i = 0; var p = 0; var utf8 = []; var len = str.length; for (; i < len; i++) { char = str.charCodeAt(i); if (char < 128) { utf8[p++] = char; } else if (char < 2048) { utf8[p++] = (char >> 6) | 192; utf8[p++] = (char & 63) | 128; } else if ( ((char & 0xFC00) === 0xD800) && (i + 1) < str.length && ((str.charCodeAt(i + 1) & 0xFC00) === 0xDC00)) { char = 0x10000 + ((char & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF); utf8[p++] = (char >> 18) | 240; utf8[p++] = ((char >> 12) & 63) | 128; utf8[p++] = ((char >> 6) & 63) | 128; utf8[p++] = (char & 63) | 128; } else { utf8[p++] = (char >> 12) | 224; utf8[p++] = ((char >> 6) & 63) | 128; utf8[p++] = (char & 63) | 128; } } return utf8; }; /** * Convert a string into a redis slot hash. * @param str * @returns {number} */ var generate = module.exports = function generate(str) { var char; var i = 0; var start = -1; var result = 0; var resultHash = 0; var utf8 = typeof str === 'string' ? toUTF8Array(str) : str; var len = utf8.length; while (i < len) { char = utf8[i++]; if (start === -1) { if (char === 0x7B) { start = i; } } else if (char !== 0x7D) { resultHash = lookup[(char ^ (resultHash >> 8)) & 0xFF] ^ (resultHash << 8); } else if (i - 1 !== start) { return resultHash & 0x3FFF; } result = lookup[(char ^ (result >> 8)) & 0xFF] ^ (result << 8); } return result & 0x3FFF; }; /** * Convert an array of multiple strings into a redis slot hash. * Returns -1 if one of the keys is not for the same slot as the others * @param keys * @returns {number} */ module.exports.generateMulti = function generateMulti(keys) { var i = 1; var len = keys.length; var base = generate(keys[0]); while (i < len) { if (generate(keys[i++]) !== base) return -1; } return base; }; cluster-key-slot-1.1.2/package.json000066400000000000000000000030151433022342400172230ustar00rootroot00000000000000{ "name": "cluster-key-slot", "version": "1.1.2", "description": "Generates CRC hashes for strings - for use by node redis clients to determine key slots.", "main": "lib/index.js", "types": "index.d.ts", "scripts": { "benchmark": "node ./benchmark", "posttest": "eslint ./lib && npm run coveralls", "coveralls": "cat ./coverage/lcov.info | coveralls", "test": "node ./node_modules/istanbul/lib/cli.js cover --preserve-comments ./node_modules/mocha/bin/_mocha -- -R spec", "coverage:check": "node ./node_modules/istanbul/lib/cli.js check-coverage --branch 100 --statement 100" }, "repository": { "type": "git", "url": "git+https://github.com/Salakar/cluster-key-slot.git" }, "keywords": [ "redis", "hash", "crc", "slot", "calc", "javascript", "node", "node_redis", "ioredis" ], "engines": { "node": ">=0.10.0" }, "devDependencies": { "benchmark": "^2.1.0", "codeclimate-test-reporter": "^0.3.1", "coveralls": "^2.11.9", "eslint": "^3.5.0", "eslint-config-airbnb-base": "^7.1.0", "eslint-plugin-import": "^1.8.0", "istanbul": "^0.4.0", "mocha": "^3.0.2" }, "author": { "name": "Mike Diarmid", "email": "mike.diarmid@gmail.com", "url": "http://github.com/Salakar/" }, "license": "Apache-2.0", "bugs": { "url": "https://github.com/Salakar/cluster-key-slot/issues" }, "homepage": "https://github.com/Salakar/cluster-key-slot#readme", "directories": { "test": "test", "lib": "lib" } } cluster-key-slot-1.1.2/test/000077500000000000000000000000001433022342400157155ustar00rootroot00000000000000cluster-key-slot-1.1.2/test/hash.spec.js000066400000000000000000000034211433022342400201270ustar00rootroot00000000000000/* eslint-env mocha */ /* eslint func-names: 0 */ var assert = require('assert'); var generate = require('../lib'); var generateMulti = require('../lib').generateMulti; var tests = [ ['123465', 1492], ['foobar', 12325], ['abcdefghijklmnopqrstuvwxyz', 9132], ['gsdfhan$%^&*(sdgsdnhshcs', 15532], ['abc{foobar}', 12325], ['{foobar}', 12325], ['h8a9sd{foobar}}{asd}}', 12325], ['{foobar', 16235], ['foobar{}', 4435], ['{{foobar}', 16235], ['éêe', 13690], ['àâa', 3872], ['漢字', 14191], ['汉字', 16196], ['호텔', 4350], ['\uD83D\uDC80', 9284], ['\uD800\uDC00', 11620], // surrogate pair ['{}foobar', 14573], [Buffer.from([0x7b, 0x7d, 0x2a, 0x2]), 3932], [Buffer.from([0x7b, 0x2a, 0x7d, 0x2]), 1320], [Buffer.from('汉字'), 16196] ]; var testsMulti = [ 'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz' ]; var testsMultiResult = 9132; function assertHash(key, expectedSlot) { assert.strictEqual(generate(key), expectedSlot, key + ' - generated invalid hash: ' + generate(key)); } describe('single hash: generate()', function () { it('generate a correct hash from string', function () { tests.forEach(([key, expectedSlot]) => assertHash(key, expectedSlot)) }); }); describe('multiple hashes: generateMulti()', function () { it('generate a correct hash from multiple strings', function () { assert.strictEqual(generateMulti(testsMulti), testsMultiResult); }); it('returns -1 if any of the keys generates a different hash slot than the rest', function () { assert.strictEqual(generateMulti(Object.keys(tests)), -1); }); });