Merge "Separate DicNodePool from DicNodePriorityQueue."
This commit is contained in:
commit
94c7bd471f
6 changed files with 129 additions and 183 deletions
|
@ -24,8 +24,7 @@ DicNode::DicNode(const DicNode &dicNode)
|
||||||
mProfiler(dicNode.mProfiler),
|
mProfiler(dicNode.mProfiler),
|
||||||
#endif
|
#endif
|
||||||
mDicNodeProperties(dicNode.mDicNodeProperties), mDicNodeState(dicNode.mDicNodeState),
|
mDicNodeProperties(dicNode.mDicNodeProperties), mDicNodeState(dicNode.mDicNodeState),
|
||||||
mIsCachedForNextSuggestion(dicNode.mIsCachedForNextSuggestion), mIsUsed(dicNode.mIsUsed),
|
mIsCachedForNextSuggestion(dicNode.mIsCachedForNextSuggestion) {
|
||||||
mReleaseListener(nullptr) {
|
|
||||||
/* empty */
|
/* empty */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,8 +35,6 @@ DicNode &DicNode::operator=(const DicNode &dicNode) {
|
||||||
mDicNodeProperties = dicNode.mDicNodeProperties;
|
mDicNodeProperties = dicNode.mDicNodeProperties;
|
||||||
mDicNodeState = dicNode.mDicNodeState;
|
mDicNodeState = dicNode.mDicNodeState;
|
||||||
mIsCachedForNextSuggestion = dicNode.mIsCachedForNextSuggestion;
|
mIsCachedForNextSuggestion = dicNode.mIsCachedForNextSuggestion;
|
||||||
mIsUsed = dicNode.mIsUsed;
|
|
||||||
mReleaseListener = dicNode.mReleaseListener;
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "suggest/core/dicnode/dic_node_profiler.h"
|
#include "suggest/core/dicnode/dic_node_profiler.h"
|
||||||
#include "suggest/core/dicnode/dic_node_release_listener.h"
|
|
||||||
#include "suggest/core/dicnode/dic_node_utils.h"
|
#include "suggest/core/dicnode/dic_node_utils.h"
|
||||||
#include "suggest/core/dicnode/internal/dic_node_state.h"
|
#include "suggest/core/dicnode/internal/dic_node_state.h"
|
||||||
#include "suggest/core/dicnode/internal/dic_node_properties.h"
|
#include "suggest/core/dicnode/internal/dic_node_properties.h"
|
||||||
|
@ -89,8 +88,7 @@ class DicNode {
|
||||||
#if DEBUG_DICT
|
#if DEBUG_DICT
|
||||||
mProfiler(),
|
mProfiler(),
|
||||||
#endif
|
#endif
|
||||||
mDicNodeProperties(), mDicNodeState(), mIsCachedForNextSuggestion(false),
|
mDicNodeProperties(), mDicNodeState(), mIsCachedForNextSuggestion(false) {}
|
||||||
mIsUsed(false), mReleaseListener(nullptr) {}
|
|
||||||
|
|
||||||
DicNode(const DicNode &dicNode);
|
DicNode(const DicNode &dicNode);
|
||||||
DicNode &operator=(const DicNode &dicNode);
|
DicNode &operator=(const DicNode &dicNode);
|
||||||
|
@ -98,7 +96,6 @@ class DicNode {
|
||||||
|
|
||||||
// Init for copy
|
// Init for copy
|
||||||
void initByCopy(const DicNode *const dicNode) {
|
void initByCopy(const DicNode *const dicNode) {
|
||||||
mIsUsed = true;
|
|
||||||
mIsCachedForNextSuggestion = dicNode->mIsCachedForNextSuggestion;
|
mIsCachedForNextSuggestion = dicNode->mIsCachedForNextSuggestion;
|
||||||
mDicNodeProperties.initByCopy(&dicNode->mDicNodeProperties);
|
mDicNodeProperties.initByCopy(&dicNode->mDicNodeProperties);
|
||||||
mDicNodeState.initByCopy(&dicNode->mDicNodeState);
|
mDicNodeState.initByCopy(&dicNode->mDicNodeState);
|
||||||
|
@ -107,7 +104,6 @@ class DicNode {
|
||||||
|
|
||||||
// Init for root with prevWordPtNodePos which is used for bigram
|
// Init for root with prevWordPtNodePos which is used for bigram
|
||||||
void initAsRoot(const int rootPtNodeArrayPos, const int prevWordPtNodePos) {
|
void initAsRoot(const int rootPtNodeArrayPos, const int prevWordPtNodePos) {
|
||||||
mIsUsed = true;
|
|
||||||
mIsCachedForNextSuggestion = false;
|
mIsCachedForNextSuggestion = false;
|
||||||
mDicNodeProperties.init(rootPtNodeArrayPos, prevWordPtNodePos);
|
mDicNodeProperties.init(rootPtNodeArrayPos, prevWordPtNodePos);
|
||||||
mDicNodeState.init();
|
mDicNodeState.init();
|
||||||
|
@ -116,7 +112,6 @@ class DicNode {
|
||||||
|
|
||||||
// Init for root with previous word
|
// Init for root with previous word
|
||||||
void initAsRootWithPreviousWord(const DicNode *const dicNode, const int rootPtNodeArrayPos) {
|
void initAsRootWithPreviousWord(const DicNode *const dicNode, const int rootPtNodeArrayPos) {
|
||||||
mIsUsed = true;
|
|
||||||
mIsCachedForNextSuggestion = dicNode->mIsCachedForNextSuggestion;
|
mIsCachedForNextSuggestion = dicNode->mIsCachedForNextSuggestion;
|
||||||
mDicNodeProperties.init(rootPtNodeArrayPos, dicNode->mDicNodeProperties.getPtNodePos());
|
mDicNodeProperties.init(rootPtNodeArrayPos, dicNode->mDicNodeProperties.getPtNodePos());
|
||||||
mDicNodeState.initAsRootWithPreviousWord(&dicNode->mDicNodeState,
|
mDicNodeState.initAsRootWithPreviousWord(&dicNode->mDicNodeState,
|
||||||
|
@ -125,7 +120,6 @@ class DicNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
void initAsPassingChild(DicNode *parentDicNode) {
|
void initAsPassingChild(DicNode *parentDicNode) {
|
||||||
mIsUsed = true;
|
|
||||||
mIsCachedForNextSuggestion = parentDicNode->mIsCachedForNextSuggestion;
|
mIsCachedForNextSuggestion = parentDicNode->mIsCachedForNextSuggestion;
|
||||||
const int parentCodePoint = parentDicNode->getNodeTypedCodePoint();
|
const int parentCodePoint = parentDicNode->getNodeTypedCodePoint();
|
||||||
mDicNodeProperties.init(&parentDicNode->mDicNodeProperties, parentCodePoint);
|
mDicNodeProperties.init(&parentDicNode->mDicNodeProperties, parentCodePoint);
|
||||||
|
@ -137,7 +131,6 @@ class DicNode {
|
||||||
const int childrenPtNodeArrayPos, const int probability, const bool isTerminal,
|
const int childrenPtNodeArrayPos, const int probability, const bool isTerminal,
|
||||||
const bool hasChildren, const bool isBlacklistedOrNotAWord,
|
const bool hasChildren, const bool isBlacklistedOrNotAWord,
|
||||||
const uint16_t mergedNodeCodePointCount, const int *const mergedNodeCodePoints) {
|
const uint16_t mergedNodeCodePointCount, const int *const mergedNodeCodePoints) {
|
||||||
mIsUsed = true;
|
|
||||||
uint16_t newDepth = static_cast<uint16_t>(dicNode->getNodeCodePointCount() + 1);
|
uint16_t newDepth = static_cast<uint16_t>(dicNode->getNodeCodePointCount() + 1);
|
||||||
mIsCachedForNextSuggestion = dicNode->mIsCachedForNextSuggestion;
|
mIsCachedForNextSuggestion = dicNode->mIsCachedForNextSuggestion;
|
||||||
const uint16_t newLeavingDepth = static_cast<uint16_t>(
|
const uint16_t newLeavingDepth = static_cast<uint16_t>(
|
||||||
|
@ -150,17 +143,6 @@ class DicNode {
|
||||||
PROF_NODE_COPY(&dicNode->mProfiler, mProfiler);
|
PROF_NODE_COPY(&dicNode->mProfiler, mProfiler);
|
||||||
}
|
}
|
||||||
|
|
||||||
AK_FORCE_INLINE void finalize() {
|
|
||||||
mIsUsed = false;
|
|
||||||
if (mReleaseListener) {
|
|
||||||
mReleaseListener->onReleased(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isUsed() const {
|
|
||||||
return mIsUsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isRoot() const {
|
bool isRoot() const {
|
||||||
return getNodeCodePointCount() == 0;
|
return getNodeCodePointCount() == 0;
|
||||||
}
|
}
|
||||||
|
@ -466,10 +448,6 @@ class DicNode {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void setReleaseListener(DicNodeReleaseListener *releaseListener) {
|
|
||||||
mReleaseListener = releaseListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
AK_FORCE_INLINE bool compare(const DicNode *right) const {
|
AK_FORCE_INLINE bool compare(const DicNode *right) const {
|
||||||
// Promote exact matches to prevent them from being pruned.
|
// Promote exact matches to prevent them from being pruned.
|
||||||
const bool leftExactMatch = ErrorTypeUtils::isExactMatch(getContainedErrorTypes());
|
const bool leftExactMatch = ErrorTypeUtils::isExactMatch(getContainedErrorTypes());
|
||||||
|
@ -507,8 +485,6 @@ class DicNode {
|
||||||
DicNodeState mDicNodeState;
|
DicNodeState mDicNodeState;
|
||||||
// TODO: Remove
|
// TODO: Remove
|
||||||
bool mIsCachedForNextSuggestion;
|
bool mIsCachedForNextSuggestion;
|
||||||
bool mIsUsed;
|
|
||||||
DicNodeReleaseListener *mReleaseListener;
|
|
||||||
|
|
||||||
AK_FORCE_INLINE int getTotalInputIndex() const {
|
AK_FORCE_INLINE int getTotalInputIndex() const {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
87
native/jni/src/suggest/core/dicnode/dic_node_pool.h
Normal file
87
native/jni/src/suggest/core/dicnode/dic_node_pool.h
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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_NODE_POOL_H
|
||||||
|
#define LATINIME_DIC_NODE_POOL_H
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "defines.h"
|
||||||
|
#include "suggest/core/dicnode/dic_node.h"
|
||||||
|
|
||||||
|
namespace latinime {
|
||||||
|
|
||||||
|
class DicNodePool {
|
||||||
|
public:
|
||||||
|
explicit DicNodePool(const int capacity) : mDicNodes(), mPooledDicNodes() {
|
||||||
|
reset(capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(const int capacity) {
|
||||||
|
if (capacity == static_cast<int>(mDicNodes.size())
|
||||||
|
&& capacity == static_cast<int>(mPooledDicNodes.size())) {
|
||||||
|
// No need to reset.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mDicNodes.resize(capacity);
|
||||||
|
mDicNodes.shrink_to_fit();
|
||||||
|
mPooledDicNodes.clear();
|
||||||
|
for (auto &dicNode : mDicNodes) {
|
||||||
|
mPooledDicNodes.emplace_back(&dicNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a DicNode instance from the pool. The instance has to be returned by returnInstance().
|
||||||
|
DicNode *getInstance() {
|
||||||
|
if (mPooledDicNodes.empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
DicNode *const dicNode = mPooledDicNodes.back();
|
||||||
|
mPooledDicNodes.pop_back();
|
||||||
|
return dicNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return an instance that has been removed from the pool by getInstance() to the pool. The
|
||||||
|
// instance must not be used after returning without getInstance().
|
||||||
|
void placeBackInstance(DicNode *dicNode) {
|
||||||
|
mPooledDicNodes.emplace_back(dicNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump() const {
|
||||||
|
AKLOGI("\n\n\n\n\n===========================");
|
||||||
|
std::unordered_set<const DicNode*> usedDicNodes;
|
||||||
|
for (const auto &dicNode : mDicNodes) {
|
||||||
|
usedDicNodes.insert(&dicNode);
|
||||||
|
}
|
||||||
|
for (const auto &dicNodePtr : mPooledDicNodes) {
|
||||||
|
usedDicNodes.erase(dicNodePtr);
|
||||||
|
}
|
||||||
|
for (const auto &usedDicNodePtr : usedDicNodes) {
|
||||||
|
usedDicNodePtr->dump("DIC_NODE_POOL: ");
|
||||||
|
}
|
||||||
|
AKLOGI("===========================\n\n\n\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
DISALLOW_IMPLICIT_CONSTRUCTORS(DicNodePool);
|
||||||
|
|
||||||
|
std::vector<DicNode> mDicNodes;
|
||||||
|
std::deque<DicNode*> mPooledDicNodes;
|
||||||
|
};
|
||||||
|
} // namespace latinime
|
||||||
|
#endif // LATINIME_DIC_NODE_POOL_H
|
|
@ -23,38 +23,30 @@
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "suggest/core/dicnode/dic_node.h"
|
#include "suggest/core/dicnode/dic_node.h"
|
||||||
#include "suggest/core/dicnode/dic_node_release_listener.h"
|
#include "suggest/core/dicnode/dic_node_pool.h"
|
||||||
|
|
||||||
namespace latinime {
|
namespace latinime {
|
||||||
|
|
||||||
class DicNodePriorityQueue : public DicNodeReleaseListener {
|
class DicNodePriorityQueue {
|
||||||
public:
|
public:
|
||||||
AK_FORCE_INLINE explicit DicNodePriorityQueue(const int capacity)
|
AK_FORCE_INLINE explicit DicNodePriorityQueue(const int capacity)
|
||||||
: mCapacity(capacity), mMaxSize(capacity), mDicNodesBuf(),
|
: mMaxSize(capacity), mDicNodesQueue(), mDicNodePool(capacity) {
|
||||||
mUnusedNodeIndices(), mNextUnusedNodeId(0), mDicNodesQueue() {
|
clear();
|
||||||
mDicNodesBuf.resize(mCapacity + 1);
|
|
||||||
mUnusedNodeIndices.resize(mCapacity + 1);
|
|
||||||
clearAndResizeToCapacity();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non virtual inline destructor -- never inherit this class
|
// Non virtual inline destructor -- never inherit this class
|
||||||
AK_FORCE_INLINE ~DicNodePriorityQueue() {}
|
AK_FORCE_INLINE ~DicNodePriorityQueue() {}
|
||||||
|
|
||||||
int getSize() const {
|
AK_FORCE_INLINE int getSize() const {
|
||||||
return static_cast<int>(mDicNodesQueue.size());
|
return static_cast<int>(mDicNodesQueue.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
int getMaxSize() const {
|
AK_FORCE_INLINE int getMaxSize() const {
|
||||||
return mMaxSize;
|
return mMaxSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
AK_FORCE_INLINE void setMaxSize(const int maxSize) {
|
AK_FORCE_INLINE void setMaxSize(const int maxSize) {
|
||||||
ASSERT(maxSize <= mCapacity);
|
mMaxSize = maxSize;
|
||||||
mMaxSize = std::min(maxSize, mCapacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
AK_FORCE_INLINE void clearAndResizeToCapacity() {
|
|
||||||
clearAndResize(mCapacity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AK_FORCE_INLINE void clear() {
|
AK_FORCE_INLINE void clear() {
|
||||||
|
@ -62,25 +54,32 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
AK_FORCE_INLINE void clearAndResize(const int maxSize) {
|
AK_FORCE_INLINE void clearAndResize(const int maxSize) {
|
||||||
ASSERT(maxSize <= mCapacity);
|
mMaxSize = maxSize;
|
||||||
while (!mDicNodesQueue.empty()) {
|
while (!mDicNodesQueue.empty()) {
|
||||||
mDicNodesQueue.pop();
|
mDicNodesQueue.pop();
|
||||||
}
|
}
|
||||||
setMaxSize(maxSize);
|
mDicNodePool.reset(mMaxSize + 1);
|
||||||
for (int i = 0; i < mCapacity + 1; ++i) {
|
}
|
||||||
mDicNodesBuf[i].finalize();
|
|
||||||
mDicNodesBuf[i].setReleaseListener(this);
|
AK_FORCE_INLINE void copyPush(const DicNode *const dicNode) {
|
||||||
mUnusedNodeIndices[i] = (i == mCapacity) ? NOT_A_NODE_ID : (i + 1);
|
DicNode *const pooledDicNode = newDicNode(dicNode);
|
||||||
|
if (!pooledDicNode) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
mNextUnusedNodeId = 0;
|
if (getSize() < mMaxSize) {
|
||||||
|
mDicNodesQueue.push(pooledDicNode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (betterThanWorstDicNode(pooledDicNode)) {
|
||||||
|
mDicNodePool.placeBackInstance(mDicNodesQueue.top());
|
||||||
|
mDicNodesQueue.pop();
|
||||||
|
mDicNodesQueue.push(pooledDicNode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mDicNodePool.placeBackInstance(pooledDicNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy
|
AK_FORCE_INLINE void copyPop(DicNode *const dest) {
|
||||||
AK_FORCE_INLINE DicNode *copyPush(const DicNode *const dicNode) {
|
|
||||||
return copyPush(dicNode, mMaxSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
AK_FORCE_INLINE void copyPop(DicNode *dest) {
|
|
||||||
if (mDicNodesQueue.empty()) {
|
if (mDicNodesQueue.empty()) {
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
return;
|
return;
|
||||||
|
@ -89,34 +88,16 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
|
||||||
if (dest) {
|
if (dest) {
|
||||||
DicNodeUtils::initByCopy(node, dest);
|
DicNodeUtils::initByCopy(node, dest);
|
||||||
}
|
}
|
||||||
node->finalize();
|
mDicNodePool.placeBackInstance(node);
|
||||||
mDicNodesQueue.pop();
|
mDicNodesQueue.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onReleased(const DicNode *dicNode) {
|
AK_FORCE_INLINE void dump() {
|
||||||
const int index = static_cast<int>(dicNode - &mDicNodesBuf[0]);
|
mDicNodePool.dump();
|
||||||
if (mUnusedNodeIndices[index] != NOT_A_NODE_ID) {
|
|
||||||
// it's already released
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mUnusedNodeIndices[index] = mNextUnusedNodeId;
|
|
||||||
mNextUnusedNodeId = index;
|
|
||||||
ASSERT(index >= 0 && index < (mCapacity + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
AK_FORCE_INLINE void dump() const {
|
|
||||||
AKLOGI("\n\n\n\n\n===========================");
|
|
||||||
for (int i = 0; i < mCapacity + 1; ++i) {
|
|
||||||
if (mDicNodesBuf[i].isUsed()) {
|
|
||||||
mDicNodesBuf[i].dump("QUEUE: ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AKLOGI("===========================\n\n\n\n\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(DicNodePriorityQueue);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(DicNodePriorityQueue);
|
||||||
static const int NOT_A_NODE_ID = -1;
|
|
||||||
|
|
||||||
AK_FORCE_INLINE static bool compareDicNode(const DicNode *const left,
|
AK_FORCE_INLINE static bool compareDicNode(const DicNode *const left,
|
||||||
const DicNode *const right) {
|
const DicNode *const right) {
|
||||||
|
@ -124,26 +105,15 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DicNodeComparator {
|
struct DicNodeComparator {
|
||||||
bool operator ()(DicNode *left, DicNode *right) {
|
bool operator ()(const DicNode *left, const DicNode *right) const {
|
||||||
return compareDicNode(left, right);
|
return compareDicNode(left, right);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::priority_queue<DicNode *, std::vector<DicNode *>, DicNodeComparator> DicNodesQueue;
|
typedef std::priority_queue<DicNode *, std::vector<DicNode *>, DicNodeComparator> DicNodesQueue;
|
||||||
const int mCapacity;
|
|
||||||
int mMaxSize;
|
int mMaxSize;
|
||||||
std::vector<DicNode> mDicNodesBuf; // of each element of mDicNodesBuf respectively
|
|
||||||
std::vector<int> mUnusedNodeIndices;
|
|
||||||
int mNextUnusedNodeId;
|
|
||||||
DicNodesQueue mDicNodesQueue;
|
DicNodesQueue mDicNodesQueue;
|
||||||
|
DicNodePool mDicNodePool;
|
||||||
inline bool isFull(const int maxSize) const {
|
|
||||||
return getSize() >= maxSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
AK_FORCE_INLINE void pop() {
|
|
||||||
copyPop(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
AK_FORCE_INLINE bool betterThanWorstDicNode(const DicNode *const dicNode) const {
|
AK_FORCE_INLINE bool betterThanWorstDicNode(const DicNode *const dicNode) const {
|
||||||
DicNode *worstNode = mDicNodesQueue.top();
|
DicNode *worstNode = mDicNodesQueue.top();
|
||||||
|
@ -153,61 +123,13 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
|
||||||
return compareDicNode(dicNode, worstNode);
|
return compareDicNode(dicNode, worstNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
AK_FORCE_INLINE DicNode *searchEmptyDicNode() {
|
|
||||||
if (mCapacity == 0) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
if (mNextUnusedNodeId == NOT_A_NODE_ID) {
|
|
||||||
AKLOGI("No unused node found.");
|
|
||||||
for (int i = 0; i < mCapacity + 1; ++i) {
|
|
||||||
AKLOGI("Dump node availability, %d, %d, %d",
|
|
||||||
i, mDicNodesBuf[i].isUsed(), mUnusedNodeIndices[i]);
|
|
||||||
}
|
|
||||||
ASSERT(false);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
DicNode *dicNode = &mDicNodesBuf[mNextUnusedNodeId];
|
|
||||||
markNodeAsUsed(dicNode);
|
|
||||||
return dicNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
AK_FORCE_INLINE void markNodeAsUsed(DicNode *dicNode) {
|
|
||||||
const int index = static_cast<int>(dicNode - &mDicNodesBuf[0]);
|
|
||||||
mNextUnusedNodeId = mUnusedNodeIndices[index];
|
|
||||||
mUnusedNodeIndices[index] = NOT_A_NODE_ID;
|
|
||||||
ASSERT(index >= 0 && index < (mCapacity + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
AK_FORCE_INLINE DicNode *pushPoolNodeWithMaxSize(DicNode *dicNode, const int maxSize) {
|
|
||||||
if (!dicNode) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
if (!isFull(maxSize)) {
|
|
||||||
mDicNodesQueue.push(dicNode);
|
|
||||||
return dicNode;
|
|
||||||
}
|
|
||||||
if (betterThanWorstDicNode(dicNode)) {
|
|
||||||
pop();
|
|
||||||
mDicNodesQueue.push(dicNode);
|
|
||||||
return dicNode;
|
|
||||||
}
|
|
||||||
dicNode->finalize();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy
|
|
||||||
AK_FORCE_INLINE DicNode *copyPush(const DicNode *const dicNode, const int maxSize) {
|
|
||||||
return pushPoolNodeWithMaxSize(newDicNode(dicNode), maxSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
AK_FORCE_INLINE DicNode *newDicNode(const DicNode *const dicNode) {
|
AK_FORCE_INLINE DicNode *newDicNode(const DicNode *const dicNode) {
|
||||||
DicNode *newNode = searchEmptyDicNode();
|
DicNode *newNode = mDicNodePool.getInstance();
|
||||||
if (newNode) {
|
if (newNode) {
|
||||||
DicNodeUtils::initByCopy(dicNode, newNode);
|
DicNodeUtils::initByCopy(dicNode, newNode);
|
||||||
}
|
}
|
||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
} // namespace latinime
|
} // namespace latinime
|
||||||
#endif // LATINIME_DIC_NODE_PRIORITY_QUEUE_H
|
#endif // LATINIME_DIC_NODE_PRIORITY_QUEUE_H
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* 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_NODE_RELEASE_LISTENER_H
|
|
||||||
#define LATINIME_DIC_NODE_RELEASE_LISTENER_H
|
|
||||||
|
|
||||||
#include "defines.h"
|
|
||||||
|
|
||||||
namespace latinime {
|
|
||||||
|
|
||||||
class DicNode;
|
|
||||||
|
|
||||||
class DicNodeReleaseListener {
|
|
||||||
public:
|
|
||||||
DicNodeReleaseListener() {}
|
|
||||||
virtual ~DicNodeReleaseListener() {}
|
|
||||||
virtual void onReleased(const DicNode *dicNode) = 0;
|
|
||||||
private:
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(DicNodeReleaseListener);
|
|
||||||
};
|
|
||||||
} // namespace latinime
|
|
||||||
#endif // LATINIME_DIC_NODE_RELEASE_LISTENER_H
|
|
|
@ -49,15 +49,14 @@ class DicNodesCache {
|
||||||
AK_FORCE_INLINE void reset(const int nextActiveSize, const int terminalSize) {
|
AK_FORCE_INLINE void reset(const int nextActiveSize, const int terminalSize) {
|
||||||
mInputIndex = 0;
|
mInputIndex = 0;
|
||||||
mLastCachedInputIndex = 0;
|
mLastCachedInputIndex = 0;
|
||||||
// We want to use the max capacity for the current active dic node queue.
|
// The size of current active DicNode queue doesn't have to be changed.
|
||||||
mActiveDicNodes->clearAndResizeToCapacity();
|
mActiveDicNodes->clear();
|
||||||
// nextActiveSize is used to limit the next iteration's active dic node size.
|
// nextActiveSize is used to limit the next iteration's active DicNode size.
|
||||||
const int nextActiveSizeFittingToTheCapacity = std::min(nextActiveSize, getCacheCapacity());
|
const int nextActiveSizeFittingToTheCapacity = std::min(nextActiveSize, getCacheCapacity());
|
||||||
mNextActiveDicNodes->clearAndResize(nextActiveSizeFittingToTheCapacity);
|
mNextActiveDicNodes->clearAndResize(nextActiveSizeFittingToTheCapacity);
|
||||||
mTerminalDicNodes->clearAndResize(terminalSize);
|
mTerminalDicNodes->clearAndResize(terminalSize);
|
||||||
// We want to use the max capacity for the cached dic nodes that will be used for the
|
// The size of cached DicNode queue doesn't have to be changed.
|
||||||
// continuous suggestion.
|
mCachedDicNodesForContinuousSuggestion->clear();
|
||||||
mCachedDicNodesForContinuousSuggestion->clearAndResizeToCapacity();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AK_FORCE_INLINE void continueSearch() {
|
AK_FORCE_INLINE void continueSearch() {
|
||||||
|
@ -95,8 +94,8 @@ class DicNodesCache {
|
||||||
mActiveDicNodes->copyPush(dicNode);
|
mActiveDicNodes->copyPush(dicNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
AK_FORCE_INLINE bool copyPushContinue(DicNode *dicNode) {
|
AK_FORCE_INLINE void copyPushContinue(DicNode *dicNode) {
|
||||||
return mCachedDicNodesForContinuousSuggestion->copyPush(dicNode);
|
mCachedDicNodesForContinuousSuggestion->copyPush(dicNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
AK_FORCE_INLINE void copyPushNextActive(DicNode *dicNode) {
|
AK_FORCE_INLINE void copyPushNextActive(DicNode *dicNode) {
|
||||||
|
|
Loading…
Reference in a new issue