PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/ZenScript/src/main/java/stanhebben/zenscript/parser/HashMapII.java

https://gitlab.com/MineYourMind/MineTweaker3
Java | 237 lines | 143 code | 28 blank | 66 comment | 42 complexity | 0bcf477daa222d407892f95dd35f1726 MD5 | raw file
  1. /*
  2. * This file is subject to the license.txt file in the main folder
  3. * of this project.
  4. */
  5. package stanhebben.zenscript.parser;
  6. /**
  7. * A HashMap implementation which is optimized to associate integers with integers.
  8. *
  9. * @author Stan Hebben
  10. */
  11. public class HashMapII {
  12. private int[] keys;
  13. private int[] values;
  14. private int[] next;
  15. private int mask;
  16. private int size;
  17. /**
  18. * Creates a new HashMap for integer keys and values.
  19. */
  20. public HashMapII() {
  21. keys = new int[16];
  22. values = new int[16];
  23. next = new int[16];
  24. mask = 15;
  25. size = 0;
  26. for (int i = 0; i < keys.length; i++) {
  27. keys[i] = Integer.MIN_VALUE;
  28. }
  29. }
  30. /**
  31. * Returns the number of key/value pairs in the hashmap.
  32. *
  33. * @return hashmap size
  34. */
  35. public int size() {
  36. return size;
  37. }
  38. /**
  39. * Associates the specified value with the specified key in this map. If the
  40. * map previously contained a mapping for the key, the old value is replaced.
  41. *
  42. * @param key key with which the specified value is to be associated
  43. * @param value value to be associated with the specified key
  44. */
  45. public void put(int key, int value) {
  46. if (size > (keys.length * 3) >> 2) {
  47. expand();
  48. }
  49. int index = key & mask;
  50. if (keys[index] == Integer.MIN_VALUE) {
  51. keys[index] = key;
  52. values[index] = value;
  53. } else {
  54. while (next[index] != 0) {
  55. index = next[index] - 1;
  56. if (keys[index] == key) {
  57. values[index] = value;
  58. return;
  59. }
  60. }
  61. int ref = index;
  62. while (keys[index] != Integer.MIN_VALUE) {
  63. index++;
  64. if (index == keys.length) index = 0;
  65. }
  66. next[ref] = index + 1;
  67. keys[index] = key;
  68. values[index] = value;
  69. }
  70. size++;
  71. }
  72. /**
  73. * Returns the value to which the specified key is mapped, or null if this
  74. * map contains no mapping for the key.
  75. *
  76. * @param key the key whose associated value is to be returned
  77. * @return the value to which the specified key is mapped, or Integer.MIN_VALUE if this map contains no mapping for the key
  78. */
  79. public int get(int key) {
  80. int index = key & mask;
  81. while (keys[index] != key) {
  82. if (next[index] == 0) {
  83. return Integer.MIN_VALUE;
  84. }
  85. index = next[index] - 1;
  86. }
  87. return values[index];
  88. }
  89. /**
  90. * Returns the value to which the specified key is mapped, or null if this
  91. * map contains no mapping for the key.
  92. *
  93. * @param key the key whose associated value is to be returned
  94. * @param def the default key value
  95. * @return the value to which the specified key is mapped, or the default value if this map contains no mapping for the key
  96. */
  97. public int get(int key, int def) {
  98. int index = key & mask;
  99. while (keys[index] != key) {
  100. if (next[index] == 0) {
  101. return def;
  102. }
  103. index = next[index] - 1;
  104. }
  105. return values[index];
  106. }
  107. /**
  108. * Returns true if this map contains a mapping for the specified key.
  109. *
  110. * @param key The key whose presence in this map is to be tested
  111. * @return true if this map contains a mapping for the specified key.
  112. */
  113. public boolean containsKey(int key) {
  114. int index = key & mask;
  115. while (keys[index] != key) {
  116. if (next[index] == 0) {
  117. return false;
  118. }
  119. index = next[index] - 1;
  120. }
  121. return true;
  122. }
  123. /**
  124. * Returns an iterator over the keys in this HashMap. The elements are
  125. * returned in no particular order.
  126. *
  127. * @return an iterator over the keys in this HashMap
  128. */
  129. public IteratorI keys() {
  130. return new KeyIterator();
  131. }
  132. /**
  133. * Returns an array with all keys in this HashMap. The elements are returned
  134. * in no particular order.
  135. *
  136. * @return an array with all keys in this HashMap
  137. */
  138. public int[] keysArray() {
  139. int[] result = new int[size];
  140. int ix = 0;
  141. for (int i = 0; i < keys.length; i++) {
  142. if (keys[i] != Integer.MIN_VALUE) result[ix++] = keys[i];
  143. }
  144. return result;
  145. }
  146. ////////////////////
  147. // Private methods
  148. ////////////////////
  149. /**
  150. * Expands the size of this array. (it doubles the size)
  151. */
  152. private void expand() {
  153. int[] newKeys = new int[keys.length * 2];
  154. int[] newValues = new int[values.length * 2];
  155. int[] newNext = new int[next.length * 2];
  156. int newMask = newKeys.length - 1;
  157. for (int i = 0; i < newKeys.length; i++) {
  158. newKeys[i] = Integer.MIN_VALUE;
  159. }
  160. for (int i = 0; i < keys.length; i++) {
  161. if (keys[i] == Integer.MIN_VALUE) {
  162. continue;
  163. }
  164. int key = keys[i];
  165. int value = values[i];
  166. int index = key & newMask;
  167. if (newKeys[index] == Integer.MIN_VALUE) {
  168. newKeys[index] = key;
  169. newValues[index] = value;
  170. } else {
  171. while (newNext[index] != 0) {
  172. index = newNext[index] - 1;
  173. }
  174. int ref = index;
  175. while (newKeys[index] != Integer.MIN_VALUE) {
  176. index = (index + 1) & newMask;
  177. }
  178. newNext[ref] = index + 1;
  179. newKeys[index] = key;
  180. newValues[index] = value;
  181. }
  182. }
  183. keys = newKeys;
  184. values = newValues;
  185. next = newNext;
  186. mask = newMask;
  187. }
  188. //////////////////////////
  189. // Private inner classes
  190. //////////////////////////
  191. private class KeyIterator implements IteratorI {
  192. private int i;
  193. public KeyIterator() {
  194. i = 0;
  195. skip();
  196. }
  197. public boolean hasNext() {
  198. return i < keys.length;
  199. }
  200. public int next() {
  201. int result = keys[i++];
  202. skip();
  203. return result;
  204. }
  205. private void skip() {
  206. while (i < keys.length && keys[i] == Integer.MIN_VALUE) i++;
  207. }
  208. }
  209. }