Skip to content

Commit 4600c5a

Browse files
committed
Merge pull request #68 from liskin/offsetposition-index-cache
Speed up line/column in OffsetPosition
2 parents 29960ad + ab6e080 commit 4600c5a

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

src/main/scala/scala/util/parsing/input/OffsetPosition.scala

+27-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ package scala
1010
package util.parsing.input
1111

1212
import 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

Comments
 (0)