sqtable.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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 SQObject &key)
  12. {
  13. switch(sq_type(key)) {
  14. case OT_STRING_UTF8:
  15. case OT_STRING: return _string(key)->_hash;
  16. case OT_FLOAT: return (SQHash)((SQInteger)_float(key));
  17. case OT_BOOL: case OT_INTEGER: return (SQHash)((SQInteger)_integer(key));
  18. default: return hashptr(key._unVal.pRefCounted);
  19. }
  20. }
  21. #define SQTABLE_HASH_NUMNODES(h) (h & (_numofnodes - 1))
  22. struct SQTable : public SQDelegable
  23. {
  24. private:
  25. struct _HashNode
  26. {
  27. _HashNode():next(NULL) {}
  28. SQObjectPtr val;
  29. SQObjectPtr key;
  30. _HashNode *next;
  31. };
  32. _HashNode *_firstfree;
  33. _HashNode *_nodes;
  34. SQInteger _numofnodes;
  35. SQInteger _usednodes;
  36. ///////////////////////////
  37. void AllocNodes(SQInteger nSize);
  38. void Rehash(bool force);
  39. SQTable(SQSharedState *ss, SQInteger nInitialSize);
  40. void _ClearNodes();
  41. public:
  42. static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize)
  43. {
  44. SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
  45. new (newtable) SQTable(ss, nInitialSize);
  46. newtable->_delegate = NULL;
  47. return newtable;
  48. }
  49. void Finalize();
  50. SQTable *Clone();
  51. ~SQTable()
  52. {
  53. SetDelegate(NULL);
  54. REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
  55. for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
  56. SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
  57. }
  58. #ifndef NO_GARBAGE_COLLECTOR
  59. void Mark(SQCollectable **chain);
  60. SQObjectType GetType() {return OT_TABLE;}
  61. #endif
  62. inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash)
  63. {
  64. _HashNode *n = &_nodes[hash];
  65. do{
  66. if(_rawval(n->key) == _rawval(key) && sq_type(n->key) == sq_type(key)){
  67. return n;
  68. }
  69. }while((n = n->next));
  70. return NULL;
  71. }
  72. //for compiler use
  73. inline bool GetStr(const SQChar* key,SQInteger keylen,SQObjectPtr &val)
  74. {
  75. SQHash hash = _hashstr(key,keylen);
  76. _HashNode *n = &_nodes[SQTABLE_HASH_NUMNODES(hash)];
  77. _HashNode *res = NULL;
  78. do{
  79. if(sq_type(n->key) & _RT_STRING && (scstrcmp(_stringval(n->key),key) == 0)){
  80. res = n;
  81. break;
  82. }
  83. }while((n = n->next));
  84. if (res) {
  85. val = _realval(res->val);
  86. return true;
  87. }
  88. return false;
  89. }
  90. bool Get(const SQObjectPtr &key,SQObjectPtr &val);
  91. bool Exists(const SQObjectPtr &key);
  92. void Remove(const SQObjectPtr &key);
  93. bool Set(const SQObjectPtr &key, const SQObjectPtr &val);
  94. bool IncNum(const SQObjectPtr &key, const SQObjectPtr &val, bool addMissing=false);
  95. //returns true if a new slot has been created false if it was already present
  96. bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);
  97. SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
  98. SQInteger CountUsed(){ return _usednodes;}
  99. void Clear();
  100. void Release()
  101. {
  102. sq_delete(this, SQTable);
  103. }
  104. };
  105. #endif //_SQTABLE_H_