anshdadhich commited on
Commit
96b5209
·
verified ·
1 Parent(s): e351d28

Upload FastSeekWpf/Core/SearchEngine.cs

Browse files
Files changed (1) hide show
  1. FastSeekWpf/Core/SearchEngine.cs +4 -20
FastSeekWpf/Core/SearchEngine.cs CHANGED
@@ -20,16 +20,8 @@ public class SearchResult
20
  public ResultKind Kind { get; set; }
21
  }
22
 
23
- /// <summary>
24
- /// Allocation-free search engine matching Rust behavior:
25
- /// - Pre-cached lowercase names (no UTF8 decoding in hot loop)
26
- /// - Span-based prefix/contains matching
27
- /// - Stack-allocated candidate buffer
28
- /// - Reusable StringBuilder for path building
29
- /// </summary>
30
  public static class SearchEngine
31
  {
32
- // Reusable StringBuilder for path building
33
  [ThreadStatic]
34
  private static StringBuilder? _pathBuilder;
35
 
@@ -96,9 +88,6 @@ public static class SearchEngine
96
  return false;
97
  }
98
 
99
- /// <summary>
100
- /// Checks if haystack span contains needle span (Ordinal comparison).
101
- /// </summary>
102
  private static bool SpanContains(ReadOnlySpan<char> haystack, ReadOnlySpan<char> needle)
103
  {
104
  if (needle.IsEmpty) return true;
@@ -113,9 +102,6 @@ public static class SearchEngine
113
  return false;
114
  }
115
 
116
- /// <summary>
117
- /// Zero-allocation search using cached lowercase names and Span-based matching.
118
- /// </summary>
119
  public static List<SearchResult> Search(
120
  IndexStore store,
121
  string query,
@@ -126,10 +112,10 @@ public static class SearchEngine
126
  if (string.IsNullOrWhiteSpace(query))
127
  return new List<SearchResult>();
128
 
 
129
  string q = caseSensitive ? query : query.ToLowerInvariant();
130
  ReadOnlySpan<char> qSpan = q.AsSpan();
131
 
132
- // Stack-allocated candidate array (avoid List allocations)
133
  Span<(int idx, byte rank)> candidates = stackalloc (int, byte)[10000];
134
  int candidateCount = 0;
135
 
@@ -152,7 +138,6 @@ public static class SearchEngine
152
  }
153
  }
154
 
155
- // Sort candidates by rank
156
  candidates[..candidateCount].Sort((a, b) => a.rank.CompareTo(b.rank));
157
 
158
  int overshoot = Math.Max(limit * 5, 1000);
@@ -215,6 +200,9 @@ public static class SearchEngine
215
  if (results.Count > limit)
216
  results.RemoveRange(limit, results.Count - limit);
217
 
 
 
 
218
  return results;
219
  }
220
 
@@ -266,13 +254,9 @@ public static class SearchEngine
266
  return results;
267
  }
268
 
269
- /// <summary>
270
- /// Fast path building using reusable StringBuilder instead of List allocation.
271
- /// </summary>
272
  private static string BuildPathFast(IndexStore store, ulong fileRef, StringBuilder sb)
273
  {
274
  sb.Clear();
275
- // string is a managed type, can't stackalloc it. Use small heap array.
276
  string[] components = new string[64];
277
  int compCount = 0;
278
  ulong current = fileRef;
 
20
  public ResultKind Kind { get; set; }
21
  }
22
 
 
 
 
 
 
 
 
23
  public static class SearchEngine
24
  {
 
25
  [ThreadStatic]
26
  private static StringBuilder? _pathBuilder;
27
 
 
88
  return false;
89
  }
90
 
 
 
 
91
  private static bool SpanContains(ReadOnlySpan<char> haystack, ReadOnlySpan<char> needle)
92
  {
93
  if (needle.IsEmpty) return true;
 
102
  return false;
103
  }
104
 
 
 
 
105
  public static List<SearchResult> Search(
106
  IndexStore store,
107
  string query,
 
112
  if (string.IsNullOrWhiteSpace(query))
113
  return new List<SearchResult>();
114
 
115
+ var searchSw = System.Diagnostics.Stopwatch.StartNew();
116
  string q = caseSensitive ? query : query.ToLowerInvariant();
117
  ReadOnlySpan<char> qSpan = q.AsSpan();
118
 
 
119
  Span<(int idx, byte rank)> candidates = stackalloc (int, byte)[10000];
120
  int candidateCount = 0;
121
 
 
138
  }
139
  }
140
 
 
141
  candidates[..candidateCount].Sort((a, b) => a.rank.CompareTo(b.rank));
142
 
143
  int overshoot = Math.Max(limit * 5, 1000);
 
200
  if (results.Count > limit)
201
  results.RemoveRange(limit, results.Count - limit);
202
 
203
+ searchSw.Stop();
204
+ Logger.Log($"Search '{query}': {candidateCount} candidates, {results.Count} results, {searchSw.ElapsedMilliseconds}ms (index={store.Count:N0})");
205
+
206
  return results;
207
  }
208
 
 
254
  return results;
255
  }
256
 
 
 
 
257
  private static string BuildPathFast(IndexStore store, ulong fileRef, StringBuilder sb)
258
  {
259
  sb.Clear();
 
260
  string[] components = new string[64];
261
  int compCount = 0;
262
  ulong current = fileRef;