Skip to content

Commit

Permalink
BestFirstSearch: switch to Long as State key
Browse files Browse the repository at this point in the history
State column is unlikely to exceed 24 bits (or 16+ mln bytes), but even
in cases when it might, a given token (that is, at a given State depth)
cannot conceivably be formatted at two different column values which are
a multiple of 2^24 bytes apart.

Hence, let's form state key by keeping indentation (just like before)
at 8 bits, limiting column to 24 bits and combining with depth in the
remaining 32 bits (and this combining is what ensures no hash conflict).
  • Loading branch information
kitbellew committed Apr 28, 2024
1 parent a44fd2f commit c841285
Showing 1 changed file with 4 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ private class BestFirstSearch private (
val visits = new Array[Int](tokens.length)
var keepSlowStates = !pruneSlowStates

type StateHash = Long

def isInsideNoOptZone(token: FormatToken): Boolean =
!disableOptimizationsInsideSensitiveAreas ||
noOptimizations.contains(token.left)
Expand All @@ -71,21 +69,17 @@ private class BestFirstSearch private (
)
}

def stateColumnKey(state: State): StateHash = state.column << 8 |
state.indentation

val memo = mutable.Map.empty[(Int, StateHash), State]
private val memo = mutable.Map.empty[Long, State]

def shortestPathMemo(
start: State,
stop: Token,
depth: Int,
maxCost: Int,
): Option[State] = {
val key = (start.depth, stateColumnKey(start))
val cachedState = memo.get(key)
if (cachedState.nonEmpty) cachedState
else {
val key = (start.indentation & 0xffL) | (start.column & 0xffffffL) << 8 |
(start.depth & 0xffffffffL) << 32
memo.get(key).orElse {
// Only update state if it reached stop.
val nextState = shortestPath(start, stop, depth, maxCost)
if (null == nextState) None
Expand Down

0 comments on commit c841285

Please sign in to comment.