1/*
2 * Copyright (C) 2012 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_DIC_NODE_PROPERTIES_H
18#define LATINIME_DIC_NODE_PROPERTIES_H
19
20#include <cstdint>
21
22#include "defines.h"
23
24namespace latinime {
25
26/**
27 * PtNode information related to the DicNode from the lexicon trie.
28 */
29class DicNodeProperties {
30 public:
31    AK_FORCE_INLINE DicNodeProperties()
32            : mPtNodePos(NOT_A_DICT_POS), mChildrenPtNodeArrayPos(NOT_A_DICT_POS),
33              mProbability(NOT_A_PROBABILITY), mDicNodeCodePoint(NOT_A_CODE_POINT),
34              mIsTerminal(false), mHasChildrenPtNodes(false),
35              mIsBlacklistedOrNotAWord(false), mDepth(0), mLeavingDepth(0) {}
36
37    ~DicNodeProperties() {}
38
39    // Should be called only once per DicNode is initialized.
40    void init(const int pos, const int childrenPos, const int nodeCodePoint, const int probability,
41            const bool isTerminal, const bool hasChildren, const bool isBlacklistedOrNotAWord,
42            const uint16_t depth, const uint16_t leavingDepth, const int *const prevWordsNodePos) {
43        mPtNodePos = pos;
44        mChildrenPtNodeArrayPos = childrenPos;
45        mDicNodeCodePoint = nodeCodePoint;
46        mProbability = probability;
47        mIsTerminal = isTerminal;
48        mHasChildrenPtNodes = hasChildren;
49        mIsBlacklistedOrNotAWord = isBlacklistedOrNotAWord;
50        mDepth = depth;
51        mLeavingDepth = leavingDepth;
52        memmove(mPrevWordsTerminalPtNodePos, prevWordsNodePos, sizeof(mPrevWordsTerminalPtNodePos));
53    }
54
55    // Init for root with prevWordsPtNodePos which is used for n-gram
56    void init(const int rootPtNodeArrayPos, const int *const prevWordsNodePos) {
57        mPtNodePos = NOT_A_DICT_POS;
58        mChildrenPtNodeArrayPos = rootPtNodeArrayPos;
59        mDicNodeCodePoint = NOT_A_CODE_POINT;
60        mProbability = NOT_A_PROBABILITY;
61        mIsTerminal = false;
62        mHasChildrenPtNodes = true;
63        mIsBlacklistedOrNotAWord = false;
64        mDepth = 0;
65        mLeavingDepth = 0;
66        memmove(mPrevWordsTerminalPtNodePos, prevWordsNodePos, sizeof(mPrevWordsTerminalPtNodePos));
67    }
68
69    void initByCopy(const DicNodeProperties *const dicNodeProp) {
70        mPtNodePos = dicNodeProp->mPtNodePos;
71        mChildrenPtNodeArrayPos = dicNodeProp->mChildrenPtNodeArrayPos;
72        mDicNodeCodePoint = dicNodeProp->mDicNodeCodePoint;
73        mProbability = dicNodeProp->mProbability;
74        mIsTerminal = dicNodeProp->mIsTerminal;
75        mHasChildrenPtNodes = dicNodeProp->mHasChildrenPtNodes;
76        mIsBlacklistedOrNotAWord = dicNodeProp->mIsBlacklistedOrNotAWord;
77        mDepth = dicNodeProp->mDepth;
78        mLeavingDepth = dicNodeProp->mLeavingDepth;
79        memmove(mPrevWordsTerminalPtNodePos, dicNodeProp->mPrevWordsTerminalPtNodePos,
80                sizeof(mPrevWordsTerminalPtNodePos));
81    }
82
83    // Init as passing child
84    void init(const DicNodeProperties *const dicNodeProp, const int codePoint) {
85        mPtNodePos = dicNodeProp->mPtNodePos;
86        mChildrenPtNodeArrayPos = dicNodeProp->mChildrenPtNodeArrayPos;
87        mDicNodeCodePoint = codePoint; // Overwrite the node char of a passing child
88        mProbability = dicNodeProp->mProbability;
89        mIsTerminal = dicNodeProp->mIsTerminal;
90        mHasChildrenPtNodes = dicNodeProp->mHasChildrenPtNodes;
91        mIsBlacklistedOrNotAWord = dicNodeProp->mIsBlacklistedOrNotAWord;
92        mDepth = dicNodeProp->mDepth + 1; // Increment the depth of a passing child
93        mLeavingDepth = dicNodeProp->mLeavingDepth;
94        memmove(mPrevWordsTerminalPtNodePos, dicNodeProp->mPrevWordsTerminalPtNodePos,
95                sizeof(mPrevWordsTerminalPtNodePos));
96    }
97
98    int getPtNodePos() const {
99        return mPtNodePos;
100    }
101
102    int getChildrenPtNodeArrayPos() const {
103        return mChildrenPtNodeArrayPos;
104    }
105
106    int getProbability() const {
107        return mProbability;
108    }
109
110    int getDicNodeCodePoint() const {
111        return mDicNodeCodePoint;
112    }
113
114    uint16_t getDepth() const {
115        return mDepth;
116    }
117
118    // TODO: Move to output?
119    uint16_t getLeavingDepth() const {
120        return mLeavingDepth;
121    }
122
123    bool isTerminal() const {
124        return mIsTerminal;
125    }
126
127    bool hasChildren() const {
128        return mHasChildrenPtNodes || mDepth != mLeavingDepth;
129    }
130
131    bool isBlacklistedOrNotAWord() const {
132        return mIsBlacklistedOrNotAWord;
133    }
134
135    const int *getPrevWordsTerminalPtNodePos() const {
136        return mPrevWordsTerminalPtNodePos;
137    }
138
139 private:
140    // Caution!!!
141    // Use a default copy constructor and an assign operator because shallow copies are ok
142    // for this class
143    int mPtNodePos;
144    int mChildrenPtNodeArrayPos;
145    int mProbability;
146    int mDicNodeCodePoint;
147    bool mIsTerminal;
148    bool mHasChildrenPtNodes;
149    bool mIsBlacklistedOrNotAWord;
150    uint16_t mDepth;
151    uint16_t mLeavingDepth;
152    int mPrevWordsTerminalPtNodePos[MAX_PREV_WORD_COUNT_FOR_N_GRAM];
153};
154} // namespace latinime
155#endif // LATINIME_DIC_NODE_PROPERTIES_H
156