mirror of
https://github.com/mii443/mozc.git
synced 2025-08-22 16:15:46 +00:00
Add a experimental flag to control the bugfix in cl/694010741
PiperOrigin-RevId: 730762929
This commit is contained in:
committed by
Hiroyuki Komatsu
parent
d939d1446b
commit
4af84e37ba
@ -543,7 +543,7 @@ message Capability {
|
|||||||
[default = NO_TEXT_DELETION_CAPABILITY];
|
[default = NO_TEXT_DELETION_CAPABILITY];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next ID: 105
|
// Next ID: 106
|
||||||
// Bundles together some Android experiment flags so that they can be easily
|
// Bundles together some Android experiment flags so that they can be easily
|
||||||
// retrieved throughout the native code. These flags are generally specific to
|
// retrieved throughout the native code. These flags are generally specific to
|
||||||
// the decoder, and are made available when the decoder is initialized.
|
// the decoder, and are made available when the decoder is initialized.
|
||||||
@ -646,6 +646,9 @@ message DecoderExperimentParams {
|
|||||||
// history rewriter wheh the target segment contains proper noun candidate.
|
// history rewriter wheh the target segment contains proper noun candidate.
|
||||||
optional bool user_segment_history_rewriter_replace_proper_noun = 103
|
optional bool user_segment_history_rewriter_replace_proper_noun = 103
|
||||||
[default = false];
|
[default = false];
|
||||||
|
|
||||||
|
// Apply inner segment boundary information to the single segment candidate.
|
||||||
|
optional bool apply_single_inner_segment_boundary = 105 [default = true];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clients' request to the server.
|
// Clients' request to the server.
|
||||||
|
@ -740,11 +740,21 @@ bool UserSegmentHistoryRewriter::IsAvailable(const ConversionRequest &request,
|
|||||||
// Returns segments for learning.
|
// Returns segments for learning.
|
||||||
// Inner segments boundary will be expanded.
|
// Inner segments boundary will be expanded.
|
||||||
Segments UserSegmentHistoryRewriter::MakeLearningSegmentsFromInnerSegments(
|
Segments UserSegmentHistoryRewriter::MakeLearningSegmentsFromInnerSegments(
|
||||||
const Segments &segments) {
|
const ConversionRequest &request, const Segments &segments) {
|
||||||
|
auto inner_segments_info_available = [&request](const Segment::Candidate &c) {
|
||||||
|
if (request.request()
|
||||||
|
.decoder_experiment_params()
|
||||||
|
.apply_single_inner_segment_boundary()) {
|
||||||
|
return !c.inner_segment_boundary.empty();
|
||||||
|
} else {
|
||||||
|
return c.inner_segment_boundary.size() > 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Segments ret;
|
Segments ret;
|
||||||
for (const Segment &segment : segments) {
|
for (const Segment &segment : segments) {
|
||||||
const Segment::Candidate &candidate = segment.candidate(0);
|
const Segment::Candidate &candidate = segment.candidate(0);
|
||||||
if (candidate.inner_segment_boundary.empty()) {
|
if (!inner_segments_info_available(candidate)) {
|
||||||
// No inner segment info
|
// No inner segment info
|
||||||
Segment *seg = ret.add_segment();
|
Segment *seg = ret.add_segment();
|
||||||
*seg = segment;
|
*seg = segment;
|
||||||
@ -796,7 +806,7 @@ void UserSegmentHistoryRewriter::Finish(const ConversionRequest &request,
|
|||||||
|
|
||||||
const Segments target_segments =
|
const Segments target_segments =
|
||||||
UseInnerSegments(request)
|
UseInnerSegments(request)
|
||||||
? MakeLearningSegmentsFromInnerSegments(*segments)
|
? MakeLearningSegmentsFromInnerSegments(request, *segments)
|
||||||
: *segments;
|
: *segments;
|
||||||
std::vector<Segments::RevertEntry> revert_entries;
|
std::vector<Segments::RevertEntry> revert_entries;
|
||||||
for (size_t i = target_segments.history_segments_size();
|
for (size_t i = target_segments.history_segments_size();
|
||||||
|
@ -90,7 +90,7 @@ class UserSegmentHistoryRewriter : public RewriterInterface {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static Segments MakeLearningSegmentsFromInnerSegments(
|
static Segments MakeLearningSegmentsFromInnerSegments(
|
||||||
const Segments &segments);
|
const ConversionRequest &request, const Segments &segments);
|
||||||
|
|
||||||
// Returns id for RevertEntry
|
// Returns id for RevertEntry
|
||||||
static uint16_t revert_id();
|
static uint16_t revert_id();
|
||||||
|
@ -67,9 +67,9 @@ class UserSegmentHistoryRewriterTestPeer {
|
|||||||
UserSegmentHistoryRewriterTestPeer() = delete;
|
UserSegmentHistoryRewriterTestPeer() = delete;
|
||||||
|
|
||||||
static Segments MakeLearningSegmentsFromInnerSegments(
|
static Segments MakeLearningSegmentsFromInnerSegments(
|
||||||
const Segments &segments) {
|
const ConversionRequest &request, const Segments &segments) {
|
||||||
return UserSegmentHistoryRewriter::MakeLearningSegmentsFromInnerSegments(
|
return UserSegmentHistoryRewriter::MakeLearningSegmentsFromInnerSegments(
|
||||||
segments);
|
request, segments);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1755,9 +1755,11 @@ TEST_F(UserSegmentHistoryRewriterTest, SupportInnerSegmentsOnLearning) {
|
|||||||
Segment::Candidate::RERANKED;
|
Segment::Candidate::RERANKED;
|
||||||
segments.mutable_segment(0)->set_segment_type(Segment::FIXED_VALUE);
|
segments.mutable_segment(0)->set_segment_type(Segment::FIXED_VALUE);
|
||||||
|
|
||||||
|
const ConversionRequest default_mobile_convreq = CreateConversionRequest();
|
||||||
{
|
{
|
||||||
const Segments learning_segments = UserSegmentHistoryRewriterTestPeer::
|
const Segments learning_segments = UserSegmentHistoryRewriterTestPeer::
|
||||||
MakeLearningSegmentsFromInnerSegments(segments);
|
MakeLearningSegmentsFromInnerSegments(default_mobile_convreq,
|
||||||
|
segments);
|
||||||
EXPECT_EQ(learning_segments.segments_size(), 3);
|
EXPECT_EQ(learning_segments.segments_size(), 3);
|
||||||
EXPECT_EQ(learning_segments.segment(0).key(), "わたしの");
|
EXPECT_EQ(learning_segments.segment(0).key(), "わたしの");
|
||||||
EXPECT_EQ(learning_segments.segment(0).candidate(0).key, "わたしの");
|
EXPECT_EQ(learning_segments.segment(0).candidate(0).key, "わたしの");
|
||||||
@ -1795,8 +1797,7 @@ TEST_F(UserSegmentHistoryRewriterTest, SupportInnerSegmentsOnLearning) {
|
|||||||
Segment::FIXED_VALUE);
|
Segment::FIXED_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ConversionRequest convreq = CreateConversionRequest();
|
rewriter->Finish(default_mobile_convreq, &segments);
|
||||||
rewriter->Finish(convreq, &segments);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1823,9 +1824,11 @@ TEST_F(UserSegmentHistoryRewriterTest, SupportInnerSegmentsOnLearning) {
|
|||||||
Segment::Candidate::RERANKED;
|
Segment::Candidate::RERANKED;
|
||||||
segments.mutable_segment(0)->set_segment_type(Segment::FIXED_VALUE);
|
segments.mutable_segment(0)->set_segment_type(Segment::FIXED_VALUE);
|
||||||
|
|
||||||
|
const ConversionRequest default_mobile_convreq = CreateConversionRequest();
|
||||||
{
|
{
|
||||||
const Segments learning_segments = UserSegmentHistoryRewriterTestPeer::
|
const Segments learning_segments = UserSegmentHistoryRewriterTestPeer::
|
||||||
MakeLearningSegmentsFromInnerSegments(segments);
|
MakeLearningSegmentsFromInnerSegments(default_mobile_convreq,
|
||||||
|
segments);
|
||||||
EXPECT_EQ(learning_segments.segments_size(), 1);
|
EXPECT_EQ(learning_segments.segments_size(), 1);
|
||||||
EXPECT_EQ(learning_segments.segment(0).key(), "わたしの");
|
EXPECT_EQ(learning_segments.segment(0).key(), "わたしの");
|
||||||
EXPECT_EQ(learning_segments.segment(0).candidate(0).key, "わたしの");
|
EXPECT_EQ(learning_segments.segment(0).candidate(0).key, "わたしの");
|
||||||
@ -1839,52 +1842,7 @@ TEST_F(UserSegmentHistoryRewriterTest, SupportInnerSegmentsOnLearning) {
|
|||||||
Segment::FIXED_VALUE);
|
Segment::FIXED_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ConversionRequest convreq = CreateConversionRequest();
|
rewriter->Finish(default_mobile_convreq, &segments);
|
||||||
rewriter->Finish(convreq, &segments);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// Inner segment boundary with size 1 may have better information.
|
|
||||||
segments.Clear();
|
|
||||||
InitSegments(&segments, 1, 2);
|
|
||||||
constexpr absl::string_view kKey = "わたしの";
|
|
||||||
constexpr absl::string_view kValue = "私の";
|
|
||||||
segments.mutable_segment(0)->set_key(kKey);
|
|
||||||
Segment::Candidate *candidate =
|
|
||||||
segments.mutable_segment(0)->mutable_candidate(1);
|
|
||||||
|
|
||||||
candidate->value = kValue;
|
|
||||||
candidate->content_value = kValue;
|
|
||||||
candidate->key = kKey;
|
|
||||||
candidate->content_key = kKey;
|
|
||||||
// "わたしの, 私の", "わたし, 私"
|
|
||||||
candidate->PushBackInnerSegmentBoundary(12, 6, 9, 3);
|
|
||||||
candidate->lid = 10;
|
|
||||||
candidate->rid = 10;
|
|
||||||
|
|
||||||
segments.mutable_segment(0)->move_candidate(1, 0);
|
|
||||||
segments.mutable_segment(0)->mutable_candidate(0)->attributes |=
|
|
||||||
Segment::Candidate::RERANKED;
|
|
||||||
segments.mutable_segment(0)->set_segment_type(Segment::FIXED_VALUE);
|
|
||||||
|
|
||||||
{
|
|
||||||
const Segments learning_segments = UserSegmentHistoryRewriterTestPeer::
|
|
||||||
MakeLearningSegmentsFromInnerSegments(segments);
|
|
||||||
EXPECT_EQ(learning_segments.segments_size(), 1);
|
|
||||||
EXPECT_EQ(learning_segments.segment(0).key(), "わたしの");
|
|
||||||
EXPECT_EQ(learning_segments.segment(0).candidate(0).key, "わたしの");
|
|
||||||
EXPECT_EQ(learning_segments.segment(0).candidate(0).value, "私の");
|
|
||||||
EXPECT_EQ(learning_segments.segment(0).candidate(0).content_key,
|
|
||||||
"わたし");
|
|
||||||
EXPECT_EQ(learning_segments.segment(0).candidate(0).content_value, "私");
|
|
||||||
EXPECT_EQ(learning_segments.segment(0).candidate(0).lid, 10);
|
|
||||||
EXPECT_EQ(learning_segments.segment(0).candidate(0).rid, 10);
|
|
||||||
EXPECT_EQ(learning_segments.segment(0).segment_type(),
|
|
||||||
Segment::FIXED_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
const ConversionRequest convreq = CreateConversionRequest();
|
|
||||||
rewriter->Finish(convreq, &segments);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1904,10 +1862,59 @@ TEST_F(UserSegmentHistoryRewriterTest, SupportInnerSegmentsOnLearning) {
|
|||||||
candidate->content_key = "なかの";
|
candidate->content_key = "なかの";
|
||||||
candidate->content_key = "なかの";
|
candidate->content_key = "なかの";
|
||||||
|
|
||||||
const ConversionRequest convreq = CreateConversionRequest();
|
const ConversionRequest default_mobile_convreq = CreateConversionRequest();
|
||||||
EXPECT_TRUE(rewriter->Rewrite(convreq, &segments));
|
EXPECT_TRUE(rewriter->Rewrite(default_mobile_convreq, &segments));
|
||||||
EXPECT_EQ(segments.segment(0).candidate(0).value, "中野");
|
EXPECT_EQ(segments.segment(0).candidate(0).value, "中野");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Disable inner segment boundary for single segment
|
||||||
|
request_->mutable_decoder_experiment_params()
|
||||||
|
->set_apply_single_inner_segment_boundary(false);
|
||||||
|
|
||||||
|
// Inner segment boundary with size 1 may have better information.
|
||||||
|
segments.Clear();
|
||||||
|
InitSegments(&segments, 1, 2);
|
||||||
|
constexpr absl::string_view kKey = "わたしの";
|
||||||
|
constexpr absl::string_view kValue = "私の";
|
||||||
|
segments.mutable_segment(0)->set_key(kKey);
|
||||||
|
Segment::Candidate *candidate =
|
||||||
|
segments.mutable_segment(0)->mutable_candidate(1);
|
||||||
|
|
||||||
|
candidate->value = kValue;
|
||||||
|
candidate->content_value = kValue;
|
||||||
|
candidate->key = kKey;
|
||||||
|
candidate->content_key = kKey;
|
||||||
|
// "わたしの, 私の", "わたし, 私"
|
||||||
|
candidate->PushBackInnerSegmentBoundary(12, 6, 9, 3);
|
||||||
|
candidate->lid = 10;
|
||||||
|
candidate->rid = 10;
|
||||||
|
|
||||||
|
segments.mutable_segment(0)->move_candidate(1, 0);
|
||||||
|
segments.mutable_segment(0)->mutable_candidate(0)->attributes |=
|
||||||
|
Segment::Candidate::RERANKED;
|
||||||
|
segments.mutable_segment(0)->set_segment_type(Segment::FIXED_VALUE);
|
||||||
|
|
||||||
|
const ConversionRequest convreq = CreateConversionRequest();
|
||||||
|
{
|
||||||
|
const Segments learning_segments = UserSegmentHistoryRewriterTestPeer::
|
||||||
|
MakeLearningSegmentsFromInnerSegments(convreq, segments);
|
||||||
|
EXPECT_EQ(learning_segments.segments_size(), 1);
|
||||||
|
EXPECT_EQ(learning_segments.segment(0).key(), "わたしの");
|
||||||
|
EXPECT_EQ(learning_segments.segment(0).candidate(0).key, "わたしの");
|
||||||
|
EXPECT_EQ(learning_segments.segment(0).candidate(0).value, "私の");
|
||||||
|
EXPECT_EQ(learning_segments.segment(0).candidate(0).content_key,
|
||||||
|
"わたしの");
|
||||||
|
EXPECT_EQ(learning_segments.segment(0).candidate(0).content_value,
|
||||||
|
"私の");
|
||||||
|
EXPECT_EQ(learning_segments.segment(0).candidate(0).lid, 10);
|
||||||
|
EXPECT_EQ(learning_segments.segment(0).candidate(0).rid, 10);
|
||||||
|
EXPECT_EQ(learning_segments.segment(0).segment_type(),
|
||||||
|
Segment::FIXED_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
rewriter->Finish(convreq, &segments);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(UserSegmentHistoryRewriterTest, ReplaceableSingleKanji) {
|
TEST_F(UserSegmentHistoryRewriterTest, ReplaceableSingleKanji) {
|
||||||
|
Reference in New Issue
Block a user