PageRenderTime 42ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/Assets/LUA/KopiLua/ltable.cs

https://bitbucket.org/rusoaica/judgement-day-map-editor
C# | 517 lines | 476 code | 41 blank | 0 comment | 113 complexity | 6325003ce713f4b2ae5a93c2fa635742 MD5 | raw file
  1. using System;
  2. namespace KopiLua
  3. {
  4. using lua_Number = System.Double;
  5. using StkId = Lua.LuaTypeValue;
  6. using TValue = Lua.LuaTypeValue;
  7. public partial class Lua
  8. {
  9. public const int MAXBITS = 26;
  10. public const int MAXASIZE = (1 << MAXBITS);
  11. internal static Node GNode(Table _t, int _i) { return _t.node[_i]; }
  12. internal static TKeyNK GKey(Node _n) { return _n.i_key.nk; }
  13. internal static TValue GVal(Node _n) { return _n.i_val; }
  14. internal static Node GNext(Node _n) { return _n.i_key.nk.next; }
  15. internal static void GNextSet(Node _n, Node _v) { _n.i_key.nk.next = _v; }
  16. internal static TValue Key2TVal(Node _n) { return _n.i_key.tvk; }
  17. internal static Node HashPow2(Table _t, lua_Number _n) { return GNode(_t, (int)LMod(_n, SizeNode(_t))); }
  18. public static Node HashStr(Table _t, TString _str) { return HashPow2(_t, _str.tsv.hash); }
  19. public static Node HashBoolean(Table _t, int _p) { return HashPow2(_t, _p); }
  20. public static Node HashMod(Table _t, int _n) { return GNode(_t, (int)((uint)_n % ((SizeNode(_t) - 1) | 1))); }
  21. public static Node HashPointer(Table _t, object _p) { return HashMod(_t, _p.GetHashCode()); }
  22. public const int NumInts = sizeof(lua_Number) / sizeof(int);
  23. public static Node DummyNode_ = new Node(new LuaTypeValue(new Value(), LUA_TNIL), new TKey(new Value(), LUA_TNIL, null));
  24. public static Node dummynode = DummyNode_;
  25. private static Node HashNum(Table _t, lua_Number _n)
  26. {
  27. byte[] _a = BitConverter.GetBytes(_n);
  28. for (int i = 1; i < _a.Length; i++) _a[0] += _a[i];
  29. return HashMod(_t, (int)_a[0]);
  30. }
  31. private static Node MainPosition(Table _t, TValue _key)
  32. {
  33. switch (TType(_key))
  34. {
  35. case LUA_TNUMBER:
  36. return HashNum(_t, NValue(_key));
  37. case LUA_TSTRING:
  38. return HashStr(_t, RawTSValue(_key));
  39. case LUA_TBOOLEAN:
  40. return HashBoolean(_t, BValue(_key));
  41. case LUA_TLIGHTUSERDATA:
  42. return HashPointer(_t, PValue(_key));
  43. default:
  44. return HashPointer(_t, GCValue(_key));
  45. }
  46. }
  47. private static int ArrayIndex(TValue _key)
  48. {
  49. if (TTIsNumber(_key))
  50. {
  51. lua_Number _n = NValue(_key);
  52. int _k;
  53. LuaNumber2Int(out _k, _n);
  54. if (LuaINumEq(CastNum(_k), _n))
  55. return _k;
  56. }
  57. return -1;
  58. }
  59. private static int FindIndex(LuaState _l, Table _t, StkId _key)
  60. {
  61. int _i;
  62. if (TTIsNil(_key)) return -1;
  63. _i = ArrayIndex(_key);
  64. if (0 < _i && _i <= _t.sizeArray)
  65. return _i - 1;
  66. else
  67. {
  68. Node _n = MainPosition(_t, _key);
  69. do
  70. {
  71. if ((LuaORawEqualObj(Key2TVal(_n), _key) != 0) ||
  72. (TType(GKey(_n)) == LUATDEADKEY && IsCollectable(_key) &&
  73. GCValue(GKey(_n)) == GCValue(_key)))
  74. {
  75. _i = CastInt(_n - GNode(_t, 0));
  76. return _i + _t.sizeArray;
  77. }
  78. else _n = GNext(_n);
  79. } while (_n != null);
  80. LuaGRunError(_l, "invalid key to " + LUA_QL("next"));
  81. return 0;
  82. }
  83. }
  84. public static int LuaHNext(LuaState _l, Table _t, StkId _key)
  85. {
  86. int _i = FindIndex(_l, _t, _key);
  87. for (_i++; _i < _t.sizeArray; _i++)
  88. {
  89. if (!TTIsNil(_t.array[_i]))
  90. {
  91. SetNValue(_key, CastNum(_i + 1));
  92. SetObj2S(_l, _key + 1, _t.array[_i]);
  93. return 1;
  94. }
  95. }
  96. for (_i -= _t.sizeArray; _i < SizeNode(_t); _i++)
  97. {
  98. if (!TTIsNil(GVal(GNode(_t, _i))))
  99. {
  100. SetObj2S(_l, _key, Key2TVal(GNode(_t, _i)));
  101. SetObj2S(_l, _key + 1, GVal(GNode(_t, _i)));
  102. return 1;
  103. }
  104. }
  105. return 0;
  106. }
  107. private static int ComputeSizes(int[] _nums, ref int _n_array)
  108. {
  109. int _i;
  110. int _two_to_i;
  111. int _a = 0;
  112. int _na = 0;
  113. int _n = 0;
  114. for (_i = 0, _two_to_i = 1; _two_to_i / 2 < _n_array; _i++, _two_to_i *= 2)
  115. {
  116. if (_nums[_i] > 0)
  117. {
  118. _a += _nums[_i];
  119. if (_a > _two_to_i / 2)
  120. {
  121. _n = _two_to_i;
  122. _na = _a;
  123. }
  124. }
  125. if (_a == _n_array) break;
  126. }
  127. _n_array = _n;
  128. LuaAssert(_n_array / 2 <= _na && _na <= _n_array);
  129. return _na;
  130. }
  131. private static int CountInt(TValue _key, int[] _nums)
  132. {
  133. int _k = ArrayIndex(_key);
  134. if (0 < _k && _k <= MAXASIZE)
  135. {
  136. _nums[CeilLog2(_k)]++;
  137. return 1;
  138. }
  139. else
  140. return 0;
  141. }
  142. private static int NumUseArray(Table _t, int[] _nums)
  143. {
  144. int _lg;
  145. int _ttlg;
  146. int _ause = 0;
  147. int _i = 1;
  148. for (_lg = 0, _ttlg = 1; _lg <= MAXBITS; _lg++, _ttlg *= 2)
  149. {
  150. int _lc = 0;
  151. int _lim = _ttlg;
  152. if (_lim > _t.sizeArray)
  153. {
  154. _lim = _t.sizeArray;
  155. if (_i > _lim)
  156. break;
  157. }
  158. for (; _i <= _lim; _i++)
  159. {
  160. if (!TTIsNil(_t.array[_i - 1]))
  161. _lc++;
  162. }
  163. _nums[_lg] += _lc;
  164. _ause += _lc;
  165. }
  166. return _ause;
  167. }
  168. private static int NumUsehash(Table _t, int[] _nums, ref int _pna_size)
  169. {
  170. int _total_use = 0;
  171. int _ause = 0;
  172. int _i = SizeNode(_t);
  173. while ((_i--) != 0)
  174. {
  175. Node n = _t.node[_i];
  176. if (!TTIsNil(GVal(n)))
  177. {
  178. _ause += CountInt(Key2TVal(n), _nums);
  179. _total_use++;
  180. }
  181. }
  182. _pna_size += _ause;
  183. return _total_use;
  184. }
  185. private static void SetArrayVector(LuaState _l, Table _t, int _size)
  186. {
  187. int _i;
  188. LuaMReallocVector<TValue>(_l, ref _t.array, _t.sizeArray, _size);
  189. for (_i = _t.sizeArray; _i < _size; _i++)
  190. SetNilValue(_t.array[_i]);
  191. _t.sizeArray = _size;
  192. }
  193. private static void SetNodeVector(LuaState _l, Table _t, int _size)
  194. {
  195. int _l_size;
  196. if (_size == 0)
  197. {
  198. _t.node = new Node[] { dummynode };
  199. _l_size = 0;
  200. }
  201. else
  202. {
  203. int _i;
  204. _l_size = CeilLog2(_size);
  205. if (_l_size > MAXBITS)
  206. LuaGRunError(_l, "table overflow");
  207. _size = TwoTo(_l_size);
  208. Node[] nodes = LuaMNewVector<Node>(_l, _size);
  209. _t.node = nodes;
  210. for (_i = 0; _i < _size; _i++)
  211. {
  212. Node n = GNode(_t, _i);
  213. GNextSet(n, null);
  214. SetNilValue(GKey(n));
  215. SetNilValue(GVal(n));
  216. }
  217. }
  218. _t.lSizeNode = CastByte(_l_size);
  219. _t.lastFree = _size;
  220. }
  221. private static void Resize(LuaState _l, Table _t, int _na_size, int _nh_size)
  222. {
  223. int _i;
  224. int _old_a_size = _t.sizeArray;
  225. int _old_h_size = _t.lSizeNode;
  226. Node[] _n_old = _t.node;
  227. if (_na_size > _old_a_size)
  228. SetArrayVector(_l, _t, _na_size);
  229. SetNodeVector(_l, _t, _nh_size);
  230. if (_na_size < _old_a_size)
  231. {
  232. _t.sizeArray = _na_size;
  233. for (_i = _na_size; _i < _old_a_size; _i++)
  234. if (!TTIsNil(_t.array[_i]))
  235. SetObjT2T(_l, LuaHSetNum(_l, _t, _i + 1), _t.array[_i]);
  236. LuaMReallocVector<TValue>(_l, ref _t.array, _old_a_size, _na_size);
  237. }
  238. for (_i = TwoTo(_old_h_size) - 1; _i >= 0; _i--)
  239. {
  240. Node _old = _n_old[_i];
  241. if (!TTIsNil(GVal(_old)))
  242. SetObjT2T(_l, LuaHSet(_l, _t, Key2TVal(_old)), GVal(_old));
  243. }
  244. if (_n_old[0] != dummynode)
  245. LuaMFreeArray(_l, _n_old);
  246. }
  247. public static void LuaHResizeArray(LuaState _l, Table _t, int _na_size)
  248. {
  249. int _n_size = (_t.node[0] == dummynode) ? 0 : SizeNode(_t);
  250. Resize(_l, _t, _na_size, _n_size);
  251. }
  252. private static void Rehash(LuaState _l, Table _t, TValue _ek)
  253. {
  254. int _na_size, na;
  255. int[] _nums = new int[MAXBITS + 1];
  256. int _i;
  257. int _total_use;
  258. for (_i = 0; _i <= MAXBITS; _i++) _nums[_i] = 0;
  259. _na_size = NumUseArray(_t, _nums);
  260. _total_use = _na_size;
  261. _total_use += NumUsehash(_t, _nums, ref _na_size);
  262. _na_size += CountInt(_ek, _nums);
  263. _total_use++;
  264. na = ComputeSizes(_nums, ref _na_size);
  265. Resize(_l, _t, _na_size, _total_use - na);
  266. }
  267. public static Table LuaHNew(LuaState _l, int _n_array, int _n_hash)
  268. {
  269. Table _t = LuaMNew<Table>(_l);
  270. LuaCLink(_l, obj2gco(_t), LUA_TTABLE);
  271. _t.metatable = null;
  272. _t.flags = CastByte(~0);
  273. _t.array = null;
  274. _t.sizeArray = 0;
  275. _t.lSizeNode = 0;
  276. _t.node = new Node[] { dummynode };
  277. SetArrayVector(_l, _t, _n_array);
  278. SetNodeVector(_l, _t, _n_hash);
  279. return _t;
  280. }
  281. public static void LuaHFree(LuaState _l, Table _t)
  282. {
  283. if (_t.node[0] != dummynode)
  284. LuaMFreeArray(_l, _t.node);
  285. LuaMFreeArray(_l, _t.array);
  286. LuaMFree(_l, _t);
  287. }
  288. private static Node GetFreePos(Table _t)
  289. {
  290. while (_t.lastFree-- > 0)
  291. if (TTIsNil(GKey(_t.node[_t.lastFree])))
  292. return _t.node[_t.lastFree];
  293. return null;
  294. }
  295. private static TValue newkey(LuaState _l, Table _t, TValue _key)
  296. {
  297. Node _mp = MainPosition(_t, _key);
  298. if (!TTIsNil(GVal(_mp)) || _mp == dummynode)
  299. {
  300. Node _other_n;
  301. Node _n = GetFreePos(_t);
  302. if (_n == null)
  303. {
  304. Rehash(_l, _t, _key);
  305. return LuaHSet(_l, _t, _key);
  306. }
  307. LuaAssert(_n != dummynode);
  308. _other_n = MainPosition(_t, Key2TVal(_mp));
  309. if (_other_n != _mp)
  310. {
  311. while (GNext(_other_n) != _mp) _other_n = GNext(_other_n);
  312. GNextSet(_other_n, _n);
  313. _n.i_val = new LuaTypeValue(_mp.i_val);
  314. _n.i_key = new TKey(_mp.i_key);
  315. GNextSet(_mp, null);
  316. SetNilValue(GVal(_mp));
  317. }
  318. else
  319. {
  320. GNextSet(_n, GNext(_mp));
  321. GNextSet(_mp, _n);
  322. _mp = _n;
  323. }
  324. }
  325. GKey(_mp).value.Copy(_key.value); GKey(_mp).tt = _key.tt;
  326. LuaCBarrierT(_l, _t, _key);
  327. LuaAssert(TTIsNil(GVal(_mp)));
  328. return GVal(_mp);
  329. }
  330. public static TValue LuaHGetnum(Table _t, int _key)
  331. {
  332. if ((uint)(_key - 1) < (uint)_t.sizeArray)
  333. return _t.array[_key - 1];
  334. else
  335. {
  336. lua_Number _nk = CastNum(_key);
  337. Node _n = HashNum(_t, _nk);
  338. do
  339. {
  340. if (TTIsNumber(GKey(_n)) && LuaINumEq(NValue(GKey(_n)), _nk))
  341. return GVal(_n); /* that's it */
  342. else _n = GNext(_n);
  343. } while (_n != null);
  344. return LuaONilObject;
  345. }
  346. }
  347. public static TValue LuaHGetStr(Table _t, TString _key)
  348. {
  349. Node _n = HashStr(_t, _key);
  350. do
  351. {
  352. if (TTIsString(GKey(_n)) && RawTSValue(GKey(_n)) == _key)
  353. return GVal(_n);
  354. else _n = GNext(_n);
  355. } while (_n != null);
  356. return LuaONilObject;
  357. }
  358. public static TValue LuaHGet(Table _t, TValue _key)
  359. {
  360. switch (TType(_key))
  361. {
  362. case LUA_TNIL: return LuaONilObject;
  363. case LUA_TSTRING: return LuaHGetStr(_t, RawTSValue(_key));
  364. case LUA_TNUMBER:
  365. {
  366. int _k;
  367. lua_Number _n = NValue(_key);
  368. LuaNumber2Int(out _k, _n);
  369. if (LuaINumEq(CastNum(_k), NValue(_key)))
  370. return LuaHGetnum(_t, _k);
  371. Node node = MainPosition(_t, _key);
  372. do
  373. {
  374. if (LuaORawEqualObj(Key2TVal(node), _key) != 0)
  375. return GVal(node);
  376. else node = GNext(node);
  377. } while (node != null);
  378. return LuaONilObject;
  379. }
  380. default:
  381. {
  382. Node _node = MainPosition(_t, _key);
  383. do
  384. {
  385. if (LuaORawEqualObj(Key2TVal(_node), _key) != 0)
  386. return GVal(_node);
  387. else _node = GNext(_node);
  388. } while (_node != null);
  389. return LuaONilObject;
  390. }
  391. }
  392. }
  393. public static TValue LuaHSet(LuaState _l, Table _t, TValue _key)
  394. {
  395. TValue _p = LuaHGet(_t, _key);
  396. _t.flags = 0;
  397. if (_p != LuaONilObject)
  398. return (TValue)_p;
  399. else
  400. {
  401. if (TTIsNil(_key)) LuaGRunError(_l, "table index is nil");
  402. else if (TTIsNumber(_key) && LuaINumIsNaN(NValue(_key)))
  403. LuaGRunError(_l, "table index is NaN");
  404. return newkey(_l, _t, _key);
  405. }
  406. }
  407. public static TValue LuaHSetNum(LuaState _l, Table _t, int _key)
  408. {
  409. TValue _p = LuaHGetnum(_t, _key);
  410. if (_p != LuaONilObject)
  411. return (TValue)_p;
  412. else
  413. {
  414. TValue k = new LuaTypeValue();
  415. SetNValue(k, CastNum(_key));
  416. return newkey(_l, _t, k);
  417. }
  418. }
  419. public static TValue LuaHSetStr(LuaState _l, Table _t, TString _key)
  420. {
  421. TValue _p = LuaHGetStr(_t, _key);
  422. if (_p != LuaONilObject)
  423. return (TValue)_p;
  424. else
  425. {
  426. TValue k = new LuaTypeValue();
  427. SetSValue(_l, k, _key);
  428. return newkey(_l, _t, k);
  429. }
  430. }
  431. #if !UNITY_3D
  432. [CLSCompliantAttribute(false)]
  433. #endif
  434. public static int UnboundSearch(Table _t, uint _j)
  435. {
  436. uint _i = _j;
  437. _j++;
  438. while (!TTIsNil(LuaHGetnum(_t, (int)_j)))
  439. {
  440. _i = _j;
  441. _j *= 2;
  442. if (_j > (uint)MAXINT)
  443. {
  444. _i = 1;
  445. while (!TTIsNil(LuaHGetnum(_t, (int)_i))) _i++;
  446. return (int)(_i - 1);
  447. }
  448. }
  449. while (_j - _i > 1)
  450. {
  451. uint _m = (_i + _j) / 2;
  452. if (TTIsNil(LuaHGetnum(_t, (int)_m))) _j = _m;
  453. else _i = _m;
  454. }
  455. return (int)_i;
  456. }
  457. public static int LuaHGetN(Table _t)
  458. {
  459. uint _j = (uint)_t.sizeArray;
  460. if (_j > 0 && TTIsNil(_t.array[_j - 1]))
  461. {
  462. uint _i = 0;
  463. while (_j - _i > 1)
  464. {
  465. uint _m = (_i + _j) / 2;
  466. if (TTIsNil(_t.array[_m - 1])) _j = _m;
  467. else _i = _m;
  468. }
  469. return (int)_i;
  470. }
  471. else if (_t.node[0] == dummynode)
  472. return (int)_j;
  473. else return UnboundSearch(_t, _j);
  474. }
  475. }
  476. }