sqtable.h
00001
00002 #ifndef _SQTABLE_H_
00003 #define _SQTABLE_H_
00004
00005
00006
00007
00008
00009
00010 #include "sqstring.h"
00011
00012
00013 #define hashptr(p) ((SQHash)(((SQInteger)p) >> 3))
00014
00015 inline SQHash HashObj(const SQObjectPtr &key)
00016 {
00017 switch(type(key)) {
00018 case OT_STRING: return _string(key)->_hash;
00019 case OT_FLOAT: return (SQHash)((SQInteger)_float(key));
00020 case OT_BOOL: case OT_INTEGER: return (SQHash)((SQInteger)_integer(key));
00021 default: return hashptr(key._unVal.pRefCounted);
00022 }
00023 }
00024
00025 struct SQTable : public SQDelegable
00026 {
00027 private:
00028 struct _HashNode
00029 {
00030 _HashNode() { next = NULL; }
00031 SQObjectPtr val;
00032 SQObjectPtr key;
00033 _HashNode *next;
00034 };
00035 _HashNode *_firstfree;
00036 _HashNode *_nodes;
00037 SQInteger _numofnodes;
00038 SQInteger _usednodes;
00039
00041 void AllocNodes(SQInteger nSize);
00042 void Rehash(bool force);
00043 SQTable(SQSharedState *ss, SQInteger nInitialSize);
00044 void _ClearNodes();
00045 public:
00046 static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize)
00047 {
00048 SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
00049 new (newtable) SQTable(ss, nInitialSize);
00050 newtable->_delegate = NULL;
00051 return newtable;
00052 }
00053 void Finalize();
00054 SQTable *Clone();
00055 ~SQTable()
00056 {
00057 SetDelegate(NULL);
00058 REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
00059 for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
00060 SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
00061 }
00062 #ifndef NO_GARBAGE_COLLECTOR
00063 void Mark(SQCollectable **chain);
00064 #endif
00065 inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash)
00066 {
00067 _HashNode *n = &_nodes[hash];
00068 do{
00069 if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){
00070 return n;
00071 }
00072 }while((n = n->next));
00073 return NULL;
00074 }
00075 bool Get(const SQObjectPtr &key,SQObjectPtr &val);
00076 void Remove(const SQObjectPtr &key);
00077 bool Set(const SQObjectPtr &key, const SQObjectPtr &val);
00078
00079 bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);
00080 SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
00081
00082 SQInteger CountUsed(){ return _usednodes;}
00083 void Clear();
00084 void Release()
00085 {
00086 sq_delete(this, SQTable);
00087 }
00088
00089 };
00090
00091 #endif //_SQTABLE_H_