kdecore: replace most of KRandomSequence with new KRandom::randomMax() function

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2022-09-26 11:39:26 +03:00
parent a692d6026e
commit 7dc5187778
14 changed files with 65 additions and 507 deletions

View file

@ -241,7 +241,6 @@ install(
KProtocolManager
KPushButton
KRandom
KRandomSequence
KRatingPainter
KRatingWidget
KRecentDocument

View file

@ -1 +0,0 @@
#include "../krandomsequence.h"

View file

@ -206,7 +206,6 @@ set(kdecore_LIB_SRCS
util/kpluginloader.cpp
util/kshell.cpp
util/krandom.cpp
util/krandomsequence.cpp
util/kunitconversion.cpp
util/qtest_kde.cpp
@ -356,7 +355,6 @@ install(
util/kpluginloader.h
util/kshell.h
util/krandom.h
util/krandomsequence.h
util/kunitconversion.h
util/ksharedptr.h
util/ksortablelist.h

View file

@ -446,7 +446,7 @@ KLockFile::LockResult KLockFile::lock(LockFlags options)
break;
}
::usleep((KRandom::random() % 1000) + 200);
::usleep(KRandom::randomMax(1000) + 200);
}
if (result == LockOK) {
d->isLocked = true;

View file

@ -66,7 +66,6 @@ KDECORE_UNIT_TESTS(
)
KDECORE_EXECUTABLE_TESTS(
krandomsequencetest
ktartest
kziptest
kdebugtest

View file

@ -93,7 +93,7 @@ void KFilterTest::test_biggerWrites()
data.reserve(10000);
// Prepare test data
for (int i = 0; i < 8170; ++i)
data.append((char)(KRandom::random() % 256));
data.append(static_cast<char>(KRandom::randomMax(256)));
QCOMPARE(data.size(), 8170);
// 8170 random bytes compress to 8194 bytes due to the gzip header/footer.
// Now we can go one by one until we pass 8192.
@ -107,7 +107,7 @@ void KFilterTest::test_biggerWrites()
test_readall(outFile, QString::fromLatin1("application/x-gzip"), data);
data.append((char)(KRandom::random() % 256));
data.append(static_cast<char>(KRandom::randomMax(256)));
}
}

View file

@ -1,96 +0,0 @@
/* This file is part of the KDE libraries
Copyright (c) 1999 Waldo Bastian <bastian@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <QtCore/QList>
#include <QtCore/QString>
#include "krandomsequence.h"
#include "krandom.h"
#include "kcmdlineargs.h"
#include "kaboutdata.h"
//#include "kapplication.h"
#include <stdio.h>
int
main( /*int argc, char *argv[]*/ )
{
//KAboutData about("krandomsequencetest", 0, ki18n("krandomsequencetest"), "version");
//KCmdLineArgs::init(argc, argv, &about);
//KApplication a;
long seed;
KRandomSequence seq;
seed = 2;
seq.setSeed(seed);printf("Seed = %4ld :", seed);
for(int i = 0; i < 20; i++)
printf("%3ld ", seq.getLong(100));
printf("\n");
seed = 0;
seq.setSeed(seed);printf("Seed = %4ld :", seed);
for(int i = 0; i < 20; i++)
printf("%3ld ", seq.getLong(100));
printf("\n");
seed = 0;
seq.setSeed(seed);printf("Seed = %4ld :", seed);
for(int i = 0; i < 20; i++)
printf("%3ld ", seq.getLong(100));
printf("\n");
seed = 2;
seq.setSeed(seed);printf("Seed = %4ld :", seed);
for(int i = 0; i < 20; i++)
printf("%3ld ", seq.getLong(100));
printf("\n");
seq.setSeed(KRandom::random());
QList<QString> list;
list.append(QString("A"));
list.append(QString("B"));
list.append(QString("C"));
list.append(QString("D"));
list.append(QString("E"));
list.append(QString("F"));
list.append(QString("G"));
for(QList<QString>::Iterator str = list.begin(); str != list.end(); ++str)
printf("%s", str->toLatin1().data());
printf("\n");
seq.randomize(list);
for(QList<QString>::Iterator str = list.begin(); str != list.end(); ++str)
printf("%s", str->toLatin1().data());
printf("\n");
seq.randomize(list);
for(QList<QString>::Iterator str = list.begin(); str != list.end(); ++str)
printf("%s", str->toLatin1().data());
printf("\n");
seq.randomize(list);
for(QList<QString>::Iterator str = list.begin(); str != list.end(); ++str)
printf("%s", str->toLatin1().data());
printf("\n");
}

