mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-29 20:22:02 +00:00
template specialized Hash functions for 16-bit hash types (#4631)
added access to HashFunction for 16 bit
This commit is contained in:
committed by
Wouter van Oortmerssen
parent
b24c0b07a3
commit
6e2e909b5c
@@ -57,13 +57,28 @@ template<typename T> T HashFnv1a(const char *input) {
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> struct NamedHashFunction {
|
template <> inline uint16_t HashFnv1<uint16_t>(const char *input) {
|
||||||
|
uint32_t hash = HashFnv1<uint32_t>(input);
|
||||||
|
return (hash >> 16) ^ (hash & 0xffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> inline uint16_t HashFnv1a<uint16_t>(const char *input) {
|
||||||
|
uint32_t hash = HashFnv1a<uint32_t>(input);
|
||||||
|
return (hash >> 16) ^ (hash & 0xffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> struct NamedHashFunction {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
typedef T (*HashFunction)(const char *);
|
typedef T (*HashFunction)(const char *);
|
||||||
HashFunction function;
|
HashFunction function;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const NamedHashFunction<uint16_t> kHashFunctions16[] = {
|
||||||
|
{ "fnv1_16", HashFnv1<uint16_t> },
|
||||||
|
{ "fnv1a_16", HashFnv1a<uint16_t> },
|
||||||
|
};
|
||||||
|
|
||||||
const NamedHashFunction<uint32_t> kHashFunctions32[] = {
|
const NamedHashFunction<uint32_t> kHashFunctions32[] = {
|
||||||
{ "fnv1_32", HashFnv1<uint32_t> },
|
{ "fnv1_32", HashFnv1<uint32_t> },
|
||||||
{ "fnv1a_32", HashFnv1a<uint32_t> },
|
{ "fnv1a_32", HashFnv1a<uint32_t> },
|
||||||
@@ -74,6 +89,17 @@ const NamedHashFunction<uint64_t> kHashFunctions64[] = {
|
|||||||
{ "fnv1a_64", HashFnv1a<uint64_t> },
|
{ "fnv1a_64", HashFnv1a<uint64_t> },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline NamedHashFunction<uint16_t>::HashFunction FindHashFunction16(
|
||||||
|
const char *name) {
|
||||||
|
std::size_t size = sizeof(kHashFunctions16) / sizeof(kHashFunctions16[0]);
|
||||||
|
for (std::size_t i = 0; i < size; ++i) {
|
||||||
|
if (std::strcmp(name, kHashFunctions16[i].name) == 0) {
|
||||||
|
return kHashFunctions16[i].function;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
inline NamedHashFunction<uint32_t>::HashFunction FindHashFunction32(
|
inline NamedHashFunction<uint32_t>::HashFunction FindHashFunction32(
|
||||||
const char *name) {
|
const char *name) {
|
||||||
std::size_t size = sizeof(kHashFunctions32) / sizeof(kHashFunctions32[0]);
|
std::size_t size = sizeof(kHashFunctions32) / sizeof(kHashFunctions32[0]);
|
||||||
|
|||||||
@@ -26,8 +26,15 @@ int main(int argc, char *argv[]) {
|
|||||||
const char *name = argv[0];
|
const char *name = argv[0];
|
||||||
if (argc <= 1) {
|
if (argc <= 1) {
|
||||||
printf("%s HASH [OPTION]... STRING... [-- STRING...]\n", name);
|
printf("%s HASH [OPTION]... STRING... [-- STRING...]\n", name);
|
||||||
printf("Available hashing algorithms:\n 32 bit:\n");
|
printf("Available hashing algorithms:\n");
|
||||||
size_t size = sizeof(flatbuffers::kHashFunctions32) /
|
printf(" 16 bit:\n");
|
||||||
|
size_t size = sizeof(flatbuffers::kHashFunctions16) /
|
||||||
|
sizeof(flatbuffers::kHashFunctions16[0]);
|
||||||
|
for (size_t i = 0; i < size; ++i) {
|
||||||
|
printf(" * %s\n", flatbuffers::kHashFunctions16[i].name);
|
||||||
|
}
|
||||||
|
printf(" 32 bit:\n");
|
||||||
|
size = sizeof(flatbuffers::kHashFunctions32) /
|
||||||
sizeof(flatbuffers::kHashFunctions32[0]);
|
sizeof(flatbuffers::kHashFunctions32[0]);
|
||||||
for (size_t i = 0; i < size; ++i) {
|
for (size_t i = 0; i < size; ++i) {
|
||||||
printf(" * %s\n", flatbuffers::kHashFunctions32[i].name);
|
printf(" * %s\n", flatbuffers::kHashFunctions32[i].name);
|
||||||
@@ -48,12 +55,14 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
const char *hash_algorithm = argv[1];
|
const char *hash_algorithm = argv[1];
|
||||||
|
|
||||||
|
flatbuffers::NamedHashFunction<uint16_t>::HashFunction hash_function16 =
|
||||||
|
flatbuffers::FindHashFunction16(hash_algorithm);
|
||||||
flatbuffers::NamedHashFunction<uint32_t>::HashFunction hash_function32 =
|
flatbuffers::NamedHashFunction<uint32_t>::HashFunction hash_function32 =
|
||||||
flatbuffers::FindHashFunction32(hash_algorithm);
|
flatbuffers::FindHashFunction32(hash_algorithm);
|
||||||
flatbuffers::NamedHashFunction<uint64_t>::HashFunction hash_function64 =
|
flatbuffers::NamedHashFunction<uint64_t>::HashFunction hash_function64 =
|
||||||
flatbuffers::FindHashFunction64(hash_algorithm);
|
flatbuffers::FindHashFunction64(hash_algorithm);
|
||||||
|
|
||||||
if (!hash_function32 && !hash_function64) {
|
if (!hash_function16 && !hash_function32 && !hash_function64) {
|
||||||
printf("\"%s\" is not a known hash algorithm.\n", hash_algorithm);
|
printf("\"%s\" is not a known hash algorithm.\n", hash_algorithm);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -87,7 +96,9 @@ int main(int argc, char *argv[]) {
|
|||||||
ss << std::hex;
|
ss << std::hex;
|
||||||
ss << "0x";
|
ss << "0x";
|
||||||
}
|
}
|
||||||
if (hash_function32)
|
if (hash_function16)
|
||||||
|
ss << hash_function16(arg);
|
||||||
|
else if (hash_function32)
|
||||||
ss << hash_function32(arg);
|
ss << hash_function32(arg);
|
||||||
else if (hash_function64)
|
else if (hash_function64)
|
||||||
ss << hash_function64(arg);
|
ss << hash_function64(arg);
|
||||||
|
|||||||
@@ -681,6 +681,13 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
|
|||||||
auto hash_name = field->attributes.Lookup("hash");
|
auto hash_name = field->attributes.Lookup("hash");
|
||||||
if (hash_name) {
|
if (hash_name) {
|
||||||
switch ((type.base_type == BASE_TYPE_VECTOR) ? type.element : type.base_type) {
|
switch ((type.base_type == BASE_TYPE_VECTOR) ? type.element : type.base_type) {
|
||||||
|
case BASE_TYPE_SHORT:
|
||||||
|
case BASE_TYPE_USHORT: {
|
||||||
|
if (FindHashFunction16(hash_name->constant.c_str()) == nullptr)
|
||||||
|
return Error("Unknown hashing algorithm for 16 bit types: " +
|
||||||
|
hash_name->constant);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case BASE_TYPE_INT:
|
case BASE_TYPE_INT:
|
||||||
case BASE_TYPE_UINT: {
|
case BASE_TYPE_UINT: {
|
||||||
if (FindHashFunction32(hash_name->constant.c_str()) == nullptr)
|
if (FindHashFunction32(hash_name->constant.c_str()) == nullptr)
|
||||||
@@ -697,7 +704,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return Error(
|
return Error(
|
||||||
"only int, uint, long and ulong data types support hashing.");
|
"only short, ushort, int, uint, long and ulong data types support hashing.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto cpp_type = field->attributes.Lookup("cpp_type");
|
auto cpp_type = field->attributes.Lookup("cpp_type");
|
||||||
@@ -1278,6 +1285,18 @@ CheckedError Parser::ParseHash(Value &e, FieldDef *field) {
|
|||||||
assert(field);
|
assert(field);
|
||||||
Value *hash_name = field->attributes.Lookup("hash");
|
Value *hash_name = field->attributes.Lookup("hash");
|
||||||
switch (e.type.base_type) {
|
switch (e.type.base_type) {
|
||||||
|
case BASE_TYPE_SHORT: {
|
||||||
|
auto hash = FindHashFunction16(hash_name->constant.c_str());
|
||||||
|
int16_t hashed_value = static_cast<int16_t>(hash(attribute_.c_str()));
|
||||||
|
e.constant = NumToString(hashed_value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_USHORT: {
|
||||||
|
auto hash = FindHashFunction16(hash_name->constant.c_str());
|
||||||
|
uint16_t hashed_value = hash(attribute_.c_str());
|
||||||
|
e.constant = NumToString(hashed_value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case BASE_TYPE_INT: {
|
case BASE_TYPE_INT: {
|
||||||
auto hash = FindHashFunction32(hash_name->constant.c_str());
|
auto hash = FindHashFunction32(hash_name->constant.c_str());
|
||||||
int32_t hashed_value = static_cast<int32_t>(hash(attribute_.c_str()));
|
int32_t hashed_value = static_cast<int32_t>(hash(attribute_.c_str()));
|
||||||
|
|||||||
Reference in New Issue
Block a user