런처 유휴 CPU와 AX Agent 백그라운드 갱신 부담을 줄임
Some checks failed
Release Gate / gate (push) Has been cancelled
Some checks failed
Release Gate / gate (push) Has been cancelled
- FuzzyEngine에 인덱스 버전 기준 쿼리 캐시를 추가해 색인 완료 후 반복 검색 반응성을 개선함 - 캐시된 인덱스가 없을 때는 앱 시작 시 watcher를 먼저 켜지 않도록 조정해 런처 유휴 CPU 부담을 완화함 - AX Agent는 최소화/백그라운드 상태에서 task summary, 입력 보조 UI, agent UI flush를 지연했다가 활성화 시 한 번에 반영하도록 정리함 - README와 DEVELOPMENT 문서에 2026-04-06 23:33 (KST) 기준 이력을 반영함 - 검증: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\ (경고 0 / 오류 0)
This commit is contained in:
@@ -9,10 +9,16 @@ namespace AxCopilot.Core;
|
||||
public class FuzzyEngine
|
||||
{
|
||||
private readonly IndexService _index;
|
||||
private readonly object _cacheLock = new();
|
||||
private readonly Dictionary<string, List<FuzzyResult>> _queryCache = new(StringComparer.Ordinal);
|
||||
private readonly Queue<string> _queryCacheOrder = new();
|
||||
private const int QueryCacheLimit = 64;
|
||||
private int _indexGeneration;
|
||||
|
||||
public FuzzyEngine(IndexService index)
|
||||
{
|
||||
_index = index;
|
||||
_index.IndexRebuilt += (_, _) => InvalidateQueryCache();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -25,6 +31,13 @@ public class FuzzyEngine
|
||||
return Enumerable.Empty<FuzzyResult>();
|
||||
|
||||
var normalized = query.Trim().ToLowerInvariant();
|
||||
var cacheKey = $"{_indexGeneration}:{maxResults}:{normalized}";
|
||||
lock (_cacheLock)
|
||||
{
|
||||
if (_queryCache.TryGetValue(cacheKey, out var cached))
|
||||
return cached;
|
||||
}
|
||||
|
||||
var entries = _index.Entries;
|
||||
|
||||
// 쿼리 언어 타입 1회 사전 분류 — 항목마다 재계산하지 않음
|
||||
@@ -36,20 +49,56 @@ public class FuzzyEngine
|
||||
}
|
||||
|
||||
// 300개 초과 시 PLINQ 병렬 처리
|
||||
List<FuzzyResult> results;
|
||||
if (entries.Count > 300)
|
||||
{
|
||||
return entries.AsParallel()
|
||||
results = entries.AsParallel()
|
||||
.Select(e => new FuzzyResult(e, CalculateScoreFast(normalized, e, queryHasKorean)))
|
||||
.Where(r => r.Score > 0)
|
||||
.OrderByDescending(r => r.Score)
|
||||
.Take(maxResults);
|
||||
.Take(maxResults)
|
||||
.ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
results = entries
|
||||
.Select(e => new FuzzyResult(e, CalculateScoreFast(normalized, e, queryHasKorean)))
|
||||
.Where(r => r.Score > 0)
|
||||
.OrderByDescending(r => r.Score)
|
||||
.Take(maxResults)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
return entries
|
||||
.Select(e => new FuzzyResult(e, CalculateScoreFast(normalized, e, queryHasKorean)))
|
||||
.Where(r => r.Score > 0)
|
||||
.OrderByDescending(r => r.Score)
|
||||
.Take(maxResults);
|
||||
StoreCachedResults(cacheKey, results);
|
||||
return results;
|
||||
}
|
||||
|
||||
private void InvalidateQueryCache()
|
||||
{
|
||||
lock (_cacheLock)
|
||||
{
|
||||
_indexGeneration++;
|
||||
_queryCache.Clear();
|
||||
_queryCacheOrder.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void StoreCachedResults(string cacheKey, List<FuzzyResult> results)
|
||||
{
|
||||
lock (_cacheLock)
|
||||
{
|
||||
if (_queryCache.ContainsKey(cacheKey))
|
||||
return;
|
||||
|
||||
_queryCache[cacheKey] = results;
|
||||
_queryCacheOrder.Enqueue(cacheKey);
|
||||
|
||||
while (_queryCacheOrder.Count > QueryCacheLimit)
|
||||
{
|
||||
var oldKey = _queryCacheOrder.Dequeue();
|
||||
_queryCache.Remove(oldKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>미리 계산된 캐시 필드를 활용하는 빠른 점수 계산.</summary>
|
||||
|
||||
Reference in New Issue
Block a user