| /* |
| * Copyright (C) 2010 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.quicksearchbox; |
| |
| import com.android.quicksearchbox.util.CachedLater; |
| import com.android.quicksearchbox.util.Consumer; |
| |
| import android.database.DataSetObserver; |
| import android.util.Log; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.List; |
| import java.util.Map; |
| |
| /** |
| * A corpus ranker that uses corpus scores from the shortcut repository to rank |
| * corpora. |
| */ |
| public class DefaultCorpusRanker implements CorpusRanker { |
| |
| private static final boolean DBG = false; |
| private static final String TAG = "QSB.DefaultCorpusRanker"; |
| |
| private final ShortcutRepository mShortcuts; |
| |
| private final Corpora mCorpora; |
| |
| // Cached list of ranked corpora. |
| private final RankedCorporaCache mRankedCorpora; |
| |
| /** |
| * Creates a new default corpus ranker. |
| * |
| * @param corpora Corpora to rank. |
| * @param shortcuts Shortcut repository for getting corpus scores. |
| */ |
| public DefaultCorpusRanker(Corpora corpora, ShortcutRepository shortcuts) { |
| mCorpora = corpora; |
| mCorpora.registerDataSetObserver(new CorporaObserver()); |
| mShortcuts = shortcuts; |
| mRankedCorpora = new RankedCorporaCache(); |
| } |
| |
| public void getCorporaInAll(Consumer<List<Corpus>> consumer) { |
| mRankedCorpora.getLater(consumer); |
| } |
| |
| public void clear() { |
| mRankedCorpora.clear(); |
| } |
| |
| private class CorporaObserver extends DataSetObserver { |
| @Override |
| public void onChanged() { |
| clear(); |
| } |
| } |
| |
| private class RankedCorporaCache extends CachedLater<List<Corpus>> { |
| |
| @Override |
| protected void create() { |
| mShortcuts.getCorpusScores(new Consumer<Map<String,Integer>>(){ |
| public boolean consume(Map<String, Integer> clickScores) { |
| Collection<Corpus> enabledCorpora = mCorpora.getCorporaInAll(); |
| if (DBG) Log.d(TAG, "Ranking: " + enabledCorpora); |
| ArrayList<Corpus> ordered = new ArrayList<Corpus>(enabledCorpora); |
| Collections.sort(ordered, new CorpusComparator(clickScores)); |
| |
| if (DBG) Log.d(TAG, "Click scores: " + clickScores); |
| if (DBG) Log.d(TAG, "Ordered: " + ordered); |
| |
| store(ordered); |
| return true; |
| } |
| }); |
| } |
| |
| } |
| |
| private static class CorpusComparator implements Comparator<Corpus> { |
| private final Map<String,Integer> mClickScores; |
| |
| public CorpusComparator(Map<String,Integer> clickScores) { |
| mClickScores = clickScores; |
| } |
| |
| public int compare(Corpus corpus1, Corpus corpus2) { |
| boolean corpus1IsDefault = corpus1.isCorpusDefaultEnabled(); |
| boolean corpus2IsDefault = corpus2.isCorpusDefaultEnabled(); |
| |
| if (corpus1IsDefault != corpus2IsDefault) { |
| // Default corpora always come before non-default |
| return corpus1IsDefault ? -1 : 1; |
| } |
| |
| // Then by descending score |
| int scoreDiff = getCorpusScore(corpus2) - getCorpusScore(corpus1); |
| if (scoreDiff != 0) { |
| return scoreDiff; |
| } |
| |
| // Finally by name |
| return corpus1.getLabel().toString().compareTo(corpus2.getLabel().toString()); |
| } |
| |
| /** |
| * Scores a corpus. Higher score is better. |
| */ |
| private int getCorpusScore(Corpus corpus) { |
| // Web corpus always comes first |
| if (corpus.isWebCorpus()) { |
| return Integer.MAX_VALUE; |
| } |
| // Then use click score |
| return getClickScore(corpus); |
| } |
| |
| private int getClickScore(Corpus corpus) { |
| if (mClickScores == null) return 0; |
| Integer clickScore = mClickScores.get(corpus.getName()); |
| return clickScore == null ? 0 : clickScore; |
| } |
| } |
| |
| } |