Arquivos
hhvm/hphp/runtime/vm/fixed-string-map.cpp
T
Jordan DeLong ae9d50eb93 Use StringData::{i,}same in FixedStringMap comparisons
So it can use the inline word-at-a-time comparison thing, but
also just shares code.

Differential Revision: D952995
2013-09-05 19:39:53 -07:00

102 linhas
3.4 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#include "hphp/runtime/vm/fixed-string-map.h"
#include "hphp/runtime/base/complex-types.h"
#include "hphp/runtime/base/macros.h"
namespace HPHP {
TRACE_SET_MOD(runtime);
///////////////////////////////////////////////////////////////////////////////
class Func;
static const StringData* null_key;
template<bool CaseSensitive>
inline bool strEqual(const StringData* sd1, const StringData* sd2) {
if (sd1 == sd2) return true;
return CaseSensitive ? sd1->same(sd2) : sd1->isame(sd2);
}
template<class V, bool CaseSensitive, class E>
void FixedStringMap<V,CaseSensitive,E>::clear() {
if (m_table != (Elm*)&null_key) free(m_table);
m_table = nullptr;
m_mask = 0;
}
template<class V, bool CaseSensitive, class E>
void FixedStringMap<V,CaseSensitive,E>::init(int num) {
if (!num) {
m_table = (Elm*)&null_key;
m_mask = 0;
return;
}
static const double kLoadFactor = 0.80;
int capac = 1;
while (num >= kLoadFactor * capac) {
capac *= 2;
}
TRACE(1, "FixedStringMap::init: %d -> %d\n", num, capac);
assert(!m_table);
m_table = (Elm*)calloc(capac * sizeof(Elm), 1);
assert(m_table);
m_mask = capac - 1;
}
template<class V, bool CaseSensitive, class E>
void FixedStringMap<V,CaseSensitive,E>::add(const StringData* sd, const V& v) {
assert(sd->isStatic());
Elm* elm = &m_table[sd->hash() & m_mask];
UNUSED unsigned numProbes = 0;
while (elm->sd) {
assert(numProbes++ < m_mask + 1);
// Semantics for multiple insertion: new value wins.
if (strEqual<CaseSensitive>(elm->sd, sd)) break;
if (UNLIKELY(++elm == &m_table[m_mask + 1])) elm = m_table;
}
elm->sd = sd;
elm->data = v;
}
template<class V, bool CaseSensitive, class E>
V* FixedStringMap<V,CaseSensitive,E>::find(const StringData* sd) const {
Elm* elm = &m_table[sd->hash() & m_mask];
UNUSED unsigned numProbes = 0;
for(;;) {
assert(numProbes++ < m_mask + 1);
if (UNLIKELY(nullptr == elm->sd)) return nullptr;
if (strEqual<CaseSensitive>(elm->sd, sd)) return &elm->data;
if (UNLIKELY(++elm == &m_table[m_mask + 1])) elm = m_table;
}
}
template class FixedStringMap<Slot,false,Slot>;
template class FixedStringMap<Slot,true,Slot>;
template class FixedStringMap<Id,false,Id>;
template class FixedStringMap<Id,true,Id>;
template class FixedStringMap<Func*,false,int32_t>;
template class FixedStringMap<unsigned char* /* TCA */,true,int32_t>;
///////////////////////////////////////////////////////////////////////////////
}