Skip to content

Commit 3e49781

Browse files
committed
Different tag index.
1 parent bdf5532 commit 3e49781

File tree

3 files changed

+40
-43
lines changed

3 files changed

+40
-43
lines changed

app/lib/search/mem_index.dart

Lines changed: 26 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class InMemoryPackageIndex {
2828
late final TokenIndex<String> _readmeIndex;
2929
late final TokenIndex<IndexedApiDocPage> _apiSymbolIndex;
3030
late final _scorePool = ScorePool(_packageNameIndex._packageNames);
31-
final _tagIds = <String, int>{};
31+
final _tagDocumentIndexes = <String, List<int>>{};
3232
final _documentTagIds = <List<int>>[];
3333

3434
/// Adjusted score takes the overall score and transforms
@@ -63,7 +63,7 @@ class InMemoryPackageIndex {
6363
// transform tags into numberical IDs
6464
final tagIds = <int>[];
6565
for (final tag in doc.tags) {
66-
tagIds.add(_tagIds.putIfAbsent(tag, () => _tagIds.length));
66+
_tagDocumentIndexes.putIfAbsent(tag, () => []).add(i);
6767
}
6868
tagIds.sort();
6969
_documentTagIds.add(tagIds);
@@ -134,11 +134,7 @@ class InMemoryPackageIndex {
134134
PackageSearchResult search(ServiceSearchQuery query) {
135135
// prevent any work if offset is outside of the range
136136
if ((query.offset ?? 0) > _documents.length) {
137-
return PackageSearchResult(
138-
timestamp: clock.now(),
139-
totalCount: 0,
140-
packageHits: [],
141-
);
137+
return PackageSearchResult.empty();
142138
}
143139
return _scorePool.withScore(
144140
value: 1.0,
@@ -162,49 +158,36 @@ class InMemoryPackageIndex {
162158
final combinedTagsPredicate =
163159
query.tagsPredicate.appendPredicate(query.parsedQuery.tagsPredicate);
164160
if (combinedTagsPredicate.isNotEmpty) {
165-
// The list of predicate tag entries, converted to tag IDs (or -1 if there is no indexed tag),
166-
// sorted by their id.
167-
final entriesToCheck = combinedTagsPredicate.entries
168-
.map((e) => MapEntry(_tagIds[e.key] ?? -1, e.value))
169-
.toList()
170-
..sort((a, b) => a.key.compareTo(b.key));
171-
172-
packageScores.retainWhere((docIndex, _) {
173-
// keeping track of tag id iteration with the `nextTagIndex`
174-
final tagIds = _documentTagIds[docIndex];
175-
var nextTagIndex = 0;
176-
177-
for (final entry in entriesToCheck) {
178-
if (entry.key == -1) {
179-
// no tag id is present for this predicate
180-
if (entry.value) {
181-
// the predicate is required, no document will match it
182-
return false;
183-
} else {
184-
// the predicate is prohibited, no document has it, always a match
161+
for (final entry in combinedTagsPredicate.entries) {
162+
final docIndexes = _tagDocumentIndexes[entry.key];
163+
164+
if (entry.value) {
165+
// predicate is required, zeroing the gaps between index values
166+
if (docIndexes == null) {
167+
// the predicate is required, no document will match it
168+
return PackageSearchResult.empty();
169+
}
170+
171+
for (var i = 0; i < docIndexes.length; i++) {
172+
if (i == 0) {
173+
packageScores.fillRange(0, docIndexes[i], 0.0);
185174
continue;
186175
}
176+
packageScores.fillRange(docIndexes[i - 1] + 1, docIndexes[i], 0.0);
187177
}
178+
packageScores.fillRange(docIndexes.last + 1, _documents.length, 0.0);
179+
} else {
180+
// predicate is prohibited, zeroing the values
188181

189-
// skipping the present tag ids until the currently matched predicate tag id
190-
while (nextTagIndex < tagIds.length &&
191-
tagIds[nextTagIndex] < entry.key) {
192-
nextTagIndex++;
182+
if (docIndexes == null) {
183+
// the predicate is prohibited, no document has it, always a match
184+
continue;
193185
}
194-
195-
// checking presence
196-
late bool present;
197-
if (nextTagIndex == tagIds.length) {
198-
present = false;
199-
} else {
200-
present = tagIds[nextTagIndex] == entry.key;
186+
for (final i in docIndexes) {
187+
packageScores.setValue(i, 0.0);
201188
}
202-
203-
if (entry.value && !present) return false;
204-
if (!entry.value && present) return false;
205189
}
206-
return true;
207-
});
190+
}
208191
}
209192

210193
// filter on dependency

app/lib/search/search_service.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,12 @@ class PackageSearchResult {
341341
sdkLibraryHits = sdkLibraryHits ?? <SdkLibraryHit>[],
342342
statusCode = statusCode;
343343

344+
factory PackageSearchResult.empty() => PackageSearchResult(
345+
timestamp: clock.now(),
346+
totalCount: 0,
347+
packageHits: [],
348+
);
349+
344350
PackageSearchResult.error({
345351
required this.errorMessage,
346352
required this.statusCode,

app/lib/search/token_index.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,14 @@ class IndexedScore<K> {
219219
_values[index] = math.max(_values[index], value);
220220
}
221221

222+
/// Sets the positions greater than or equal to [start] and less than [end],
223+
/// to [fillValue].
224+
void fillRange(int start, int end, double fillValue) {
225+
assert(start <= end);
226+
if (start == end) return;
227+
_values.fillRange(start, end, fillValue);
228+
}
229+
222230
void removeWhere(bool Function(int index, K key) fn) {
223231
for (var i = 0; i < length; i++) {
224232
if (isNotPositive(i)) continue;

0 commit comments

Comments
 (0)