Merge "Support controlling some unigram flags in addUnigramWord."
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/probability_dict_content.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/probability_dict_content.cpp
index 473ab0d..7a75499 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/probability_dict_content.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/probability_dict_content.cpp
@@ -23,12 +23,10 @@
 
 namespace latinime {
 
-void ProbabilityDictContent::getProbabilityEntry(const int terminalId,
-        ProbabilityEntry *const outProbabilityEntry) const {
+const ProbabilityEntry ProbabilityDictContent::getProbabilityEntry(const int terminalId) const {
     if (terminalId < 0 || terminalId >= mSize) {
         // This method can be called with invalid terminal id during GC.
-        outProbabilityEntry->setProbability(0 /* flags */, NOT_A_PROBABILITY);
-        return;
+        return ProbabilityEntry(0 /* flags */, NOT_A_PROBABILITY);
     }
     const BufferWithExtendableBuffer *const buffer = getBuffer();
     int entryPos = getEntryPos(terminalId);
@@ -43,10 +41,9 @@
                 Ver4DictConstants::WORD_LEVEL_FIELD_SIZE, &entryPos);
         const int count = buffer->readUintAndAdvancePosition(
                 Ver4DictConstants::WORD_COUNT_FIELD_SIZE, &entryPos);
-        outProbabilityEntry->setProbabilityWithHistricalInfo(flags, probability, timestamp, level,
-                count);
+        return ProbabilityEntry(flags, probability, timestamp, level, count);
     } else {
-        outProbabilityEntry->setProbability(flags, probability);
+        return ProbabilityEntry(flags, probability);
     }
 }
 
@@ -76,9 +73,8 @@
 bool ProbabilityDictContent::flushToFile(const char *const dictDirPath) const {
     if (getEntryPos(mSize) < getBuffer()->getTailPosition()) {
         ProbabilityDictContent probabilityDictContentToWrite(mHasHistoricalInfo);
-        ProbabilityEntry probabilityEntry;
         for (int i = 0; i < mSize; ++i) {
-            getProbabilityEntry(i, &probabilityEntry);
+            const ProbabilityEntry probabilityEntry = getProbabilityEntry(i);
             if (!probabilityDictContentToWrite.setProbabilityEntry(i, &probabilityEntry)) {
                 AKLOGE("Cannot set probability entry in flushToFile. terminalId: %d", i);
                 return false;
@@ -95,10 +91,10 @@
         const TerminalPositionLookupTable::TerminalIdMap *const terminalIdMap,
         const ProbabilityDictContent *const originalProbabilityDictContent) {
     mSize = 0;
-    ProbabilityEntry probabilityEntry;
     for (TerminalPositionLookupTable::TerminalIdMap::const_iterator it = terminalIdMap->begin();
             it != terminalIdMap->end(); ++it) {
-        originalProbabilityDictContent->getProbabilityEntry(it->first, &probabilityEntry);
+        const ProbabilityEntry probabilityEntry =
+                originalProbabilityDictContent->getProbabilityEntry(it->first);
         if (!setProbabilityEntry(it->second, &probabilityEntry)) {
             AKLOGE("Cannot set probability entry in runGC. terminalId: %d", it->second);
             return false;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/probability_dict_content.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/probability_dict_content.h
index 7e78272..db96f90 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/probability_dict_content.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/probability_dict_content.h
@@ -38,8 +38,7 @@
     ProbabilityDictContent(const bool hasHistoricalInfo)
             : mHasHistoricalInfo(hasHistoricalInfo), mSize(0) {}
 
-    void getProbabilityEntry(const int terminalId,
-            ProbabilityEntry *const outProbabilityEntry) const;
+    const ProbabilityEntry getProbabilityEntry(const int terminalId) const;
 
     bool setProbabilityEntry(const int terminalId, const ProbabilityEntry *const probabilityEntry);
 
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/probability_entry.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/probability_entry.h
index 95e2e28..274c465 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/probability_entry.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/probability_entry.h
@@ -24,25 +24,29 @@
 
 class ProbabilityEntry {
  public:
+    ProbabilityEntry(const ProbabilityEntry &probabilityEntry)
+            : mFlags(probabilityEntry.mFlags), mProbability(probabilityEntry.mProbability),
+              mTimestamp(probabilityEntry.mTimestamp), mLevel(probabilityEntry.mLevel),
+              mCount(probabilityEntry.mCount) {}
+
+    // Dummy entry
     ProbabilityEntry()
             : mFlags(0), mProbability(NOT_A_PROBABILITY),
               mTimestamp(Ver4DictConstants::NOT_A_TIME_STAMP), mLevel(0), mCount(0) {}
 
-    void setProbability(const int flags, const int probability) {
-        mFlags = flags;
-        mProbability = probability;
-        mTimestamp = Ver4DictConstants::NOT_A_TIME_STAMP;
-        mLevel = 0;
-        mCount = 0;
-    }
+    // Entry without historical information
+    ProbabilityEntry(const int flags, const int probability)
+            : mFlags(flags), mProbability(probability),
+              mTimestamp(Ver4DictConstants::NOT_A_TIME_STAMP), mLevel(0), mCount(0) {}
 
-    void setProbabilityWithHistricalInfo(const int flags, const int probability,
-            const int timestamp, const int level, const int count) {
-        mFlags = flags;
-        mProbability = probability;
-        mTimestamp = timestamp;
-        mLevel = level;
-        mCount = count;
+    // Entry with historical information.
+    ProbabilityEntry(const int flags, const int probability, const int timestamp,
+            const int level, const int count)
+            : mFlags(flags), mProbability(probability), mTimestamp(timestamp), mLevel(level),
+              mCount(count) {}
+
+    const ProbabilityEntry createEntryWithUpdatedProbability(const int probability) const {
+        return ProbabilityEntry(mFlags, probability, mTimestamp, mLevel, mCount);
     }
 
     int getFlags() const {
@@ -66,13 +70,14 @@
     }
 
  private:
-    DISALLOW_COPY_AND_ASSIGN(ProbabilityEntry);
+    // Copy constructor is public to use this class as a type of return value.
+    DISALLOW_ASSIGNMENT_OPERATOR(ProbabilityEntry);
 
-    int mFlags;
-    int mProbability;
-    int mTimestamp;
-    int mLevel;
-    int mCount;
+    const int mFlags;
+    const int mProbability;
+    const int mTimestamp;
+    const int mLevel;
+    const int mCount;
 };
 } // namespace latinime
 #endif /* LATINIME_PROBABILITY_ENTRY_H */
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.cpp
index 3926a93..5fa657d 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.cpp
@@ -60,8 +60,8 @@
             terminalIdFieldPos += mBuffer->getOriginalBufferSize();
         }
         terminalId = Ver4PatriciaTrieReadingUtils::getTerminalIdAndAdvancePosition(dictBuf, &pos);
-        ProbabilityEntry probabilityEntry;
-        mProbabilityDictContent->getProbabilityEntry(terminalId, &probabilityEntry);
+        const ProbabilityEntry probabilityEntry =
+                mProbabilityDictContent->getProbabilityEntry(terminalId);
         probability = probabilityEntry.getProbability();
     }
     int childrenPosFieldPos = pos;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp
index 483c854..00ce061 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.cpp
@@ -112,12 +112,11 @@
     if (!toBeUpdatedPtNodeParams->isTerminal()) {
         return false;
     }
-    const int probabilityToWrite = getUpdatedProbability(toBeUpdatedPtNodeParams->getProbability(),
-            newProbability);
-    ProbabilityEntry probabilityEntry;
-    mBuffers->getProbabilityDictContent()->getProbabilityEntry(
-            toBeUpdatedPtNodeParams->getTerminalId(), &probabilityEntry);
-    probabilityEntry.setProbability(probabilityEntry.getFlags(), probabilityToWrite);
+    const ProbabilityEntry originalProbabilityEntry =
+            mBuffers->getProbabilityDictContent()->getProbabilityEntry(
+                    toBeUpdatedPtNodeParams->getTerminalId());
+    const ProbabilityEntry probabilityEntry = createUpdatedEntryFrom(&originalProbabilityEntry,
+            newProbability, timestamp);
     return mBuffers->getUpdatableProbabilityDictContent()->setProbabilityEntry(
             toBeUpdatedPtNodeParams->getTerminalId(), &probabilityEntry);
 }
@@ -150,12 +149,11 @@
         return false;
     }
     // Write probability.
-    const int probabilityToWrite = getUpdatedProbability(NOT_A_PROBABILITY,
-            ptNodeParams->getProbability());
-    ProbabilityEntry probabilityEntry;
-    probabilityEntry.setProbability(0 /* flags */, probabilityToWrite);
+    ProbabilityEntry newProbabilityEntry;
+    const ProbabilityEntry probabilityEntryToWrite = createUpdatedEntryFrom(
+            &newProbabilityEntry, ptNodeParams->getProbability(), timestamp);
     return mBuffers->getUpdatableProbabilityDictContent()->setProbabilityEntry(terminalId,
-            &probabilityEntry);
+            &probabilityEntryToWrite);
 }
 
 bool Ver4PatriciaTrieNodeWriter::addNewBigramEntry(
@@ -283,13 +281,16 @@
     return true;
 }
 
