sqtable.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /* see copyright notice in squirrel.h */
  2. #ifndef _SQTABLE_H_
  3. #define _SQTABLE_H_
  4. /*
  5. * The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
  6. * http://www.lua.org/copyright.html#4
  7. * http://www.lua.org/source/4.0.1/src_ltable.c.html
  8. */
  9. #include "sqstring.h"
  10. #define hashptr(p) ((SQHash)(((SQInteger)p) >> 3))
  11. inline SQHash HashObj(const SQObjectPtr &key)
  12. {
  13. switch(type(key)) {
  14. case OT_STRING: return _string(key)->_hash;
  15. case OT_FLOAT: return (SQHash)((SQInteger)_float(key));
  16. case OT_BOOL: case OT_INTEGER: return (SQHash)((SQInteger)_integer(key));
  17. default: return hashptr(key._unVal.pRefCounted);
  18. }
  19. }
  20. struct SQTable : public SQDelegable
  21. {
  22. private:
  23. struct _HashNode
  24. {
  25. _HashNode() { next = NULL; }
  26. SQObjectPtr val;
  27. SQObjectPtr key;
  28. _HashNode *next;
  29. };
  30. _HashNode *_firstfree;
  31. _HashNode *_nodes;
  32. SQInteger _numofnodes;
  33. SQInteger _usednodes;
  34. ///////////////////////////
  35. void AllocNodes(SQInteger nSize);
  36. void Rehash(bool force);
  37. SQTable(SQSharedState *ss, SQInteger nInitialSize);
  38. void _ClearNodes();
  39. public:
  40. static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize)
  41. {
  42. SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
  43. new (newtable) SQTable(ss, nInitialSize);
  44. newtable->_delegate = NULL;
  45. return newtable;
  46. }
  47. void Finalize();
  48. SQTable *Clone();
  49. ~SQTable()
  50. {
  51. SetDelegate(NULL);
  52. REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
  53. for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
  54. SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
  55. }
  56. #ifndef NO_GARBAGE_COLLECTOR
  57. void Mark(SQCollectable **chain);
  58. SQObjectType GetType() {return OT_TABLE;}
  59. #endif
  60. inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash)
  61. {
  62. _HashNode *n = &_nodes[hash];
  63. do{
  64. if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){
  65. return n;
  66. }
  67. }while((n = n->next));
  68. return NULL;
  69. }
  70. //for compiler use
  71. inline bool GetStr(const SQChar* key,SQInteger keylen,SQObjectPtr &val)
  72. {
  73. SQHash hash = _hashstr(key,keylen);
  74. _HashNode *n = &_nodes[hash & (_numofnodes - 1)];
  75. _HashNode *res = NULL;
  76. do{
  77. if(type(n->key) == OT_STRING && (scstrcmp(_stringval(n->key),key) == 0)){
  78. res = n;
  79. break;
  80. }
  81. }while((n = n->next));
  82. if (res) {
  83. val = _realval(res->val);
  84. return true;
  85. }
  86. return false;
  87. }
  88. bool Get(const SQObjectPtr &key,SQObjectPtr &val);
  89. void Remove(const SQObjectPtr &key);
  90. bool Set(const SQObjectPtr &key, const SQObjectPtr &val);
  91. //returns true if a new slot has been created false if it was already present
  92. bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);
  93. SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
  94. SQInteger CountUsed(){ return _usednodes;}
  95. void Clear();
  96. void Release()
  97. {
  98. sq_delete(this, SQTable);
  99. }
  100. };
  101. #endif //_SQTABLE_H_