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

Commit 5b6ec109 authored by Keisuke Kuroyanagi's avatar Keisuke Kuroyanagi Committed by Android Git Automerger
Browse files

am 1b80a45e: Merge "Make terminal cache small."

* commit '1b80a45e':
  Make terminal cache small.
parents c6df31d4 1b80a45e
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;