bool ProbabilityDictContent::writeEntry(const ProbabilityEntry *const probabilityEntry,
        const int entryPos) {
    BufferWithExtendableBuffer *const bufferToWrite = getWritableBuffer();
    int writingPos = entryPos;
    if (!bufferToWrite->writeUintAndAdvancePosition(probabilityEntry->getFlags(),
            Ver4DictConstants::FLAGS_IN_PROBABILITY_FILE_SIZE, &writingPos)) {
        AKLOGE("Cannot write flags in probability dict content. pos: %d", writingPos);
        return false;
    }
    if (!bufferToWrite->writeUintAndAdvancePosition(probabilityEntry->getProbability(),
            Ver4DictConstants::PROBABILITY_SIZE, &writingPos)) {
        AKLOGE("Cannot write probability in probability dict content. pos: %d", writingPos);
        return false;
    }
    if (mHasHistoricalInfo) {
        const HistoricalInfo *const historicalInfo = probabilityEntry->getHistoricalInfo();
        if (!bufferToWrite->writeUintAndAdvancePosition(historicalInfo->getTimestamp(),
                Ver4DictConstants::TIME_STAMP_FIELD_SIZE, &writingPos)) {
            AKLOGE("Cannot write timestamp in probability dict content. pos: %d", writingPos);
            return false;
        }
        if (!bufferToWrite->writeUintAndAdvancePosition(historicalInfo->getLevel(),
                Ver4DictConstants::WORD_LEVEL_FIELD_SIZE, &writingPos)) {
            AKLOGE("Cannot write level in probability dict content. pos: %d", writingPos);
            return false;
        }
        if (!bufferToWrite->writeUintAndAdvancePosition(historicalInfo->getCount(),
                Ver4DictConstants::WORD_COUNT_FIELD_SIZE, &writingPos)) {
            AKLOGE("Cannot write count in probability dict content. pos: %d", writingPos);
            return false;
        }
    }
    return true;
}
bool TerminalPositionLookupTable::setTerminalPtNodePosition(
        const int terminalId, const int terminalPtNodePos) {
    if (terminalId < 0) {
        return NOT_A_DICT_POS;
    }
    while (terminalId >= mSize) {
        // Write new entry.
        if (!getWritableBuffer()->writeUint(Ver4DictConstants::NOT_A_TERMINAL_ADDRESS,
                Ver4DictConstants::TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE, getEntryPos(mSize))) {
            return false;
        }
        mSize++;
    }
    const int terminalPos = (terminalPtNodePos != NOT_A_DICT_POS) ?
            terminalPtNodePos : Ver4DictConstants::NOT_A_TERMINAL_ADDRESS;
    return getWritableBuffer()->writeUint(terminalPos,
            Ver4DictConstants::TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE, getEntryPos(terminalId));
}
bool TerminalPositionLookupTable::runGCTerminalIds(TerminalIdMap *const terminalIdMap) {
    int removedEntryCount = 0;
    int nextNewTerminalId = 0;
    for (int i = 0; i < mSize; ++i) {
        const int terminalPos = getBuffer()->readUint(
                Ver4DictConstants::TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE, getEntryPos(i));
        if (terminalPos == Ver4DictConstants::NOT_A_TERMINAL_ADDRESS) {
            // This entry is a garbage.
            removedEntryCount++;
        } else {
            // Give a new terminal id to the entry.
            if (!getWritableBuffer()->writeUint(terminalPos,
                    Ver4DictConstants::TERMINAL_ADDRESS_TABLE_ADDRESS_SIZE,
                    getEntryPos(nextNewTerminalId))) {
                return false;
            }
            // Memorize the mapping to the old terminal id to the new terminal id.
            terminalIdMap->insert(TerminalIdMap::value_type(i, nextNewTerminalId));
            nextNewTerminalId++;
        }
    }
    mSize = nextNewTerminalId;
    return true;
}