1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef LATINIME_DIC_NODE_POOL_H
18 #define LATINIME_DIC_NODE_POOL_H
19 
20 #include <deque>
21 #include <unordered_set>
22 #include <vector>
23 
24 #include "defines.h"
25 #include "suggest/core/dicnode/dic_node.h"
26 
27 namespace latinime {
28 
29 class DicNodePool {
30  public:
DicNodePool(const int capacity)31     explicit DicNodePool(const int capacity) : mDicNodes(), mPooledDicNodes() {
32         reset(capacity);
33     }
34 
reset(const int capacity)35     void reset(const int capacity) {
36         if (capacity == static_cast<int>(mDicNodes.size())
37                 && capacity == static_cast<int>(mPooledDicNodes.size())) {
38             // No need to reset.
39             return;
40         }
41         mDicNodes.resize(capacity);
42         mDicNodes.shrink_to_fit();
43         mPooledDicNodes.clear();
44         for (auto &dicNode : mDicNodes) {
45             mPooledDicNodes.emplace_back(&dicNode);
46         }
47     }
48 
49     // Get a DicNode instance from the pool. The instance has to be returned by returnInstance().
getInstance()50     DicNode *getInstance() {
51         if (mPooledDicNodes.empty()) {
52             return nullptr;
53         }
54         DicNode *const dicNode = mPooledDicNodes.back();
55         mPooledDicNodes.pop_back();
56         return dicNode;
57     }
58 
59     // Return an instance that has been removed from the pool by getInstance() to the pool. The
60     // instance must not be used after returning without getInstance().
placeBackInstance(DicNode * dicNode)61     void placeBackInstance(DicNode *dicNode) {
62         mPooledDicNodes.emplace_back(dicNode);
63     }
64 
dump()65     void dump() const {
66         AKLOGI("\n\n\n\n\n===========================");
67         std::unordered_set<const DicNode*> usedDicNodes;
68         for (const auto &dicNode : mDicNodes) {
69             usedDicNodes.insert(&dicNode);
70         }
71         for (const auto &dicNodePtr : mPooledDicNodes) {
72             usedDicNodes.erase(dicNodePtr);
73         }
74         for (const auto &usedDicNodePtr : usedDicNodes) {
75             usedDicNodePtr->dump("DIC_NODE_POOL: ");
76         }
77         AKLOGI("===========================\n\n\n\n\n");
78     }
79 
80  private:
81     DISALLOW_IMPLICIT_CONSTRUCTORS(DicNodePool);
82 
83     std::vector<DicNode> mDicNodes;
84     std::deque<DicNode*> mPooledDicNodes;
85 };
86 } // namespace latinime
87 #endif // LATINIME_DIC_NODE_POOL_H
88