Home | History | Annotate | Download | only in content
      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