Fill 'all_candidate_words' field even for NaCl.
Historically Output::all_candidate_words field has been omitted only in
NaCl mainly because of performance reasons. With this CL, that field is
enabled even in NaCl build.
To mitigate the impact on performance, this CL also introduces
Request::candidates_size_limit field so that clients can change the
maximum number of candidates for each conversion request.
BUG=
TEST=unittest
REF_BUG=
REF_CL=88403136
Hiroshi Sumita authored 8 years ago
Yohei Yukawa committed 8 years ago
254 | 254 | segments->set_request_type(Segments::CONVERSION); |
255 | 255 | immutable_converter_->ConvertForRequest(request, segments); |
256 | 256 | RewriteAndSuppressCandidates(request, segments); |
257 | TrimCandidates(request, segments); | |
257 | 258 | return IsValidSegments(request, *segments); |
258 | 259 | } |
259 | 260 | |
267 | 268 | const ConversionRequest default_request; |
268 | 269 | immutable_converter_->ConvertForRequest(default_request, segments); |
269 | 270 | RewriteAndSuppressCandidates(default_request, segments); |
271 | TrimCandidates(default_request, segments); | |
270 | 272 | return IsValidSegments(default_request, *segments); |
271 | 273 | } |
272 | 274 | |
375 | 377 | segments->set_request_type(request_type); |
376 | 378 | predictor_->PredictForRequest(request, segments); |
377 | 379 | RewriteAndSuppressCandidates(request, segments); |
380 | TrimCandidates(request, segments); | |
378 | 381 | if (request_type == Segments::PARTIAL_SUGGESTION || |
379 | 382 | request_type == Segments::PARTIAL_PREDICTION) { |
380 | 383 | // Here 1st segment's key is the query string of |
772 | 775 | |
773 | 776 | immutable_converter_->ConvertForRequest(request, segments); |
774 | 777 | RewriteAndSuppressCandidates(request, segments); |
778 | TrimCandidates(request, segments); | |
775 | 779 | return true; |
776 | 780 | } |
777 | 781 | |
831 | 835 | |
832 | 836 | immutable_converter_->ConvertForRequest(request, segments); |
833 | 837 | RewriteAndSuppressCandidates(request, segments); |
838 | TrimCandidates(request, segments); | |
834 | 839 | return true; |
835 | 840 | } |
836 | 841 | |
920 | 925 | } |
921 | 926 | } |
922 | 927 | |
928 | void ConverterImpl::TrimCandidates(const ConversionRequest &request, | |
929 | Segments *segments) const { | |
930 | const mozc::commands::Request &request_proto = request.request(); | |
931 | if (!request_proto.has_candidates_size_limit()) { | |
932 | return; | |
933 | } | |
934 | ||
935 | const int limit = request_proto.candidates_size_limit(); | |
936 | for (size_t segment_index = 0; | |
937 | segment_index < segments->conversion_segments_size(); ++segment_index) { | |
938 | Segment *seg = segments->mutable_conversion_segment(segment_index); | |
939 | const int candidates_size = seg->candidates_size(); | |
940 | // A segment should have at least one candidate. | |
941 | const int candidates_limit = | |
942 | max(1, limit - static_cast<int>(seg->meta_candidates_size())); | |
943 | if (candidates_size < candidates_limit) { | |
944 | continue; | |
945 | } | |
946 | seg->erase_candidates(candidates_limit, candidates_size - candidates_limit); | |
947 | } | |
948 | } | |
949 | ||
923 | 950 | void ConverterImpl::CommitUsageStats(const Segments *segments, |
924 | 951 | size_t begin_segment_index, |
925 | 952 | size_t segment_length) const { |
153 | 153 | void RewriteAndSuppressCandidates(const ConversionRequest &request, |
154 | 154 | Segments *segments) const; |
155 | 155 | |
156 | // Limits the number of candidates based on a request. | |
157 | // This method doesn't drop meta candidates for T13n conversion. | |
158 | void TrimCandidates(const ConversionRequest &request, | |
159 | Segments *segments) const; | |
160 | ||
156 | 161 | // Commits usage stats for committed text. |
157 | 162 | // |begin_segment_index| is a index of whole segments. (history and conversion |
158 | 163 | // segments) |
1649 | 1649 | EXPECT_NE(0, candidate.rid); |
1650 | 1650 | } |
1651 | 1651 | |
1652 | TEST_F(ConverterTest, LimitCandidatesSize) { | |
1653 | std::unique_ptr<EngineInterface> engine(MockDataEngineFactory::Create()); | |
1654 | ConverterInterface *converter = engine->GetConverter(); | |
1655 | ||
1656 | composer::Table table; | |
1657 | mozc::commands::Request request_proto; | |
1658 | mozc::composer::Composer composer(&table, &request_proto); | |
1659 | composer.InsertCharacterPreedit("\xE3\x81\x82"); // "あ" | |
1660 | ConversionRequest request(&composer, &request_proto); | |
1661 | ||
1662 | Segments segments; | |
1663 | ASSERT_TRUE(converter->StartConversionForRequest(request, &segments)); | |
1664 | ASSERT_EQ(1, segments.conversion_segments_size()); | |
1665 | const int original_candidates_size = | |
1666 | segments.segment(0).candidates_size(); | |
1667 | const int original_meta_candidates_size = | |
1668 | segments.segment(0).meta_candidates_size(); | |
1669 | EXPECT_LT(0, original_candidates_size - 1 - original_meta_candidates_size) | |
1670 | << "original candidates size: " << original_candidates_size | |
1671 | << ", original meta candidates size: " << original_meta_candidates_size; | |
1672 | ||
1673 | segments.Clear(); | |
1674 | request_proto.set_candidates_size_limit(original_candidates_size - 1); | |
1675 | ASSERT_TRUE(converter->StartConversionForRequest(request, &segments)); | |
1676 | ASSERT_EQ(1, segments.conversion_segments_size()); | |
1677 | EXPECT_GE(original_candidates_size - 1, | |
1678 | segments.segment(0).candidates_size()); | |
1679 | EXPECT_LE(original_candidates_size - 1 - original_meta_candidates_size, | |
1680 | segments.segment(0).candidates_size()); | |
1681 | EXPECT_EQ(original_meta_candidates_size, | |
1682 | segments.segment(0).meta_candidates_size()); | |
1683 | ||
1684 | segments.Clear(); | |
1685 | request_proto.set_candidates_size_limit(0); | |
1686 | ASSERT_TRUE(converter->StartConversionForRequest(request, &segments)); | |
1687 | ASSERT_EQ(1, segments.conversion_segments_size()); | |
1688 | EXPECT_EQ(1, segments.segment(0).candidates_size()); | |
1689 | EXPECT_EQ(original_meta_candidates_size, | |
1690 | segments.segment(0).meta_candidates_size()); | |
1691 | } | |
1692 | ||
1652 | 1693 | } // namespace mozc |
0 | 0 | MAJOR=2 |
1 | 1 | MINOR=17 |
2 | BUILD=2232 | |
2 | BUILD=2233 | |
3 | 3 | REVISION=102 |
4 | 4 | # NACL_DICTIONARY_VERSION is the target version of the system dictionary to be |
5 | 5 | # downloaded by NaCl Mozc. |
765 | 765 | |
766 | 766 | // Page size of the candidate list. |
767 | 767 | optional int32 candidate_page_size = 15 [default = 9]; |
768 | ||
769 | // The maximum limit of the candidates size. | |
770 | // If not set, converter doesn't limit the size. | |
771 | // NOTE: Each segment has at least one candidate and meta candidates even if | |
772 | // this value is set to 0. | |
773 | optional int32 candidates_size_limit = 16; | |
768 | 774 | } |
769 | 775 | |
770 | 776 | // Note there is another ApplicationInfo inside RendererCommand. |
1116 | 1116 | candidate_list_visible_) { |
1117 | 1117 | FillCandidates(output->mutable_candidates()); |
1118 | 1118 | } |
1119 | #ifndef __native_client__ | |
1119 | ||
1120 | 1120 | // All candidate words |
1121 | // In NaCl, we don't use the all candidate word data. | |
1122 | 1121 | if (CheckState(SUGGESTION | PREDICTION | CONVERSION)) { |
1123 | 1122 | FillAllCandidateWords(output->mutable_all_candidate_words()); |
1124 | 1123 | } |
1125 | #endif // __native_client__ | |
1126 | 1124 | } |
1127 | 1125 | |
1128 | 1126 | // static |