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 28namespace latinime { 29namespace backward { 30namespace v402 { 31 32void 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 63int 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 71bool 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 77bool 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 105bool ShortcutDictContent::createNewShortcutList(const int terminalId) { 106 const int shortcutListListPos = getContentBuffer()->getTailPosition(); 107 return getUpdatableAddressLookupTable()->set(terminalId, shortcutListListPos); 108} 109 110bool ShortcutDictContent::copyShortcutList(const int shortcutListPos, const int toPos) { 111 return copyShortcutListFromDictContent(shortcutListPos, this, toPos); 112} 113 114bool 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 134bool 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 144bool 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. 163int 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 191int 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