IntObjHash.java 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /*
  2. XOWA: the XOWA Offline Wiki Application
  3. Copyright (C) 2012-2017 gnosygnu@gmail.com
  4. XOWA is licensed under the terms of the General Public License (GPL) Version 3,
  5. or alternatively under the terms of the Apache License Version 2.0.
  6. You may use XOWA according to either of these licenses as is most appropriate
  7. for your project on a case-by-case basis.
  8. The terms of each license can be found in the source code repository:
  9. GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
  10. Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
  11. */
  12. package gplx.gfml;
  13. import gplx.types.basics.utls.ArrayUtl;
  14. import gplx.types.errs.ErrUtl;
  15. class IntObjHash_base {
  16. public int Count() {return count;} int count;
  17. public boolean Has(int key) {return Get_by(key) != null;}
  18. public Object Get_by(int key) {
  19. if (key < 0) throw ErrUtl.NewArgs("key must be >= 0", "key", key);
  20. if (key > maxKey) return null;
  21. Object[] subAry = FetchSubAry(key);
  22. return subAry == null ? null : subAry[subIdx];
  23. }
  24. public void Add(int key, Object obj) {PutObjAtKey(key, obj, true);}
  25. public void Set(int key, Object obj) {PutObjAtKey(key, obj, false);}
  26. public void Del(int key) {
  27. if (key > maxKey) return; // key does not exist; exit
  28. Object[] subAry = FetchSubAry(key);
  29. if (subAry == null) return;
  30. subAry[subIdx] = null;
  31. count--;
  32. }
  33. public void Clear() {
  34. rootAry = new Object[0];
  35. count = 0;
  36. maxKey = -1;
  37. }
  38. void PutObjAtKey(int key, Object obj, boolean isAdd) {
  39. if (key < 0) throw ErrUtl.NewArgs("key must be >= 0", "key", key);
  40. if (obj == null) throw ErrUtl.NewArgs("Object cannot be null; call .Del on key instead", "key", key);
  41. if (key > maxKey) ExpandRootAry(key);
  42. Object[] subAry = FetchSubAry(key);
  43. if (subAry == null) {
  44. subAry = new Object[subAryLength];
  45. rootAry[rootIdx] = subAry;
  46. }
  47. Object curVal = subAry[subIdx];
  48. if ( isAdd && curVal != null) throw ErrUtl.NewArgs(".Add cannot be called on non-null vals; call .Set instead", "key", key, "val", curVal);
  49. if (!isAdd && curVal == null) throw ErrUtl.NewArgs(".Set cannot be called on null vals; call .Add instead", "key", key);
  50. subAry[subIdx] = obj;
  51. if (isAdd) count++;
  52. }
  53. void ExpandRootAry(int key) {
  54. int newRootAryBound = (key / subAryLength) + 1;
  55. Object[] newRootAry = new Object[newRootAryBound];
  56. ArrayUtl.Copy(rootAry, newRootAry);
  57. rootAry = newRootAry;
  58. maxKey = (rootAry.length * subAryLength) - 1;
  59. }
  60. Object[] FetchSubAry(int key) {
  61. rootIdx = key / subAryLength;
  62. subIdx = key % subAryLength;
  63. return (Object[])rootAry[rootIdx];
  64. }
  65. Object[] rootAry = new Object[0]; int maxKey = -1;
  66. int rootIdx, subIdx; // NOTE: these are temp values that are cached at class level for PERF (originally out)
  67. public Object Bay() {return bay;} public void Bay_set(Object v) {bay = v;} Object bay = null;
  68. static final int subAryLength = 16;
  69. }
  70. class IntObjHash_base_ {
  71. public static IntObjHash_base new_() {return new IntObjHash_base();}
  72. public static IntObjHash_base as_(Object obj) {return obj instanceof IntObjHash_base ? (IntObjHash_base)obj : null;}
  73. }