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