@@ -10,6 +10,8 @@ package scala
10
10
package util .parsing .input
11
11
12
12
import scala .collection .mutable .ArrayBuffer
13
+ import java .lang .{CharSequence , ThreadLocal }
14
+ import java .util .WeakHashMap
13
15
14
16
/** `OffsetPosition` is a standard class for positions
15
17
* represented as offsets into a source ``document''.
@@ -19,10 +21,20 @@ import scala.collection.mutable.ArrayBuffer
19
21
*
20
22
* @author Martin Odersky
21
23
*/
22
- case class OffsetPosition (source : java.lang. CharSequence , offset : Int ) extends Position {
24
+ case class OffsetPosition (source : CharSequence , offset : Int ) extends Position {
23
25
24
26
/** An index that contains all line starts, including first line, and eof. */
25
27
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 ] = {
26
38
val lineStarts = new ArrayBuffer [Int ]
27
39
lineStarts += 0
28
40
for (i <- 0 until source.length)
@@ -71,3 +83,17 @@ case class OffsetPosition(source: java.lang.CharSequence, offset: Int) extends P
71
83
this .line == that.line && this .column < that.column
72
84
}
73
85
}
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