1b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert/*
2b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert * Copyright (C) 2010 The Android Open Source Project
3b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert *
4b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
5b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert * you may not use this file except in compliance with the License.
6b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert * You may obtain a copy of the License at
7b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert *
8b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert *      http://www.apache.org/licenses/LICENSE-2.0
9b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert *
10b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert * Unless required by applicable law or agreed to in writing, software
11b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
12b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert * See the License for the specific language governing permissions and
14b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert * limitations under the License.
15b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert */
16b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert
17b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringertpackage com.android.quicksearchbox;
18b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert
19b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringertimport com.google.common.annotations.VisibleForTesting;
20b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringertimport com.google.common.collect.HashMultiset;
21b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert
22b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert/**
23b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert * A promoter limits the maximum number of shortcuts per source
24b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert * (from non-web sources) and blends results
25b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert * from multiple sources.
26b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert */
27af1ca2cc65a2c2fdf6f396126e235d64e4da0936Mathew Inwoodpublic class ShortcutPromoter extends AbstractPromoter {
28b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert
29af1ca2cc65a2c2fdf6f396126e235d64e4da0936Mathew Inwood    public ShortcutPromoter(Config config, Promoter next, SuggestionFilter filter) {
3027691bfcdcf3d2918b45bfadd57b08547c317ce5Mathew Inwood        super(filter, next, config);
31b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert    }
32b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert
33b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert    @Override
3427691bfcdcf3d2918b45bfadd57b08547c317ce5Mathew Inwood    public void doPickPromoted(Suggestions suggestions, int maxPromoted,
35b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert            ListSuggestionCursor promoted) {
36b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert        promoteShortcuts(suggestions.getShortcuts(), maxPromoted, promoted);
37b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert    }
38b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert
39b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert    @VisibleForTesting
40b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert    void promoteShortcuts(SuggestionCursor shortcuts, int maxPromoted,
41b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert            ListSuggestionCursor promoted) {
42b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert        int shortcutCount = shortcuts == null ? 0 : shortcuts.getCount();
43b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert        if (shortcutCount == 0) return;
44b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert        HashMultiset<Source> sourceShortcutCounts = HashMultiset.create(shortcutCount);
45b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert        for (int i = 0; i < shortcutCount && promoted.getCount() < maxPromoted; i++) {
46b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert            shortcuts.moveTo(i);
47b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert            Source source = shortcuts.getSuggestionSource();
48b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert            if (source != null && accept(shortcuts)) {
49b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert                int prevCount = sourceShortcutCounts.add(source, 1);
5053aab8c4459f45664d04ec882d67094c52b78695Bjorn Bringert                int maxShortcuts = source.getMaxShortcuts(getConfig());
51b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert                if (prevCount < maxShortcuts) {
52b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert                    promoted.add(new SuggestionPosition(shortcuts));
53b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert                }
54b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert            }
55b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert        }
56b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert    }
57b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert
58b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert}
59