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

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

Merge "Move policy and session to AOSP"

parents 43341ba0 3107b467
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -29,7 +29,9 @@ LATIN_IME_SRC_FULLPATH_DIR := $(LOCAL_PATH)/$(LATIN_IME_SRC_DIR)
LOCAL_C_INCLUDES += \
    $(LATIN_IME_SRC_FULLPATH_DIR) \
    $(LATIN_IME_SRC_FULLPATH_DIR)/suggest \
    $(LATIN_IME_SRC_FULLPATH_DIR)/suggest/core/dicnode
    $(LATIN_IME_SRC_FULLPATH_DIR)/suggest/core/dicnode \
    $(LATIN_IME_SRC_FULLPATH_DIR)/suggest/core/policy \
    $(LATIN_IME_SRC_FULLPATH_DIR)/suggest/core/session

LOCAL_CFLAGS += -Werror -Wall -Wextra -Weffc++ -Wformat=2 -Wcast-qual -Wcast-align \
    -Wwrite-strings -Wfloat-equal -Wpointer-arith -Winit-self -Wredundant-decls -Wno-system-headers
@@ -63,7 +65,10 @@ LATIN_IME_CORE_SRC_FILES := \
    unigram_dictionary.cpp \
    words_priority_queue.cpp \
    suggest/core/dicnode/dic_node.cpp \
    suggest/core/dicnode/dic_nodes_cache.cpp \
    suggest/core/dicnode/dic_node_utils.cpp \
    suggest/core/policy/weighting.cpp \
    suggest/core/session/dic_traverse_session.cpp \
    suggest/gesture_suggest.cpp \
    suggest/typing_suggest.cpp

+59 −0
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 <list>

#include "defines.h"
#include "dic_node_priority_queue.h"
#include "dic_node_utils.h"
#include "dic_nodes_cache.h"

namespace latinime {

/**
 * Truncates all of the dicNodes so that they start at the given commit point.
 * Only called for multi-word typing input.
 */
DicNode *DicNodesCache::setCommitPoint(int commitPoint) {
    std::list<DicNode> dicNodesList;
    while (mCachedDicNodesForContinuousSuggestion->getSize() > 0) {
        DicNode dicNode;
        mCachedDicNodesForContinuousSuggestion->copyPop(&dicNode);
        dicNodesList.push_front(dicNode);
    }

    // Get the starting words of the top scoring dicNode (last dicNode popped from priority queue)
    // up to the commit point. These words have already been committed to the text view.
    DicNode *topDicNode = &dicNodesList.front();
    DicNode topDicNodeCopy;
    DicNodeUtils::initByCopy(topDicNode, &topDicNodeCopy);

    // Keep only those dicNodes that match the same starting words.
    std::list<DicNode>::iterator iter;
    for (iter = dicNodesList.begin(); iter != dicNodesList.end(); iter++) {
        DicNode *dicNode = &*iter;
        if (dicNode->truncateNode(&topDicNodeCopy, commitPoint)) {
            mCachedDicNodesForContinuousSuggestion->copyPush(dicNode);
        } else {
            // Top dicNode should be reprocessed.
            ASSERT(dicNode != topDicNode);
            DicNode::managedDelete(dicNode);
        }
    }
    mInputIndex -= commitPoint;
    return topDicNode;
}
}  // namespace latinime
+185 −0
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.
 */

#ifndef LATINIME_DIC_NODES_CACHE_H
#define LATINIME_DIC_NODES_CACHE_H

#include <stdint.h>

#include "defines.h"
#include "dic_node_priority_queue.h"

#define INITIAL_QUEUE_ID_ACTIVE 0
#define INITIAL_QUEUE_ID_NEXT_ACTIVE 1
#define INITIAL_QUEUE_ID_TERMINAL 2
#define INITIAL_QUEUE_ID_CACHE_FOR_CONTINUOUS_SUGGESTION 3
#define PRIORITY_QUEUES_SIZE 4

