From f3796333b3ea43a5bc6bbdb550265fdc3cd69ca7 Mon Sep 17 00:00:00 2001 From: Stuart Fraser Date: Tue, 1 May 2012 16:01:36 +1000 Subject: [PATCH] added gauge function --- lib/statsd.js | 7 + node_modules/mersenne/index.js | 1 + node_modules/mersenne/lib/mersenne.js | 283 ++++++++++++++++++++++++++ node_modules/mersenne/package.json | 45 ++++ node_modules/mersenne/test.js | 65 ++++++ 5 files changed, 401 insertions(+) create mode 100644 node_modules/mersenne/index.js create mode 100644 node_modules/mersenne/lib/mersenne.js create mode 100644 node_modules/mersenne/package.json create mode 100644 node_modules/mersenne/test.js diff --git a/lib/statsd.js b/lib/statsd.js index ccbe52d..b388eae 100644 --- a/lib/statsd.js +++ b/lib/statsd.js @@ -25,6 +25,13 @@ Client.prototype.decrement = function (stats, sample_rate) { self.update_stats(stats, -1, sample_rate); } +Client.prototype.gauge = function (stat, value, sample_rate) { + var self = this; + var stats = {}; + stats[stat] = value+"|g"; + self.send(stats, sample_rate); +} + Client.prototype.update_stats = function (stats, delta, sampleRate) { var self = this; if (typeof(stats) === 'string') { diff --git a/node_modules/mersenne/index.js b/node_modules/mersenne/index.js new file mode 100644 index 0000000..5d793a6 --- /dev/null +++ b/node_modules/mersenne/index.js @@ -0,0 +1 @@ +module.exports = require('./lib/mersenne.js'); diff --git a/node_modules/mersenne/lib/mersenne.js b/node_modules/mersenne/lib/mersenne.js new file mode 100644 index 0000000..4c7f8fe --- /dev/null +++ b/node_modules/mersenne/lib/mersenne.js @@ -0,0 +1,283 @@ +// this program is a JavaScript version of Mersenne Twister, with concealment and encapsulation in class, +// an almost straight conversion from the original program, mt19937ar.c, +// translated by y. okada on July 17, 2006. +// and modified a little at july 20, 2006, but there are not any substantial differences. +// in this program, procedure descriptions and comments of original source code were not removed. +// lines commented with //c// were originally descriptions of c procedure. and a few following lines are appropriate JavaScript descriptions. +// lines commented with /* and */ are original comments. +// lines commented with // are additional comments in this JavaScript version. +// before using this version, create at least one instance of MersenneTwister19937 class, and initialize the each state, given below in c comments, of all the instances. +/* + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Before using, initialize the state by using init_genrand(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. 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. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + 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. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +*/ + +function MersenneTwister19937() +{ + /* Period parameters */ + //c//#define N 624 + //c//#define M 397 + //c//#define MATRIX_A 0x9908b0dfUL /* constant vector a */ + //c//#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ + //c//#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ + N = 624; + M = 397; + MATRIX_A = 0x9908b0df; /* constant vector a */ + UPPER_MASK = 0x80000000; /* most significant w-r bits */ + LOWER_MASK = 0x7fffffff; /* least significant r bits */ + //c//static unsigned long mt[N]; /* the array for the state vector */ + //c//static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ + var mt = new Array(N); /* the array for the state vector */ + var mti = N+1; /* mti==N+1 means mt[N] is not initialized */ + + function unsigned32 (n1) // returns a 32-bits unsiged integer from an operand to which applied a bit operator. + { + return n1 < 0 ? (n1 ^ UPPER_MASK) + UPPER_MASK : n1; + } + + function subtraction32 (n1, n2) // emulates lowerflow of a c 32-bits unsiged integer variable, instead of the operator -. these both arguments must be non-negative integers expressible using unsigned 32 bits. + { + return n1 < n2 ? unsigned32((0x100000000 - (n2 - n1)) & 0xffffffff) : n1 - n2; + } + + function addition32 (n1, n2) // emulates overflow of a c 32-bits unsiged integer variable, instead of the operator +. these both arguments must be non-negative integers expressible using unsigned 32 bits. + { + return unsigned32((n1 + n2) & 0xffffffff) + } + + function multiplication32 (n1, n2) // emulates overflow of a c 32-bits unsiged integer variable, instead of the operator *. these both arguments must be non-negative integers expressible using unsigned 32 bits. + { + var sum = 0; + for (var i = 0; i < 32; ++i){ + if ((n1 >>> i) & 0x1){ + sum = addition32(sum, unsigned32(n2 << i)); + } + } + return sum; + } + + /* initializes mt[N] with a seed */ + //c//void init_genrand(unsigned long s) + this.init_genrand = function (s) + { + //c//mt[0]= s & 0xffffffff; + mt[0]= unsigned32(s & 0xffffffff); + for (mti=1; mti> 30)) + mti); + addition32(multiplication32(1812433253, unsigned32(mt[mti-1] ^ (mt[mti-1] >>> 30))), mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + //c//mt[mti] &= 0xffffffff; + mt[mti] = unsigned32(mt[mti] & 0xffffffff); + /* for >32 bit machines */ + } + } + + /* initialize by an array with array-length */ + /* init_key is the array for initializing keys */ + /* key_length is its length */ + /* slight change for C++, 2004/2/26 */ + //c//void init_by_array(unsigned long init_key[], int key_length) + this.init_by_array = function (init_key, key_length) + { + //c//int i, j, k; + var i, j, k; + //c//init_genrand(19650218); + this.init_genrand(19650218); + i=1; j=0; + k = (N>key_length ? N : key_length); + for (; k; k--) { + //c//mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525)) + //c// + init_key[j] + j; /* non linear */ + mt[i] = addition32(addition32(unsigned32(mt[i] ^ multiplication32(unsigned32(mt[i-1] ^ (mt[i-1] >>> 30)), 1664525)), init_key[j]), j); + mt[i] = + //c//mt[i] &= 0xffffffff; /* for WORDSIZE > 32 machines */ + unsigned32(mt[i] & 0xffffffff); + i++; j++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + if (j>=key_length) j=0; + } + for (k=N-1; k; k--) { + //c//mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941)) + //c//- i; /* non linear */ + mt[i] = subtraction32(unsigned32((dbg=mt[i]) ^ multiplication32(unsigned32(mt[i-1] ^ (mt[i-1] >>> 30)), 1566083941)), i); + //c//mt[i] &= 0xffffffff; /* for WORDSIZE > 32 machines */ + mt[i] = unsigned32(mt[i] & 0xffffffff); + i++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + } + mt[0] = 0x80000000; /* MSB is 1; assuring non-zero initial array */ + } + + /* moved outside of genrand_int32() by jwatte 2010-11-17; generate less garbage */ + var mag01 = [0x0, MATRIX_A]; + + /* generates a random number on [0,0xffffffff]-interval */ + //c//unsigned long genrand_int32(void) + this.genrand_int32 = function () + { + //c//unsigned long y; + //c//static unsigned long mag01[2]={0x0UL, MATRIX_A}; + var y; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (mti >= N) { /* generate N words at one time */ + //c//int kk; + var kk; + + if (mti == N+1) /* if init_genrand() has not been called, */ + //c//init_genrand(5489); /* a default initial seed is used */ + this.init_genrand(5489); /* a default initial seed is used */ + + for (kk=0;kk> 1) ^ mag01[y & 0x1]; + y = unsigned32((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK)); + mt[kk] = unsigned32(mt[kk+M] ^ (y >>> 1) ^ mag01[y & 0x1]); + } + for (;kk> 1) ^ mag01[y & 0x1]; + y = unsigned32((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK)); + mt[kk] = unsigned32(mt[kk+(M-N)] ^ (y >>> 1) ^ mag01[y & 0x1]); + } + //c//y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + //c//mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1]; + y = unsigned32((mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK)); + mt[N-1] = unsigned32(mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1]); + mti = 0; + } + + y = mt[mti++]; + + /* Tempering */ + //c//y ^= (y >> 11); + //c//y ^= (y << 7) & 0x9d2c5680; + //c//y ^= (y << 15) & 0xefc60000; + //c//y ^= (y >> 18); + y = unsigned32(y ^ (y >>> 11)); + y = unsigned32(y ^ ((y << 7) & 0x9d2c5680)); + y = unsigned32(y ^ ((y << 15) & 0xefc60000)); + y = unsigned32(y ^ (y >>> 18)); + + return y; + } + + /* generates a random number on [0,0x7fffffff]-interval */ + //c//long genrand_int31(void) + this.genrand_int31 = function () + { + //c//return (genrand_int32()>>1); + return (this.genrand_int32()>>>1); + } + + /* generates a random number on [0,1]-real-interval */ + //c//double genrand_real1(void) + this.genrand_real1 = function () + { + //c//return genrand_int32()*(1.0/4294967295.0); + return this.genrand_int32()*(1.0/4294967295.0); + /* divided by 2^32-1 */ + } + + /* generates a random number on [0,1)-real-interval */ + //c//double genrand_real2(void) + this.genrand_real2 = function () + { + //c//return genrand_int32()*(1.0/4294967296.0); + return this.genrand_int32()*(1.0/4294967296.0); + /* divided by 2^32 */ + } + + /* generates a random number on (0,1)-real-interval */ + //c//double genrand_real3(void) + this.genrand_real3 = function () + { + //c//return ((genrand_int32()) + 0.5)*(1.0/4294967296.0); + return ((this.genrand_int32()) + 0.5)*(1.0/4294967296.0); + /* divided by 2^32 */ + } + + /* generates a random number on [0,1) with 53-bit resolution*/ + //c//double genrand_res53(void) + this.genrand_res53 = function () + { + //c//unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; + var a=this.genrand_int32()>>>5, b=this.genrand_int32()>>>6; + return(a*67108864.0+b)*(1.0/9007199254740992.0); + } + /* These real versions are due to Isaku Wada, 2002/01/09 added */ +} + +// Exports: Public API + +// Export the twister class +exports.MersenneTwister19937 = MersenneTwister19937; + +// Export a simplified function to generate random numbers +var gen = new MersenneTwister19937; +gen.init_genrand((new Date).getTime() % 1000000000); +exports.rand = function(N) { + if (!N) + { + N = 32768; + } + return Math.floor(gen.genrand_real2() * N); +} +exports.seed = function(S) { + if (typeof(S) != 'number') + { + throw new Error("seed(S) must take numeric argument; is " + typeof(S)); + } + gen.init_genrand(S); +} +exports.seed_array = function(A) { + if (typeof(A) != 'object') + { + throw new Error("seed_array(A) must take array of numbers; is " + typeof(A)); + } + gen.init_by_array(A); +} + + diff --git a/node_modules/mersenne/package.json b/node_modules/mersenne/package.json new file mode 100644 index 0000000..a727615 --- /dev/null +++ b/node_modules/mersenne/package.json @@ -0,0 +1,45 @@ +{ + "name": "mersenne", + "author": { + "name": "Jon Watte", + "url": "http://www.enchantedage.com/" + }, + "contributors": [ + { + "name": "Yasuharu Okada" + }, + { + "name": "Jon Watte", + "url": "http://www.enchantedage.com/" + } + ], + "version": "0.0.3", + "description": "A node.js module for generating high-quality Mersenne Twister random numbers.", + "keywords": [ + "random", + "mersenne", + "twister", + "number", + "generator" + ], + "homepage": "http://www.enchantedage.com/node-mersenne", + "directories": { + "lib": "lib" + }, + "main": "lib/mersenne", + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": "*" + }, + "_id": "mersenne@0.0.3", + "optionalDependencies": {}, + "_engineSupported": true, + "_npmVersion": "1.1.18", + "_nodeVersion": "v0.6.15", + "_defaultsLoaded": true, + "dist": { + "shasum": "c0309467a7e507b88ec495be971f840a4fd294cd" + }, + "_from": "mersenne@*" +} diff --git a/node_modules/mersenne/test.js b/node_modules/mersenne/test.js new file mode 100644 index 0000000..a885dd8 --- /dev/null +++ b/node_modules/mersenne/test.js @@ -0,0 +1,65 @@ + +mt = require('./lib/mersenne.js'); + +function test_gen(f, iter) + { + var a = new Array(); + var n = Math.floor(iter / 1000); + if (n * 1000 != iter) + { + throw new Error("Iteration count " + iter + " must be divisible by 1000"); + } + for (var i = 0; i < n; i += 1) + { + a[i] = 0; + } + for (var i = 0; i < iter; i += 1) + { + q = Math.floor(f(n)); + if (isNaN(q)) + { + throw new Error("NaN: " + q + " for iter " + i); + } + a[q % n] += 1; + } + var err = null; + for (var i = 0; i < n; i += 1) + { + if (a[i] < 900 || a[i] > 1100) + { + err = new Error("Index " + i + " out of " + n + " is outside [900,1100]: " + a[i]); + } + } + if (err) + { + throw new Error(err); + } + } + +mt.seed(1); +var v = mt.rand(); +if (isNaN(v)) + { + throw new Error('NaN from mt.rand(): ' + v); + } + +var g = new mt.MersenneTwister19937(); +g.init_genrand(12345); +var f = function(range) + { + var ret = g.genrand_real1() * range; + return ret; + } +test_gen(f, 100000); + +mt.seed(4711); +f = function(range) + { + return mt.rand(range); + } +test_gen(f, 100000); + +mt.seed_array([15, 9932, 11147]); +test_gen(f, 100000); + +process.exit(0);