4 #include "sqpcheader.h" 7 #include "sqfuncproto.h" 10 SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize)
12 SQInteger pow2size=MINPOWER2;
13 while(nInitialSize>pow2size)pow2size=pow2size<<1;
18 ADD_TO_CHAIN(&_sharedstate->_gc_chain,
this);
21 void SQTable::Remove(
const SQObjectPtr &key)
24 _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
32 void SQTable::AllocNodes(SQInteger nSize)
34 _HashNode *nodes=(_HashNode *)SQ_MALLOC(
sizeof(_HashNode)*nSize);
35 for(SQInteger i=0;i<nSize;i++){
36 new (&nodes[i]) _HashNode;
41 _firstfree=&_nodes[_numofnodes-1];
44 void SQTable::Rehash(
bool force)
46 SQInteger oldsize=_numofnodes;
48 if(oldsize<4)oldsize=4;
49 _HashNode *nold=_nodes;
50 SQInteger nelems=CountUsed();
51 if (nelems >= oldsize-oldsize/4)
52 AllocNodes(oldsize*2);
53 else if (nelems <= oldsize/4 &&
55 AllocNodes(oldsize/2);
61 for (SQInteger i=0; i<oldsize; i++) {
62 _HashNode *old = nold+i;
63 if (type(old->key) != OT_NULL)
64 NewSlot(old->key,old->val);
66 for(SQInteger k=0;k<oldsize;k++)
68 SQ_FREE(nold,oldsize*
sizeof(_HashNode));
71 SQTable *SQTable::Clone()
73 SQTable *nt=Create(_opt_ss(
this),_numofnodes);
76 while((ridx=Next(
true,ridx,key,val))!=-1){
79 nt->SetDelegate(_delegate);
83 bool SQTable::Get(
const SQObjectPtr &key,SQObjectPtr &val)
85 if(type(key) == OT_NULL)
87 _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
89 val = _realval(n->val);
94 bool SQTable::NewSlot(
const SQObjectPtr &key,
const SQObjectPtr &val)
96 assert(type(key) != OT_NULL);
97 SQHash h = HashObj(key) & (_numofnodes - 1);
98 _HashNode *n = _Get(key, h);
103 _HashNode *mp = &_nodes[h];
110 if(type(mp->key) != OT_NULL) {
112 SQHash mph = HashObj(mp->key) & (_numofnodes - 1);
115 if (mp > n && (othern = &_nodes[mph]) != mp){
117 while (othern->next != mp){
118 assert(othern->next !=
NULL);
119 othern = othern->next;
139 if (type(_firstfree->key) == OT_NULL && _firstfree->next ==
NULL) {
144 else if (_firstfree == _nodes)
break;
148 return NewSlot(key, val);
151 SQInteger SQTable::Next(
bool getweakrefs,
const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
154 while (idx < _numofnodes) {
155 if(type(_nodes[idx].key) != OT_NULL) {
157 _HashNode &n = _nodes[idx];
159 outval = getweakrefs?(SQObject)n.val:_realval(n.val);
170 bool SQTable::Set(
const SQObjectPtr &key,
const SQObjectPtr &val)
172 _HashNode *n = _Get(key, HashObj(key) & (_numofnodes - 1));
180 void SQTable::_ClearNodes()
182 for(SQInteger i = 0;i < _numofnodes; i++) { _nodes[i].key =
_null_; _nodes[i].val =
_null_; }
185 void SQTable::Finalize()
191 void SQTable::Clear()
SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx)