SuggestionsProviderImpl.java revision b5fc08b7f16a32d3865f44b7f26d8aaa5304a2ad
10484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert/*
20484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * Copyright (C) 2009 The Android Open Source Project
30484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert *
40484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
50484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * you may not use this file except in compliance with the License.
60484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * You may obtain a copy of the License at
70484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert *
80484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert *      http://www.apache.org/licenses/LICENSE-2.0
90484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert *
100484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
110484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
120484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * See the License for the specific language governing permissions and
140484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * limitations under the License.
150484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert */
160484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
170484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringertpackage com.android.quicksearchbox;
180484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
19a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringertimport com.android.quicksearchbox.util.BatchingNamedTaskExecutor;
20f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringertimport com.android.quicksearchbox.util.Consumer;
21a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringertimport com.android.quicksearchbox.util.NamedTaskExecutor;
2282bcf002f2f736afcd6cb548c19aa4e8ac12b421Bjorn Bringertimport com.android.quicksearchbox.util.Util;
23a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert
240484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringertimport android.os.Handler;
250484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringertimport android.util.Log;
260484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
270484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringertimport java.util.ArrayList;
28ce4cdcf739b57563ddcdbed6944128b8c1f7522aBjorn Bringertimport java.util.List;
2982bcf002f2f736afcd6cb548c19aa4e8ac12b421Bjorn Bringertimport java.util.Set;
300484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
310484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert/**
3247d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert * Suggestions provider implementation.
330484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert *
340484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * The provider will only handle a single query at a time. If a new query comes
350484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert * in, the old one is canceled.
360484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert */
3747d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringertpublic class SuggestionsProviderImpl implements SuggestionsProvider {
380484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
39b5fc08b7f16a32d3865f44b7f26d8aaa5304a2adBjorn Bringert    private static final boolean DBG = false;
4047d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert    private static final String TAG = "QSB.SuggestionsProviderImpl";
410484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
420484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert    private final Config mConfig;
430484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
44a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert    private final NamedTaskExecutor mQueryExecutor;
450484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
460484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert    private final Handler mPublishThread;
470484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
480484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert    private final Promoter mPromoter;
490484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
5047d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert    private final ShortcutRepository mShortcutRepo;
5147d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert
52f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    private final Logger mLogger;
53f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert
5453bf1409474f26ab0f3754ee9b4d2de901a6be00Bryan Mawhinney    private final ShouldQueryStrategy mShouldQueryStrategy = new ShouldQueryStrategy();
5553bf1409474f26ab0f3754ee9b4d2de901a6be00Bryan Mawhinney
5639bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney    private final Corpora mCorpora;
5739bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney
58a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert    private BatchingNamedTaskExecutor mBatchingExecutor;
5927d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney
6047d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert    public SuggestionsProviderImpl(Config config,
61a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert            NamedTaskExecutor queryExecutor,
620484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert            Handler publishThread,
6347d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert            Promoter promoter,
64f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert            ShortcutRepository shortcutRepo,
6539bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney            Corpora corpora,
66f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert            Logger logger) {
670484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        mConfig = config;
680484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        mQueryExecutor = queryExecutor;
690484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        mPublishThread = publishThread;
700484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        mPromoter = promoter;
7147d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert        mShortcutRepo = shortcutRepo;
72f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        mLogger = logger;
7339bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney        mCorpora = corpora;
740484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert    }
750484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
760484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert    public void close() {
770484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        cancelPendingTasks();
780484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert    }
790484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
800484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert    /**
810484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert     * Cancels all pending query tasks.
820484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert     */
830484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert    private void cancelPendingTasks() {
8427d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney        if (mBatchingExecutor != null) {
8527d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney            mBatchingExecutor.cancelPendingTasks();
8627d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney            mBatchingExecutor = null;
8727d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney        }
880484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert    }
890484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
906d5cbd67f7a5f824babb5c892b0f30bfd9f4ff23Bjorn Bringert    protected SuggestionCursor getShortcutsForQuery(String query, List<Corpus> corpora,
916d5cbd67f7a5f824babb5c892b0f30bfd9f4ff23Bjorn Bringert            int maxShortcuts) {
9247d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert        if (mShortcutRepo == null) return null;
936d5cbd67f7a5f824babb5c892b0f30bfd9f4ff23Bjorn Bringert        return mShortcutRepo.getShortcutsForQuery(query, corpora, maxShortcuts);
9447d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert    }
950484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
960484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert    /**
970484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert     * Gets the sources that should be queried for the given query.
980484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert     */
9947d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert    private List<Corpus> getCorporaToQuery(String query, List<Corpus> orderedCorpora) {
100fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        ArrayList<Corpus> corporaToQuery = new ArrayList<Corpus>(orderedCorpora.size());
101fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        for (Corpus corpus : orderedCorpora) {
102fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert            if (shouldQueryCorpus(corpus, query)) {
103fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert                corporaToQuery.add(corpus);
1040484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert            }
1050484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        }
106fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        return corporaToQuery;
1070484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert    }
1080484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
109fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    protected boolean shouldQueryCorpus(Corpus corpus, String query) {
110503aceaac1aad820f2958a03f7327df18a07f713Bryan Mawhinney        if (query.length() == 0 && !corpus.isWebCorpus()) {
111503aceaac1aad820f2958a03f7327df18a07f713Bryan Mawhinney            // Only the web corpus sees zero length queries.
112503aceaac1aad820f2958a03f7327df18a07f713Bryan Mawhinney            return false;
113503aceaac1aad820f2958a03f7327df18a07f713Bryan Mawhinney        }
114fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        return mShouldQueryStrategy.shouldQueryCorpus(corpus, query);
1150484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert    }
1160484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
117fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    private void updateShouldQueryStrategy(CorpusResult cursor) {
11827d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney        if (cursor.getCount() == 0) {
119fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert            mShouldQueryStrategy.onZeroResults(cursor.getCorpus(),
12027d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney                    cursor.getUserQuery());
12127d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney        }
12227d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney    }
12327d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney
124e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney    public Suggestions getSuggestions(String query, List<Corpus> corpora, int maxSuggestions) {
1250484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        if (DBG) Log.d(TAG, "getSuggestions(" + query + ")");
1260484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        cancelPendingTasks();
12747d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert        List<Corpus> corporaToQuery = getCorporaToQuery(query, corpora);
1280484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        final Suggestions suggestions = new Suggestions(mPromoter,
129e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney                maxSuggestions,
1300484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert                query,
13139bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney                corporaToQuery.size());
1326d5cbd67f7a5f824babb5c892b0f30bfd9f4ff23Bjorn Bringert        int maxShortcuts = mConfig.getMaxShortcutsReturned();
1336d5cbd67f7a5f824babb5c892b0f30bfd9f4ff23Bjorn Bringert        SuggestionCursor shortcuts = getShortcutsForQuery(query, corpora, maxShortcuts);
1340484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        if (shortcuts != null) {
1350484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert            suggestions.setShortcuts(shortcuts);
1360484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        }
1370484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
1380484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        // Fast path for the zero sources case
139fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        if (corporaToQuery.size() == 0) {
1400484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert            return suggestions;
1410484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        }
1420484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
14339bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney        int initialBatchSize = countDefaultCorpora(corporaToQuery);
14439bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney        initialBatchSize = Math.min(initialBatchSize, mConfig.getNumPromotedSources());
14539bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney        if (initialBatchSize == 0) {
14639bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney            initialBatchSize = mConfig.getNumPromotedSources();
14739bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney        }
14839bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney
14939bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney        mBatchingExecutor = new BatchingNamedTaskExecutor(mQueryExecutor);
15027d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney
15127d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney        SuggestionCursorReceiver receiver = new SuggestionCursorReceiver(
15239bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney                mBatchingExecutor, suggestions, initialBatchSize);
1530484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
1540484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        int maxResultsPerSource = mConfig.getMaxResultsPerSource();
155f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert        QueryTask.startQueries(query, maxResultsPerSource, corporaToQuery, mBatchingExecutor,
156f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert                mPublishThread, receiver);
15739bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney        mBatchingExecutor.executeNextBatch(initialBatchSize);
1580484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
1590484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert        return suggestions;
1600484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert    }
1610484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
16239bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney    private int countDefaultCorpora(List<Corpus> corpora) {
16339bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney        int count = 0;
16439bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney        for (Corpus corpus : corpora) {
16539bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney            if (mCorpora.isCorpusDefaultEnabled(corpus)) {
16639bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney                count++;
16739bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney            }
16839bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney        }
16939bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney        return count;
17039bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney    }
17139bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney
172f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert    private class SuggestionCursorReceiver implements Consumer<CorpusResult> {
173a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert        private final BatchingNamedTaskExecutor mExecutor;
17427d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney        private final Suggestions mSuggestions;
17527d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney
17639bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney        private int mCountAtWhichToExecuteNextBatch;
17739bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney
178a48af083ff81555261f334a1e050eae3b02a746cBjorn Bringert        public SuggestionCursorReceiver(BatchingNamedTaskExecutor executor,
17939bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney                Suggestions suggestions, int initialBatchSize) {
18027d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney            mExecutor = executor;
18127d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney            mSuggestions = suggestions;
18239bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney            mCountAtWhichToExecuteNextBatch = initialBatchSize;
18327d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney        }
18427d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney
185f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert        public boolean consume(CorpusResult cursor) {
18627d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney            updateShouldQueryStrategy(cursor);
187f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert            mSuggestions.addCorpusResult(cursor);
188f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert            if (!mSuggestions.isClosed()) {
189f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert                executeNextBatchIfNeeded();
190f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert            }
191f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert            if (cursor != null && mLogger != null) {
192f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert                mLogger.logLatency(cursor);
193f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert            }
194f252dc7a25ba08b973ecc1cfbbce58eb78d42167Bjorn Bringert            return true;
19527d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney        }
19627d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney
19727d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney        private void executeNextBatchIfNeeded() {
19839bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney            if (mSuggestions.getSourceCount() == mCountAtWhichToExecuteNextBatch) {
19927d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney                // We've just finished one batch
20027d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney                if (mSuggestions.getPromoted().getCount() < mConfig.getMaxPromotedSuggestions()) {
20127d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney                    // But we still don't have enough results, ask for more
20239bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney                    int nextBatchSize = mConfig.getNumPromotedSources();
20339bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney                    mCountAtWhichToExecuteNextBatch += nextBatchSize;
20439bbcdc1a485ded93059de4a3f70bfda85e9f304Bryan Mawhinney                    mExecutor.executeNextBatch(nextBatchSize);
20527d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney                }
20627d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney            }
20727d3d4eb3b0414cf7001020d8ddcfdde81fd516bBryan Mawhinney        }
2080484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert    }
2090484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert
2100484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert}
211