From a159ad473c8f96dea607fab8b4599cc649f67aa9 Mon Sep 17 00:00:00 2001
From: Keisuke Kuroyanagi <ksk@google.com>
Date: Mon, 9 Sep 2013 16:44:17 +0900
Subject: [PATCH] Implement create children array and add child method.

Bug: 6669677
Change-Id: Ic89c3dfe01937e771db8fc59d5259496a9464a47
---
 .../dynamic_patricia_trie_node_reader.cpp     |  4 ++
 .../dynamic_patricia_trie_node_reader.h       | 12 +++-
 .../dynamic_patricia_trie_writing_helper.cpp  | 63 +++++++++++++------
 .../dynamic_patricia_trie_writing_helper.h    |  7 +++
 4 files changed, 64 insertions(+), 22 deletions(-)

diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp
index 5d0c79c202..405628b308 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.cpp
@@ -52,6 +52,10 @@ void DynamicPatriciaTrieNodeReader::fetchNodeInfoFromBufferAndProcessMovedNode(c
         mProbabilityFieldPos = NOT_A_DICT_POS;
         mProbability = NOT_A_PROBABILITY;
     }
+    mChildrenPosFieldPos = pos;
+    if (usesAdditionalBuffer) {
+        mChildrenPosFieldPos += mBuffer->getOriginalBufferSize();
+    }
     mChildrenPos = DynamicPatriciaTrieReadingUtils::readChildrenPositionAndAdvancePosition(
             dictBuf, mFlags, &pos);
     if (usesAdditionalBuffer && mChildrenPos != NOT_A_DICT_POS) {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h
index 08e1cb4d87..2ee7c24959 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_node_reader.h
@@ -42,8 +42,9 @@ class DynamicPatriciaTrieNodeReader {
               mShortcutsPolicy(shortcutsPolicy), mNodePos(NOT_A_VALID_WORD_POS), mFlags(0),
               mParentPos(NOT_A_DICT_POS),  mCodePointCount(0),
               mProbabilityFieldPos(NOT_A_DICT_POS), mProbability(NOT_A_PROBABILITY),
-              mChildrenPos(NOT_A_DICT_POS), mShortcutPos(NOT_A_DICT_POS),
-              mBigramPos(NOT_A_DICT_POS), mSiblingPos(NOT_A_VALID_WORD_POS) {}
+              mChildrenPosFieldPos(NOT_A_DICT_POS), mChildrenPos(NOT_A_DICT_POS),
+              mShortcutPos(NOT_A_DICT_POS), mBigramPos(NOT_A_DICT_POS),
+              mSiblingPos(NOT_A_VALID_WORD_POS) {}
 
     ~DynamicPatriciaTrieNodeReader() {}
 
@@ -104,7 +105,11 @@ class DynamicPatriciaTrieNodeReader {
         return mProbability;
     }
 
-    // Children node group position
+    // Children PtNode array position
+    AK_FORCE_INLINE int getChildrenPosFieldPos() const {
+        return mChildrenPosFieldPos;
+    }
+
     AK_FORCE_INLINE int getChildrenPos() const {
         return mChildrenPos;
     }
@@ -136,6 +141,7 @@ class DynamicPatriciaTrieNodeReader {
     uint8_t mCodePointCount;
     int mProbabilityFieldPos;
     int mProbability;
+    int mChildrenPosFieldPos;
     int mChildrenPos;
     int mShortcutPos;
     int mBigramPos;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.cpp b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.cpp
index 2f0bc855bc..e244212193 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.cpp
@@ -60,15 +60,20 @@ bool DynamicPatriciaTrieWritingHelper::addUnigramWord(
         // All characters are matched.
         if (codePointCount == readingHelper->getTotalCodePointCount()) {
             if (ENABLE_DYNAMIC_UPDATE) {
-                setPtNodeProbability(nodeReader, probability,
+                return setPtNodeProbability(nodeReader, probability,
                         readingHelper->getMergedNodeCodePoints());
             } else {
                 return false;
             }
         }
         if (!nodeReader->hasChildren()) {
-            // TODO: Create children node array and add new node as a child.
-            return false;
+            if (ENABLE_DYNAMIC_UPDATE) {
+                return createChildrenPtNodeArrayAndAChildPtNode(nodeReader, probability,
+                        wordCodePoints + readingHelper->getTotalCodePointCount(),
+                        codePointCount - readingHelper->getTotalCodePointCount());
+            } else {
+                return false;
+            }
         }
         // Advance to the children nodes.
         parentPos = nodeReader->getNodePos();
@@ -201,22 +206,8 @@ bool DynamicPatriciaTrieWritingHelper::createAndInsertNodeIntoPtNodeArray(const
             newPtNodeArrayPos, forwardLinkFieldPos)) {
         return false;
     }
-    int writingPos = newPtNodeArrayPos;
-    if (!DynamicPatriciaTrieWritingUtils::writePtNodeArraySizeAndAdvancePosition(mBuffer,
-            1 /* arraySize */, &writingPos)) {
-        return false;
-    }
-    if (!writeNodeToBuffer(false /* isBlacklisted */, false /* isNotAWord */, parentPos,
-            nodeCodePoints, nodeCodePointCount, probability, NOT_A_DICT_POS /* childrenPos */,
-            NOT_A_DICT_POS /* originalBigramsPos */, NOT_A_DICT_POS /* originalShortcutPos */,
-            &writingPos)) {
-        return false;
-    }
-    if (!DynamicPatriciaTrieWritingUtils::writeForwardLinkPositionAndAdvancePosition(mBuffer,
-            NOT_A_DICT_POS /* forwardLinkPos */, &writingPos)) {
-        return false;
-    }
-    return true;
+    return createNewPtNodeArrayWithAChildPtNode(parentPos, nodeCodePoints, nodeCodePointCount,
+            probability);
 }
 
 bool DynamicPatriciaTrieWritingHelper::setPtNodeProbability(
@@ -245,4 +236,38 @@ bool DynamicPatriciaTrieWritingHelper::setPtNodeProbability(
     return true;
 }
 
+bool DynamicPatriciaTrieWritingHelper::createChildrenPtNodeArrayAndAChildPtNode(
+        const DynamicPatriciaTrieNodeReader *const parentNode, const int probability,
+        const int *const codePoints, const int codePointCount) {
+    const int newPtNodeArrayPos = mBuffer->getTailPosition();
+    int childrenPosFieldPos = parentNode->getChildrenPosFieldPos();
+    if (!DynamicPatriciaTrieWritingUtils::writeChildrenPositionAndAdvancePosition(mBuffer,
+            newPtNodeArrayPos, &childrenPosFieldPos)) {
+        return false;
+    }
+    return createNewPtNodeArrayWithAChildPtNode(parentNode->getNodePos(), codePoints,
+            codePointCount, probability);
+}
+
+bool DynamicPatriciaTrieWritingHelper::createNewPtNodeArrayWithAChildPtNode(
+        const int parentPtNodePos, const int *const nodeCodePoints, const int nodeCodePointCount,
+        const int probability) {
+    int writingPos = mBuffer->getTailPosition();
+    if (!DynamicPatriciaTrieWritingUtils::writePtNodeArraySizeAndAdvancePosition(mBuffer,
+            1 /* arraySize */, &writingPos)) {
+        return false;
+    }
+    if (!writeNodeToBuffer(false /* isBlacklisted */, false /* isNotAWord */, parentPtNodePos,
+            nodeCodePoints, nodeCodePointCount, probability, NOT_A_DICT_POS /* childrenPos */,
+            NOT_A_DICT_POS /* originalBigramsPos */, NOT_A_DICT_POS /* originalShortcutPos */,
+            &writingPos)) {
+        return false;
+    }
+    if (!DynamicPatriciaTrieWritingUtils::writeForwardLinkPositionAndAdvancePosition(mBuffer,
+            NOT_A_DICT_POS /* forwardLinkPos */, &writingPos)) {
+        return false;
+    }
+    return true;
+}
+
 } // namespace latinime
diff --git a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.h b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.h
index 7803ce8c8c..16b84bac3b 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/dynamic_patricia_trie_writing_helper.h
@@ -67,6 +67,13 @@ class DynamicPatriciaTrieWritingHelper {
 
     bool setPtNodeProbability(const DynamicPatriciaTrieNodeReader *const originalNode,
             const int probability, const int *const codePoints);
+
+    bool createChildrenPtNodeArrayAndAChildPtNode(
+            const DynamicPatriciaTrieNodeReader *const parentNode, const int probability,
+            const int *const codePoints, const int codePointCount);
+
+    bool createNewPtNodeArrayWithAChildPtNode(const int parentPos, const int *const nodeCodePoints,
+            const int nodeCodePointCount, const int probability);
 };
 } // namespace latinime
 #endif /* LATINIME_DYNAMIC_PATRICIA_TRIE_WRITING_HELPER_H */
-- 
GitLab