mirror of
https://github.com/NixOS/nix.git
synced 2025-11-08 19:46:02 +01:00
Merge pull request #13680 from avnik/avnik/fast-base32
Improve base-32 hash decoding performance with reverse map
This commit is contained in:
commit
6ab8cbe31a
3 changed files with 20 additions and 18 deletions
|
|
@ -72,7 +72,19 @@ static std::string printHash16(const Hash & hash)
|
|||
}
|
||||
|
||||
// omitted: E O U T
|
||||
const std::string nix32Chars = "0123456789abcdfghijklmnpqrsvwxyz";
|
||||
constexpr char nix32Chars[] = "0123456789abcdfghijklmnpqrsvwxyz";
|
||||
|
||||
constexpr const std::array<unsigned char, 256> reverseNix32Map = [] {
|
||||
std::array<unsigned char, 256> map{};
|
||||
|
||||
for (size_t i = 0; i < map.size(); ++i)
|
||||
map[i] = 0xFF; // invalid
|
||||
|
||||
for (unsigned char i = 0; i < 32; ++i)
|
||||
map[static_cast<unsigned char>(nix32Chars[i])] = i;
|
||||
|
||||
return map;
|
||||
}();
|
||||
|
||||
static std::string printHash32(const Hash & hash)
|
||||
{
|
||||
|
|
@ -217,12 +229,11 @@ Hash::Hash(std::string_view rest, HashAlgorithm algo, bool isSRI)
|
|||
|
||||
for (unsigned int n = 0; n < rest.size(); ++n) {
|
||||
char c = rest[rest.size() - n - 1];
|
||||
unsigned char digit;
|
||||
for (digit = 0; digit < nix32Chars.size(); ++digit) /* !!! slow */
|
||||
if (nix32Chars[digit] == c)
|
||||
break;
|
||||
if (digit >= 32)
|
||||
throw BadHash("invalid base-32 hash '%s'", rest);
|
||||
unsigned char digit = reverseNix32Map[static_cast<unsigned char>(c)];
|
||||
|
||||
if (digit == 0xFF)
|
||||
throw BadHash("invalid base-32 hash: '%s'", rest);
|
||||
|
||||
unsigned int b = n * 5;
|
||||
unsigned int i = b / 8;
|
||||
unsigned int j = b % 8;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ constexpr inline size_t regularHashSize(HashAlgorithm type)
|
|||
|
||||
extern const StringSet hashAlgorithms;
|
||||
|
||||
extern const std::string nix32Chars;
|
||||
extern const std::array<unsigned char, 256> reverseNix32Map;
|
||||
|
||||
/**
|
||||
* @brief Enumeration representing the hash formats.
|
||||
|
|
|
|||
|
|
@ -13,20 +13,11 @@ static size_t refLength = 32; /* characters */
|
|||
|
||||
static void search(std::string_view s, StringSet & hashes, StringSet & seen)
|
||||
{
|
||||
static std::once_flag initialised;
|
||||
static bool isBase32[256];
|
||||
std::call_once(initialised, []() {
|
||||
for (unsigned int i = 0; i < 256; ++i)
|
||||
isBase32[i] = false;
|
||||
for (unsigned int i = 0; i < nix32Chars.size(); ++i)
|
||||
isBase32[(unsigned char) nix32Chars[i]] = true;
|
||||
});
|
||||
|
||||
for (size_t i = 0; i + refLength <= s.size();) {
|
||||
int j;
|
||||
bool match = true;
|
||||
for (j = refLength - 1; j >= 0; --j)
|
||||
if (!isBase32[(unsigned char) s[i + j]]) {
|
||||
if (reverseNix32Map[(unsigned char) s[i + j]] == 0xFF) {
|
||||
i += j + 1;
|
||||
match = false;
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue