gecko-dev/xpcom/ds/PerfectHash.h
Nika Layzell 5b24f801f7 Bug 1500927 - Add copy-free jsstring support to perfecthash.py, r=bzbarsky
This is needed for bug 1500926. It takes the approach of taking a JSFlatString
and using AutoAssertCannotGC to read the memory directly from the JS heap.
This lets us avoid re-encoding strings when performing lookups, which can be
advantageous.

Only ASCII strings are supported by this handler, and wide strings are hashed
as though they contain only values under 0x7f. This is OK as invalid keys to
perfecthash may return any hashtable entry.

Differential Revision: https://phabricator.services.mozilla.com/D9405
2018-10-24 20:11:01 -04:00

53 lines
1.6 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Helper routines for perfecthash.py. Not to be used directly. */
#ifndef mozilla_PerfectHash_h
#define mozilla_PerfectHash_h
#include "mozilla/TypeTraits.h"
namespace mozilla {
namespace perfecthash {
// 32-bit FNV offset basis and prime value.
// NOTE: Must match values in |perfecthash.py|
constexpr uint32_t FNV_OFFSET_BASIS = 0x811C9DC5;
constexpr uint32_t FNV_PRIME = 16777619;
/**
* Basic FNV hasher function used by perfecthash. Generic over the unit type.
*/
template<typename C>
inline uint32_t
Hash(uint32_t aBasis, const C* aKey, size_t aLen)
{
for (size_t i = 0; i < aLen; ++i) {
aBasis = (aBasis ^ static_cast<typename MakeUnsigned<C>::Type>(aKey[i])) * FNV_PRIME;
}
return aBasis;
}
/**
* Helper method for getting the index from a perfect hash.
* Called by code generated from |perfecthash.py|.
*/
template<typename C, typename Base, size_t NBases,
typename Entry, size_t NEntries>
inline const Entry&
Lookup(const C* aKey, size_t aLen,
const Base(& aTable)[NBases],
const Entry(& aEntries)[NEntries])
{
uint32_t basis = aTable[Hash(FNV_OFFSET_BASIS, aKey, aLen) % NBases];
return aEntries[Hash(basis, aKey, aLen) % NEntries];
}
} // namespace perfecthash
} // namespace mozilla
#endif // !defined(mozilla_PerfectHash_h)