View file

@ -1,12 +1,9 @@
/* This file is part of the KDE libraries
Copyright (c) 1999 Matthias Kalle Dalheimer <kalle@kde.org>
Copyright (c) 2000 Charles Samuels <charles@kde.org>
Copyright (c) 2005 Joseph Wenninger <kde@jowenn.at>
/* This file is part of the KDE libraries
Copyright (C) 2022 Ivailo Monev <xakepa10@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
License version 2, as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -17,20 +14,31 @@
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
*/
#include "krandom.h"
#include "kdebug.h"
int KRandom::randomMax(int max)
{
if (Q_UNLIKELY(max <= 0)) {
kWarning() << "Maximum value must be greater than zero";
return 0;
}
return KRandom::random() % max;
}
QString KRandom::randomString(int length)
{
if (length <= 0)
if (length <= 0) {
return QString();
}
QString str(length, Qt::Uninitialized);
static const char rndstrchars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (int i = 0; i < length; i++) {
str[i] = rndstrchars[random() % 62];
str[i] = rndstrchars[KRandom::randomMax(62)];
}
return str;
return str;
}

View file

@ -1,12 +1,10 @@
/* This file is part of the KDE libraries
Copyright (c) 1999 Matthias Kalle Dalheimer <kalle@kde.org>
Copyright (c) 2000 Charles Samuels <charles@kde.org>
Copyright (c) 2005 Joseph Wenninger <kde@jowenn.at>
/* This file is part of the KDE libraries
Copyright (C) 2022 Ivailo Monev <xakepa10@gmail.com>
Copyright (c) 1999 Sean Harmer <sh@astro.keele.ac.uk>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
License version 2, as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -36,19 +34,41 @@
namespace KRandom {
/**
* Generates a uniform random number.
* @return A random number in the range [0, RAND_MAX). The RNG is seeded
* on first use.
* @return A random number in the range [0, RAND_MAX]
*/
inline int random() { return qrand(); };
/**
* Generates a random string. It operates in the range [A-Za-z0-9]
* Generates a uniform random number.
* @param max Maximum value for the returned number.
* @return A random number in the range [0, @p max]
*/
KDECORE_EXPORT int randomMax(int max);
/**
* Generates a random string. It operates in the range [A-Za-z0-9]
* @param length Generate a string of this length.
* @return the random string
*/
KDECORE_EXPORT QString randomString(int length);
/**
* Put a list in random order. Since KDE 4.11, this function uses a more
* efficient algorithm (Fisher-Yates). Therefore, the order of the items
* in the randomized list is different from the one in earlier versions
* if the same seed value is used for the random sequence.
*
* @param list the list whose order will be modified
* @note modifies the list in place
* @author Sean Harmer <sh@astro.keele.ac.uk>
*/
template<typename T> void randomize(QList<T>& list) {
// Fisher-Yates algorithm
for (int index = list.count() - 1; index > 0; --index) {
const int swapIndex = randomMax(index + 1);
qSwap(list[index], list[swapIndex]);
}
}
}
#endif
#endif // KRANDOM_H

View file

