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 /*
18  * !!!!! DO NOT EDIT THIS FILE !!!!!
19  *
20  * This file was generated from
21  *   dictionary/structure/v4/content/shortcut_dict_content.cpp
22  */
23 
24 #include "dictionary/structure/backward/v402/content/shortcut_dict_content.h"
25 
26 #include "dictionary/utils/buffer_with_extendable_buffer.h"
27 
28 namespace latinime {
29 namespace backward {
30 namespace v402 {
31 
getShortcutEntryAndAdvancePosition(const int maxCodePointCount,int * const outCodePoint,int * const outCodePointCount,int * const outProbability,bool * const outhasNext,int * const shortcutEntryPos) const32 void ShortcutDictContent::getShortcutEntryAndAdvancePosition(const int maxCodePointCount,
33         int *const outCodePoint, int *const outCodePointCount, int *const outProbability,
34         bool *const outhasNext, int *const shortcutEntryPos) const {
35     const BufferWithExtendableBuffer *const shortcutListBuffer = getContentBuffer();
36     if (*shortcutEntryPos < 0 || *shortcutEntryPos >=  shortcutListBuffer->getTailPosition()) {
37         AKLOGE("Invalid shortcut entry position. shortcutEntryPos: %d, bufSize: %d",
38                 *shortcutEntryPos, shortcutListBuffer->getTailPosition());
39         ASSERT(false);
40         if (outhasNext) {
41             *outhasNext = false;
42         }
43         if (outCodePointCount) {
44             *outCodePointCount = 0;
45         }
46         return;
47     }
48 
49     const int shortcutFlags = shortcutListBuffer->readUintAndAdvancePosition(
50             Ver4DictConstants::SHORTCUT_FLAGS_FIELD_SIZE, shortcutEntryPos);
51     if (outProbability) {
52         *outProbability = shortcutFlags & Ver4DictConstants::SHORTCUT_PROBABILITY_MASK;
53     }
54     if (outhasNext) {
55         *outhasNext = shortcutFlags & Ver4DictConstants::SHORTCUT_HAS_NEXT_MASK;
56     }
57     if (outCodePoint && outCodePointCount) {
58         shortcutListBuffer->readCodePointsAndAdvancePosition(
59                 maxCodePointCount, outCodePoint, outCodePointCount, shortcutEntryPos);
60     }
61 }
62 
getShortcutListHeadPos(const int terminalId) const63 int ShortcutDictContent::getShortcutListHeadPos(const int terminalId) const {
64     const SparseTable *const addressLookupTable = getAddressLookupTable();
65     if (!addressLookupTable->contains(terminalId)) {
66         return NOT_A_DICT_POS;
67     }
68     return addressLookupTable->get(terminalId);
69 }
70 
flushToFile(const char * const dictPath) const71 bool ShortcutDictContent::flushToFile(const char *const dictPath) const {
72     return flush(dictPath, Ver4DictConstants::SHORTCUT_LOOKUP_TABLE_FILE_EXTENSION,
73             Ver4DictConstants::SHORTCUT_CONTENT_TABLE_FILE_EXTENSION,
74             Ver4DictConstants::SHORTCUT_FILE_EXTENSION);
75 }
76 
runGC(const TerminalPositionLookupTable::TerminalIdMap * const terminalIdMap,const ShortcutDictContent * const originalShortcutDictContent)77 bool ShortcutDictContent::runGC(
78         const TerminalPositionLookupTable::TerminalIdMap *const terminalIdMap,
79         const ShortcutDictContent *const originalShortcutDictContent) {
80    for (TerminalPositionLookupTable::TerminalIdMap::const_iterator it = terminalIdMap->begin();
81            it != terminalIdMap->end(); ++it) {
82        const int originalShortcutListPos =
83                originalShortcutDictContent->getShortcutListHeadPos(it->first);
84        if (originalShortcutListPos == NOT_A_DICT_POS) {
85            continue;
86        }
87        const int shortcutListPos = getContentBuffer()->getTailPosition();
88        // Copy shortcut list from original content.
89        if (!copyShortcutListFromDictContent(originalShortcutListPos, originalShortcutDictContent,
90                shortcutListPos)) {
91            AKLOGE("Cannot copy shortcut list during GC. original pos: %d, pos: %d",
92                    originalShortcutListPos, shortcutListPos);
93            return false;
94        }
95        // Set shortcut list position to the lookup table.
96        if (!getUpdatableAddressLookupTable()->set(it->second, shortcutListPos)) {
97            AKLOGE("Cannot set shortcut list position. terminal id: %d, pos: %d",
98                    it->second, shortcutListPos);
99            return false;
100        }
101    }
102    return true;
103 }
104 
createNewShortcutList(const int terminalId)105 bool ShortcutDictContent::createNewShortcutList(const int terminalId) {
106     const int shortcutListListPos = getContentBuffer()->getTailPosition();
107     return getUpdatableAddressLookupTable()->set(terminalId, shortcutListListPos);
108 }
109 
copyShortcutList(const int shortcutListPos,const int toPos)110 bool ShortcutDictContent::copyShortcutList(const int shortcutListPos, const int toPos) {
111     return copyShortcutListFromDictContent(shortcutListPos, this, toPos);
112 }
113 
copyShortcutListFromDictContent(const int shortcutListPos,const ShortcutDictContent * const sourceShortcutDictContent,const int toPos)114 bool ShortcutDictContent::copyShortcutListFromDictContent(const int shortcutListPos,
115         const ShortcutDictContent *const sourceShortcutDictContent, const int toPos) {
116     bool hasNext = true;
117     int readingPos = shortcutListPos;
118     int writingPos = toPos;
119     int codePoints[MAX_WORD_LENGTH];
120     while (hasNext) {
121         int probability = 0;
122         int codePointCount = 0;
123         sourceShortcutDictContent->getShortcutEntryAndAdvancePosition(MAX_WORD_LENGTH,
124                 codePoints, &codePointCount, &probability, &hasNext, &readingPos);
125         if (!writeShortcutEntryAndAdvancePosition(codePoints, codePointCount, probability,
126                 hasNext, &writingPos)) {
127             AKLOGE("Cannot write shortcut entry to copy. pos: %d", writingPos);
128             return false;
129         }
130     }
131     return true;
132 }
133 
setProbability(const int probability,const int shortcutEntryPos)134 bool ShortcutDictContent::setProbability(const int probability, const int shortcutEntryPos) {
135     BufferWithExtendableBuffer *const shortcutListBuffer = getWritableContentBuffer();
136     const int shortcutFlags = shortcutListBuffer->readUint(
137             Ver4DictConstants::SHORTCUT_FLAGS_FIELD_SIZE, shortcutEntryPos);
138     const bool hasNext = shortcutFlags & Ver4DictConstants::SHORTCUT_HAS_NEXT_MASK;
139     const int shortcutFlagsToWrite = createAndGetShortcutFlags(probability, hasNext);
140     return shortcutListBuffer->writeUint(shortcutFlagsToWrite,
141             Ver4DictConstants::SHORTCUT_FLAGS_FIELD_SIZE, shortcutEntryPos);
142 }
143 
writeShortcutEntryAndAdvancePosition(const int * const codePoint,const int codePointCount,const int probability,const bool hasNext,int * const shortcutEntryPos)144 bool ShortcutDictContent::writeShortcutEntryAndAdvancePosition(const int *const codePoint,
145         const int codePointCount, const int probability, const bool hasNext,
146         int *const shortcutEntryPos) {
147     BufferWithExtendableBuffer *const shortcutListBuffer = getWritableContentBuffer();
148     const int shortcutFlags = createAndGetShortcutFlags(probability, hasNext);
149     if (!shortcutListBuffer->writeUintAndAdvancePosition(shortcutFlags,
150             Ver4DictConstants::SHORTCUT_FLAGS_FIELD_SIZE, shortcutEntryPos)) {
151         AKLOGE("Cannot write shortcut flags. flags; %x, pos: %d", shortcutFlags, *shortcutEntryPos);
152         return false;
153     }
154     if (!shortcutListBuffer->writeCodePointsAndAdvancePosition(codePoint, codePointCount,
155             true /* writesTerminator */, shortcutEntryPos)) {
156         AKLOGE("Cannot write shortcut target code points. pos: %d", *shortcutEntryPos);
157         return false;
158     }
159     return true;
160 }
161 
162 // Find a shortcut entry that has specified target and return its position.
findShortcutEntryAndGetPos(const int shortcutListPos,const int * const targetCodePointsToFind,const int codePointCount) const163 int ShortcutDictContent::findShortcutEntryAndGetPos(const int shortcutListPos,
164         const int *const targetCodePointsToFind, const int codePointCount) const {
165     bool hasNext = true;
166     int readingPos = shortcutListPos;
167     int targetCodePoints[MAX_WORD_LENGTH];
168     while (hasNext) {
169         const int entryPos = readingPos;
170         int probability = 0;
171         int targetCodePointCount = 0;
172         getShortcutEntryAndAdvancePosition(MAX_WORD_LENGTH, targetCodePoints, &targetCodePointCount,
173                 &probability, &hasNext, &readingPos);
174         if (targetCodePointCount != codePointCount) {
175             continue;
176         }
177         bool matched = true;
178         for (int i = 0; i < codePointCount; ++i) {
179             if (targetCodePointsToFind[i] != targetCodePoints[i]) {
180                 matched = false;
181                 break;
182             }
183         }
184         if (matched) {
185             return entryPos;
186         }
187     }
188     return NOT_A_DICT_POS;
189 }
190 
createAndGetShortcutFlags(const int probability,const bool hasNext) const191 int ShortcutDictContent::createAndGetShortcutFlags(const int probability,
192         const bool hasNext) const {
193     return (probability & Ver4DictConstants::SHORTCUT_PROBABILITY_MASK)
194             | (hasNext ? Ver4DictConstants::SHORTCUT_HAS_NEXT_MASK : 0);
195 }
196 
197 } // namespace v402
198 } // namespace backward
199 } // namespace latinime
200