namespace latinime {

class DicNode;

/**
 * Class for controlling dicNode search priority queue and lexicon trie traversal.
 */
class DicNodesCache {
 public:
    AK_FORCE_INLINE DicNodesCache()
            : mActiveDicNodes(&mDicNodePriorityQueues[INITIAL_QUEUE_ID_ACTIVE]),
              mNextActiveDicNodes(&mDicNodePriorityQueues[INITIAL_QUEUE_ID_NEXT_ACTIVE]),
              mTerminalDicNodes(&mDicNodePriorityQueues[INITIAL_QUEUE_ID_TERMINAL]),
              mCachedDicNodesForContinuousSuggestion(
                      &mDicNodePriorityQueues[INITIAL_QUEUE_ID_CACHE_FOR_CONTINUOUS_SUGGESTION]),
              mInputIndex(0), mLastCachedInputIndex(0) {
    }

    AK_FORCE_INLINE virtual ~DicNodesCache() {}

    AK_FORCE_INLINE void reset(const int nextActiveSize, const int terminalSize) {
        mInputIndex = 0;
        mLastCachedInputIndex = 0;
        mActiveDicNodes->reset();
        mNextActiveDicNodes->clearAndResize(nextActiveSize);
        mTerminalDicNodes->clearAndResize(terminalSize);
        mCachedDicNodesForContinuousSuggestion->reset();
    }

    AK_FORCE_INLINE void continueSearch() {
        resetTemporaryCaches();
        restoreActiveDicNodesFromCache();
    }

    AK_FORCE_INLINE void advanceActiveDicNodes() {
        if (DEBUG_DICT) {
            AKLOGI("Advance active %d nodes.", mNextActiveDicNodes->getSize());
        }
        if (DEBUG_DICT_FULL) {
            mNextActiveDicNodes->dump();
        }
        mNextActiveDicNodes =
                moveNodesAndReturnReusableEmptyQueue(mNextActiveDicNodes, &mActiveDicNodes);
    }

    DicNode *setCommitPoint(int commitPoint);

    int activeSize() const { return mActiveDicNodes->getSize(); }
    int terminalSize() const { return mTerminalDicNodes->getSize(); }
    bool isLookAheadCorrectionInputIndex(const int inputIndex) const {
        return inputIndex == mInputIndex - 1;
    }
    void advanceInputIndex(const int inputSize) {
        if (mInputIndex < inputSize) {
            mInputIndex++;
        }
    }

    AK_FORCE_INLINE void copyPushTerminal(DicNode *dicNode) {
        mTerminalDicNodes->copyPush(dicNode);
    }

    AK_FORCE_INLINE void copyPushActive(DicNode *dicNode) {
        mActiveDicNodes->copyPush(dicNode);
    }

    AK_FORCE_INLINE bool copyPushContinue(DicNode *dicNode) {
        return mCachedDicNodesForContinuousSuggestion->copyPush(dicNode);
    }

    AK_FORCE_INLINE void copyPushNextActive(DicNode *dicNode) {
        DicNode *pushedDicNode = mNextActiveDicNodes->copyPush(dicNode);
        if (!pushedDicNode) {
            if (dicNode->isCached()) {
                dicNode->remove();
            }
            // We simply drop any dic node that was not cached, ignoring the slim chance
            // that one of its children represents what the user really wanted.
        }
    }

    void popTerminal(DicNode *dest) {
        mTerminalDicNodes->copyPop(dest);
    }

    void popActive(DicNode *dest) {
        mActiveDicNodes->copyPop(dest);
    }

    bool hasCachedDicNodesForContinuousSuggestion() const {
        return mCachedDicNodesForContinuousSuggestion
                && mCachedDicNodesForContinuousSuggestion->getSize() > 0;
    }

    AK_FORCE_INLINE bool isCacheBorderForTyping(const int inputSize) const {
        // TODO: Move this variable to header
        static const int CACHE_BACK_LENGTH = 3;
        const int cacheInputIndex = inputSize - CACHE_BACK_LENGTH;
        const bool shouldCache = (cacheInputIndex == mInputIndex)
                && (cacheInputIndex != mLastCachedInputIndex);
        return shouldCache;
    }

    AK_FORCE_INLINE void updateLastCachedInputIndex() {
        mLastCachedInputIndex = mInputIndex;
    }

 private:
    DISALLOW_COPY_AND_ASSIGN(DicNodesCache);

