Skip to content

Commit 6b5e2d6

Browse files
authored
Reduce Map creation on SDK API search. (#8276)
1 parent cb64a1c commit 6b5e2d6

File tree

3 files changed

+26
-10
lines changed

3 files changed

+26
-10
lines changed

app/lib/search/sdk_mem_index.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ class SdkMemIndex {
136136

137137
final tokens = _tokensPerLibrary[library]!;
138138
final plainResults =
139-
tokens.searchWords(words).toScore().top(3, minValue: 0.05);
139+
Score(tokens.searchWords(words).top(3, minValue: 0.05));
140140
if (plainResults.isEmpty) continue;
141141

142142
final libraryWeight = _libraryWeights[library] ?? 1.0;

app/lib/search/token_index.dart

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,6 @@ extension type const Score._(Map<String, double> _values)
102102
Score mapValues(double Function(String key, double value) f) =>
103103
Score.fromEntries(
104104
_values.entries.map((e) => MapEntry(e.key, f(e.key, e.value))));
105-
106-
/// Returns a new [Score] object with the top [count] entry.
107-
Score top(int count, {double? minValue}) {
108-
final entries = _values.entries
109-
.where((e) => minValue == null || e.value >= minValue)
110-
.toList();
111-
entries.sort((a, b) => -a.value.compareTo(b.value));
112-
return Score(Map.fromEntries(entries.take(count)));
113-
}
114105
}
115106

116107
/// The weighted tokens used for the final search.
@@ -261,6 +252,9 @@ class IndexedScore<K> {
261252
factory IndexedScore(List<K> keys, [double value = 0.0]) =>
262253
IndexedScore._(keys, List<double>.filled(keys.length, value));
263254

255+
factory IndexedScore.fromMap(Map<K, double> values) =>
256+
IndexedScore._(values.keys.toList(), values.values.toList());
257+
264258
List<K> get keys => _keys;
265259
late final length = _values.length;
266260

@@ -321,6 +315,24 @@ class IndexedScore<K> {
321315
}
322316
return set;
323317
}
318+
319+
Map<K, double> top(int count, {double? minValue}) {
320+
final list = <int>[];
321+
double? lastValue;
322+
for (var i = 0; i < length; i++) {
323+
final v = _values[i];
324+
if (minValue != null && v < minValue) continue;
325+
if (list.length == count) {
326+
if (lastValue != null && lastValue >= v) continue;
327+
list[count - 1] = i;
328+
} else {
329+
list.add(i);
330+
}
331+
list.sort((a, b) => -_values[a].compareTo(_values[b]));
332+
lastValue = _values[list.last];
333+
}
334+
return Map.fromEntries(list.map((i) => MapEntry(_keys[i], _values[i])));
335+
}
324336
}
325337

326338
extension StringIndexedScoreExt on IndexedScore<String> {

app/test/search/token_index_test.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ void main() {
126126
'a': 100.0,
127127
});
128128
});
129+
});
130+
131+
group('IndexedScore', () {
132+
final score = IndexedScore.fromMap({'a': 100.0, 'b': 30.0, 'c': 55.0});
129133

130134
test('top', () {
131135
expect(score.top(1), {'a': 100.0});

0 commit comments

Comments
 (0)