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

Commit 04e37fb9 authored by Satoshi Kataoka's avatar Satoshi Kataoka
Browse files

Purge WordsPriorityQueue

Change-Id: If14034c09d0dd335c84dd3a6ea2775655eefd38f
parent cbb1ee48
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