Skip to content

Commit

Permalink
Merge pull request #351 from guymers/query-parsing-pref
Browse files Browse the repository at this point in the history
Improve query parsing performance
  • Loading branch information
OlegIlyenko committed Mar 26, 2018
2 parents 5d22088 + 3da1db7 commit 048dc64
Showing 1 changed file with 41 additions and 4 deletions.
45 changes: 41 additions & 4 deletions src/main/scala/sangria/parser/PositionTracking.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,55 @@ package sangria.parser
import org.parboiled2._
import sangria.ast.AstLocation

import scala.annotation.tailrec

trait PositionTracking { this: Parser
private var lineIdx = Vector(0)
private var lineIdx = Array(0)

def sourceId: String

def trackNewLine: Rule0 = rule { run(if (!(lineIdx contains cursor)) lineIdx = lineIdx :+ cursor) }
def trackNewLine: Rule0 = rule {
run {
if (!contains(lineIdx, cursor)) lineIdx = lineIdx :+ cursor
}
}

def trackPos = rule {
push {
val currLines = lineIdx.takeWhile(_ <= cursor)
val (size, lastCursor) = findLastItem(lineIdx, cursor)

AstLocation(sourceId, cursor, size, cursor - lastCursor + 1)
}
}

AstLocation(sourceId, cursor, currLines.size, cursor - currLines.last + 1)
/**
* Returns true if the array contains the given item.
*
* Assumes that the array is sorted in ascending order.
*/
private def contains(arr: Array[Int], item: Int) = {
@tailrec def go(i: Int): Boolean = {
if (i < 0) false
else if (arr(i) < item) false // no remaining values will match as the array is sorted
else if (arr(i) == item) true
else go(i - 1)
}
go(arr.length - 1)
}

/**
* Returns the first item that is less than or equal to the given item
* along with the number of elements that come before it.
*
* Assumes that the array is sorted in ascending order.
*/
private def findLastItem(arr: Array[Int], item: Int) = {
@tailrec def go(i: Int, last: Int): (Int, Int) = {
if (i < 0) (i + 1, last)
else if (arr(i) <= item) (i + 1, arr(i))
else go(i - 1, arr(i))
}
go(arr.length - 1, 0)
}

}

0 comments on commit 048dc64

Please sign in to comment.