-
Notifications
You must be signed in to change notification settings - Fork 0
Guidpcg #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Guidpcg #2
Conversation
Modified bdlb.mem to add PCGAdded bdlb_pcg.t.cpp
khlebnikov
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some comments to the GuidUtil integration. Will make another review round when you apply all the changes we discussed.
…tation of GuidUtil::generateNonSecure; modified PCG documentation
…le; modified bldb_guidutil.cpp and bldb.mem accordingly
| if (0 != RandomDevice::getRandomBytes((unsigned char *)&state, | ||
| sizeof(state))) { | ||
| state = time(NULL) ^ (intptr_t)&bsl::printf; // fallback state | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(for the future) This might be a candidate for factoring into local function - this is repeated twice here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I considered that. Also in the GuidUtil implementation, the following code is duplicated (by my new function). Perhaps a candidate for factoring as well:
while (bytes != end) {
typedef unsigned char uc;
bytes[6] = uc(0x40 | (bytes[6] & 0x0F));
bytes[8] = uc(0x80 | (bytes[8] & 0x3F));
bytes += Guid::k_GUID_NUM_BYTES;
}
My reasoning there was that I ought not touch working code.
| ///Example 1: Generating random 32-bit numbers | ||
| ///- - - - - - - - - - - - - - - - - - - - - - | ||
| // The PCGRandomGenerator constructor takes two 64-bit constants (the initial | ||
| // state, and the rng sequence selector. Instances of PCGRandomGenerator with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // state, and the rng sequence selector. Instances of PCGRandomGenerator with | |
| // state, and the rng sequence selector. Instances of 'PCGRandomGenerator' with |
mversche
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would lean towards having:
bsl::uint32_t bdlb::Random::generatePcg(PcgRandomGenerator *);
Which I realize is window dressing, but is where users will likely first look for a function providing random numbers.
groups/bdl/bdlb/bdlb_guidutil.h
Outdated
| // The behavior is undefined unless 'result' refers to a contiguous | ||
| // sequence of at least 'numGuids' Guid objects. Note that this | ||
| // function uses the PCG random engine to generate high quality, albeit | ||
| // not cryptographically secure, random numbers for Guids. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should explain why someone might chose t use this method:
...random numbers for Guids, which is typically faster than generating cryptographically secure guids.
| // specified, 0 is used as the initial state. If 'streamSelector' is | ||
| // not specified, 1 is used as the stream selector. | ||
|
|
||
| //! PCGRandomGenerator(const PCGRandomGenerator& original) = default; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this a value semantic type?
|
|
||
| public: | ||
| // CREATORS | ||
| PCGRandomGenerator(bsl::uint64_t initState = 0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are 'initState' and 'streamSelector'? they are not explained what they do or control.
Further, there needs to be some discussion in this component (probably in whatever usage example we choose to show first) how these values should typically be chosen. This should probably show both how one might want to deterministically select them, and how one might want to generate them randomly from bdlb_RandomDevice (or whatever).
In summary: explain what initState and streamSelector do in the function doc here, then have the function doc refer to a usage example showing how someone might use these values
…nced documentation
…these; enhanced Pcgrandomgenerator documentation
groups/bdl/bdlb/bdlb_guidutil.h
Outdated
| // 'variant' bits set to '10' and four 'version' bits set to '0100'. | ||
|
|
||
| static void generateNonSecure(Guid *result, bsl::size_t numGuids = 1); | ||
| // Generate a sequence of GUIDs meeting the RFC 4122 version 4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bde-format
groups/bdl/bdlb/bdlb_guidutil.h
Outdated
| // is typically faster than generating cryptographically secure Guids. | ||
|
|
||
| static Guid generateNonSecure(); | ||
| // Generate and return a single GUID meeting the RFC 4122 version 4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // Generate and return a single GUID meeting the RFC 4122 version 4 | |
| // Generate and return a single GUID meeting the RFC 4122 version 4 |
|
|
||
| cout << "TEST " << __FILE__ << " CASE " << test << endl;; | ||
| switch (test) { case 0: | ||
| case 8: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make this case 7, Usage - case 8.
| // int Die::roll() | ||
| // { | ||
| // int result; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
//
|
|
||
| // int d1 = a.roll(); | ||
| // int d2 = b.roll(); | ||
| // ASSERT(d2 == d1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // ASSERT(d2 == d1); | |
| // assert(d2 == d1); |
groups/bdl/bdlb/bdlb_random.h
Outdated
|
|
||
| static bsl::uint32_t generatePcg(PcgRandomGenerator *generator); | ||
| // Return the next unsigned 32-bit random number generated from the | ||
| // specified PcgRandomGenerator. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // specified PcgRandomGenerator. | |
| // specified 'PcgRandomGenerator'. |
| "==============" "\n"; | ||
|
|
||
| enum { NUM_ITERATIONS = 2000 }; | ||
| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add generatePcg to the test plan.
…anced Random test documentation
khlebnikov
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple small comments.
groups/bdl/bdlb/bdlb_guidutil.cpp
Outdated
|
|
||
| void GuidUtil::generate(unsigned char *result, bsl::size_t numGuids) | ||
| namespace { | ||
| inline |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| inline |
| void GuidUtil::generate(unsigned char *result, bsl::size_t numGuids) | ||
| namespace { | ||
| inline | ||
| void makeRfc4122Compliant(unsigned char *bytes, unsigned char *end) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this function into the anonymous namespace at the beginning of the file: we always put such implementation helper functions before implementation of any functions from the header.
| // algorithm. PCG stands for "permuted congruential generator." The state | ||
| // is 64 bits. It uses a so-called stream selector, also 64 bits. For | ||
| // details, please refer below to the constructor. For details of the | ||
| // algorithm,see http://www.pcg-random.org. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // algorithm,see http://www.pcg-random.org. | |
| // algorithm, see http://www.pcg-random.org. |
…; added documentation to GuidUtil component; changed to the way streamSelector is generated in GuidUtil::generateNonSecure
… beginning of the file; cleaned up some formatting
groups/bdl/bdlb/bdlb_guidutil.h
Outdated
| ///RANDOMNESS: | ||
| ///----------- | ||
| // There are two different ways provided for generating GUIDs: | ||
| // 1. 'generate': comparatively more secure but slower | ||
| // 2. 'generateNonSecure': comparatively less secure but faster | ||
| // 'generateNonSecure' employs the PCG random engine toproduce | ||
| // high-quality, but not cryptographically secure, GUIDs. | ||
| // |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I think the proper name for this section is
Cryptographic Securityrather thanRANDOMNESS EXAMPLESbelow refers to theGUID String Formatsection, so the security section should go after those examples.- We need to provide the people who read our doc with a coherent narrative, otherwise it's difficult to understand without prior knowledge. Maybe something like this:
'GuidUtil' provides two families of functions for generating GUIDs: 'generate' and 'generateNonSecure'. The primary difference between them is cryptographic security of the resulting GUIDs and performance. The slower 'generate' methods aim to produce cryptographically secure GUIDs by accessing the underlying system resources to obtain truly random numbers, whereas faster 'generateNonSecure' methods use a fast high-quality (but not strictly cryptographically secure) in-process random-number generator.
groups/bdl/bdlb/bdlb_guidutil.h
Outdated
| // sequence of at least 'numGuids' Guid objects. Note that this | ||
| // function uses the PCG random engine to generate high quality, albeit | ||
| // not cryptographically secure, random numbers for Guids. This method | ||
| // is typically faster than generating cryptographically secure Guids. | ||
| // not cryptographically secure, random numbers for GUIDs. This method | ||
| // is typically faster than generating cryptographically secure GUIDs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should remove mention of our implementation details from out public documentation. Maybe we decide to switch to something else than PCG - it shouldn't matter to our clients. Given our changes to the component documentation, I think we should only leave Note that this function generates high-quality, albeit not cryptographically secure GUIDs. Kind of "for safety" and to explain the function name.
| // linear congruential generator. In the PCG algorithm, rather than a single | ||
| // seed parameter, there are two parameters, 'initState' and 'streamSelector'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // linear congruential generator. In the PCG algorithm, rather than a single | |
| // seed parameter, there are two parameters, 'initState' and 'streamSelector'. | |
| // linear congruential generator. The PCG algorithm is seeded with two | |
| // values: its initial state and a "stream selector". |
| // linear congruential generator. | ||
| // linear congruential generator. In the PCG algorithm, rather than a single | ||
| // seed parameter, there are two parameters, 'initState' and 'streamSelector'. | ||
| // The use of a second parameter ('streamSelector') is to address a potential |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // The use of a second parameter ('streamSelector') is to address a potential | |
| // Stream selector is intended to address a potential |
| // linear congruential generator. In the PCG algorithm, rather than a single | ||
| // seed parameter, there are two parameters, 'initState' and 'streamSelector'. | ||
| // The use of a second parameter ('streamSelector') is to address a potential | ||
| // hazard when multiple instances of a random number generator are used: an |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // hazard when multiple instances of a random number generator are used: an | |
| // hazard of multiple instances of a random number generators having unintended correlation between their outputs. |
| // This class implements a random number generator (RNG) based on the PCG | ||
| // algorithm. PCG stands for "permuted congruential generator." The state | ||
| // is 64 bits. It uses a so-called stream selector, also 64 bits. For | ||
| // details, please refer below to the constructor. For details of the | ||
| // algorithm, see http://www.pcg-random.org. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorporate this sentence PCG stands for "permuted congruential generator." and the link in component doc. Leave only the first sentence here.
| PcgRandomGenerator(bsl::uint64_t initState = 0, | ||
| bsl::uint64_t streamSelector = 1); | ||
| // Create a 'PcgRandomGenerator' object and seed it with the optionally | ||
| // specified 'initState' and 'streamSelector.' If 'initState' is not |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // specified 'initState' and 'streamSelector.' If 'initState' is not | |
| // specified 'initState' and 'streamSelector'. If 'initState' is not |
The ticks are for code font, they don't abide by the rules of English text, so the period goes outside the quote.
| // not specified, 1 is used as the stream selector. 'initState' is the | ||
| // starting state for the RNG. Any 64-bit value may be passed. | ||
| // 'streamSelector' selects the output sequence for the RNG. Any | ||
| // 64-bit value may be passed, although only the low 63 bits are | ||
| // significant. There are 2^63 different RNGs available, and | ||
| // 'streamSelector' selects from among them. Invoking different |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too much information here, which is at the same time unclear. Most of it covered in component doc, so let's keep this simple.
| // not specified, 1 is used as the stream selector. 'initState' is the | |
| // starting state for the RNG. Any 64-bit value may be passed. | |
| // 'streamSelector' selects the output sequence for the RNG. Any | |
| // 64-bit value may be passed, although only the low 63 bits are | |
| // significant. There are 2^63 different RNGs available, and | |
| // 'streamSelector' selects from among them. Invoking different | |
| // not specified, 1 is used as the stream selector. Only the | |
| // low 63 bits of 'streamSelector' are | |
| // significant. Note that invoking different |
groups/bdl/bdlb/bdlb_random.t.cpp
Outdated
| // Extracted from component header file. For 'generatePcg' (PCG) | ||
| // usage example please refer bdlb_pcgrandomgenerator.t.cpp. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // Extracted from component header file. For 'generatePcg' (PCG) | |
| // usage example please refer bdlb_pcgrandomgenerator.t.cpp. | |
| // Extracted from component header file. |
This is not really relevant for the test driver. The PCG stuff should be just be linked in component documentation in @SEE_ALSO section - search the code for where it goes and how it's formatted.
groups/bdl/bdlb/bdlb_random.h
Outdated
|
|
||
| static bsl::uint32_t generatePcg(PcgRandomGenerator *generator); | ||
| // Return the next unsigned 32-bit random number generated from the | ||
| // specified 'PcgRandomGenerator'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // specified 'PcgRandomGenerator'. | |
| // specified 'generator'. |
groups/bdl/bdlb/bdlb_guidutil.h
Outdated
| // secure, random numbers for GUIDs. This method is typically faster | ||
| // than generating cryptographically secure GUIDs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the last sentence - it doesn't refer to this function only, thus this information is in the component doc. Also please update the rest of generateNonSecure function doc to match.
| // a backup mechanism for obtaining random bytes. | ||
| ///Example 2: Generating unique random sequences of 32-bit numbers | ||
| ///- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
| // This example shows how one might construct two sequences of random numbers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took a stab at this example - please see the differences in the delivery style (also note that code is indented with 2 spaces after //):
///Example 2: Using stream selector to guarantee uncorrelated sequences
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// This example illustrates how the stream selector can be used to guarantee
// that two distinct instances of 'PCGRandomGenerator' produce uncorrelated
// sequences.
//
// First, we use the 'RandomDevice' to choose the initial states for the
// generators using a source of true randomness:
//..
// uint64_t state1;
// int rc = bdlb::RandomDevice::getRandomBytes(
// reinterpret_cast<unsigned char *>(&state1), sizeof(state1));
// (void)rc; // error handling omitted
//
// uint64_t state2;
// int rc = bdlb::RandomDevice::getRandomBytes(
// reinterpret_cast<unsigned char *>(&state2), sizeof(state2));
// (void)rc; // error handling omitted
//..
// Then we select two distinct stream selectors for the generators, which, due
// to the PCG algorithmic properties will guarantee that the sequences will be
// uncorrelated even if the initial state is exactly the same:
//..
// const uint64_t streamSelector1 = 1;
// const uint64_t streamSelector2 = 2;
//..
// Finally, we initialize the generators with their respective initial states
// and stream selectors and check that they produce distinct sequences of
// random numbers. The check is guaranteed to pass even in the rare, but
// possible case of 'state1 == state2'.
//..
// bdlb::PcgRandomGenerator rng1(state1, streamSelector1);
// bdlb::PcgRandomGenerator rng2(state2, streamSelector2);
//
// const int NUM_VALUES = 1000;
// bsl::vector<bsl::uint32_t> sequence1(NUM_VALUES);
// bsl::vector<bsl::uint32_t> sequence2(NUM_VALUES);
//
// for (int i = 0; i < NUM_VALUES; ++i) {
// sequence1[i] = rng1.generate();
// sequence2[i] = rng2.generate();
// }
//
// assert(sequence1 != sequence2);
//..
| // stands for "permuted congruential generator." For details of the algorithm, | ||
| // see http://www.pcg-random.org. The PCG technique employs the concepts of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // stands for "permuted congruential generator." For details of the algorithm, | |
| // see http://www.pcg-random.org. The PCG technique employs the concepts of | |
| // stands for "permuted congruential generator" (see http://www.pcg-random.org | |
| // for details). The PCG technique employs the concepts of |
* add references to 'bdlb_stringviewutil' in the doc * add 'std::string' overloads; test 'toLower', 'toUpper' * 'std::string' overloads: test 'pad' * 'std::string' overloads: test 'ltrim', 'rtrim', 'trim' * add 'std::pmr::string' overloads; test 'toLower', 'toUpper' * clear compiler warnings and bde_verify diagnostics * 'std::pmr::string' overloads: test 'pad' * 'std::pmr::string' overloads: test 'ltrim', 'rtrim', 'trim' * fix build for use of 'std::pmr::string' * adjust 'bdlb_string.h' doc * clear bde_verify warning * doc improvements prompted by Attila's review comments * implementation changes suggested by Attila * test driver changes per Attila's review comments * final test driver changes per Attila's review comments * address Attila's review comments
No description provided.