Skip to content
This repository was archived by the owner on Dec 11, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions core/src/main/scala/codesearch/core/search/Search.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import cats.syntax.option._
import codesearch.core.config.{Config, SnippetConfig}
import codesearch.core.index.directory.СindexDirectory
import codesearch.core.index.repository.Extensions
import codesearch.core.regex.RegexConstructor
import codesearch.core.search.Search.{CSearchPage, CSearchResult, CodeSnippet, Package, PackageResult, snippetConfig}
import codesearch.core.search.SnippetsGrouper.SnippetInfo
import codesearch.core.syntax.stream._
import codesearch.core.util.Helper.readFileAsync
import fs2.{Pipe, Stream}
import io.chrisdavenport.log4cats.SelfAwareStructuredLogger
import io.chrisdavenport.log4cats.slf4j.Slf4jLogger
import codesearch.core.regex.RegexConstructor
import codesearch.core.syntax.stream._

import scala.sys.process.Process

Expand All @@ -34,16 +34,14 @@ trait Search {
def search(request: SearchRequest): IO[CSearchPage] = {
for {
lines <- csearch(request)

snippetsInfo = Stream
.emits(lines)
.through(SnippetsGrouper.groupLines(snippetConfig))
.through(SnippetsGrouper.groupLines(snippetConfig, request.query))

filteredSnippetsInfo = if (request.withoutTests)
filteredSnippetsInfo: Stream[fs2.Pure, SnippetsGrouper.SnippetInfo] = if (request.withoutTests)
snippetsInfo.filterNot(snippetInfo => isTestInPath(snippetInfo.filePath))
else
snippetsInfo

results <- filteredSnippetsInfo
.drop(snippetConfig.pageSize * (request.page - 1))
.take(snippetConfig.pageSize)
Expand Down
25 changes: 16 additions & 9 deletions core/src/main/scala/codesearch/core/search/SnippetsGrouper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,46 @@ object SnippetsGrouper {
*/
case class SnippetInfo(filePath: String, lines: NonEmptyVector[Int], totalMatches: Int)

private case class ResultRow(path: String, lineNumber: Int)
private case class ResultRow(path: String, lineNumber: Int, matchedString: Array[String])

/**
* Transforms raw search output in format `filePath:lineNumber:matchedString` to snippets grouping matched lines
* from the same file if they are close to each other
*
* @param config config for creating a snippet
*/
def groupLines[F[_]](config: SnippetConfig): Pipe[F, String, SnippetInfo] = { lines =>
def groupLines[F[_]](config: SnippetConfig, query: String): Pipe[F, String, SnippetInfo] = { lines =>
for {
(_, resultRows) <- lines.map { row =>
val Array(path, lineNumber) = row.split(":").take(2) //filePath:lineNumber:matchedString
ResultRow(path, lineNumber.toInt)
val Array(path, lineNumber) = row.split(":").take(2) // filePath:lineNumber:matchedString
ResultRow(path, lineNumber.toInt, row.split(":").drop(2))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You already computed it values. Please, reuse it.

}.groupAdjacentBy(_.path)
snippet <- Stream.emits {
groupRowsToSnippets(config)(resultRows)
groupRowsToSnippets(config, query)(resultRows)
}
} yield snippet
}

private def groupRowsToSnippets(config: SnippetConfig)(rows: Chunk[ResultRow]): Seq[SnippetInfo] = {
private def groupRowsToSnippets(config: SnippetConfig, query: String)(rows: Chunk[ResultRow]): Seq[SnippetInfo] = {
rows.foldLeft(Vector.empty[SnippetInfo]) { (snippets, row) =>
val count = math.max(countSubstring(row.matchedString, query), 1)
snippets.lastOption match {
case Some(snippet) =>
if (row.lineNumber < snippet.lines.last + config.linesAfter) {
snippets.init :+ snippet.copy(lines = snippet.lines :+ row.lineNumber,
totalMatches = snippet.totalMatches + 1)
totalMatches = snippet.totalMatches + count)
} else {
snippets :+ SnippetInfo(row.path, NonEmptyVector.one(row.lineNumber), 1)
snippets :+ SnippetInfo(row.path, NonEmptyVector.one(row.lineNumber), count)
}
case None =>
snippets :+ SnippetInfo(row.path, NonEmptyVector.one(row.lineNumber), 1)
snippets :+ SnippetInfo(row.path, NonEmptyVector.one(row.lineNumber), count)
}
}
}

private def countSubstring(str: Array[String], sub: String): Int = {
str.foldLeft(0) { (count, str) =>
count + str.sliding(sub.length).count(_ == sub)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class SnippetsGrouperSpec extends WordSpec with Matchers {
val snippets: List[SnippetInfo] = fs2.Stream
.emits(matchedLines)
.through(
SnippetsGrouper.groupLines(SnippetConfig(pageSize = 30, linesBefore = 5, linesAfter = 5))
SnippetsGrouper.groupLines(SnippetConfig(pageSize = 30, linesBefore = 5, linesAfter = 5), "import")
)
.compile
.toList
Expand All @@ -44,7 +44,7 @@ class SnippetsGrouperSpec extends WordSpec with Matchers {
val snippets: List[SnippetInfo] = fs2.Stream
.emits(matchedLines)
.through(
SnippetsGrouper.groupLines(SnippetConfig(pageSize = 30, linesBefore = 5, linesAfter = 5))
SnippetsGrouper.groupLines(SnippetConfig(pageSize = 30, linesBefore = 5, linesAfter = 5), "deriving")
)
.compile
.toList
Expand Down Expand Up @@ -73,7 +73,7 @@ class SnippetsGrouperSpec extends WordSpec with Matchers {
val snippets: List[SnippetInfo] = fs2.Stream
.emits(matchedLines)
.through(
SnippetsGrouper.groupLines(SnippetConfig(pageSize = 30, linesBefore = 5, linesAfter = 5))
SnippetsGrouper.groupLines(SnippetConfig(pageSize = 30, linesBefore = 5, linesAfter = 5), "import")
)
.compile
.toList
Expand Down