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

Commit 1b80a45e authored by Keisuke Kuroyanagi's avatar Keisuke Kuroyanagi Committed by Android (Google) Code Review
Browse files

Merge "Make terminal cache small."

parents 76e431b3 80ca7abe
Loading
Loading
Loading
Loading
+2 −7
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@
#define MAX_WORD_LENGTH 48
// Must be equal to BinaryDictionary.MAX_RESULTS in Java
#define MAX_RESULTS 18
// The biggest value among MAX_CACHE_DIC_NODE_SIZE, MAX_CACHE_DIC_NODE_SIZE_FOR_SINGLE_POINT, ...
#define MAX_DIC_NODE_PRIORITY_QUEUE_CAPACITY 310
// Must be equal to ProximityInfo.MAX_PROXIMITY_CHARS_SIZE in Java
#define MAX_PROXIMITY_CHARS_SIZE 16
#define ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE 2
@@ -322,13 +324,6 @@ static inline void prof_out(void) {
#define MAX_POINTER_COUNT 1
#define MAX_POINTER_COUNT_G 2

// Queue IDs and size for DicNodesCache
#define DIC_NODES_CACHE_INITIAL_QUEUE_ID_ACTIVE 0
#define DIC_NODES_CACHE_INITIAL_QUEUE_ID_NEXT_ACTIVE 1
#define DIC_NODES_CACHE_INITIAL_QUEUE_ID_TERMINAL 2
#define DIC_NODES_CACHE_INITIAL_QUEUE_ID_CACHE_FOR_CONTINUOUS_SUGGESTION 3
#define DIC_NODES_CACHE_PRIORITY_QUEUES_SIZE 4

template<typename T> AK_FORCE_INLINE const T &min(const T &a, const T &b) { return a < b ? a : b; }
template<typename T> AK_FORCE_INLINE const T &max(const T &a, const T &b) { return a > b ? a : b; }

+29 −32
Original line number Diff line number Diff line
@@ -24,20 +24,16 @@
#include "suggest/core/dicnode/dic_node.h"
#include "suggest/core/dicnode/dic_node_release_listener.h"

// The biggest value among MAX_CACHE_DIC_NODE_SIZE, MAX_CACHE_DIC_NODE_SIZE_FOR_SINGLE_POINT, ...
#define MAX_DIC_NODE_PRIORITY_QUEUE_CAPACITY 310

namespace latinime {

class DicNodePriorityQueue : public DicNodeReleaseListener {
 public:
    AK_FORCE_INLINE DicNodePriorityQueue()
            : MAX_CAPACITY(MAX_DIC_NODE_PRIORITY_QUEUE_CAPACITY),
              mMaxSize(MAX_DIC_NODE_PRIORITY_QUEUE_CAPACITY), mDicNodesBuf(), mUnusedNodeIndices(),
              mNextUnusedNodeId(0), mDicNodesQueue() {
        mDicNodesBuf.resize(MAX_CAPACITY + 1);
        mUnusedNodeIndices.resize(MAX_CAPACITY + 1);
        reset();
    AK_FORCE_INLINE explicit DicNodePriorityQueue(const int capacity)
            : mCapacity(capacity), mMaxSize(capacity), mDicNodesBuf(),
              mUnusedNodeIndices(), mNextUnusedNodeId(0), mDicNodesQueue() {
        mDicNodesBuf.resize(mCapacity + 1);
        mUnusedNodeIndices.resize(mCapacity + 1);
        clearAndResizeToCapacity();
    }

    // Non virtual inline destructor -- never inherit this class
@@ -52,11 +48,12 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
    }

    AK_FORCE_INLINE void setMaxSize(const int maxSize) {
        mMaxSize = min(maxSize, MAX_CAPACITY);
        ASSERT(maxSize <= mCapacity);
        mMaxSize = min(maxSize, mCapacity);
    }

    AK_FORCE_INLINE void reset() {
        clearAndResize(MAX_CAPACITY);
    AK_FORCE_INLINE void clearAndResizeToCapacity() {
        clearAndResize(mCapacity);
    }

    AK_FORCE_INLINE void clear() {
@@ -64,27 +61,19 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
    }

    AK_FORCE_INLINE void clearAndResize(const int maxSize) {
        ASSERT(maxSize <= mCapacity);
        while (!mDicNodesQueue.empty()) {
            mDicNodesQueue.pop();
        }
        setMaxSize(maxSize);
        for (int i = 0; i < MAX_CAPACITY + 1; ++i) {
        for (int i = 0; i < mCapacity + 1; ++i) {
            mDicNodesBuf[i].remove();
            mDicNodesBuf[i].setReleaseListener(this);
            mUnusedNodeIndices[i] = i == MAX_CAPACITY ? NOT_A_NODE_ID : static_cast<int>(i) + 1;
            mUnusedNodeIndices[i] = i == mCapacity ? NOT_A_NODE_ID : static_cast<int>(i) + 1;
        }
        mNextUnusedNodeId = 0;
    }

    AK_FORCE_INLINE DicNode *newDicNode(DicNode *dicNode) {
        DicNode *newNode = searchEmptyDicNode();
        if (newNode) {
            DicNodeUtils::initByCopy(dicNode, newNode);
            return newNode;
        }
        return 0;
    }

    // Copy
    AK_FORCE_INLINE DicNode *copyPush(DicNode *dicNode) {
        return copyPush(dicNode, mMaxSize);
@@ -111,12 +100,12 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
        }
        mUnusedNodeIndices[index] = mNextUnusedNodeId;
        mNextUnusedNodeId = index;
        ASSERT(index >= 0 && index < (MAX_CAPACITY + 1));
        ASSERT(index >= 0 && index < (mCapacity + 1));
    }

    AK_FORCE_INLINE void dump() const {
        AKLOGI("\n\n\n\n\n===========================");
        for (int i = 0; i < MAX_CAPACITY + 1; ++i) {
        for (int i = 0; i < mCapacity + 1; ++i) {
            if (mDicNodesBuf[i].isUsed()) {
                mDicNodesBuf[i].dump("QUEUE: ");
            }
@@ -125,7 +114,7 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
    }

 private:
    DISALLOW_COPY_AND_ASSIGN(DicNodePriorityQueue);
    DISALLOW_IMPLICIT_CONSTRUCTORS(DicNodePriorityQueue);
    static const int NOT_A_NODE_ID = -1;

    AK_FORCE_INLINE static bool compareDicNode(DicNode *left, DicNode *right) {
@@ -139,7 +128,7 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
    };

    typedef std::priority_queue<DicNode *, std::vector<DicNode *>, DicNodeComparator> DicNodesQueue;
    const int MAX_CAPACITY;
    const int mCapacity;
    int mMaxSize;
    std::vector<DicNode> mDicNodesBuf; // of each element of mDicNodesBuf respectively
    std::vector<int> mUnusedNodeIndices;
@@ -163,13 +152,12 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
    }

    AK_FORCE_INLINE DicNode *searchEmptyDicNode() {
        // TODO: Currently O(n) but should be improved to O(1)
        if (MAX_CAPACITY == 0) {
        if (mCapacity == 0) {
            return 0;
        }
        if (mNextUnusedNodeId == NOT_A_NODE_ID) {
            AKLOGI("No unused node found.");
            for (int i = 0; i < MAX_CAPACITY + 1; ++i) {
            for (int i = 0; i < mCapacity + 1; ++i) {
                AKLOGI("Dump node availability, %d, %d, %d",
                        i, mDicNodesBuf[i].isUsed(), mUnusedNodeIndices[i]);
            }
@@ -185,7 +173,7 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
        const int index = static_cast<int>(dicNode - &mDicNodesBuf[0]);
        mNextUnusedNodeId = mUnusedNodeIndices[index];
        mUnusedNodeIndices[index] = NOT_A_NODE_ID;
        ASSERT(index >= 0 && index < (MAX_CAPACITY + 1));
        ASSERT(index >= 0 && index < (mCapacity + 1));
    }

    AK_FORCE_INLINE DicNode *pushPoolNodeWithMaxSize(DicNode *dicNode, const int maxSize) {
@@ -209,6 +197,15 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
    AK_FORCE_INLINE DicNode *copyPush(DicNode *dicNode, const int maxSize) {
        return pushPoolNodeWithMaxSize(newDicNode(dicNode), maxSize);
    }

    AK_FORCE_INLINE DicNode *newDicNode(DicNode *dicNode) {
        DicNode *newNode = searchEmptyDicNode();
        if (newNode) {
            DicNodeUtils::initByCopy(dicNode, newNode);
        }
        return newNode;
    }

};
} // namespace latinime
#endif // LATINIME_DIC_NODE_PRIORITY_QUEUE_H
+23 −13
Original line number Diff line number Diff line
@@ -32,24 +32,29 @@ class DicNode;
class DicNodesCache {
 public:
    AK_FORCE_INLINE DicNodesCache()
            : mActiveDicNodes(&mDicNodePriorityQueues[DIC_NODES_CACHE_INITIAL_QUEUE_ID_ACTIVE]),
              mNextActiveDicNodes(&mDicNodePriorityQueues[
                      DIC_NODES_CACHE_INITIAL_QUEUE_ID_NEXT_ACTIVE]),
              mTerminalDicNodes(&mDicNodePriorityQueues[DIC_NODES_CACHE_INITIAL_QUEUE_ID_TERMINAL]),
              mCachedDicNodesForContinuousSuggestion(&mDicNodePriorityQueues[
                      DIC_NODES_CACHE_INITIAL_QUEUE_ID_CACHE_FOR_CONTINUOUS_SUGGESTION]),
              mInputIndex(0), mLastCachedInputIndex(0) {
    }
            : mDicNodePriorityQueue0(MAX_DIC_NODE_PRIORITY_QUEUE_CAPACITY),
              mDicNodePriorityQueue1(MAX_DIC_NODE_PRIORITY_QUEUE_CAPACITY),
              mDicNodePriorityQueue2(MAX_DIC_NODE_PRIORITY_QUEUE_CAPACITY),
              mDicNodePriorityQueueForTerminal(MAX_RESULTS),
              mActiveDicNodes(&mDicNodePriorityQueue0),
              mNextActiveDicNodes(&mDicNodePriorityQueue1),
              mCachedDicNodesForContinuousSuggestion(&mDicNodePriorityQueue2),
              mTerminalDicNodes(&mDicNodePriorityQueueForTerminal),
              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();
        // We want to use the max capacity for the current active dic node queue.
        mActiveDicNodes->clearAndResizeToCapacity();
        // nextActiveSize is used to limit the next iteration's active dic node size.
        mNextActiveDicNodes->clearAndResize(nextActiveSize);
        mTerminalDicNodes->clearAndResize(terminalSize);
        mCachedDicNodesForContinuousSuggestion->reset();
        // We want to use the max capacity for the cached dic nodes that will be used for the
        // continuous suggestion.
        mCachedDicNodesForContinuousSuggestion->clearAndResizeToCapacity();
    }

    AK_FORCE_INLINE void continueSearch() {
@@ -163,15 +168,20 @@ class DicNodesCache {
        mTerminalDicNodes->clear();
    }

    DicNodePriorityQueue mDicNodePriorityQueues[DIC_NODES_CACHE_PRIORITY_QUEUES_SIZE];
    // Instances
    DicNodePriorityQueue mDicNodePriorityQueue0;
    DicNodePriorityQueue mDicNodePriorityQueue1;
    DicNodePriorityQueue mDicNodePriorityQueue2;
    DicNodePriorityQueue mDicNodePriorityQueueForTerminal;

    // 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;
    // Current top terminal dicNodes.
    DicNodePriorityQueue *mTerminalDicNodes;
    int mInputIndex;
    int mLastCachedInputIndex;
};
+3 −2
Original line number Diff line number Diff line
@@ -59,8 +59,9 @@ const DictionaryStructureWithBufferPolicy *DicTraverseSession::getDictionaryStru
    return mDictionary->getDictionaryStructurePolicy();
}

void DicTraverseSession::resetCache(const int nextActiveCacheSize, const int maxWords) {
    mDicNodesCache.reset(nextActiveCacheSize, maxWords);
void DicTraverseSession::resetCache(const int thresholdForNextActiveDicNodes, const int maxWords) {
    mDicNodesCache.reset(thresholdForNextActiveDicNodes /* nextActiveSize */,
            maxWords /* terminalSize */);
    mMultiBigramMap.clear();
    mPartiallyCommited = false;
}
+1 −1
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ class DicTraverseSession {
            const int inputSize, const int *const inputXs, const int *const inputYs,
            const int *const times, const int *const pointerIds, const float maxSpatialDistance,
            const int maxPointerCount);
    void resetCache(const int nextActiveCacheSize, const int maxWords);
    void resetCache(const int thresholdForNextActiveDicNodes, const int maxWords);

    const DictionaryStructureWithBufferPolicy *getDictionaryStructurePolicy() const;