-int Ver4PatriciaTrieNodeWriter::getUpdatedProbability(const int originalProbability,
-        const int newProbability) const {
+const ProbabilityEntry Ver4PatriciaTrieNodeWriter::createUpdatedEntryFrom(
+        const ProbabilityEntry *const originalProbabilityEntry, const int newProbability,
+        const int timestamp) const {
     if (mNeedsToDecayWhenUpdating) {
-        return ForgettingCurveUtils::getUpdatedEncodedProbability(originalProbability,
-                newProbability);
+        // TODO: Update historical information.
+        const int updatedProbability = ForgettingCurveUtils::getUpdatedEncodedProbability(
+                originalProbabilityEntry->getProbability(), newProbability);
+        return originalProbabilityEntry->createEntryWithUpdatedProbability(updatedProbability);
     } else {
-        return newProbability;
+        return originalProbabilityEntry->createEntryWithUpdatedProbability(newProbability);
     }
 }
 
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h
index 36b714b..31b47c1 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_writer.h
@@ -23,6 +23,7 @@
 #include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h"
 #include "suggest/policyimpl/dictionary/structure/pt_common/pt_node_writer.h"
 #include "suggest/policyimpl/dictionary/structure/v3/dynamic_patricia_trie_reading_helper.h"
+#include "suggest/policyimpl/dictionary/structure/v4/content/probability_entry.h"
 #include "suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_node_reader.h"
 
 namespace latinime {
@@ -89,7 +90,11 @@
             const PtNodeParams *const ptNodeParams, int *const outTerminalId,
             int *const ptNodeWritingPos);
 
-    int getUpdatedProbability(const int originalProbability, const int newProbability) const;
+    // Create updated probability entry using given probability and timestamp. In addition to the
+    // probability, this method updates historical information if needed.
+    const ProbabilityEntry createUpdatedEntryFrom(
+            const ProbabilityEntry *const originalProbabilityEntry, const int newProbability,
+            const int timestamp) const;
 
     static const int CHILDREN_POSITION_FIELD_SIZE;