From ce793e31f387c0715fa5b50c20e06510cc3e95ff Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 22 May 2012 17:15:40 +0000 Subject: Moved random to stable, just needs some minor tweaks. But it's already in use in a couple of core components, including in tempFile name generation. --- src/stable/file.cpp | 8 +++--- src/stable/random.cpp | 32 ++++++++++++++++++++++++ src/stable/random.h | 59 +++++++++++++++++++++++++++++++++++++++++++++ src/stable/randombase.cpp | 16 ++++++++++++ src/stable/randombase.h | 25 +++++++++++++++++++ src/stable/randombasic.cpp | 31 ++++++++++++++++++++++++ src/stable/randombasic.h | 29 ++++++++++++++++++++++ src/stable/randomcmwc.cpp | 52 +++++++++++++++++++++++++++++++++++++++ src/stable/randomcmwc.h | 29 ++++++++++++++++++++++ src/stable/randomsystem.cpp | 40 ++++++++++++++++++++++++++++++ src/stable/randomsystem.h | 37 ++++++++++++++++++++++++++++ 11 files changed, 354 insertions(+), 4 deletions(-) create mode 100644 src/stable/random.cpp create mode 100644 src/stable/random.h create mode 100644 src/stable/randombase.cpp create mode 100644 src/stable/randombase.h create mode 100644 src/stable/randombasic.cpp create mode 100644 src/stable/randombasic.h create mode 100644 src/stable/randomcmwc.cpp create mode 100644 src/stable/randomcmwc.h create mode 100644 src/stable/randomsystem.cpp create mode 100644 src/stable/randomsystem.h (limited to 'src/stable') diff --git a/src/stable/file.cpp b/src/stable/file.cpp index 8d10596..81b476d 100644 --- a/src/stable/file.cpp +++ b/src/stable/file.cpp @@ -12,6 +12,7 @@ #include #include #include +#include "bu/random.h" #include "bu/config.h" @@ -190,7 +191,6 @@ void Bu::File::setBlocking( bool bBlocking ) Bu::File Bu::File::tempFile( Bu::String &sName ) { uint32_t iX; - iX = time( NULL ) + getpid(); int iXes; for( iXes = sName.getSize()-1; iXes >= 0; iXes-- ) { @@ -200,11 +200,11 @@ Bu::File Bu::File::tempFile( Bu::String &sName ) iXes++; if( iXes == sName.getSize() ) throw Bu::ExceptionBase("Invalid temporary filename template."); - for( int iter = 0; iter < 100; iter++ ) + for( int iter = 0; iter < 1000; iter++ ) { for( int j = iXes; j < sName.getSize(); j++ ) { - iX = (1103515245 * iX + 12345); + uint32_t iX = Bu::Random::rand(); sName[j] = ('A'+(iX%26)) | ((iX&0x1000)?(0x20):(0)); } @@ -214,7 +214,7 @@ Bu::File Bu::File::tempFile( Bu::String &sName ) |Bu::File::Create|Bu::File::Exclusive ); } catch(...) { } } - throw Bu::FileException("Failed to create unique temporary file after 100" + throw Bu::FileException("Failed to create unique temporary file after 1000" " iterations."); } diff --git a/src/stable/random.cpp b/src/stable/random.cpp new file mode 100644 index 0000000..725948a --- /dev/null +++ b/src/stable/random.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2007-2012 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ +#include "bu/random.h" + +#include "bu/randombasic.h" + +Bu::Random::Random() : + pGen( NULL ) +{ + pGen = new RandomBasic(); +} + +Bu::Random::~Random() +{ + delete pGen; + pGen = NULL; +} + +int32_t Bu::Random::rand() +{ + return getInstance().pGen->rand(); +} + +void Bu::Random::seed( int32_t iSeed ) +{ + getInstance().pGen->seed( iSeed ); +} + diff --git a/src/stable/random.h b/src/stable/random.h new file mode 100644 index 0000000..ba26f21 --- /dev/null +++ b/src/stable/random.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2007-2012 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ +#ifndef BU_RANDOM_H +#define BU_RANDOM_H + +#include "bu/singleton.h" +#include + +namespace Bu +{ + class RandomBase; + class Random : public Bu::Singleton + { + friend class Bu::Singleton; + private: + Random(); + virtual ~Random(); + + public: + template + static void setGenerator() + { + delete getInstance().pGen; + getInstance().pGen = new cl(); + } + + template + static void setGenerator( t1 p1 ) + { + delete getInstance().pGen; + getInstance().pGen = new cl( p1 ); + } + + template + static void setGenerator( t1 p1, t2 p2 ) + { + delete getInstance().pGen; + getInstance().pGen = new cl( p1, p2 ); + } + + RandomBase &getGenerator() { return *pGen; } + + static int32_t rand(); + static void seed( int32_t iSeed ); + + private: + void checkInit(); + + private: + Bu::RandomBase *pGen; + }; +}; + +#endif + diff --git a/src/stable/randombase.cpp b/src/stable/randombase.cpp new file mode 100644 index 0000000..6514df3 --- /dev/null +++ b/src/stable/randombase.cpp @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2007-2012 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ +#include "bu/randombase.h" + +Bu::RandomBase::RandomBase() +{ +} + +Bu::RandomBase::~RandomBase() +{ +} + diff --git a/src/stable/randombase.h b/src/stable/randombase.h new file mode 100644 index 0000000..aff1d45 --- /dev/null +++ b/src/stable/randombase.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2007-2012 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ +#ifndef BU_RANDOM_BASE_H +#define BU_RANDOM_BASE_H + +#include + +namespace Bu +{ + class RandomBase + { + public: + RandomBase(); + virtual ~RandomBase(); + + virtual void seed( int32_t iSeed )=0; + virtual int32_t rand()=0; + }; +}; + +#endif diff --git a/src/stable/randombasic.cpp b/src/stable/randombasic.cpp new file mode 100644 index 0000000..ac591be --- /dev/null +++ b/src/stable/randombasic.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2007-2012 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ + +#include "bu/randombasic.h" + +Bu::RandomBasic::RandomBasic() : + a( 6364136223846793005 ), + c( 1442695040888963407 ), + x( 0 ) +{ +} + +Bu::RandomBasic::~RandomBasic() +{ +} + +void Bu::RandomBasic::seed( int32_t iSeed ) +{ + c = iSeed; +} + +int32_t Bu::RandomBasic::rand() +{ + x = (a*x + c); + return (int32_t)x; +} + diff --git a/src/stable/randombasic.h b/src/stable/randombasic.h new file mode 100644 index 0000000..a53e16f --- /dev/null +++ b/src/stable/randombasic.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2007-2012 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ +#ifndef BU_RANDOM_BASIC_H +#define BU_RANDOM_BASIC_H + +#include "bu/randombase.h" + +namespace Bu +{ + class RandomBasic : public RandomBase + { + public: + RandomBasic(); + virtual ~RandomBasic(); + + virtual void seed( int32_t iSeed ); + + virtual int32_t rand(); + + private: + int64_t a, c, x; + }; +}; + +#endif diff --git a/src/stable/randomcmwc.cpp b/src/stable/randomcmwc.cpp new file mode 100644 index 0000000..a4e807e --- /dev/null +++ b/src/stable/randomcmwc.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2007-2012 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ + +#include "bu/randomcmwc.h" + +#define PHI 0x9e3779b9 + +Bu::RandomCmwc::RandomCmwc() : + q( 0 ), + c( 362436 ) +{ + q = new uint32_t[4096]; +} + +Bu::RandomCmwc::~RandomCmwc() +{ + delete[] q; +} + +void Bu::RandomCmwc::seed( int32_t iSeed ) +{ + int i; + + q[0] = iSeed; + q[1] = iSeed + PHI; + q[2] = iSeed + PHI + PHI; + + for (i = 3; i < 4096; i++) + q[i] = q[i - 3] ^ q[i - 2] ^ PHI ^ i; +} + +int32_t Bu::RandomCmwc::rand() +{ + uint64_t t, a = 18782LL; + static uint32_t i = 4095; + uint32_t x, r = 0xfffffffe; + i = (i + 1) & 4095; + t = a * q[i] + c; + c = (t >> 32); + x = t + c; + if( x < c ) + { + x++; + c++; + } + return (q[i] = r - x); +} + diff --git a/src/stable/randomcmwc.h b/src/stable/randomcmwc.h new file mode 100644 index 0000000..747eb6a --- /dev/null +++ b/src/stable/randomcmwc.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2007-2012 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ +#ifndef BU_RANDOM_CMWC_H +#define BU_RANDOM_CMWC_H + +#include "bu/randombase.h" + +namespace Bu +{ + class RandomCmwc : public RandomBase + { + public: + RandomCmwc(); + virtual ~RandomCmwc(); + + virtual void seed( int32_t iSeed ); + + virtual int32_t rand(); + + private: + uint32_t *q, c; + }; +}; + +#endif diff --git a/src/stable/randomsystem.cpp b/src/stable/randomsystem.cpp new file mode 100644 index 0000000..0501587 --- /dev/null +++ b/src/stable/randomsystem.cpp @@ -0,0 +1,40 @@ +#include "bu/randomsystem.h" +#include "bu/file.h" + +Bu::RandomSystem::RandomSystem( Type eType ) : + eType( eType ), + pSrc( 0 ) +{ + switch( eType ) + { + case Bu::RandomSystem::Fast: + pSrc = new Bu::File("/dev/urandom", Bu::File::Read ); + break; + + case Bu::RandomSystem::Good: + pSrc = new Bu::File("/dev/random", Bu::File::Read ); + break; + } +} + +Bu::RandomSystem::~RandomSystem() +{ + delete pSrc; +} + +void Bu::RandomSystem::seed( int32_t /*iSeed*/ ) +{ + // Seed really has no effect here... + // on linux, if we were root, we could write data to random/urandom to + // perturb the data, but it's not necesarry +} + +int32_t Bu::RandomSystem::rand() +{ + if( !pSrc ) + throw Bu::ExceptionBase("Not initialized"); + int32_t i; + pSrc->read( &i, sizeof(int32_t) ); + return i; +} + diff --git a/src/stable/randomsystem.h b/src/stable/randomsystem.h new file mode 100644 index 0000000..7106d58 --- /dev/null +++ b/src/stable/randomsystem.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2007-2012 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ +#ifndef BU_RANDOM_SYSTEM_H +#define BU_RANDOM_SYSTEM_H + +#include "bu/randombase.h" + +namespace Bu +{ + class File; + class RandomSystem : public RandomBase + { + public: + enum Type + { + Fast, + Good + }; + + RandomSystem( Type eType=Fast ); + virtual ~RandomSystem(); + + virtual void seed( int32_t iSeed ); + + virtual int32_t rand(); + + private: + Type eType; + File *pSrc; + }; +}; + +#endif -- cgit v1.2.3