@ -1,220 +0,0 @@
/*
This file is part of the KDE libraries
Copyright (c) 1999 Sean Harmer <sh@astro.keele.ac.uk>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "krandomsequence.h"
#include "krandom.h"
static const int s_nShuffleTableSize = 32;
class KRandomSequence::Private
{
public:
// Generate the random number
void draw();
long lngSeed1;
long lngSeed2;
long lngShufflePos;
long shuffleArray[s_nShuffleTableSize];
};
//////////////////////////////////////////////////////////////////////////////
// Construction / Destruction
//////////////////////////////////////////////////////////////////////////////
KRandomSequence::KRandomSequence( long lngSeed1 ) : d(new Private)
{
// Seed the generator
setSeed( lngSeed1 );
}
KRandomSequence::~KRandomSequence()
{
delete d;
}
KRandomSequence::KRandomSequence(const KRandomSequence &a) : d(new Private)
{
*d = *a.d;
}
KRandomSequence & KRandomSequence::operator=(const KRandomSequence &a)
{
if ( this != &a ) {
*d = *a.d;
}
return *this;
}
//////////////////////////////////////////////////////////////////////////////
// Member Functions
//////////////////////////////////////////////////////////////////////////////
void KRandomSequence::setSeed( long lngSeed1 )
{
// Convert the positive seed number to a negative one so that the draw()
// function can intialise itself the first time it is called. We just have
// to make sure that the seed used != 0 as zero perpetuates itself in a
// sequence of random numbers.
if ( lngSeed1 < 0 )
{
d->lngSeed1 = -1;
}
else if (lngSeed1 == 0)
{
d->lngSeed1 = -((KRandom::random() & ~1)+1);
}
else
{
d->lngSeed1 = -lngSeed1;
}
}
static const long sMod1 = 2147483563;
static const long sMod2 = 2147483399;
void KRandomSequence::Private::draw()
{
static const long sMM1 = sMod1 - 1;
static const long sA1 = 40014;
static const long sA2 = 40692;
static const long sQ1 = 53668;
static const long sQ2 = 52774;
static const long sR1 = 12211;
static const long sR2 = 3791;
static const long sDiv = 1 + sMM1 / s_nShuffleTableSize;
// Long period (>2 * 10^18) random number generator of L'Ecuyer with
// Bayes-Durham shuffle and added safeguards. Returns a uniform random
// deviate between 0.0 and 1.0 (exclusive of the endpoint values). Call
// with a negative number to initialize; thereafter, do not alter idum
// between successive deviates in a sequence. RNMX should approximate
// the largest floating point value that is less than 1.
int j; // Index for the shuffle table
long k;
// Initialise
if ( lngSeed1 <= 0 )
{
lngSeed2 = lngSeed1;
// Load the shuffle table after 8 warm-ups
for ( j = s_nShuffleTableSize + 7; j >= 0; --j )
{
k = lngSeed1 / sQ1;
lngSeed1 = sA1 * ( lngSeed1 - k*sQ1) - k*sR1;
if ( lngSeed1 < 0 )
{
lngSeed1 += sMod1;
}
if ( j < s_nShuffleTableSize )
{
shuffleArray[j] = lngSeed1;
}
}
lngShufflePos = shuffleArray[0];
}
// Start here when not initializing
// Compute lngSeed1 = ( lngIA1*lngSeed1 ) % lngIM1 without overflows
// by Schrage's method
k = lngSeed1 / sQ1;
lngSeed1 = sA1 * ( lngSeed1 - k*sQ1 ) - k*sR1;
if ( lngSeed1 < 0 )
{
lngSeed1 += sMod1;
}
// Compute lngSeed2 = ( lngIA2*lngSeed2 ) % lngIM2 without overflows
// by Schrage's method
k = lngSeed2 / sQ2;
lngSeed2 = sA2 * ( lngSeed2 - k*sQ2 ) - k*sR2;
if ( lngSeed2 < 0 )
{
lngSeed2 += sMod2;
}
j = lngShufflePos / sDiv;
lngShufflePos = shuffleArray[j] - lngSeed2;
shuffleArray[j] = lngSeed1;
if ( lngShufflePos < 1 )
{
lngShufflePos += sMM1;
}
}
void
KRandomSequence::modulate(int i)
{
d->lngSeed2 -= i;
if ( d->lngSeed2 < 0 )
{
d->lngShufflePos += sMod2;
}
d->draw();
d->lngSeed1 -= i;
if ( d->lngSeed1 < 0 )
{
d->lngSeed1 += sMod1;
}
d->draw();
}
double
KRandomSequence::getDouble()
{
static const double finalAmp = 1.0 / double( sMod1 );
static const double epsilon = 1.2E-7;
static const double maxRand = 1.0 - epsilon;
double temp;
d->draw();
// Return a value that is not one of the endpoints
if ( ( temp = finalAmp * d->lngShufflePos ) > maxRand )
{
// We don't want to return 1.0
return maxRand;
}
else
{
return temp;
}
}
unsigned long
KRandomSequence::getLong(unsigned long max)
{
d->draw();
return max ? (((unsigned long) d->lngShufflePos) % max) : 0;
}
bool
KRandomSequence::getBool()
{
d->draw();
return (((unsigned long) d->lngShufflePos) & 1);
}

View file

@ -1,149 +0,0 @@
/* This file is part of the KDE libraries
Copyright (c) 1999 Sean Harmer <sh@astro.keele.ac.uk>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef K_RANDOM_SEQUENCE_H
#define K_RANDOM_SEQUENCE_H
#include <kdecore_export.h>
#include <QtCore/QList>
/**
* \class KRandomSequence krandomsequence.h <KRandomSequence>
*
* A class to create a pseudo-random sequence
*
* Given a seed number, this class will produce a sequence of
* pseudo-random numbers. This would typically be used in
* applications like games.
*
* In general, you should instantiate a KRandomSequence object and
* pass along your seed number in the constructor. From then on,
* simply call getDouble or getLong to obtain the next
* number in the sequence.
*
* @author Sean Harmer <sh@astro.keele.ac.uk>
*/
class KDECORE_EXPORT KRandomSequence
{
public:
/**
* Creates a pseudo-random sequence based on the seed lngSeed.
*
* A Pseudo-random sequence is different for each seed but can be
* reproduced by starting the sequence with the same seed.
*
* If you need a single value which needs to be unpredictable,
* you need to use KRandom::random() instead.
*
* @param lngSeed Seed to initialize the sequence with.
* If lngSeed is 0, the sequence is initialized with a value from
* KRandom::random().
*/
explicit KRandomSequence( long lngSeed = 0 );
/**
* Standard destructor
*/
virtual ~KRandomSequence();
/**
* Copy constructor
*/
KRandomSequence(const KRandomSequence &a);
/**
* Assignment
*/
KRandomSequence &operator=(const KRandomSequence &a);
/**
* Restart the sequence based on lngSeed.
* @param lngSeed Seed to initialize the sequence with.
* If lngSeed is 0, the sequence is initialized with a value from
* KRandom::random().
*/
void setSeed( long lngSeed = 0 );
/**
* Get the next number from the pseudo-random sequence.
*
* @return a pseudo-random double value between [0,1)
*/
double getDouble();
/**
* Get the next number from the pseudo-random sequence.
*
* @return a pseudo-random integer value between [0, max)
* with 0 <= max < 1.000.000
*/
unsigned long getLong(unsigned long max);
/**
* Get a boolean from the pseudo-random sequence.
*
* @return a boolean which is either true or false
*/
bool getBool();
/**
* Put a list in random order. Since KDE 4.11, this function uses a more
* efficient algorithm (Fisher-Yates). Therefore, the order of the items
* in the randomized list is different from the one in earlier versions
* if the same seed value is used for the random sequence.
*
* @param list the list whose order will be modified
* @note modifies the list in place
*/
template<typename T> void randomize(QList<T>& list) {
// Fisher-Yates algorithm
for (int index = list.count() - 1; index > 0; --index) {
const int swapIndex = getLong(index + 1);
qSwap(list[index], list[swapIndex]);
}
}
/**
* Modulate the random sequence.
*
* If S(i) is the sequence of numbers that will follow
* given the current state after calling modulate(i),
* then S(i) != S(j) for i != j and
* S(i) == S(j) for i == j.
*
* This can be useful in game situation where "undo" restores
* the state of the random sequence. If the game modulates the
* random sequence with the move chosen by the player, the
* random sequence will be identical whenever the player "redo"-s
* his or hers original move, but different when the player
* chooses another move.
*
* With this scenario "undo" can no longer be used to repeat a
* certain move over and over again until the computer reacts
* with a favorable response or to predict the response for a
* certain move based on the response to another move.
* @param i the sequence identified
*/
void modulate(int i);
private:
class Private;
Private *const d;
};
#endif