    AK_FORCE_INLINE void restoreActiveDicNodesFromCache() {
        if (DEBUG_DICT) {
            AKLOGI("Restore %d nodes. inputIndex = %d.",
                    mCachedDicNodesForContinuousSuggestion->getSize(), mLastCachedInputIndex);
        }
        if (DEBUG_DICT_FULL || DEBUG_CACHE) {
            mCachedDicNodesForContinuousSuggestion->dump();
        }
        mInputIndex = mLastCachedInputIndex;
        mCachedDicNodesForContinuousSuggestion =
                moveNodesAndReturnReusableEmptyQueue(
                        mCachedDicNodesForContinuousSuggestion, &mActiveDicNodes);
    }

    AK_FORCE_INLINE static DicNodePriorityQueue *moveNodesAndReturnReusableEmptyQueue(
            DicNodePriorityQueue *src, DicNodePriorityQueue **dest) {
        const int srcMaxSize = src->getMaxSize();
        const int destMaxSize = (*dest)->getMaxSize();
        DicNodePriorityQueue *tmp = *dest;
        *dest = src;
        (*dest)->setMaxSize(destMaxSize);
        tmp->clearAndResize(srcMaxSize);
        return tmp;
    }

    AK_FORCE_INLINE void resetTemporaryCaches() {
        mActiveDicNodes->clear();
        mNextActiveDicNodes->clear();
        mTerminalDicNodes->clear();
    }

    DicNodePriorityQueue mDicNodePriorityQueues[PRIORITY_QUEUES_SIZE];
    // Active dicNodes currently being expanded.
    DicNodePriorityQueue *mActiveDicNodes;
    // Next dicNodes to be expanded.
    DicNodePriorityQueue *mNextActiveDicNodes;
    // Current top terminal dicNodes.
    DicNodePriorityQueue *mTerminalDicNodes;
    // Cached dicNodes used for continuous suggestion.
    DicNodePriorityQueue *mCachedDicNodesForContinuousSuggestion;
    int mInputIndex;
    int mLastCachedInputIndex;
};
} // namespace latinime
#endif // LATINIME_DIC_NODES_CACHE_H
+57 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 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_SCORING_H
#define LATINIME_SCORING_H

#include "defines.h"

namespace latinime {

class DicNode;
class DicTraverseSession;

// This class basically tweaks suggestions and distances apart from CompoundDistance
class Scoring {
 public:
    virtual int calculateFinalScore(const float compoundDistance, const int inputSize,
            const bool forceCommit) const = 0;
    virtual bool getMostProbableString(
            const DicTraverseSession *const traverseSession, const int terminalSize,
            const float languageWeight, int *const outputCodePoints, int *const type,
            int *const freq) const = 0;
    virtual void safetyNetForMostProbableString(const int terminalSize,
            const int maxScore, int *const outputCodePoints, int *const frequencies) const = 0;
    // TODO: Make more generic
    virtual void searchWordWithDoubleLetter(DicNode *terminals,
            const int terminalSize, int *doubleLetterTerminalIndex,
            DoubleLetterLevel *doubleLetterLevel) const = 0;
    virtual float getAdjustedLanguageWeight(DicTraverseSession *const traverseSession,
            DicNode *const terminals, const int size) const = 0;
    virtual float getDoubleLetterDemotionDistanceCost(const int terminalIndex,
            const int doubleLetterTerminalIndex,
            const DoubleLetterLevel doubleLetterLevel) const = 0;
    virtual bool doesAutoCorrectValidWord() const = 0;

 protected:
    Scoring() {}
    virtual ~Scoring() {}

 private:
    DISALLOW_COPY_AND_ASSIGN(Scoring);
};
} // namespace latinime
#endif // LATINIME_SCORING_H
+39 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 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_SUGGEST_POLICY_H
#define LATINIME_SUGGEST_POLICY_H

#include "defines.h"

namespace latinime {
class Traversal;
class Scoring;
class Weighting;

class SuggestPolicy {
 public:
    SuggestPolicy() {}
    virtual ~SuggestPolicy() {}
    virtual const Traversal *getTraversal() const = 0;
    virtual const Scoring *getScoring() const = 0;
    virtual const Weighting *getWeighting() const = 0;

 private:
    DISALLOW_COPY_AND_ASSIGN(SuggestPolicy);
};
} // namespace latinime
#endif // LATINIME_SUGGEST_POLICY_H
Loading