Guest User

Untitled

a guest
Nov 18th, 2018
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.03 KB | None | 0 0
  1. import java.util.Arrays
  2. import scala.reflect.ClassTag
  3. import scala.collection.AbstractIterator
  4.  
  5. /**
  6. * Conceptually, a map where the (implicit) keys are positive `Int` values and the values are
  7. * non-`null`; `null` values are not permitted!
  8. * The key values always have to be larger than or equal to 0 and are ideally continues
  9. * (0,1,2,3,...). The values are stored in a plain array to enable true O(1) retrieval.
  10. * Furthermore, the array is only as large as it has to be to keep the value associated
  11. * with the largest key.
  12. */
  13. class ArrayMap[T >: Null <: AnyRef: ClassTag] private (private var data: Array[T]) extends Serializable { self ⇒
  14.  
  15. /**
  16. * Clears, but does not resize/shrink the map.
  17. */
  18. def clear(): Unit = { Arrays.fill(data.asInstanceOf[Array[Object]], null) }
  19.  
  20. /**
  21. * Returns the value stored for the given key or `null` instead.
  22. *
  23. * @note If the key is not valid the result is not defined.
  24. */
  25. @throws[IndexOutOfBoundsException]("if the key is negative")
  26. def apply(key: Int): T = {
  27. val data = this.data
  28. if (key < data.length)
  29. data(key)
  30. else
  31. null
  32. }
  33.  
  34. def get(key: Int): Option[T] = {
  35. val data = this.data
  36. if (key >= 0 && key < data.length) {
  37. Option(data(key))
  38. } else
  39. None
  40. }
  41.  
  42. def remove(key: Int): Unit = {
  43. val data = this.data
  44. if (key >= 0 && key < data.length) {
  45. data(key) = null
  46. }
  47. }
  48.  
  49. def getOrElse(key: Int, f: ⇒ T): T = {
  50. val data = this.data
  51. if (key >= 0 && key < data.length) {
  52. val entry = data(key)
  53. if (entry ne null)
  54. return entry;
  55. }
  56. f
  57. }
  58.  
  59. def getOrElseUpdate(key: Int, f: ⇒ T): T = {
  60. val data = this.data
  61. if (key >= 0 && key < data.length) {
  62. val entry = data(key)
  63. if (entry ne null)
  64. return entry;
  65. }
  66.  
  67. // orElseUpdate
  68. val v: T = f
  69. update(key, v)
  70. v
  71. }
  72.  
  73. /**
  74. * Sets the value for the given key to the given value. If the key cannot be stored in
  75. * the currently used array, the underlying array is immediately resized to make
  76. * it possible to store the new value.
  77. */
  78. @throws[IndexOutOfBoundsException]("if the key is negative")
  79. final def update(key: Int, value: T): Unit = {
  80. assert(value ne null, "ArrayMap only supports non-null values")
  81. val data = this.data
  82. val max = data.length
  83. if (key < max) {
  84. data(key) = value
  85. } else {
  86. val newData = new Array[T](key + 2)
  87. System.arraycopy(data, 0, newData, 0, max)
  88. newData(key) = value
  89. this.data = newData
  90. }
  91. }
  92.  
  93. def foreachValue(f: T ⇒ Unit): Unit = {
  94. val data = this.data
  95. var i = 0
  96. val max = data.length
  97. while (i < max) {
  98. val e = data(i)
  99. // recall that all values have to be non-null...
  100. if (e ne null) f(e)
  101. i += 1
  102. }
  103. }
  104.  
  105. def foreach(f: (Int, T) ⇒ Unit): Unit = {
  106. val data = this.data
  107. var i = 0
  108. val max = data.length
  109. while (i < max) {
  110. val e = data(i)
  111. // Recall that all values have to be non-null...
  112. if (e ne null) f(i, e)
  113. i += 1
  114. }
  115. }
  116.  
  117. def forall(f: T ⇒ Boolean): Boolean = {
  118. val data = this.data
  119. var i = 0
  120. val max = data.length
  121. while (i < max) {
  122. val e = data(i)
  123. // Recall that all values have to be non-null...
  124. if ((e ne null) && !f(e))
  125. return false;
  126. i += 1
  127. }
  128. true
  129. }
  130.  
  131. def valuesIterator: Iterator[T] = data.iterator.filter(_ ne null)
  132.  
  133. def entries: Iterator[(Int, T)] = {
  134.  
  135. new AbstractIterator[(Int, T)] {
  136.  
  137. private[this] def getNextIndex(startIndex: Int): Int = {
  138. val data = self.data
  139. val max = data.length
  140. var i = startIndex
  141. while (i + 1 < max) {
  142. i = i + 1
  143. if (data(i) ne null)
  144. return i;
  145. }
  146. return max;
  147. }
  148.  
  149. private[this] var i = getNextIndex(-1)
  150.  
  151. def hasNext: Boolean = i < data.length
  152.  
  153. def next(): (Int, T) = {
  154. val r = (i, data(i))
  155. i = getNextIndex(i)
  156. r
  157. }
  158. }
  159. }
  160.  
  161. def map[X](f: (Int, T) ⇒ X): List[X] = {
  162. val data = this.data
  163. var rs = List.empty[X]
  164. var i = 0
  165. val max = data.length
  166. while (i < max) {
  167. val e = data(i)
  168. if (e != null) rs = f(i, e) :: rs
  169. i += 1
  170. }
  171. rs
  172. }
  173.  
  174. def map[X >: Null <: AnyRef: ClassTag](f: (Int, T) ⇒ X): ArrayMap[X] = {
  175. val mapped: ArrayMap[X] = ArrayMap[X](data.length)
  176. var i = 0
  177. val max = data.length
  178. while (i < max) {
  179. val e = data(i)
  180. if (e != null) mapped(i) = f(i,e)
  181. i += 1
  182. }
  183. mapped
  184. }
  185.  
  186. def flatMap[X >: Null <: AnyRef: ClassTag](f: (Int, T) ⇒ Iterable[(Int, X)]): ArrayMap[X] = {
  187. val mapped: ArrayMap[X] = ArrayMap.empty[X]
  188. var i = 0
  189. val max = data.length
  190. while (i < max) {
  191. val e = data(i)
  192. if (e != null) for ((k: Int, v: X) <- f(i, e)) mapped(k) = v
  193. i += 1
  194. }
  195. mapped
  196. }
  197.  
  198. def filter(p: (Int, T) => Boolean): ArrayMap[T] = {
  199. val filtered: ArrayMap[T] = ArrayMap.empty[T]
  200. var i = 0
  201. val max = data.length
  202. while (i < max) {
  203. val e = data(i)
  204. if (e != null && p(i, e)) filtered(i) = e
  205. i += 1
  206. }
  207. filtered
  208. }
  209.  
  210. def withFilter(p: (Int, T) ⇒ Boolean): ArrayMapWithFilter[T] = new ArrayMapWithFilter[T](data, p)
  211.  
  212. override def equals(other: Any): Boolean = {
  213. other match {
  214. case that: ArrayMap[_] ⇒
  215. val thisData = this.data.asInstanceOf[Array[Object]]
  216. val thisLength = thisData.length
  217. val thatData = that.data.asInstanceOf[Array[Object]]
  218. val thatLength = thatData.length
  219. if (thisLength == thatLength) {
  220. java.util.Arrays.equals(thisData, thatData)
  221. } else if (thisLength < thatLength) {
  222. thatData.startsWith(thisData) &&
  223. (thatData.view(thisLength, thatLength).forall { _ eq null })
  224. } else {
  225. thisData.startsWith(thatData) &&
  226. (thisData.view(thatLength, thisLength).forall { _ eq null })
  227. }
  228. case _ ⇒ false
  229. }
  230. }
  231.  
  232. override def hashCode: Int = {
  233. var hc = 1
  234. foreachValue { e ⇒
  235. hc = hc * 41 + { if (e ne null) e.hashCode else 0 /* === identityHashCode(null) */ }
  236. }
  237. hc
  238. }
  239.  
  240. def mkString(start: String, sep: String, end: String): String = {
  241. val data = this.data
  242. var s = start
  243. var i = 0
  244. val max = data.length
  245. while (i < max) {
  246. val e = data(i)
  247. if (e ne null) s += s"$i -> $e"
  248. i += 1
  249. while (i < max && (data(i) eq null)) i += 1
  250. if ((e ne null) && i < max) s += sep
  251. }
  252. s + end
  253. }
  254.  
  255. override def toString: String = mkString("ArrayMap(", ", ", ")")
  256.  
  257. }
  258.  
  259. final class ArrayMapWithFilter[T >: Null <: AnyRef: ClassTag] (
  260. private val data: Array[T],
  261. private val p: (Int, T) => Boolean) {
  262.  
  263. def map[X >: Null <: AnyRef: ClassTag](f: (Int, T) => X): ArrayMap[X] = {
  264. val mapped: ArrayMap[X] = ArrayMap[X](data.length)
  265. var i = 0
  266. val max = data.length
  267. while (i < max) {
  268. val e = data(i)
  269. if (e != null && p(i, e)) mapped(i) = f(i,e)
  270. i += 1
  271. }
  272. mapped
  273. }
  274.  
  275. def flatMap[X >: Null <: AnyRef: ClassTag](f: (Int, T) ⇒ Iterable[(Int, X)]): ArrayMap[X] = {
  276. val mapped: ArrayMap[X] = ArrayMap.empty[X]
  277. var i = 0
  278. val max = data.length
  279. while (i < max) {
  280. val e = data(i)
  281. if (e != null && p(i, e)) for ((k: Int, v: X) <- f(i, e)) mapped(k) = v
  282. i += 1
  283. }
  284. mapped
  285. }
  286.  
  287. def foreach(f: (Int, T) => Unit): Unit = {
  288. var i = 0
  289. val max = data.length
  290. while (i < max) {
  291. val e = data(i)
  292. if (e != null && p(i, e)) f(i, e)
  293. i += 1
  294. }
  295. }
  296.  
  297. def withFilter(q: (Int, T) => Boolean): ArrayMapWithFilter[T] = {
  298. new ArrayMapWithFilter[T](data, (k: Int, v: T) ⇒ p(k, v) && q(k, v))
  299. }
  300. }
  301.  
  302. object ArrayMap {
  303.  
  304. /**
  305. * Creates an empty map which initially can store 2 values.
  306. */
  307. def empty[T >: Null <: AnyRef: ClassTag]: ArrayMap[T] = new ArrayMap(new Array[T](2))
  308.  
  309. /**
  310. * Creates an empty map which initially can store up to sizeHint values.
  311. */
  312. def apply[T >: Null <: AnyRef: ClassTag](sizeHint: Int): ArrayMap[T] = {
  313. new ArrayMap(new Array[T](sizeHint))
  314. }
  315. }
Add Comment
Please, Sign In to add comment