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 * suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.cpp 22 */ 23 24 #include "suggest/policyimpl/dictionary/structure/backward/v402/content/bigram_dict_content.h" 25 26 #include "suggest/policyimpl/dictionary/utils/buffer_with_extendable_buffer.h" 27 28 namespace latinime { 29 namespace backward { 30 namespace v402 { 31 32 const BigramEntry BigramDictContent::getBigramEntryAndAdvancePosition( 33 int *const bigramEntryPos) const { 34 const BufferWithExtendableBuffer *const bigramListBuffer = getContentBuffer(); 35 const int bigramEntryTailPos = (*bigramEntryPos) + getBigramEntrySize(); 36 if (*bigramEntryPos < 0 || bigramEntryTailPos > bigramListBuffer->getTailPosition()) { 37 AKLOGE("Invalid bigram entry position. bigramEntryPos: %d, bigramEntryTailPos: %d, " 38 "bufSize: %d", *bigramEntryPos, bigramEntryTailPos, 39 bigramListBuffer->getTailPosition()); 40 ASSERT(false); 41 return BigramEntry(false /* hasNext */, NOT_A_PROBABILITY, 42 Ver4DictConstants::NOT_A_TERMINAL_ID); 43 } 44 const int bigramFlags = bigramListBuffer->readUintAndAdvancePosition( 45 Ver4DictConstants::BIGRAM_FLAGS_FIELD_SIZE, bigramEntryPos); 46 const bool hasNext = (bigramFlags & Ver4DictConstants::BIGRAM_HAS_NEXT_MASK) != 0; 47 int probability = NOT_A_PROBABILITY; 48 int timestamp = NOT_A_TIMESTAMP; 49 int level = 0; 50 int count = 0; 51 if (mHasHistoricalInfo) { 52 timestamp = bigramListBuffer->readUintAndAdvancePosition( 53 Ver4DictConstants::TIME_STAMP_FIELD_SIZE, bigramEntryPos); 54 level = bigramListBuffer->readUintAndAdvancePosition( 55 Ver4DictConstants::WORD_LEVEL_FIELD_SIZE, bigramEntryPos); 56 count = bigramListBuffer->readUintAndAdvancePosition( 57 Ver4DictConstants::WORD_COUNT_FIELD_SIZE, bigramEntryPos); 58 } else { 59 probability = bigramListBuffer->readUintAndAdvancePosition( 60 Ver4DictConstants::PROBABILITY_SIZE, bigramEntryPos); 61 } 62 const int encodedTargetTerminalId = bigramListBuffer->readUintAndAdvancePosition( 63 Ver4DictConstants::BIGRAM_TARGET_TERMINAL_ID_FIELD_SIZE, bigramEntryPos); 64 const int targetTerminalId = 65 (encodedTargetTerminalId == Ver4DictConstants::INVALID_BIGRAM_TARGET_TERMINAL_ID) ? 66 Ver4DictConstants::NOT_A_TERMINAL_ID : encodedTargetTerminalId; 67 if (mHasHistoricalInfo) { 68 const HistoricalInfo historicalInfo(timestamp, level, count); 69 return BigramEntry(hasNext, probability, &historicalInfo, targetTerminalId); 70 } else { 71 return BigramEntry(hasNext, probability, targetTerminalId); 72 } 73 } 74 75 bool BigramDictContent::writeBigramEntryAndAdvancePosition( 76 const BigramEntry *const bigramEntryToWrite, int *const entryWritingPos) { 77 BufferWithExtendableBuffer *const bigramListBuffer = getWritableContentBuffer(); 78 const int bigramFlags = createAndGetBigramFlags(bigramEntryToWrite->hasNext()); 79 if (!bigramListBuffer->writeUintAndAdvancePosition(bigramFlags, 80 Ver4DictConstants::BIGRAM_FLAGS_FIELD_SIZE, entryWritingPos)) { 81 AKLOGE("Cannot write bigram flags. pos: %d, flags: %x", *entryWritingPos, bigramFlags); 82 return false; 83 } 84 if (mHasHistoricalInfo) { 85 const HistoricalInfo *const historicalInfo = bigramEntryToWrite->getHistoricalInfo(); 86 if (!bigramListBuffer->writeUintAndAdvancePosition(historicalInfo->getTimeStamp(), 87 Ver4DictConstants::TIME_STAMP_FIELD_SIZE, entryWritingPos)) { 88 AKLOGE("Cannot write bigram timestamps. pos: %d, timestamp: %d", *entryWritingPos, 89 historicalInfo->getTimeStamp()); 90 return false; 91 } 92 if (!bigramListBuffer->writeUintAndAdvancePosition(historicalInfo->getLevel(), 93 Ver4DictConstants::WORD_LEVEL_FIELD_SIZE, entryWritingPos)) { 94 AKLOGE("Cannot write bigram level. pos: %d, level: %d", *entryWritingPos, 95 historicalInfo->getLevel()); 96 return false; 97 } 98 if (!bigramListBuffer->writeUintAndAdvancePosition(historicalInfo->getCount(), 99 Ver4DictConstants::WORD_COUNT_FIELD_SIZE, entryWritingPos)) { 100 AKLOGE("Cannot write bigram count. pos: %d, count: %d", *entryWritingPos, 101 historicalInfo->getCount()); 102 return false; 103 } 104 } else { 105 if (!bigramListBuffer->writeUintAndAdvancePosition(bigramEntryToWrite->getProbability(), 106 Ver4DictConstants::PROBABILITY_SIZE, entryWritingPos)) { 107 AKLOGE("Cannot write bigram probability. pos: %d, probability: %d", *entryWritingPos, 108 bigramEntryToWrite->getProbability()); 109 return false; 110 } 111 } 112 const int targetTerminalIdToWrite = 113 (bigramEntryToWrite->getTargetTerminalId() == Ver4DictConstants::NOT_A_TERMINAL_ID) ? 114 Ver4DictConstants::INVALID_BIGRAM_TARGET_TERMINAL_ID : 115 bigramEntryToWrite->getTargetTerminalId(); 116 if (!bigramListBuffer->writeUintAndAdvancePosition(targetTerminalIdToWrite, 117 Ver4DictConstants::BIGRAM_TARGET_TERMINAL_ID_FIELD_SIZE, entryWritingPos)) { 118 AKLOGE("Cannot write bigram target terminal id. pos: %d, target terminal id: %d", 119 *entryWritingPos, bigramEntryToWrite->getTargetTerminalId()); 120 return false; 121 } 122 return true; 123 } 124 125 bool BigramDictContent::copyBigramList(const int bigramListPos, const int toPos, 126 int *const outTailEntryPos) { 127 int readingPos = bigramListPos; 128 int writingPos = toPos; 129 bool hasNext = true; 130 while (hasNext) { 131 const BigramEntry bigramEntry = getBigramEntryAndAdvancePosition(&readingPos); 132 hasNext = bigramEntry.hasNext(); 133 if (!hasNext) { 134 *outTailEntryPos = writingPos; 135 } 136 if (!writeBigramEntryAndAdvancePosition(&bigramEntry, &writingPos)) { 137 AKLOGE("Cannot write bigram entry to copy. pos: %d", writingPos); 138 return false; 139 } 140 } 141 return true; 142 } 143 144 bool BigramDictContent::runGC(const TerminalPositionLookupTable::TerminalIdMap *const terminalIdMap, 145 const BigramDictContent *const originalBigramDictContent, 146 int *const outBigramEntryCount) { 147 for (TerminalPositionLookupTable::TerminalIdMap::const_iterator it = terminalIdMap->begin(); 148 it != terminalIdMap->end(); ++it) { 149 const int originalBigramListPos = 150 originalBigramDictContent->getBigramListHeadPos(it->first); 151 if (originalBigramListPos == NOT_A_DICT_POS) { 152 // This terminal does not have a bigram list. 153 continue; 154 } 155 const int bigramListPos = getContentBuffer()->getTailPosition(); 156 int bigramEntryCount = 0; 157 // Copy bigram list with GC from original content. 158 if (!runGCBigramList(originalBigramListPos, originalBigramDictContent, bigramListPos, 159 terminalIdMap, &bigramEntryCount)) { 160 AKLOGE("Cannot complete GC for the bigram list. original pos: %d, pos: %d", 161 originalBigramListPos, bigramListPos); 162 return false; 163 } 164 if (bigramEntryCount == 0) { 165 // All bigram entries are useless. This terminal does not have a bigram list. 166 continue; 167 } 168 *outBigramEntryCount += bigramEntryCount; 169 // Set bigram list position to the lookup table. 170 if (!getUpdatableAddressLookupTable()->set(it->second, bigramListPos)) { 171 AKLOGE("Cannot set bigram list position. terminal id: %d, pos: %d", 172 it->second, bigramListPos); 173 return false; 174 } 175 } 176 return true; 177 } 178 179 // Returns whether GC for the bigram list was succeeded or not. 180 bool BigramDictContent::runGCBigramList(const int bigramListPos, 181 const BigramDictContent *const sourceBigramDictContent, const int toPos, 182 const TerminalPositionLookupTable::TerminalIdMap *const terminalIdMap, 183 int *const outEntrycount) { 184 bool hasNext = true; 185 int readingPos = bigramListPos; 186 int writingPos = toPos; 187 int lastEntryPos = NOT_A_DICT_POS; 188 while (hasNext) { 189 const BigramEntry originalBigramEntry = 190 sourceBigramDictContent->getBigramEntryAndAdvancePosition(&readingPos); 191 hasNext = originalBigramEntry.hasNext(); 192 if (originalBigramEntry.getTargetTerminalId() == Ver4DictConstants::NOT_A_TERMINAL_ID) { 193 continue; 194 } 195 TerminalPositionLookupTable::TerminalIdMap::const_iterator it = 196 terminalIdMap->find(originalBigramEntry.getTargetTerminalId()); 197 if (it == terminalIdMap->end()) { 198 // Target word has been removed. 199 continue; 200 } 201 lastEntryPos = hasNext ? writingPos : NOT_A_DICT_POS; 202 const BigramEntry updatedBigramEntry = 203 originalBigramEntry.updateTargetTerminalIdAndGetEntry(it->second); 204 if (!writeBigramEntryAndAdvancePosition(&updatedBigramEntry, &writingPos)) { 205 AKLOGE("Cannot write bigram entry to run GC. pos: %d", writingPos); 206 return false; 207 } 208 *outEntrycount += 1; 209 } 210 if (lastEntryPos != NOT_A_DICT_POS) { 211 // Update has next flag in the last written entry. 212 const BigramEntry bigramEntry = getBigramEntry(lastEntryPos).updateHasNextAndGetEntry( 213 false /* hasNext */); 214 if (!writeBigramEntry(&bigramEntry, lastEntryPos)) { 215 AKLOGE("Cannot write bigram entry to set hasNext flag after GC. pos: %d", writingPos); 216 return false; 217 } 218 } 219 return true; 220 } 221 222 } // namespace v402 223 } // namespace backward 224 } // namespace latinime 225