refactor(gitea): address review feedback on PR #90
- position.go: Replace O(n) maxPosition scan with O(1) lookup by tracking max position during map construction. Also eliminates shadowing of the builtin max identifier (Go 1.21+). - position.go: Add comment clarifying +++ prefix ordering intent. - adapter.go: Document diff-fetch tradeoff in PostReview. - adapter_test.go: Remove extra blank line between test functions.
This commit is contained in:
+17
-10
@@ -12,6 +12,9 @@ type PositionMap struct {
|
||||
// files maps filename → (position → new-file line number).
|
||||
// Deletion lines are mapped to -1 (no new-file line).
|
||||
files map[string]map[int]int
|
||||
// maxPositions caches the highest position number per file,
|
||||
// tracked during construction to avoid O(n) scans at translate time.
|
||||
maxPositions map[string]int
|
||||
}
|
||||
|
||||
// Translate converts a GitHub diff-position to a new-file line number for a given file.
|
||||
@@ -53,15 +56,9 @@ func (pm *PositionMap) Translate(file string, position int) (int, error) {
|
||||
}
|
||||
|
||||
// maxPosition returns the highest position number for a file.
|
||||
// O(n) per call — acceptable since deletion-line fallback is rare and n is small (typical hunk size).
|
||||
// O(1) — the maximum is tracked during map construction.
|
||||
func (pm *PositionMap) maxPosition(file string) int {
|
||||
max := 0
|
||||
for pos := range pm.files[file] {
|
||||
if pos > max {
|
||||
max = pos
|
||||
}
|
||||
}
|
||||
return max
|
||||
return pm.maxPositions[file]
|
||||
}
|
||||
|
||||
// BuildPositionToLineMap parses a unified diff and builds a PositionMap
|
||||
@@ -74,7 +71,10 @@ func (pm *PositionMap) maxPosition(file string) int {
|
||||
// - Position maps to the new file line number for additions and context lines
|
||||
// - Deletion lines have a position but no new-file line number (stored as -1)
|
||||
func BuildPositionToLineMap(diff string) *PositionMap {
|
||||
pm := &PositionMap{files: make(map[string]map[int]int)}
|
||||
pm := &PositionMap{
|
||||
files: make(map[string]map[int]int),
|
||||
maxPositions: make(map[string]int),
|
||||
}
|
||||
|
||||
lines := strings.Split(diff, "\n")
|
||||
var currentFile string
|
||||
@@ -82,7 +82,10 @@ func BuildPositionToLineMap(diff string) *PositionMap {
|
||||
var newLine int
|
||||
|
||||
for _, line := range lines {
|
||||
// Detect new file in diff
|
||||
// Detect new file in diff.
|
||||
// "+++ b/" is checked before "+++ /dev/null" — the two prefixes are
|
||||
// non-overlapping ("+++ /dev/null" does not start with "+++ b/"), so
|
||||
// ordering is independent. Checking the common case first for clarity.
|
||||
if strings.HasPrefix(line, "+++ b/") {
|
||||
currentFile = strings.TrimPrefix(line, "+++ b/")
|
||||
position = 0
|
||||
@@ -123,6 +126,7 @@ func BuildPositionToLineMap(diff string) *PositionMap {
|
||||
// Parse hunk headers
|
||||
if strings.HasPrefix(line, "@@") && currentFile != "" {
|
||||
position++
|
||||
pm.maxPositions[currentFile] = position
|
||||
newLine = parseHunkStart(line)
|
||||
continue
|
||||
}
|
||||
@@ -141,15 +145,18 @@ func BuildPositionToLineMap(diff string) *PositionMap {
|
||||
// Addition: has a new-file line number
|
||||
position++
|
||||
pm.files[currentFile][position] = newLine
|
||||
pm.maxPositions[currentFile] = position
|
||||
newLine++
|
||||
} else if strings.HasPrefix(line, "-") {
|
||||
// Deletion: has a position but no new-file line number
|
||||
position++
|
||||
pm.files[currentFile][position] = -1
|
||||
pm.maxPositions[currentFile] = position
|
||||
} else if strings.HasPrefix(line, " ") {
|
||||
// Context line
|
||||
position++
|
||||
pm.files[currentFile][position] = newLine
|
||||
pm.maxPositions[currentFile] = position
|
||||
newLine++
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user