44 #if !defined(PikaScriptImpl_h)
45 #include "PikaScriptImpl.h"
52 template<
class Super,
unsigned int CACHE_SIZE = 11>
class QuickVars :
public Super {
53 public:
typedef typename Super::ForScript::String String;
54 public:
typedef typename Super::ForScript::Value Value;
55 public:
typedef std::pair<String, Value> CacheEntry;
57 public:
unsigned int hash(
const String& s) {
58 unsigned int l =
static_cast<unsigned int>(s.size());
59 if (s.size() == 1 && s[0] >=
'a' && s[0] <=
'z')
return (s[0] -
'a') % CACHE_SIZE;
60 if (s.size() == 2 && s[0] ==
'$' && s[1] >=
'0' && s[1] <=
'9')
return s[1] -
'0';
61 return (s[0] * 1733 + s[l >> 2] * 2069 + s[l >> 1] * 2377 + s[l - 1] * 2851) % CACHE_SIZE;
64 public:
virtual bool assign(
const String& identifier,
const Value& value) {
65 if (identifier.empty())
return false;
66 unsigned int i = hash(identifier);
67 if (cache[i].first == identifier) { cache[i] = CacheEntry(identifier, value);
return true; }
68 if (!cache[i].first.empty()) Super::vars[cache[i].first] = cache[i].second;
69 cache[i] = CacheEntry(identifier, value);
73 public:
virtual bool erase(
const String& identifier) {
74 bool erased = (Super::vars.erase(identifier) != 0);
75 unsigned int i = hash(identifier);
76 if (cache[i].first == identifier) { cache[i] = std::pair<const String, Value>(); erased =
true; }
80 public:
virtual bool lookup(
const String& identifier, Value& result) {
81 if (identifier.empty())
return false;
82 unsigned int i = hash(identifier);
83 if (cache[i].first == identifier) { result = cache[i].second;
return true; }
84 typename Super::VariableMap::const_iterator it = Super::vars.find(identifier);
85 if (it == Super::vars.end())
return false;
86 if (!cache[i].first.empty()) Super::vars[cache[i].first] = cache[i].second;
87 cache[i] = CacheEntry(identifier, it->second);
92 public:
virtual void list(
const String& key,
typename Super::ForScript::Variables::VarList& list) {
93 for (
unsigned int i = 0; i < CACHE_SIZE; ++i)
94 if (!cache[i].first.empty()) Super::vars[cache[i].first] = cache[i].second;
95 for (
typename Super::VariableMap::const_iterator it = Super::vars.lower_bound(key)
96 ; it != Super::vars.end() && it->first.substr(0, key.size()) == key; ++it)
100 protected: CacheEntry cache[CACHE_SIZE];