Index: third_party/prediction/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_gc_event_listeners.cpp |
diff --git a/third_party/prediction/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_gc_event_listeners.cpp b/third_party/prediction/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_gc_event_listeners.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..177769b36017668fffbaafcfb2df4cf649f7a8ce |
--- /dev/null |
+++ b/third_party/prediction/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_gc_event_listeners.cpp |
@@ -0,0 +1,155 @@ |
+/* |
+ * Copyright (C) 2013 The Android Open Source Project |
+ * |
+ * Licensed under the Apache License, Version 2.0 (the "License"); |
+ * you may not use this file except in compliance with the License. |
+ * You may obtain a copy of the License at |
+ * |
+ * http://www.apache.org/licenses/LICENSE-2.0 |
+ * |
+ * Unless required by applicable law or agreed to in writing, software |
+ * distributed under the License is distributed on an "AS IS" BASIS, |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+ * See the License for the specific language governing permissions and |
+ * limitations under the License. |
+ */ |
+ |
+#include "third_party/prediction/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_gc_event_listeners.h" |
+ |
+#include "third_party/prediction/suggest/core/policy/dictionary_header_structure_policy.h" |
+#include "third_party/prediction/suggest/policyimpl/dictionary/structure/pt_common/dynamic_pt_writing_utils.h" |
+#include "third_party/prediction/suggest/policyimpl/dictionary/structure/pt_common/pt_node_params.h" |
+#include "third_party/prediction/suggest/policyimpl/dictionary/structure/pt_common/pt_node_writer.h" |
+ |
+namespace latinime { |
+ |
+bool DynamicPtGcEventListeners:: |
+ TraversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted:: |
+ onVisitingPtNode(const PtNodeParams* const ptNodeParams) { |
+ // PtNode is useless when the PtNode is not a terminal and doesn't have any |
+ // not useless |
+ // children. |
+ bool isUselessPtNode = !ptNodeParams->isTerminal(); |
+ if (ptNodeParams->isTerminal() && !ptNodeParams->representsNonWordInfo()) { |
+ bool needsToKeepPtNode = true; |
+ if (!mPtNodeWriter->updatePtNodeProbabilityAndGetNeedsToKeepPtNodeAfterGC( |
+ ptNodeParams, &needsToKeepPtNode)) { |
+ AKLOGE( |
+ "Cannot update PtNode probability or get needs to keep PtNode after " |
+ "GC."); |
+ return false; |
+ } |
+ if (!needsToKeepPtNode) { |
+ isUselessPtNode = true; |
+ } |
+ } |
+ if (mChildrenValue > 0) { |
+ isUselessPtNode = false; |
+ } else if (ptNodeParams->isTerminal()) { |
+ // Remove children as all children are useless. |
+ if (!mPtNodeWriter->updateChildrenPosition( |
+ ptNodeParams, NOT_A_DICT_POS /* newChildrenPosition */)) { |
+ return false; |
+ } |
+ } |
+ if (isUselessPtNode) { |
+ // Current PtNode is no longer needed. Mark it as deleted. |
+ if (!mPtNodeWriter->markPtNodeAsDeleted(ptNodeParams)) { |
+ return false; |
+ } |
+ } else { |
+ mValueStack.back() += 1; |
+ if (ptNodeParams->isTerminal() && !ptNodeParams->representsNonWordInfo()) { |
+ mValidUnigramCount += 1; |
+ } |
+ } |
+ return true; |
+} |
+ |
+bool DynamicPtGcEventListeners::TraversePolicyToUpdateBigramProbability:: |
+ onVisitingPtNode(const PtNodeParams* const ptNodeParams) { |
+ if (!ptNodeParams->isDeleted()) { |
+ int bigramEntryCount = 0; |
+ if (!mPtNodeWriter->updateAllBigramEntriesAndDeleteUselessEntries( |
+ ptNodeParams, &bigramEntryCount)) { |
+ return false; |
+ } |
+ mValidBigramEntryCount += bigramEntryCount; |
+ } |
+ return true; |
+} |
+ |
+// Writes dummy PtNode array size when the head of PtNode array is read. |
+bool DynamicPtGcEventListeners:: |
+ TraversePolicyToPlaceAndWriteValidPtNodesToBuffer::onDescend( |
+ const int ptNodeArrayPos) { |
+ mValidPtNodeCount = 0; |
+ int writingPos = mBufferToWrite->getTailPosition(); |
+ mDictPositionRelocationMap->mPtNodeArrayPositionRelocationMap.insert( |
+ PtNodeWriter::PtNodeArrayPositionRelocationMap::value_type(ptNodeArrayPos, |
+ writingPos)); |
+ // Writes dummy PtNode array size because arrays can have a forward link or |
+ // needles PtNodes. |
+ // This field will be updated later in onReadingPtNodeArrayTail() with actual |
+ // PtNode count. |
+ mPtNodeArraySizeFieldPos = writingPos; |
+ return DynamicPtWritingUtils::writePtNodeArraySizeAndAdvancePosition( |
+ mBufferToWrite, 0 /* arraySize */, &writingPos); |
+} |
+ |
+// Write PtNode array terminal and actual PtNode array size. |
+bool DynamicPtGcEventListeners:: |
+ TraversePolicyToPlaceAndWriteValidPtNodesToBuffer:: |
+ onReadingPtNodeArrayTail() { |
+ int writingPos = mBufferToWrite->getTailPosition(); |
+ // Write PtNode array terminal. |
+ if (!DynamicPtWritingUtils::writeForwardLinkPositionAndAdvancePosition( |
+ mBufferToWrite, NOT_A_DICT_POS /* forwardLinkPos */, &writingPos)) { |
+ return false; |
+ } |
+ // Write actual PtNode array size. |
+ if (!DynamicPtWritingUtils::writePtNodeArraySizeAndAdvancePosition( |
+ mBufferToWrite, mValidPtNodeCount, &mPtNodeArraySizeFieldPos)) { |
+ return false; |
+ } |
+ return true; |
+} |
+ |
+// Write valid PtNode to buffer and memorize mapping from the old position to |
+// the new position. |
+bool DynamicPtGcEventListeners:: |
+ TraversePolicyToPlaceAndWriteValidPtNodesToBuffer::onVisitingPtNode( |
+ const PtNodeParams* const ptNodeParams) { |
+ if (ptNodeParams->isDeleted()) { |
+ // Current PtNode is not written in new buffer because it has been deleted. |
+ mDictPositionRelocationMap->mPtNodePositionRelocationMap.insert( |
+ PtNodeWriter::PtNodePositionRelocationMap::value_type( |
+ ptNodeParams->getHeadPos(), NOT_A_DICT_POS)); |
+ return true; |
+ } |
+ int writingPos = mBufferToWrite->getTailPosition(); |
+ mDictPositionRelocationMap->mPtNodePositionRelocationMap.insert( |
+ PtNodeWriter::PtNodePositionRelocationMap::value_type( |
+ ptNodeParams->getHeadPos(), writingPos)); |
+ mValidPtNodeCount++; |
+ // Writes current PtNode. |
+ return mPtNodeWriter->writePtNodeAndAdvancePosition(ptNodeParams, |
+ &writingPos); |
+} |
+ |
+bool DynamicPtGcEventListeners::TraversePolicyToUpdateAllPositionFields:: |
+ onVisitingPtNode(const PtNodeParams* const ptNodeParams) { |
+ // Updates parent position. |
+ int bigramCount = 0; |
+ if (!mPtNodeWriter->updateAllPositionFields( |
+ ptNodeParams, mDictPositionRelocationMap, &bigramCount)) { |
+ return false; |
+ } |
+ mBigramCount += bigramCount; |
+ if (ptNodeParams->isTerminal()) { |
+ mUnigramCount++; |
+ } |
+ return true; |
+} |
+ |
+} // namespace latinime |