1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.inputmethod.latin.utils;
18 
19 import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
20 import com.android.inputmethod.latin.define.ProductionFlags;
21 
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Comparator;
25 import java.util.Locale;
26 import java.util.TreeSet;
27 
28 /**
29  * A TreeSet of SuggestedWordInfo that is bounded in size and throws everything that's smaller
30  * than its limit
31  */
32 public final class SuggestionResults extends TreeSet<SuggestedWordInfo> {
33     public final Locale mLocale;
34     public final ArrayList<SuggestedWordInfo> mRawSuggestions;
35     // TODO: Instead of a boolean , we may want to include the context of this suggestion results,
36     // such as {@link PrevWordsInfo}.
37     public final boolean mIsBeginningOfSentence;
38     private final int mCapacity;
39 
SuggestionResults(final Locale locale, final int capacity, final boolean isBeginningOfSentence)40     public SuggestionResults(final Locale locale, final int capacity,
41             final boolean isBeginningOfSentence) {
42         this(locale, sSuggestedWordInfoComparator, capacity, isBeginningOfSentence);
43     }
44 
SuggestionResults(final Locale locale, final Comparator<SuggestedWordInfo> comparator, final int capacity, final boolean isBeginningOfSentence)45     private SuggestionResults(final Locale locale, final Comparator<SuggestedWordInfo> comparator,
46             final int capacity, final boolean isBeginningOfSentence) {
47         super(comparator);
48         mLocale = locale;
49         mCapacity = capacity;
50         if (ProductionFlags.INCLUDE_RAW_SUGGESTIONS) {
51             mRawSuggestions = new ArrayList<>();
52         } else {
53             mRawSuggestions = null;
54         }
55         mIsBeginningOfSentence = isBeginningOfSentence;
56     }
57 
58     @Override
add(final SuggestedWordInfo e)59     public boolean add(final SuggestedWordInfo e) {
60         if (size() < mCapacity) return super.add(e);
61         if (comparator().compare(e, last()) > 0) return false;
62         super.add(e);
63         pollLast(); // removes the last element
64         return true;
65     }
66 
67     @Override
addAll(final Collection<? extends SuggestedWordInfo> e)68     public boolean addAll(final Collection<? extends SuggestedWordInfo> e) {
69         if (null == e) return false;
70         return super.addAll(e);
71     }
72 
73     private static final class SuggestedWordInfoComparator
74             implements Comparator<SuggestedWordInfo> {
75         // This comparator ranks the word info with the higher frequency first. That's because
76         // that's the order we want our elements in.
77         @Override
compare(final SuggestedWordInfo o1, final SuggestedWordInfo o2)78         public int compare(final SuggestedWordInfo o1, final SuggestedWordInfo o2) {
79             if (o1.mScore > o2.mScore) return -1;
80             if (o1.mScore < o2.mScore) return 1;
81             if (o1.mCodePointCount < o2.mCodePointCount) return -1;
82             if (o1.mCodePointCount > o2.mCodePointCount) return 1;
83             return o1.mWord.compareTo(o2.mWord);
84         }
85     }
86 
87     private static final SuggestedWordInfoComparator sSuggestedWordInfoComparator =
88             new SuggestedWordInfoComparator();
89 }
90