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/terminal_position_lookup_table.cpp
22  */
23 
24 #include "dictionary/structure/backward/v402/content/terminal_position_lookup_table.h"
25 
26 #include "dictionary/structure/backward/v402/ver4_patricia_trie_reading_utils.h"
27 #include "dictionary/utils/buffer_with_extendable_buffer.h"
28 
29 namespace latinime {
30 namespace backward {
31 namespace v402 {
32 
getTerminalPtNodePosition(const int terminalId) const33 int TerminalPositionLookupTable::getTerminalPtNodePosition(const int terminalId) const {
34     if (terminalId < 0 || terminalId >= mSize) {
35         return NOT_A_DICT_POS;
36     }
37     const int terminalPos = getBuffer()->readUint(
38             Ver4DictConstants::TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE, getEntryPos(terminalId));
39     return (terminalPos == Ver4DictConstants::NOT_A_TERMINAL_ADDRESS) ?
40             NOT_A_DICT_POS : terminalPos;
41 }
42 
setTerminalPtNodePosition(const int terminalId,const int terminalPtNodePos)43 bool TerminalPositionLookupTable::setTerminalPtNodePosition(
44         const int terminalId, const int terminalPtNodePos) {
45     if (terminalId < 0) {
46         return NOT_A_DICT_POS;
47     }
48     while (terminalId >= mSize) {
49         // Write new entry.
50         if (!getWritableBuffer()->writeUint(Ver4DictConstants::NOT_A_TERMINAL_ADDRESS,
51                 Ver4DictConstants::TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE, getEntryPos(mSize))) {
52             return false;
53         }
54         mSize++;
55     }
56     const int terminalPos = (terminalPtNodePos != NOT_A_DICT_POS) ?
57             terminalPtNodePos : Ver4DictConstants::NOT_A_TERMINAL_ADDRESS;
58     return getWritableBuffer()->writeUint(terminalPos,
59             Ver4DictConstants::TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE, getEntryPos(terminalId));
60 }
61 
flushToFile(const char * const dictPath) const62 bool TerminalPositionLookupTable::flushToFile(const char *const dictPath) const {
63     // If the used buffer size is smaller than the actual buffer size, regenerate the lookup
64     // table and write the new table to the file.
65     if (getEntryPos(mSize) < getBuffer()->getTailPosition()) {
66         TerminalPositionLookupTable lookupTableToWrite;
67         for (int i = 0; i < mSize; ++i) {
68             const int terminalPtNodePosition = getTerminalPtNodePosition(i);
69             if (!lookupTableToWrite.setTerminalPtNodePosition(i, terminalPtNodePosition)) {
70                 AKLOGE("Cannot set terminal position to lookupTableToWrite."
71                         " terminalId: %d, position: %d", i, terminalPtNodePosition);
72                 return false;
73             }
74         }
75         return lookupTableToWrite.flush(dictPath,
76                 Ver4DictConstants::TERMINAL_ADDRESS_TABLE_FILE_EXTENSION);
77     } else {
78         // We can simply use this lookup table because the buffer size has not been
79         // changed.
80         return flush(dictPath, Ver4DictConstants::TERMINAL_ADDRESS_TABLE_FILE_EXTENSION);
81     }
82 }
83 
runGCTerminalIds(TerminalIdMap * const terminalIdMap)84 bool TerminalPositionLookupTable::runGCTerminalIds(TerminalIdMap *const terminalIdMap) {
85     int nextNewTerminalId = 0;
86     for (int i = 0; i < mSize; ++i) {
87         const int terminalPos = getBuffer()->readUint(
88                 Ver4DictConstants::TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE, getEntryPos(i));
89         if (terminalPos == Ver4DictConstants::NOT_A_TERMINAL_ADDRESS) {
90             // This entry is a garbage.
91         } else {
92             // Give a new terminal id to the entry.
93             if (!getWritableBuffer()->writeUint(terminalPos,
94                     Ver4DictConstants::TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE,
95                     getEntryPos(nextNewTerminalId))) {
96                 return false;
97             }
98             // Memorize the mapping to the old terminal id to the new terminal id.
99             terminalIdMap->insert(TerminalIdMap::value_type(i, nextNewTerminalId));
100             nextNewTerminalId++;
101         }
102     }
103     mSize = nextNewTerminalId;
104     return true;
105 }
106 
107 } // namespace v402
108 } // namespace backward
109 } // namespace latinime
110