зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1546853: Implement mozilla::Variant::addTagToHash. r=froydnj
Define the Variant::addTagToHash method, which perturbs a hash value according to the variant's current alternative's tag. This makes it easier to avoid collisions in variants in which different alternatives might hash similarly. Tests included. Differential Revision: https://phabricator.services.mozilla.com/D28768 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
dc4531ece2
Коммит
52031426cb
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/FunctionTypeTraits.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/OperatorNewExtensions.h"
|
||||
#include "mozilla/TemplateLib.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
@ -759,6 +760,15 @@ class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS MOZ_NON_PARAM Variant {
|
|||
return Impl::matchN(*this, std::forward<M0>(aM0), std::forward<M1>(aM1),
|
||||
std::forward<Ms>(aMs)...);
|
||||
}
|
||||
|
||||
/**
|
||||
* Incorporate the current variant's tag into hashValue.
|
||||
* Note that this does not hash the actual contents; you must take
|
||||
* care of that yourself, perhaps by using a match.
|
||||
*/
|
||||
mozilla::HashNumber addTagToHash(mozilla::HashNumber hashValue) {
|
||||
return mozilla::AddToHash(hashValue, tag);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -473,6 +473,37 @@ static void testRvalueMatcher() {
|
|||
MOZ_RELEASE_ASSERT(v.match(Describer()) == Describer::little);
|
||||
}
|
||||
|
||||
static void testAddTagToHash() {
|
||||
printf("testAddToHash\n");
|
||||
using V = Variant<uint8_t, uint16_t, uint32_t, uint64_t>;
|
||||
|
||||
// We don't know what our hash function is, and these are certainly not all
|
||||
// true under all hash functions. But they are probably true under almost any
|
||||
// decent hash function, and our aim is simply to establish that the tag
|
||||
// *does* influence the hash value.
|
||||
{
|
||||
mozilla::HashNumber h8 = V(uint8_t(1)).addTagToHash(0);
|
||||
mozilla::HashNumber h16 = V(uint16_t(1)).addTagToHash(0);
|
||||
mozilla::HashNumber h32 = V(uint32_t(1)).addTagToHash(0);
|
||||
mozilla::HashNumber h64 = V(uint64_t(1)).addTagToHash(0);
|
||||
|
||||
MOZ_RELEASE_ASSERT(h8 != h16 && h8 != h32 && h8 != h64);
|
||||
MOZ_RELEASE_ASSERT(h16 != h32 && h16 != h64);
|
||||
MOZ_RELEASE_ASSERT(h32 != h64);
|
||||
}
|
||||
|
||||
{
|
||||
mozilla::HashNumber h8 = V(uint8_t(1)).addTagToHash(0x124356);
|
||||
mozilla::HashNumber h16 = V(uint16_t(1)).addTagToHash(0x124356);
|
||||
mozilla::HashNumber h32 = V(uint32_t(1)).addTagToHash(0x124356);
|
||||
mozilla::HashNumber h64 = V(uint64_t(1)).addTagToHash(0x124356);
|
||||
|
||||
MOZ_RELEASE_ASSERT(h8 != h16 && h8 != h32 && h8 != h64);
|
||||
MOZ_RELEASE_ASSERT(h16 != h32 && h16 != h64);
|
||||
MOZ_RELEASE_ASSERT(h32 != h64);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
testDetails();
|
||||
testSimple();
|
||||
|
@ -487,6 +518,7 @@ int main() {
|
|||
testMatchingLambda();
|
||||
testMatchingLambdas();
|
||||
testRvalueMatcher();
|
||||
testAddTagToHash();
|
||||
|
||||
printf("TestVariant OK!\n");
|
||||
return 0;
|
||||
|
|
Загрузка…
Ссылка в новой задаче