1 /*
2  * Copyright (C) 2013, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef LATINIME_DYNAMIC_PT_GC_EVENT_LISTENERS_H
18 #define LATINIME_DYNAMIC_PT_GC_EVENT_LISTENERS_H
19 
20 #include <vector>
21 
22 #include "defines.h"
23 #include "dictionary/structure/pt_common/dynamic_pt_reading_helper.h"
24 #include "dictionary/structure/pt_common/pt_node_writer.h"
25 #include "dictionary/utils/buffer_with_extendable_buffer.h"
26 
27 namespace latinime {
28 
29 class PtNodeParams;
30 
31 class DynamicPtGcEventListeners {
32  public:
33     // Updates all PtNodes that can be reached from the root. Checks if each PtNode is useless or
34     // not and marks useless PtNodes as deleted. Such deleted PtNodes will be discarded in the GC.
35     // TODO: Concatenate non-terminal PtNodes.
36     class TraversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted
37         : public DynamicPtReadingHelper::TraversingEventListener {
38      public:
TraversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted(PtNodeWriter * const ptNodeWriter)39         TraversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted(
40                 PtNodeWriter *const ptNodeWriter)
41                 : mPtNodeWriter(ptNodeWriter), mValueStack(), mChildrenValue(0),
42                   mValidUnigramCount(0) {}
43 
~TraversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted()44         ~TraversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted() {};
45 
onAscend()46         bool onAscend() {
47             if (mValueStack.empty()) {
48                 return false;
49             }
50             mChildrenValue = mValueStack.back();
51             mValueStack.pop_back();
52             return true;
53         }
54 
onDescend(const int ptNodeArrayPos)55         bool onDescend(const int ptNodeArrayPos) {
56             mValueStack.push_back(0);
57             mChildrenValue = 0;
58             return true;
59         }
60 
onReadingPtNodeArrayTail()61         bool onReadingPtNodeArrayTail() { return true; }
62 
63         bool onVisitingPtNode(const PtNodeParams *const ptNodeParams);
64 
getValidUnigramCount()65         int getValidUnigramCount() const {
66             return mValidUnigramCount;
67         }
68 
69      private:
70         DISALLOW_IMPLICIT_CONSTRUCTORS(
71                 TraversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted);
72 
73         PtNodeWriter *const mPtNodeWriter;
74         std::vector<int> mValueStack;
75         int mChildrenValue;
76         int mValidUnigramCount;
77     };
78 
79     // TODO: Remove when we stop supporting v402 format.
80     // Updates all bigram entries that are held by valid PtNodes. This removes useless bigram
81     // entries.
82     class TraversePolicyToUpdateBigramProbability
83             : public DynamicPtReadingHelper::TraversingEventListener {
84      public:
TraversePolicyToUpdateBigramProbability(PtNodeWriter * const ptNodeWriter)85         TraversePolicyToUpdateBigramProbability(PtNodeWriter *const ptNodeWriter)
86                 : mPtNodeWriter(ptNodeWriter), mValidBigramEntryCount(0) {}
87 
onAscend()88         bool onAscend() { return true; }
89 
onDescend(const int ptNodeArrayPos)90         bool onDescend(const int ptNodeArrayPos) { return true; }
91 
onReadingPtNodeArrayTail()92         bool onReadingPtNodeArrayTail() { return true; }
93 
94         bool onVisitingPtNode(const PtNodeParams *const ptNodeParams);
95 
getValidBigramEntryCount()96         int getValidBigramEntryCount() const {
97             return mValidBigramEntryCount;
98         }
99 
100      private:
101         DISALLOW_IMPLICIT_CONSTRUCTORS(TraversePolicyToUpdateBigramProbability);
102 
103         PtNodeWriter *const mPtNodeWriter;
104         int mValidBigramEntryCount;
105     };
106 
107     class TraversePolicyToPlaceAndWriteValidPtNodesToBuffer
108             : public DynamicPtReadingHelper::TraversingEventListener {
109      public:
TraversePolicyToPlaceAndWriteValidPtNodesToBuffer(PtNodeWriter * const ptNodeWriter,BufferWithExtendableBuffer * const bufferToWrite,PtNodeWriter::DictPositionRelocationMap * const dictPositionRelocationMap)110         TraversePolicyToPlaceAndWriteValidPtNodesToBuffer(
111                 PtNodeWriter *const ptNodeWriter, BufferWithExtendableBuffer *const bufferToWrite,
112                 PtNodeWriter::DictPositionRelocationMap *const dictPositionRelocationMap)
113                 : mPtNodeWriter(ptNodeWriter), mBufferToWrite(bufferToWrite),
114                   mDictPositionRelocationMap(dictPositionRelocationMap), mValidPtNodeCount(0),
115                   mPtNodeArraySizeFieldPos(NOT_A_DICT_POS) {};
116 
onAscend()117         bool onAscend() { return true; }
118 
119         bool onDescend(const int ptNodeArrayPos);
120 
121         bool onReadingPtNodeArrayTail();
122 
123         bool onVisitingPtNode(const PtNodeParams *const ptNodeParams);
124 
125      private:
126         DISALLOW_IMPLICIT_CONSTRUCTORS(TraversePolicyToPlaceAndWriteValidPtNodesToBuffer);
127 
128         PtNodeWriter *const mPtNodeWriter;
129         BufferWithExtendableBuffer *const mBufferToWrite;
130         PtNodeWriter::DictPositionRelocationMap *const mDictPositionRelocationMap;
131         int mValidPtNodeCount;
132         int mPtNodeArraySizeFieldPos;
133     };
134 
135     class TraversePolicyToUpdateAllPositionFields
136             : public DynamicPtReadingHelper::TraversingEventListener {
137      public:
TraversePolicyToUpdateAllPositionFields(PtNodeWriter * const ptNodeWriter,const PtNodeWriter::DictPositionRelocationMap * const dictPositionRelocationMap)138         TraversePolicyToUpdateAllPositionFields(PtNodeWriter *const ptNodeWriter,
139                 const PtNodeWriter::DictPositionRelocationMap *const dictPositionRelocationMap)
140                 : mPtNodeWriter(ptNodeWriter),
141                   mDictPositionRelocationMap(dictPositionRelocationMap), mUnigramCount(0),
142                   mBigramCount(0) {};
143 
onAscend()144         bool onAscend() { return true; }
145 
onDescend(const int ptNodeArrayPos)146         bool onDescend(const int ptNodeArrayPos) { return true; }
147 
onReadingPtNodeArrayTail()148         bool onReadingPtNodeArrayTail() { return true; }
149 
150         bool onVisitingPtNode(const PtNodeParams *const ptNodeParams);
151 
getUnigramCount()152         int getUnigramCount() const {
153             return mUnigramCount;
154         }
155 
getBigramCount()156         int getBigramCount() const {
157             return mBigramCount;
158         }
159 
160      private:
161         DISALLOW_IMPLICIT_CONSTRUCTORS(TraversePolicyToUpdateAllPositionFields);
162 
163         PtNodeWriter *const mPtNodeWriter;
164         const PtNodeWriter::DictPositionRelocationMap *const mDictPositionRelocationMap;
165         int mUnigramCount;
166         int mBigramCount;
167     };
168 
169  private:
170     DISALLOW_IMPLICIT_CONSTRUCTORS(DynamicPtGcEventListeners);
171 };
172 } // namespace latinime
173 #endif /* LATINIME_DYNAMIC_PT_GC_EVENT_LISTENERS_H */
174