Author: tabish Date: Sun Jun 10 16:37:03 2007 New Revision: 545977 URL: http://svn.apache.org/viewvc?view=rev&rev=545977 Log: https://issues.apache.org/activemq/browse/AMQCPP-103 Building up the Decaf Library Added: activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/util/Random.cpp activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/util/Random.h activemq/activemq-cpp/trunk/src/decaf/src/test/decaf/util/RandomTest.cpp activemq/activemq-cpp/trunk/src/decaf/src/test/decaf/util/RandomTest.h Modified: activemq/activemq-cpp/trunk/src/decaf/src/main/Makefile.am activemq/activemq-cpp/trunk/src/decaf/src/test/Makefile.am Modified: activemq/activemq-cpp/trunk/src/decaf/src/main/Makefile.am URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/decaf/src/main/Makefile.am?view=diff&rev=545977&r1=545976&r2=545977 ============================================================================== --- activemq/activemq-cpp/trunk/src/decaf/src/main/Makefile.am (original) +++ activemq/activemq-cpp/trunk/src/decaf/src/main/Makefile.am Sun Jun 10 16:37:03 2007 @@ -42,6 +42,7 @@ decaf/util/Date.cpp \ decaf/util/Guid.cpp \ decaf/util/StringTokenizer.cpp \ + decaf/util/Random.cpp \ decaf/util/logging/LoggerHierarchy.cpp \ decaf/util/logging/Logger.cpp \ decaf/util/logging/LogWriter.cpp \ @@ -111,6 +112,7 @@ decaf/util/Properties.h \ decaf/util/Queue.h \ decaf/util/Set.h \ + decaf/util/Random.h \ decaf/util/StringTokenizer.h \ decaf/util/logging/Handler.h \ decaf/util/logging/Logger.h \ Added: activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/util/Random.cpp URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/util/Random.cpp?view=auto&rev=545977 ============================================================================== --- activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/util/Random.cpp (added) +++ activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/util/Random.cpp Sun Jun 10 16:37:03 2007 @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file 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. + */ + +#include "Random.h" + +#include + +using namespace decaf; +using namespace decaf::util; +using namespace decaf::lang; + +unsigned long long Random::multiplier = 0x5deece66dLL; + +//////////////////////////////////////////////////////////////////////////////// +Random::Random() { + setSeed(Date::getCurrentTimeMilliseconds()); +} + +//////////////////////////////////////////////////////////////////////////////// +Random::Random( unsigned long long seed ) { + setSeed(seed); +} + +//////////////////////////////////////////////////////////////////////////////// +bool Random::nextBoolean() { + return next(1) != 0; +} + +//////////////////////////////////////////////////////////////////////////////// +void Random::nextBytes( std::vector& buf ) { + int rand = 0; + std::size_t count = 0, loop = 0; + while (count < buf.size()) { + if (loop == 0) { + rand = nextInt(); + loop = 3; + } else { + loop--; + } + buf[count++] = (unsigned char) rand; + rand >>= 8; + } +} + +//////////////////////////////////////////////////////////////////////////////// +double Random::nextDouble() { + // was: return ((((long long) next(26) << 27) + next(27)) / (double) (1L << 53)); + long long divisor = 1LL; + divisor <<= 31; + divisor <<= 22; + return ((((long long) next(26) << 27) + next(27)) / (double) divisor); +} + +//////////////////////////////////////////////////////////////////////////////// +float Random::nextFloat() { + return (next(24) / 16777216.0f); +} + +//////////////////////////////////////////////////////////////////////////////// +double Random::nextGaussian() { + if (haveNextNextGaussian) { + // if X1 has been returned, return the second Gaussian + haveNextNextGaussian = false; + return nextNextGaussian; + } + + double v1, v2, s; + do { + // Generates two independent random variables U1, U2 + v1 = 2 * nextDouble() - 1; + v2 = 2 * nextDouble() - 1; + s = v1 * v1 + v2 * v2; + } while (s >= 1); + double norm = std::sqrt(-2 * std::log(s) / s); + // should that not be norm instead of multiplier ? + nextNextGaussian = v2 * norm; + haveNextNextGaussian = true; + // should that not be norm instead of multiplier ? + return v1 * norm; +} + +//////////////////////////////////////////////////////////////////////////////// +int Random::nextInt() { + return next(32); +} + +//////////////////////////////////////////////////////////////////////////////// +int Random::nextInt( int n ) throw( exceptions::IllegalArgumentException ) { + if (n > 0) { + if ((n & -n) == n) { + return (int) ((n * (long long) next(31)) >> 31); + } + int bits, val; + do { + bits = next(31); + val = bits % n; + } while (bits - val + (n - 1) < 0); + return val; + } + throw exceptions::IllegalArgumentException(); +} + +//////////////////////////////////////////////////////////////////////////////// +long long Random::nextLong() { + return ((long long) next(32) << 32) + next(32); +} + +//////////////////////////////////////////////////////////////////////////////// +void Random::setSeed( unsigned long long seed ) { + // was this->seed = (seed ^ multiplier) & ((1L << 48) - 1); + unsigned long long mask = 1ULL; + mask <<= 31; + mask <<= 17; + this->seed = (seed ^ multiplier) & (mask - 1); + haveNextNextGaussian = false; +} + +//////////////////////////////////////////////////////////////////////////////// +int Random::next( int bits ) { + // was: seed = (seed * multiplier + 0xbL) & ((1L << 48) - 1); + long long mask = 1L; + mask <<= 31; + mask <<= 17; + seed = (seed * multiplier + 0xbL) & (mask - 1); + // was: return (int) (seed >>> (48 - bits)); + return (int) (seed >> (48 - bits)); +} Added: activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/util/Random.h URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/util/Random.h?view=auto&rev=545977 ============================================================================== --- activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/util/Random.h (added) +++ activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/util/Random.h Sun Jun 10 16:37:03 2007 @@ -0,0 +1,199 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file 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. + */ + +#ifndef _DECAF_UTIL_RANDOM_H_ +#define _DECAF_UTIL_RANDOM_H_ + +#include +#include +#include + +namespace decaf{ +namespace util{ + + class Random + { + public: + + /** + * Construct a random generator with the current time of day in + * milliseconds as the initial state. + * + * @see #setSeed + */ + Random(); + + /** + * Construct a random generator with the given seed + * as the initial state. + * + * @param seed the seed that will determine the initial state of + * this random number generator + * + * @see #setSeed + */ + Random( unsigned long long seed ); + + /** + * Answers the next pseudo-random, uniformly distributed boolean + * value generated by this generator. + * + * @return boolean a pseudo-random, uniformly distributed boolean + * value + */ + bool nextBoolean(); + + /** + * Modifies the byte array by a random sequence of bytes generated + * by this random number generator. + * + * @param buf non-null array to contain the new random bytes + * + * @see #next + */ + void nextBytes( std::vector& buf ); + + /** + * Generates a normally distributed random double number between + * 0.0 inclusively and 1.0 exclusively. + * + * @return double + * + * @see #nextFloat + */ + double nextDouble(); + + /** + * Generates a normally distributed random float number between + * 0.0 inclusively and 1.0 exclusively. + * + * @return float a random float number between 0.0 and 1.0 + * + * @see #nextDouble + */ + float nextFloat(); + + /** + * Pseudo-randomly generates (approximately) a normally + * distributed double value with mean 0.0 and a + * standard deviation value of 1.0 using the polar + * method of G. E. P. Box, M. E. Muller, and G. Marsaglia, as + * described by Donald E. Knuth in The Art of Computer + * Programming, Volume 2: Seminumerical Algorithms, section + * 3.4.1, subsection C, algorithm P + * + * @return double + * + * @see #nextDouble + */ + double nextGaussian(); + + /** + * Generates a uniformly distributed 32-bit int value + * from the this random number sequence. + * + * @return int uniformly distributed int value + * + * @see #next + * @see #nextLong + */ + int nextInt(); + + /** + * Returns to the caller a new pseudo-random integer value which + * is uniformly distributed between 0 (inclusively) and the value + * of n (exclusively). + * + * @return int + * @param n int + * + * @throws IllegalArgumentException + */ + int nextInt( int n ) throw( lang::exceptions::IllegalArgumentException ); + + /** + * Generates a uniformly distributed 64-bit int value + * from the this random number sequence. + * + * @return 64-bit int random number + * + * @see #next + * @see #nextInt() + * @see #nextInt(int) + */ + long long nextLong(); + + /** + * Modifies the seed using linear congruential formula presented + * in The Art of Computer Programming, Volume 2, Section + * 3.2.1. + * + * @param seed the seed that alters the state of the random number + * generator + * + * @see #next + * @see #Random() + * @see #Random(long) + */ + void setSeed( unsigned long long seed ); + + protected: + + /** + * Answers a pseudo-random uniformly distributed int + * value of the number of bits specified by the argument + * bits as described by Donald E. Knuth in The Art + * of Computer Programming, Volume 2: Seminumerical + * Algorithms, section 3.2.1. + * + * @return int a pseudo-random generated int number + * @param bits number of bits of the returned value + * + * @see #nextBytes + * @see #nextDouble + * @see #nextFloat + * @see #nextInt() + * @see #nextInt(int) + * @see #nextGaussian + * @see #nextLong + */ + int next( int bits ); + + private: + + static unsigned long long multiplier; + + /** + * The boolean value indicating if the second Gaussian number is available. + */ + bool haveNextNextGaussian; + + /** + * It is associated with the internal state of this generator. + */ + unsigned long long seed; + + /** + * The second Gaussian generated number. + */ + double nextNextGaussian; + + }; + +}} + +#endif /*_DECAF_UTIL_RANDOM_H_*/ Modified: activemq/activemq-cpp/trunk/src/decaf/src/test/Makefile.am URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/decaf/src/test/Makefile.am?view=diff&rev=545977&r1=545976&r2=545977 ============================================================================== --- activemq/activemq-cpp/trunk/src/decaf/src/test/Makefile.am (original) +++ activemq/activemq-cpp/trunk/src/decaf/src/test/Makefile.am Sun Jun 10 16:37:03 2007 @@ -32,6 +32,7 @@ decaf/util/Endian.cpp \ decaf/util/DateTest.cpp \ decaf/util/GuidTest.cpp \ + decaf/util/RandomTest.cpp \ decaf/util/concurrent/CountDownLatchTest.cpp \ decaf/util/concurrent/MutexTest.cpp \ decaf/util/concurrent/ThreadPoolTest.cpp \ @@ -54,6 +55,7 @@ decaf/util/Endian.h \ decaf/util/DateTest.h \ decaf/util/GuidTest.h \ + decaf/util/RandomTest.h \ decaf/util/concurrent/CountDownLatchTest.h \ decaf/util/concurrent/MutexTest.h \ decaf/util/concurrent/ThreadPoolTest.h Added: activemq/activemq-cpp/trunk/src/decaf/src/test/decaf/util/RandomTest.cpp URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/decaf/src/test/decaf/util/RandomTest.cpp?view=auto&rev=545977 ============================================================================== --- activemq/activemq-cpp/trunk/src/decaf/src/test/decaf/util/RandomTest.cpp (added) +++ activemq/activemq-cpp/trunk/src/decaf/src/test/decaf/util/RandomTest.cpp Sun Jun 10 16:37:03 2007 @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file 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. + */ + +#include "RandomTest.h" + +CPPUNIT_TEST_SUITE_REGISTRATION( decaf::util::RandomTest ); + +using namespace std; +using namespace decaf; +using namespace decaf::util; + +void RandomTest::test(){ + + Random rand(122760); + CPPUNIT_ASSERT_EQUAL(-1524104671, rand.nextInt()); + CPPUNIT_ASSERT_EQUAL(2785759620113032781LL, rand.nextLong()); + CPPUNIT_ASSERT_EQUAL(rand.nextDouble(), 0.8173322904425151); + CPPUNIT_ASSERT_EQUAL(rand.nextFloat(), 0.8239248f); + + std::vector b(0); + rand.nextBytes(b); + CPPUNIT_ASSERT_EQUAL(-899478426, rand.nextInt()); + + rand = Random(122760); + rand.nextInt(); + rand.nextLong(); + rand.nextDouble(); + rand.nextFloat(); + b = std::vector(3); + rand.nextBytes(b); + CPPUNIT_ASSERT_EQUAL((unsigned char)102, b[0]); + CPPUNIT_ASSERT_EQUAL((unsigned char)12, b[1]); + CPPUNIT_ASSERT_EQUAL((unsigned char)99, b[2]); + CPPUNIT_ASSERT_EQUAL(-1550323395, rand.nextInt()); + + rand = Random(122760); + rand.nextInt(); + rand.nextLong(); + rand.nextDouble(); + rand.nextFloat(); + b = std::vector(4); + rand.nextBytes(b); + CPPUNIT_ASSERT_EQUAL((unsigned char)102, b[0]); + CPPUNIT_ASSERT_EQUAL((unsigned char)12, b[1]); + CPPUNIT_ASSERT_EQUAL((unsigned char)99, b[2]); + CPPUNIT_ASSERT_EQUAL((unsigned char)-54, b[3]); + CPPUNIT_ASSERT_EQUAL(-1550323395, rand.nextInt()); + + rand = Random(122760); + rand.nextInt(); + rand.nextLong(); + rand.nextDouble(); + rand.nextFloat(); + b = std::vector(5); + rand.nextBytes(b); + CPPUNIT_ASSERT_EQUAL((unsigned char)102, b[0]); + CPPUNIT_ASSERT_EQUAL((unsigned char)12, b[1]); + CPPUNIT_ASSERT_EQUAL((unsigned char)99, b[2]); + CPPUNIT_ASSERT_EQUAL((unsigned char)-54, b[3]); + CPPUNIT_ASSERT_EQUAL((unsigned char)61, b[4]); + CPPUNIT_ASSERT_EQUAL(-270809961, rand.nextInt()); + + bool ok = true; + rand = Random(0); + for (int i=0; i < 1000000; ++i) { + int x = rand.nextInt(1000); + if (x < 0 || x >= 1000) { + ok = false; + } + } + CPPUNIT_ASSERT(ok); +} Added: activemq/activemq-cpp/trunk/src/decaf/src/test/decaf/util/RandomTest.h URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/decaf/src/test/decaf/util/RandomTest.h?view=auto&rev=545977 ============================================================================== --- activemq/activemq-cpp/trunk/src/decaf/src/test/decaf/util/RandomTest.h (added) +++ activemq/activemq-cpp/trunk/src/decaf/src/test/decaf/util/RandomTest.h Sun Jun 10 16:37:03 2007 @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file 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. + */ + +#ifndef _DECAF_UTIL_RANDOMTEST_H_ +#define _DECAF_UTIL_RANDOMTEST_H_ + +#include +#include + +#include + +namespace decaf{ +namespace util{ + + class RandomTest : public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE( RandomTest ); + CPPUNIT_TEST( test ); + CPPUNIT_TEST_SUITE_END(); + + public: + + RandomTest(){} + virtual ~RandomTest(){} + + void test(); + }; + +}} + +#endif /*_DECAF_UTIL_RANDOMTEST_H_*/