@@ -10,6 +10,8 @@ package scala
1010package util .parsing .input
1111
1212import scala .collection .mutable .ArrayBuffer
13+ import java .lang .{CharSequence , ThreadLocal }
14+ import java .util .WeakHashMap
1315
1416/** `OffsetPosition` is a standard class for positions
1517 * represented as offsets into a source ``document''.
@@ -19,10 +21,20 @@ import scala.collection.mutable.ArrayBuffer
1921 *
2022 * @author Martin Odersky
2123 */
22- case class OffsetPosition (source : java.lang. CharSequence , offset : Int ) extends Position {
24+ case class OffsetPosition (source : CharSequence , offset : Int ) extends Position {
2325
2426 /** An index that contains all line starts, including first line, and eof. */
2527 private lazy val index : Array [Int ] = {
28+ Option (OffsetPosition .indexCache.get(source)) match {
29+ case Some (index) => index
30+ case None =>
31+ val index = genIndex
32+ OffsetPosition .indexCache.put(source, index)
33+ index
34+ }
35+ }
36+
37+ private def genIndex : Array [Int ] = {
2638 val lineStarts = new ArrayBuffer [Int ]
2739 lineStarts += 0
2840 for (i <- 0 until source.length)
@@ -71,3 +83,17 @@ case class OffsetPosition(source: java.lang.CharSequence, offset: Int) extends P
7183 this .line == that.line && this .column < that.column
7284 }
7385}
86+
87+ /** An object holding the index cache.
88+ *
89+ * @author Tomáš Janoušek
90+ */
91+ object OffsetPosition extends scala.runtime.AbstractFunction2 [CharSequence ,Int ,OffsetPosition ] {
92+ private lazy val indexCacheTL =
93+ // not DynamicVariable as that would share the map from parent to child :-(
94+ new ThreadLocal [java.util.Map [CharSequence , Array [Int ]]] {
95+ override def initialValue = new WeakHashMap [CharSequence , Array [Int ]]
96+ }
97+
98+ private def indexCache = indexCacheTL.get
99+ }
0 commit comments