Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db0aa747 authored by Satoshi Kataoka's avatar Satoshi Kataoka Committed by Android (Google) Code Review
Browse files

Merge "Purge WordsPriorityQueue"

parents 4caf5941 04e37fb9
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -48,8 +48,7 @@ LATIN_IME_JNI_SRC_FILES := \
LATIN_IME_CORE_SRC_FILES := \
    suggest/core/suggest.cpp \
    $(addprefix obsolete/, \
        correction.cpp \
        words_priority_queue.cpp) \
        correction.cpp) \
    $(addprefix suggest/core/dicnode/, \
        dic_node.cpp \
        dic_node_utils.cpp \
+0 −76
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "obsolete/words_priority_queue.h"

namespace latinime {

int WordsPriorityQueue::outputSuggestions(const int *before, const int beforeLength,
        int *frequencies, int *outputCodePoints, int* outputTypes) {
    mHighestSuggestedWord = 0;
    const int size = min(MAX_WORDS, static_cast<int>(mSuggestions.size()));
    SuggestedWord *swBuffer[size];
    int index = size - 1;
    while (!mSuggestions.empty() && index >= 0) {
        SuggestedWord *sw = mSuggestions.top();
        if (DEBUG_WORDS_PRIORITY_QUEUE) {
            AKLOGI("dump word. %d", sw->mScore);
            DUMP_WORD(sw->mWord, sw->mWordLength);
        }
        swBuffer[index] = sw;
        mSuggestions.pop();
        --index;
    }
    if (size >= 2) {
        SuggestedWord *nsMaxSw = 0;
        int maxIndex = 0;
        float maxNs = 0;
        for (int i = 0; i < size; ++i) {
            SuggestedWord *tempSw = swBuffer[i];
            if (!tempSw) {
                continue;
            }
            const float tempNs = getNormalizedScore(tempSw, before, beforeLength, 0, 0, 0);
            if (tempNs >= maxNs) {
                maxNs = tempNs;
                maxIndex = i;
                nsMaxSw = tempSw;
            }
        }
        if (maxIndex > 0 && nsMaxSw) {
            memmove(&swBuffer[1], &swBuffer[0], maxIndex * sizeof(swBuffer[0]));
            swBuffer[0] = nsMaxSw;
        }
    }
    for (int i = 0; i < size; ++i) {
        SuggestedWord *sw = swBuffer[i];
        if (!sw) {
            AKLOGE("SuggestedWord is null %d", i);
            continue;
        }
        const int wordLength = sw->mWordLength;
        int *targetAddress = outputCodePoints + i * MAX_WORD_LENGTH;
        frequencies[i] = sw->mScore;
        outputTypes[i] = sw->mType;
        memcpy(targetAddress, sw->mWord, wordLength * sizeof(targetAddress[0]));
        if (wordLength < MAX_WORD_LENGTH) {
            targetAddress[wordLength] = 0;
        }
        sw->mUsed = false;
    }
    return size;
}
} // namespace latinime
+0 −175
Original line number Diff line number Diff line
/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef LATINIME_WORDS_PRIORITY_QUEUE_H
#define LATINIME_WORDS_PRIORITY_QUEUE_H

#include <cstring> // for memcpy()
#include <queue>

#include "defines.h"
#include "obsolete/correction.h"

namespace latinime {

class WordsPriorityQueue {
 public:
    struct SuggestedWord {
        int mScore;
        int mWord[MAX_WORD_LENGTH];
        int mWordLength;
        bool mUsed;
        int mType;

        void setParams(int score, int *word, int wordLength, int type) {
            mScore = score;
            mWordLength = wordLength;
            memcpy(mWord, word, sizeof(mWord[0]) * wordLength);
            mUsed = true;
            mType = type;
        }
    };

    WordsPriorityQueue(int maxWords)
            : mSuggestions(), MAX_WORDS(maxWords),
              mSuggestedWords(new SuggestedWord[MAX_WORD_LENGTH]), mHighestSuggestedWord(0) {
        for (int i = 0; i < MAX_WORD_LENGTH; ++i) {
            mSuggestedWords[i].mUsed = false;
        }
    }

    // Non virtual inline destructor -- never inherit this class
    AK_FORCE_INLINE ~WordsPriorityQueue() {
        delete[] mSuggestedWords;
    }

    void push(int score, int *word, int wordLength, int type) {
        SuggestedWord *sw = 0;
        if (size() >= MAX_WORDS) {
            sw = mSuggestions.top();
            const int minScore = sw->mScore;
            if (minScore >= score) {
                return;
            }
            sw->mUsed = false;
            mSuggestions.pop();
        }
        if (sw == 0) {
            sw = getFreeSuggestedWord(score, word, wordLength, type);
        } else {
            sw->setParams(score, word, wordLength, type);
        }
        if (sw == 0) {
            AKLOGE("SuggestedWord is accidentally null.");
            return;
        }
        if (DEBUG_WORDS_PRIORITY_QUEUE) {
            AKLOGI("Push word. %d, %d", score, wordLength);
            DUMP_WORD(word, wordLength);
        }
        mSuggestions.push(sw);
        if (!mHighestSuggestedWord || mHighestSuggestedWord->mScore < sw->mScore) {
            mHighestSuggestedWord = sw;
        }
    }

    SuggestedWord *top() const {
        if (mSuggestions.empty()) return 0;
        SuggestedWord *sw = mSuggestions.top();
        return sw;
    }

    int size() const {
        return static_cast<int>(mSuggestions.size());
    }

    AK_FORCE_INLINE void clear() {
        mHighestSuggestedWord = 0;
        while (!mSuggestions.empty()) {
            SuggestedWord *sw = mSuggestions.top();
            if (DEBUG_WORDS_PRIORITY_QUEUE) {
                AKLOGI("Clear word. %d", sw->mScore);
                DUMP_WORD(sw->mWord, sw->mWordLength);
            }
            sw->mUsed = false;
            mSuggestions.pop();
        }
    }

    AK_FORCE_INLINE void dumpTopWord() const {
        if (size() <= 0) {
            return;
        }
        DUMP_WORD(mHighestSuggestedWord->mWord, mHighestSuggestedWord->mWordLength);
    }

    AK_FORCE_INLINE float getHighestNormalizedScore(const int *before, const int beforeLength,
            int **outWord, int *outScore, int *outLength) const {
        if (!mHighestSuggestedWord) {
            return 0.0f;
        }
        return getNormalizedScore(mHighestSuggestedWord, before, beforeLength, outWord, outScore,
                outLength);
    }

    int outputSuggestions(const int *before, const int beforeLength, int *frequencies,
            int *outputCodePoints, int* outputTypes);

 private:
    DISALLOW_IMPLICIT_CONSTRUCTORS(WordsPriorityQueue);
    struct wordComparator {
        bool operator ()(SuggestedWord * left, SuggestedWord * right) {
            return left->mScore > right->mScore;
        }
    };

    SuggestedWord *getFreeSuggestedWord(int score, int *word, int wordLength, int type) const {
        for (int i = 0; i < MAX_WORD_LENGTH; ++i) {
            if (!mSuggestedWords[i].mUsed) {
                mSuggestedWords[i].setParams(score, word, wordLength, type);
                return &mSuggestedWords[i];
            }
        }
        return 0;
    }

    static float getNormalizedScore(SuggestedWord *sw, const int *before, const int beforeLength,
            int **outWord, int *outScore, int *outLength) {
        const int score = sw->mScore;
        int *word = sw->mWord;
        const int wordLength = sw->mWordLength;
        if (outScore) {
            *outScore = score;
        }
        if (outWord) {
            *outWord = word;
        }
        if (outLength) {
            *outLength = wordLength;
        }
        return Correction::RankingAlgorithm::calcNormalizedScore(before, beforeLength, word,
                wordLength, score);
    }

    typedef std::priority_queue<SuggestedWord *, std::vector<SuggestedWord *>,
            wordComparator> Suggestions;
    Suggestions mSuggestions;
    const int MAX_WORDS;
    SuggestedWord *mSuggestedWords;
    SuggestedWord *mHighestSuggestedWord;
};
} // namespace latinime
#endif // LATINIME_WORDS_PRIORITY_QUEUE_H
+0 −96
Original line number Diff line number Diff line
/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef LATINIME_WORDS_PRIORITY_QUEUE_POOL_H
#define LATINIME_WORDS_PRIORITY_QUEUE_POOL_H

#include "defines.h"
#include "obsolete/words_priority_queue.h"

namespace latinime {

class WordsPriorityQueuePool {
 public:
    WordsPriorityQueuePool(int mainQueueMaxWords, int subQueueMaxWords)
            // Note: using placement new() requires the caller to call the destructor explicitly.
            : mMasterQueue(new(mMasterQueueBuf) WordsPriorityQueue(mainQueueMaxWords)) {
        for (int i = 0, subQueueBufOffset = 0;
                i < MULTIPLE_WORDS_SUGGESTION_MAX_WORDS * SUB_QUEUE_MAX_COUNT;
                ++i, subQueueBufOffset += static_cast<int>(sizeof(WordsPriorityQueue))) {
            mSubQueues[i] = new(mSubQueueBuf + subQueueBufOffset)
                    WordsPriorityQueue(subQueueMaxWords);
        }
    }

    // Non virtual inline destructor -- never inherit this class
    ~WordsPriorityQueuePool() {
        // Note: these explicit calls to the destructor match the calls to placement new() above.
        if (mMasterQueue) mMasterQueue->~WordsPriorityQueue();
        for (int i = 0; i < MULTIPLE_WORDS_SUGGESTION_MAX_WORDS * SUB_QUEUE_MAX_COUNT; ++i) {
            if (mSubQueues[i]) mSubQueues[i]->~WordsPriorityQueue();
        }
    }

    WordsPriorityQueue *getMasterQueue() const {
        return mMasterQueue;
    }

    WordsPriorityQueue *getSubQueue(const int wordIndex, const int inputWordLength) const {
        if (wordIndex >= MULTIPLE_WORDS_SUGGESTION_MAX_WORDS) {
            return 0;
        }
        if (inputWordLength < 0 || inputWordLength >= SUB_QUEUE_MAX_COUNT) {
            if (DEBUG_WORDS_PRIORITY_QUEUE) {
                ASSERT(false);
            }
            return 0;
        }
        return mSubQueues[wordIndex * SUB_QUEUE_MAX_COUNT + inputWordLength];
    }

    inline void clearAll() {
        mMasterQueue->clear();
        for (int i = 0; i < MULTIPLE_WORDS_SUGGESTION_MAX_WORDS; ++i) {
            clearSubQueue(i);
        }
    }

    AK_FORCE_INLINE void clearSubQueue(const int wordIndex) {
        for (int i = 0; i < SUB_QUEUE_MAX_COUNT; ++i) {
            WordsPriorityQueue *queue = getSubQueue(wordIndex, i);
            if (queue) {
                queue->clear();
            }
        }
    }

    void dumpSubQueue1TopSuggestions() const {
        AKLOGI("DUMP SUBQUEUE1 TOP SUGGESTIONS");
        for (int i = 0; i < SUB_QUEUE_MAX_COUNT; ++i) {
            getSubQueue(0, i)->dumpTopWord();
        }
    }

 private:
    DISALLOW_IMPLICIT_CONSTRUCTORS(WordsPriorityQueuePool);
    char mMasterQueueBuf[sizeof(WordsPriorityQueue)];
    char mSubQueueBuf[SUB_QUEUE_MAX_COUNT * MULTIPLE_WORDS_SUGGESTION_MAX_WORDS
            * sizeof(WordsPriorityQueue)];
    WordsPriorityQueue *mMasterQueue;
    WordsPriorityQueue *mSubQueues[SUB_QUEUE_MAX_COUNT * MULTIPLE_WORDS_SUGGESTION_MAX_WORDS];
};
} // namespace latinime
#endif // LATINIME_WORDS_PRIORITY_QUEUE_POOL_H