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
27namespace latinime {
28
29class PtNodeParams;
30
31class 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:
39        TraversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted(
40                PtNodeWriter *const ptNodeWriter)
41                : mPtNodeWriter(ptNodeWriter), mValueStack(), mChildrenValue(0),
42                  mValidUnigramCount(0) {}
43
44        ~TraversePolicyToUpdateUnigramProbabilityAndMarkUselessPtNodesAsDeleted() {};
45
46        bool onAscend() {
47            if (mValueStack.empty()) {
48                return false;
49            }
50            mChildrenValue = mValueStack.back();
51            mValueStack.pop_back();
52            return true;
53        }
54
55        bool onDescend(const int ptNodeArrayPos) {
56            mValueStack.push_back(0);
57            mChildrenValue = 0;
58            return true;
59        }
60
61        bool onReadingPtNodeArrayTail() { return true; }
62
63        bool onVisitingPtNode(const PtNodeParams *const ptNodeParams);
64
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:
85        TraversePolicyToUpdateBigramProbability(PtNodeWriter *const ptNodeWriter)
86                : mPtNodeWriter(ptNodeWriter), mValidBigramEntryCount(0) {}
87
88        bool onAscend() { return true; }
89
90        bool onDescend(const int ptNodeArrayPos) { return true; }
91
92        bool onReadingPtNodeArrayTail() { return true; }
93
94        bool onVisitingPtNode(const PtNodeParams *const ptNodeParams);
95
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:
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
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:
138        TraversePolicyToUpdateAllPositionFields(PtNodeWriter *const ptNodeWriter,
139                const PtNodeWriter::DictPositionRelocationMap *const dictPositionRelocationMap)
140                : mPtNodeWriter(ptNodeWriter),
141                  mDictPositionRelocationMap(dictPositionRelocationMap), mUnigramCount(0),
142                  mBigramCount(0) {};
143
144        bool onAscend() { return true; }
145
146        bool onDescend(const int ptNodeArrayPos) { return true; }
147
148        bool onReadingPtNodeArrayTail() { return true; }
149
150        bool onVisitingPtNode(const PtNodeParams *const ptNodeParams);
151
152        int getUnigramCount() const {
153            return mUnigramCount;
154        }
155
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