View file

@ -123,7 +123,7 @@ KTipDatabase::KTipDatabase( const QString &_tipFile )
d->loadTips( tipFile );
if ( !d->tips.isEmpty() )
d->currentTip = KRandom::random() % d->tips.count();
d->currentTip = KRandom::randomMax(d->tips.count());
}
KTipDatabase::KTipDatabase( const QStringList& tipsFiles )
@ -137,7 +137,7 @@ KTipDatabase::KTipDatabase( const QStringList& tipsFiles )
}
if ( !d->tips.isEmpty() )
d->currentTip = KRandom::random() % d->tips.count();
d->currentTip = KRandom::randomMax(d->tips.count());
}
KTipDatabase::~KTipDatabase()
@ -366,7 +366,7 @@ void KTipDialog::showMultiTip( QWidget *parent, const QStringList &tipFiles, boo
QDateTime lastShown = configGroup.readEntry( "TipLastShown", QDateTime() );
// Show tip roughly once a week
if ( lastShown.secsTo( QDateTime::currentDateTime() ) < (oneDay + (KRandom::random() % (10 * oneDay))) )
if ( lastShown.secsTo( QDateTime::currentDateTime() ) < (oneDay + (KRandom::randomMax(10 * oneDay))) )
return;
}

View file

@ -17,7 +17,7 @@
*/
#include "kpasswdroulettedialog.h"
#include "krandomsequence.h"
#include "krandom.h"
#include "klocale.h"
#include "kdebug.h"
@ -33,7 +33,6 @@ public:
bool isvalid;
QString validpasswd;
QMap<QString, QString> passwdmap;
KRandomSequence krandomsequence;
Ui::KPasswdRouletteDialogUI ui;
};
@ -98,7 +97,7 @@ void KPasswdRouletteDialog::addPasswd(const QString &label, const QString &passw
{
d->passwdmap.insert(label, passwd);
const int randomrange = d->krandomsequence.getLong(d->passwdmap.size());
const int randomrange = KRandom::randomMax(d->passwdmap.size());
const QList<QString> labelslist = d->passwdmap.keys();
const QString randomkey = labelslist.at(randomrange);
d->validpasswd = d->passwdmap.value(randomkey);

View file

@ -63,6 +63,7 @@
#include <kshortcut.h>
#include <kwindowsystem.h>
#include <kpushbutton.h>
#include <krandom.h>
#ifndef PLASMA_NO_KUTILS
#include <kcmoduleinfo.h>
@ -89,9 +90,6 @@
#include "svg.h"
#include "framesvg.h"
#include "popupapplet.h"
#include "private/applethandle_p.h"
#include "private/extenderitem_p.h"
#include "private/framesvg_p.h"
#include "theme.h"
#include "view.h"
#include "widgets/iconwidget.h"
@ -104,6 +102,9 @@
#include "abstractdialogmanager.h"
#include "pluginloader.h"
#include "private/applethandle_p.h"
#include "private/extenderitem_p.h"
#include "private/framesvg_p.h"
#include "private/associatedapplicationmanager_p.h"
#include "private/containment_p.h"
#include "private/extenderapplet_p.h"
@ -957,8 +958,8 @@ void Applet::setBackgroundHints(const BackgroundHints hints)
QSize overlaySize = d->background->elementSize("overlay");
//position is in the boundaries overlaySize.width()*2, overlaySize.height()
d->background->d->overlayPos.rx() = - (overlaySize.width() /2) + (overlaySize.width() /4) * (qrand() % (4 + 1));
d->background->d->overlayPos.ry() = (- (overlaySize.height() /2) + (overlaySize.height() /4) * (qrand() % (4 + 1)))/2;
d->background->d->overlayPos.rx() = - (overlaySize.width() /2) + (overlaySize.width() /4) * KRandom::randomMax(4 + 1);
d->background->d->overlayPos.ry() = (- (overlaySize.height() /2) + (overlaySize.height() /4) * (KRandom::randomMax(4 + 1)))/2;
}
} else if (d->background) {
qreal left, top, right, bottom;