1/*
2 * Copyright (C) 2011 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_WORDS_PRIORITY_QUEUE_POOL_H
18#define LATINIME_WORDS_PRIORITY_QUEUE_POOL_H
19
20#include <cassert>
21#include "words_priority_queue.h"
22
23namespace latinime {
24
25class WordsPriorityQueuePool {
26 public:
27    WordsPriorityQueuePool(int mainQueueMaxWords, int subQueueMaxWords, int maxWordLength)
28            // Note: using placement new() requires the caller to call the destructor explicitly.
29            : mMasterQueue(new(mMasterQueueBuf) WordsPriorityQueue(
30                      mainQueueMaxWords, maxWordLength)) {
31        for (int i = 0, subQueueBufOffset = 0;
32                i < MULTIPLE_WORDS_SUGGESTION_MAX_WORDS * SUB_QUEUE_MAX_COUNT;
33                ++i, subQueueBufOffset += static_cast<int>(sizeof(WordsPriorityQueue))) {
34            mSubQueues[i] = new(mSubQueueBuf + subQueueBufOffset)
35                    WordsPriorityQueue(subQueueMaxWords, maxWordLength);
36        }
37    }
38
39    virtual ~WordsPriorityQueuePool() {
40        // Note: these explicit calls to the destructor match the calls to placement new() above.
41        if (mMasterQueue) mMasterQueue->~WordsPriorityQueue();
42        for (int i = 0; i < MULTIPLE_WORDS_SUGGESTION_MAX_WORDS * SUB_QUEUE_MAX_COUNT; ++i) {
43            if (mSubQueues[i]) mSubQueues[i]->~WordsPriorityQueue();
44        }
45    }
46
47    WordsPriorityQueue *getMasterQueue() {
48        return mMasterQueue;
49    }
50
51    WordsPriorityQueue *getSubQueue(const int wordIndex, const int inputWordLength) {
52        if (wordIndex >= MULTIPLE_WORDS_SUGGESTION_MAX_WORDS) {
53            return 0;
54        }
55        if (inputWordLength < 0 || inputWordLength >= SUB_QUEUE_MAX_COUNT) {
56            if (DEBUG_WORDS_PRIORITY_QUEUE) {
57                assert(false);
58            }
59            return 0;
60        }
61        return mSubQueues[wordIndex * SUB_QUEUE_MAX_COUNT + inputWordLength];
62    }
63
64    inline void clearAll() {
65        mMasterQueue->clear();
66        for (int i = 0; i < MULTIPLE_WORDS_SUGGESTION_MAX_WORDS; ++i) {
67            clearSubQueue(i);
68        }
69    }
70
71    inline void clearSubQueue(const int wordIndex) {
72        for (int i = 0; i < SUB_QUEUE_MAX_COUNT; ++i) {
73            WordsPriorityQueue *queue = getSubQueue(wordIndex, i);
74            if (queue) {
75                queue->clear();
76            }
77        }
78    }
79
80    void dumpSubQueue1TopSuggestions() {
81        AKLOGI("DUMP SUBQUEUE1 TOP SUGGESTIONS");
82        for (int i = 0; i < SUB_QUEUE_MAX_COUNT; ++i) {
83            getSubQueue(0, i)->dumpTopWord();
84        }
85    }
86
87 private:
88    DISALLOW_IMPLICIT_CONSTRUCTORS(WordsPriorityQueuePool);
89    char mMasterQueueBuf[sizeof(WordsPriorityQueue)];
90    char mSubQueueBuf[SUB_QUEUE_MAX_COUNT * MULTIPLE_WORDS_SUGGESTION_MAX_WORDS
91            * sizeof(WordsPriorityQueue)];
92    WordsPriorityQueue *mMasterQueue;
93    WordsPriorityQueue *mSubQueues[SUB_QUEUE_MAX_COUNT * MULTIPLE_WORDS_SUGGESTION_MAX_WORDS];
94};
95} // namespace latinime
96#endif // LATINIME_WORDS_PRIORITY_QUEUE_POOL_H
97