#include "sqfuncproto.h"\r
#include "sqclosure.h"\r
\r
-SQTable::SQTable(SQSharedState *ss,int nInitialSize)\r
+SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize)\r
{\r
- int pow2size=MINPOWER2;\r
+ SQInteger pow2size=MINPOWER2;\r
while(nInitialSize>pow2size)pow2size=pow2size<<1;\r
AllocNodes(pow2size);\r
- _uiRef = 0;\r
_usednodes = 0;\r
_delegate = NULL;\r
INIT_CHAIN();\r
}\r
}\r
\r
-void SQTable::AllocNodes(int nSize)\r
+void SQTable::AllocNodes(SQInteger nSize)\r
{\r
_HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize);\r
- for(int i=0;i<nSize;i++){\r
+ for(SQInteger i=0;i<nSize;i++){\r
new (&nodes[i]) _HashNode;\r
nodes[i].next=NULL;\r
}\r
_firstfree=&_nodes[_numofnodes-1];\r
}\r
\r
-int SQTable::CountUsed()\r
-{\r
- /*int n=0;\r
- for(int i=0;i<_numofnodes;i++){\r
- if(type(_nodes[i].key)!=OT_NULL) n++;\r
- }*/\r
- return _usednodes;\r
-}\r
-\r
void SQTable::Rehash(bool force)\r
{\r
- int oldsize=_numofnodes;\r
+ SQInteger oldsize=_numofnodes;\r
//prevent problems with the integer division\r
if(oldsize<4)oldsize=4;\r
_HashNode *nold=_nodes;\r
- int nelems=CountUsed();\r
+ SQInteger nelems=CountUsed();\r
if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */\r
AllocNodes(oldsize*2);\r
else if (nelems <= oldsize/4 && /* less than 1/4? */\r
else\r
return;\r
_usednodes = 0;\r
- for (int i=0; i<oldsize; i++) {\r
+ for (SQInteger i=0; i<oldsize; i++) {\r
_HashNode *old = nold+i;\r
if (type(old->key) != OT_NULL)\r
NewSlot(old->key,old->val);\r
}\r
- for(int k=0;k<oldsize;k++) \r
+ for(SQInteger k=0;k<oldsize;k++) \r
nold[k].~_HashNode();\r
SQ_FREE(nold,oldsize*sizeof(_HashNode));\r
}\r
SQTable *nt=Create(_opt_ss(this),_numofnodes);\r
SQInteger ridx=0;\r
SQObjectPtr key,val;\r
- while((ridx=Next(ridx,key,val))!=-1){\r
+ while((ridx=Next(true,ridx,key,val))!=-1){\r
nt->NewSlot(key,val);\r
}\r
nt->SetDelegate(_delegate);\r
{\r
_HashNode *n = _Get(key, HashKey(key) & (_numofnodes - 1));\r
if (n) {\r
- val = n->val;\r
+ val = _realval(n->val);\r
return true;\r
}\r
return false;\r
}\r
bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)\r
{\r
- unsigned long h = HashKey(key) & (_numofnodes - 1);\r
+ SQHash h = HashKey(key) & (_numofnodes - 1);\r
_HashNode *n = _Get(key, h);\r
if (n) {\r
n->val = val;\r
return NewSlot(key, val);\r
}\r
\r
-int SQTable::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)\r
+SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)\r
{\r
- int idx = (int)TranslateIndex(refpos);\r
+ SQInteger idx = (SQInteger)TranslateIndex(refpos);\r
while (idx < _numofnodes) {\r
if(type(_nodes[idx].key) != OT_NULL) {\r
//first found\r
- outkey = _nodes[idx].key;\r
- outval = _nodes[idx].val;\r
+ _HashNode &n = _nodes[idx];\r
+ outkey = n.key;\r
+ outval = getweakrefs?(SQObject)n.val:_realval(n.val);\r
//return idx for the next iteration\r
return ++idx;\r
}\r
return -1;\r
}\r
\r
-bool SQTable::SetDelegate(SQTable *mt)\r
-{\r
- SQTable *temp = mt;\r
- while (temp) {\r
- if (temp->_delegate == this) return false; //cycle detected\r
- temp = temp->_delegate;\r
- }\r
- if (mt) __ObjAddRef(mt);\r
- __ObjRelease(_delegate);\r
- _delegate = mt;\r
- return true;\r
-}\r
\r
bool SQTable::Set(const SQObjectPtr &key, const SQObjectPtr &val)\r
{\r
\r
void SQTable::Finalize()\r
{\r
- for(int i = 0;i < _numofnodes; i++) { _nodes[i].key = _null_; _nodes[i].val = _null_; }\r
+ for(SQInteger i = 0;i < _numofnodes; i++) { _nodes[i].key = _null_; _nodes[i].val = _null_; }\r
SetDelegate(NULL);\r
}\r