blob: f79282e6dd2b2d4ca608205758781266ffdbd3bc [file] [log] [blame]
#pragma once
#ifndef GEODE_FWKLIB_GSRANDOM_H_
#define GEODE_FWKLIB_GSRANDOM_H_
/*
* 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>
#include <string>
#include <geode/internal/geode_base.hpp>
namespace apache {
namespace geode {
namespace client {
namespace testframework {
class GsRandom {
private:
std::default_random_engine engine;
std::uniform_int_distribution<int16_t> distBoolean;
std::uniform_int_distribution<int16_t> distUint8;
std::uniform_int_distribution<uint16_t> distUint16;
std::uniform_int_distribution<int32_t> distInt32;
std::uniform_int_distribution<uint32_t> distUint32;
std::uniform_real_distribution<double> distDouble;
GsRandom()
: distBoolean(std::numeric_limits<bool>::min(),
std::numeric_limits<bool>::max()),
distUint8(std::numeric_limits<uint8_t>::min(),
std::numeric_limits<uint8_t>::max()),
distUint16(),
distInt32(),
distUint32(),
distDouble() {
std::random_device seed;
engine = std::default_random_engine(seed());
}
~GsRandom() = default;
GsRandom(const GsRandom&) = delete;
GsRandom& operator=(const GsRandom&) = delete;
public:
/**
* Creates a new random number generator. Its seed is initialized to
* a value based on the random device.
*
*/
static GsRandom& getInstance();
/**
* @return the next pseudorandom, uniformly distributed <code>boolean</code>
* value from this random number generator's sequence.
*/
inline bool nextBoolean() { return 1 == distBoolean(engine); }
/**
* @return the next pseudorandom, uniformly distributed <code>uint16_t</code>
* value from this random number generator's sequence.
*/
inline uint16_t nextInt16() { return distUint16(engine); }
/**
* @return the next pseudorandom, uniformly distributed <code>byte</code>
* value from this random number generator's sequence.
*/
inline uint8_t nextByte() { return static_cast<uint8_t>(distUint8(engine)); }
/**
* @param min the minimum range (inclusive) for the pseudorandom.
* @param max the maximum range (inclusive) for the pseudorandom.
* @return the next pseudorandom, uniformly distributed <code>char</code>
* value from this random number generator's sequence.
* If max < min, returns 0 .
*/
inline uint8_t nextByte(uint8_t min, uint8_t max) {
return static_cast<uint8_t>(
distUint8(engine, decltype(distUint8)::param_type(min, max)));
}
/**
* @param max the maximum range (inclusive) for the pseudorandom.
* @return the next pseudorandom, uniformly distributed <code>double</code>
* value from this random number generator's sequence.
*/
inline double nextDouble(double max) { return nextDouble(0.0, max); }
/**
* @param min the minimum range (inclusive) for the pseudorandom.
* @param max the maximum range (inclusive) for the pseudorandom.
* @return the next pseudorandom, uniformly distributed <code>double</code>
* value from this random number generator's sequence within a range
* from min to max.
*/
inline double nextDouble(double min, double max) {
return distDouble(engine, decltype(distDouble)::param_type(min, max));
}
/**
* @param max the maximum range (inclusive) for the pseudorandom.
* @return the next pseudorandom, uniformly distributed <code>int32_t</code>
* value from this random number generator's sequence.
*/
inline int32_t nextInt(int32_t max) { return nextInt(0, max); }
/**
* @param min the minimum range (inclusive) for the pseudorandom.
* @param max the maximum range (inclusive) for the pseudorandom.
* @return the next pseudorandom, uniformly distributed <code>int32_t</code>
* value from this random number generator's sequence.
* If max < min, returns 0 .
*/
inline int32_t nextInt(int32_t min, int32_t max) {
return distInt32(engine, decltype(distInt32)::param_type(min, max));
}
/** @brief return random number where: min <= retValue < max */
static uint32_t random(uint32_t min, uint32_t max) {
return getInstance().nextInt(min, max - 1);
}
/** @brief return random number where: 0 <= retValue < max */
static uint32_t random(uint32_t max) { return random(0, max - 1); }
/** @brief return random double where: min <= retValue <= max */
static double random(double min, double max) {
return getInstance().nextDouble(min, max);
}
/** @brief return bounded random string,
* Like randomString(), but returns only only alphanumeric,
* underscore, or space characters.
*
* @param uSize the length of the random string to generate.
* @retval a bounded random string
*/
static std::string getAlphanumericString(uint32_t size) {
std::string str(size + 1, '\0');
static const char chooseFrom[] =
"0123456789 abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static const int32_t chooseSize = sizeof(chooseFrom) - 1;
for (uint32_t idx = 0; idx < size; idx++) {
str[idx] = chooseFrom[random(chooseSize)];
}
return str;
}
/** @brief return bounded random string,
* Like randomString(), but returns only only alphanumeric,
* underscore, or space characters.
*
* @param uSize the length of the random string to generate.
* @retval a bounded random string
*/
static void getAlphanumericString(uint32_t size, char* buffer) {
static const char chooseFrom[] =
"0123456789 abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static const int32_t chooseSize = sizeof(chooseFrom) - 1;
for (uint32_t idx = 0; idx < size; idx++) {
buffer[idx] = chooseFrom[random(chooseSize)];
}
}
/**
* @param max the maximum length of the random string to generate.
* @return a bounded random string with a length between 0 and
* max length inclusive.
*/
char* randomString(int32_t max, int32_t min = 0);
/**
* Like randomString(), but returns only readable characters.
*
* @param max the maximum length of the random string to generate.
* @return a bounded random string with a length between 0 and
* max length inclusive.
*/
char* randomReadableString(int32_t max, int32_t min = 0);
/**
* Like randomString(), but returns only alphanumeric, underscore, or space
* characters.
*
* @param max the maximum length of the random string to generate.
* @return a bounded random string with a length between 0 and
* max length inclusive.
*/
char* randomAlphanumericString(int32_t max, int32_t min);
};
} // namespace testframework
} // namespace client
} // namespace geode
} // namespace apache
#endif // GEODE_FWKLIB_GSRANDOM_H_