search: Speed up searches with many matches

Look up duplicate matches in a hash table instead of scanning the result
list for every component. Key entries by kind, ID and branch, ignoring
architecture as before.

Collect matches before sorting them for output. Record discovery order
to keep newer matches first when scores are equal. Preserve first-match
data and the remote list.

In a warm-cache synthetic test with 8,000 matches, search took 184 ms
instead of 1.87 s.
This commit is contained in:
Internal Server Error - Gitea: Git with a cup of tea
500 Internal Server Error

Gitea Version: 1.28.0+dev-477-g8b6ad49a5f