Skip to content

Commit

Permalink
Avoid allocation of new path when resolving path ambiguities (#2904)
Browse files Browse the repository at this point in the history
* Avoid allocation of new path when resolving path ambiguities

* Cleanup
  • Loading branch information
kyri-petrou authored Jun 13, 2024
1 parent baf5399 commit ec93989
Showing 1 changed file with 15 additions and 12 deletions.
27 changes: 15 additions & 12 deletions zio-http/shared/src/main/scala/zio/http/codec/PathCodec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -485,21 +485,25 @@ object PathCodec {
def add[A1 >: A](segments: Iterable[SegmentCodec[_]], value: A1): SegmentSubtree[A1] =
self ++ SegmentSubtree.single(segments, value)

def get(path: Path): Chunk[A] = {
val segments = path.segments
var subtree = self
var result = subtree.value
var i = 0
def get(path: Path): Chunk[A] =
get(path, 0)

while (i < segments.length) {
private def get(path: Path, from: Int): Chunk[A] = {
val segments = path.segments
val nSegments = segments.length
var subtree = self
var result = subtree.value
var i = from

while (i < nSegments) {
val segment = segments(i)

if (subtree.literals.contains(segment)) {
// Fast path, jump down the tree:
subtree = subtree.literals(segment)

result = subtree.value
i = i + 1
i += 1
} else {
val flattened = subtree.othersFlat

Expand All @@ -512,7 +516,7 @@ object PathCodec {
if (matched > 0) {
subtree = subtree0
result = subtree0.value
i = i + matched
i += matched
}
case n => // Slowest fallback path. Have to to find the first predicate where the subpath returns a result
val matches = Array.ofDim[Int](n)
Expand All @@ -535,15 +539,14 @@ object PathCodec {
case 1 =>
subtree = flattened(lastPositiveIdx)._2
result = subtree.value
i = i + matches(lastPositiveIdx)
i += matches(lastPositiveIdx)
case _ =>
index = 0
while (index < n && (subtree eq null)) {
val matched = matches(index)
if (matched > 0) {
val (_, subtree0) = flattened(index)
val subpath = path.dropLeadingSlash.drop(i + matched)
if (subtree0.get(subpath).nonEmpty) {
if (subtree0.get(path, i + matched).nonEmpty) {
subtree = subtree0
result = subtree.value
i += matched
Expand All @@ -556,7 +559,7 @@ object PathCodec {

if (subtree eq null) {
result = Chunk.empty
i = segments.length
i = nSegments
}
}
}
Expand Down

0 comments on commit ec93989

Please sign in to comment.