am e5cfb776: Introduce ExclusiveOwnershipPointer.
* commit 'e5cfb776949eb8b9db8a01191aa1241ac22da0e4': Introduce ExclusiveOwnershipPointer.main
commit
db917de6aa
|
@ -91,7 +91,8 @@ LATIN_IME_CORE_SRC_FILES := \
|
||||||
byte_array_utils.cpp \
|
byte_array_utils.cpp \
|
||||||
dict_file_writing_utils.cpp \
|
dict_file_writing_utils.cpp \
|
||||||
forgetting_curve_utils.cpp \
|
forgetting_curve_utils.cpp \
|
||||||
format_utils.cpp) \
|
format_utils.cpp \
|
||||||
|
mmapped_buffer.cpp) \
|
||||||
suggest/policyimpl/gesture/gesture_suggest_policy_factory.cpp \
|
suggest/policyimpl/gesture/gesture_suggest_policy_factory.cpp \
|
||||||
$(addprefix suggest/policyimpl/typing/, \
|
$(addprefix suggest/policyimpl/typing/, \
|
||||||
scoring_params.cpp \
|
scoring_params.cpp \
|
||||||
|
|
|
@ -86,11 +86,11 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jclass clazz, jstring s
|
||||||
char sourceDirChars[sourceDirUtf8Length + 1];
|
char sourceDirChars[sourceDirUtf8Length + 1];
|
||||||
env->GetStringUTFRegion(sourceDir, 0, env->GetStringLength(sourceDir), sourceDirChars);
|
env->GetStringUTFRegion(sourceDir, 0, env->GetStringLength(sourceDir), sourceDirChars);
|
||||||
sourceDirChars[sourceDirUtf8Length] = '\0';
|
sourceDirChars[sourceDirUtf8Length] = '\0';
|
||||||
DictionaryStructureWithBufferPolicy *const dictionaryStructureWithBufferPolicy =
|
DictionaryStructureWithBufferPolicy::StructurePoilcyPtr dictionaryStructureWithBufferPolicy(
|
||||||
DictionaryStructureWithBufferPolicyFactory::newDictionaryStructureWithBufferPolicy(
|
DictionaryStructureWithBufferPolicyFactory::newDictionaryStructureWithBufferPolicy(
|
||||||
sourceDirChars, static_cast<int>(dictOffset), static_cast<int>(dictSize),
|
sourceDirChars, static_cast<int>(dictOffset), static_cast<int>(dictSize),
|
||||||
isUpdatable == JNI_TRUE);
|
isUpdatable == JNI_TRUE));
|
||||||
if (!dictionaryStructureWithBufferPolicy) {
|
if (!dictionaryStructureWithBufferPolicy.get()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,9 +21,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "suggest/core/dictionary/bigram_dictionary.h"
|
|
||||||
#include "suggest/core/policy/dictionary_header_structure_policy.h"
|
#include "suggest/core/policy/dictionary_header_structure_policy.h"
|
||||||
#include "suggest/core/policy/dictionary_structure_with_buffer_policy.h"
|
|
||||||
#include "suggest/core/session/dic_traverse_session.h"
|
#include "suggest/core/session/dic_traverse_session.h"
|
||||||
#include "suggest/core/suggest.h"
|
#include "suggest/core/suggest.h"
|
||||||
#include "suggest/core/suggest_options.h"
|
#include "suggest/core/suggest_options.h"
|
||||||
|
@ -35,22 +33,15 @@ namespace latinime {
|
||||||
|
|
||||||
const int Dictionary::HEADER_ATTRIBUTE_BUFFER_SIZE = 32;
|
const int Dictionary::HEADER_ATTRIBUTE_BUFFER_SIZE = 32;
|
||||||
|
|
||||||
Dictionary::Dictionary(JNIEnv *env,
|
Dictionary::Dictionary(JNIEnv *env, const DictionaryStructureWithBufferPolicy::StructurePoilcyPtr
|
||||||
DictionaryStructureWithBufferPolicy *const dictionaryStructureWithBufferPolicy)
|
&dictionaryStructureWithBufferPolicy)
|
||||||
: mDictionaryStructureWithBufferPolicy(dictionaryStructureWithBufferPolicy),
|
: mDictionaryStructureWithBufferPolicy(dictionaryStructureWithBufferPolicy),
|
||||||
mBigramDictionary(new BigramDictionary(mDictionaryStructureWithBufferPolicy)),
|
mBigramDictionary(new BigramDictionary(mDictionaryStructureWithBufferPolicy.get())),
|
||||||
mGestureSuggest(new Suggest(GestureSuggestPolicyFactory::getGestureSuggestPolicy())),
|
mGestureSuggest(new Suggest(GestureSuggestPolicyFactory::getGestureSuggestPolicy())),
|
||||||
mTypingSuggest(new Suggest(TypingSuggestPolicyFactory::getTypingSuggestPolicy())) {
|
mTypingSuggest(new Suggest(TypingSuggestPolicyFactory::getTypingSuggestPolicy())) {
|
||||||
logDictionaryInfo(env);
|
logDictionaryInfo(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary::~Dictionary() {
|
|
||||||
delete mBigramDictionary;
|
|
||||||
delete mGestureSuggest;
|
|
||||||
delete mTypingSuggest;
|
|
||||||
delete mDictionaryStructureWithBufferPolicy;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession,
|
int Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession,
|
||||||
int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,
|
int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,
|
||||||
int inputSize, int *prevWordCodePoints, int prevWordLength, int commitPoint,
|
int inputSize, int *prevWordCodePoints, int prevWordLength, int commitPoint,
|
||||||
|
@ -60,7 +51,7 @@ int Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession
|
||||||
if (suggestOptions->isGesture()) {
|
if (suggestOptions->isGesture()) {
|
||||||
DicTraverseSession::initSessionInstance(
|
DicTraverseSession::initSessionInstance(
|
||||||
traverseSession, this, prevWordCodePoints, prevWordLength, suggestOptions);
|
traverseSession, this, prevWordCodePoints, prevWordLength, suggestOptions);
|
||||||
result = mGestureSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
|
result = mGestureSuggest.get()->getSuggestions(proximityInfo, traverseSession, xcoordinates,
|
||||||
ycoordinates, times, pointerIds, inputCodePoints, inputSize, commitPoint, outWords,
|
ycoordinates, times, pointerIds, inputCodePoints, inputSize, commitPoint, outWords,
|
||||||
frequencies, spaceIndices, outputTypes, outputAutoCommitFirstWordConfidence);
|
frequencies, spaceIndices, outputTypes, outputAutoCommitFirstWordConfidence);
|
||||||
if (DEBUG_DICT) {
|
if (DEBUG_DICT) {
|
||||||
|
@ -70,7 +61,7 @@ int Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession
|
||||||
} else {
|
} else {
|
||||||
DicTraverseSession::initSessionInstance(
|
DicTraverseSession::initSessionInstance(
|
||||||
traverseSession, this, prevWordCodePoints, prevWordLength, suggestOptions);
|
traverseSession, this, prevWordCodePoints, prevWordLength, suggestOptions);
|
||||||
result = mTypingSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
|
result = mTypingSuggest.get()->getSuggestions(proximityInfo, traverseSession, xcoordinates,
|
||||||
ycoordinates, times, pointerIds, inputCodePoints, inputSize, commitPoint,
|
ycoordinates, times, pointerIds, inputCodePoints, inputSize, commitPoint,
|
||||||
outWords, frequencies, spaceIndices, outputTypes,
|
outWords, frequencies, spaceIndices, outputTypes,
|
||||||
outputAutoCommitFirstWordConfidence);
|
outputAutoCommitFirstWordConfidence);
|
||||||
|
@ -84,7 +75,8 @@ int Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession
|
||||||
int Dictionary::getBigrams(const int *word, int length, int *outWords, int *frequencies,
|
int Dictionary::getBigrams(const int *word, int length, int *outWords, int *frequencies,
|
||||||
int *outputTypes) const {
|
int *outputTypes) const {
|
||||||
if (length <= 0) return 0;
|
if (length <= 0) return 0;
|
||||||
return mBigramDictionary->getPredictions(word, length, outWords, frequencies, outputTypes);
|
return mBigramDictionary.get()->getPredictions(word, length, outWords, frequencies,
|
||||||
|
outputTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Dictionary::getProbability(const int *word, int length) const {
|
int Dictionary::getProbability(const int *word, int length) const {
|
||||||
|
@ -98,39 +90,39 @@ int Dictionary::getProbability(const int *word, int length) const {
|
||||||
|
|
||||||
int Dictionary::getBigramProbability(const int *word0, int length0, const int *word1,
|
int Dictionary::getBigramProbability(const int *word0, int length0, const int *word1,
|
||||||
int length1) const {
|
int length1) const {
|
||||||
return mBigramDictionary->getBigramProbability(word0, length0, word1, length1);
|
return mBigramDictionary.get()->getBigramProbability(word0, length0, word1, length1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dictionary::addUnigramWord(const int *const word, const int length, const int probability) {
|
void Dictionary::addUnigramWord(const int *const word, const int length, const int probability) {
|
||||||
mDictionaryStructureWithBufferPolicy->addUnigramWord(word, length, probability);
|
mDictionaryStructureWithBufferPolicy.get()->addUnigramWord(word, length, probability);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dictionary::addBigramWords(const int *const word0, const int length0, const int *const word1,
|
void Dictionary::addBigramWords(const int *const word0, const int length0, const int *const word1,
|
||||||
const int length1, const int probability) {
|
const int length1, const int probability) {
|
||||||
mDictionaryStructureWithBufferPolicy->addBigramWords(word0, length0, word1, length1,
|
mDictionaryStructureWithBufferPolicy.get()->addBigramWords(word0, length0, word1, length1,
|
||||||
probability);
|
probability);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dictionary::removeBigramWords(const int *const word0, const int length0,
|
void Dictionary::removeBigramWords(const int *const word0, const int length0,
|
||||||
const int *const word1, const int length1) {
|
const int *const word1, const int length1) {
|
||||||
mDictionaryStructureWithBufferPolicy->removeBigramWords(word0, length0, word1, length1);
|
mDictionaryStructureWithBufferPolicy.get()->removeBigramWords(word0, length0, word1, length1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dictionary::flush(const char *const filePath) {
|
void Dictionary::flush(const char *const filePath) {
|
||||||
mDictionaryStructureWithBufferPolicy->flush(filePath);
|
mDictionaryStructureWithBufferPolicy.get()->flush(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dictionary::flushWithGC(const char *const filePath) {
|
void Dictionary::flushWithGC(const char *const filePath) {
|
||||||
mDictionaryStructureWithBufferPolicy->flushWithGC(filePath);
|
mDictionaryStructureWithBufferPolicy.get()->flushWithGC(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Dictionary::needsToRunGC(const bool mindsBlockByGC) {
|
bool Dictionary::needsToRunGC(const bool mindsBlockByGC) {
|
||||||
return mDictionaryStructureWithBufferPolicy->needsToRunGC(mindsBlockByGC);
|
return mDictionaryStructureWithBufferPolicy.get()->needsToRunGC(mindsBlockByGC);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dictionary::getProperty(const char *const query, char *const outResult,
|
void Dictionary::getProperty(const char *const query, char *const outResult,
|
||||||
const int maxResultLength) {
|
const int maxResultLength) {
|
||||||
return mDictionaryStructureWithBufferPolicy->getProperty(query, outResult, maxResultLength);
|
return mDictionaryStructureWithBufferPolicy.get()->getProperty(query, outResult, maxResultLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dictionary::logDictionaryInfo(JNIEnv *const env) const {
|
void Dictionary::logDictionaryInfo(JNIEnv *const env) const {
|
||||||
|
|
|
@ -21,14 +21,16 @@
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
|
#include "suggest/core/dictionary/bigram_dictionary.h"
|
||||||
|
#include "suggest/core/policy/dictionary_structure_with_buffer_policy.h"
|
||||||
|
#include "suggest/core/suggest_interface.h"
|
||||||
|
#include "utils/exclusive_ownership_pointer.h"
|
||||||
|
|
||||||
namespace latinime {
|
namespace latinime {
|
||||||
|
|
||||||
class BigramDictionary;
|
|
||||||
class DictionaryStructureWithBufferPolicy;
|
class DictionaryStructureWithBufferPolicy;
|
||||||
class DicTraverseSession;
|
class DicTraverseSession;
|
||||||
class ProximityInfo;
|
class ProximityInfo;
|
||||||
class SuggestInterface;
|
|
||||||
class SuggestOptions;
|
class SuggestOptions;
|
||||||
|
|
||||||
class Dictionary {
|
class Dictionary {
|
||||||
|
@ -53,8 +55,8 @@ class Dictionary {
|
||||||
static const int KIND_FLAG_POSSIBLY_OFFENSIVE = 0x80000000;
|
static const int KIND_FLAG_POSSIBLY_OFFENSIVE = 0x80000000;
|
||||||
static const int KIND_FLAG_EXACT_MATCH = 0x40000000;
|
static const int KIND_FLAG_EXACT_MATCH = 0x40000000;
|
||||||
|
|
||||||
Dictionary(JNIEnv *env,
|
Dictionary(JNIEnv *env, const DictionaryStructureWithBufferPolicy::StructurePoilcyPtr
|
||||||
DictionaryStructureWithBufferPolicy *const dictionaryStructureWithBufferPoilcy);
|
&dictionaryStructureWithBufferPoilcy);
|
||||||
|
|
||||||
int getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession,
|
int getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession,
|
||||||
int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,
|
int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,
|
||||||
|
@ -87,20 +89,22 @@ class Dictionary {
|
||||||
const int maxResultLength);
|
const int maxResultLength);
|
||||||
|
|
||||||
const DictionaryStructureWithBufferPolicy *getDictionaryStructurePolicy() const {
|
const DictionaryStructureWithBufferPolicy *getDictionaryStructurePolicy() const {
|
||||||
return mDictionaryStructureWithBufferPolicy;
|
return mDictionaryStructureWithBufferPolicy.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Dictionary();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(Dictionary);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(Dictionary);
|
||||||
|
|
||||||
|
typedef ExclusiveOwnershipPointer<BigramDictionary> BigramDictionaryPtr;
|
||||||
|
typedef ExclusiveOwnershipPointer<SuggestInterface> SuggestInterfacePtr;
|
||||||
|
|
||||||
static const int HEADER_ATTRIBUTE_BUFFER_SIZE;
|
static const int HEADER_ATTRIBUTE_BUFFER_SIZE;
|
||||||
|
|
||||||
DictionaryStructureWithBufferPolicy *const mDictionaryStructureWithBufferPolicy;
|
const DictionaryStructureWithBufferPolicy::StructurePoilcyPtr
|
||||||
const BigramDictionary *const mBigramDictionary;
|
mDictionaryStructureWithBufferPolicy;
|
||||||
const SuggestInterface *const mGestureSuggest;
|
const BigramDictionaryPtr mBigramDictionary;
|
||||||
const SuggestInterface *const mTypingSuggest;
|
const SuggestInterfacePtr mGestureSuggest;
|
||||||
|
const SuggestInterfacePtr mTypingSuggest;
|
||||||
|
|
||||||
void logDictionaryInfo(JNIEnv *const env) const;
|
void logDictionaryInfo(JNIEnv *const env) const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#define LATINIME_DICTIONARY_STRUCTURE_POLICY_H
|
#define LATINIME_DICTIONARY_STRUCTURE_POLICY_H
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
#include "utils/exclusive_ownership_pointer.h"
|
||||||
|
|
||||||
namespace latinime {
|
namespace latinime {
|
||||||
|
|
||||||
|
@ -33,6 +34,8 @@ class DictionaryShortcutsStructurePolicy;
|
||||||
*/
|
*/
|
||||||
class DictionaryStructureWithBufferPolicy {
|
class DictionaryStructureWithBufferPolicy {
|
||||||
public:
|
public:
|
||||||
|
typedef ExclusiveOwnershipPointer<DictionaryStructureWithBufferPolicy> StructurePoilcyPtr;
|
||||||
|
|
||||||
virtual ~DictionaryStructureWithBufferPolicy() {}
|
virtual ~DictionaryStructureWithBufferPolicy() {}
|
||||||
|
|
||||||
virtual int getRootPosition() const = 0;
|
virtual int getRootPosition() const = 0;
|
||||||
|
|
|
@ -26,30 +26,32 @@
|
||||||
|
|
||||||
namespace latinime {
|
namespace latinime {
|
||||||
|
|
||||||
/* static */ DictionaryStructureWithBufferPolicy *DictionaryStructureWithBufferPolicyFactory
|
/* static */ DictionaryStructureWithBufferPolicy::StructurePoilcyPtr
|
||||||
::newDictionaryStructureWithBufferPolicy(const char *const path, const int bufOffset,
|
DictionaryStructureWithBufferPolicyFactory
|
||||||
const int size, const bool isUpdatable) {
|
::newDictionaryStructureWithBufferPolicy(const char *const path,
|
||||||
// Allocated buffer in MmapedBuffer::openBuffer() will be freed in the destructor of
|
const int bufOffset, const int size, const bool isUpdatable) {
|
||||||
// impl classes of DictionaryStructureWithBufferPolicy.
|
// Allocated buffer in MmapedBuffer::newBuffer() will be freed in the destructor of
|
||||||
const MmappedBuffer *const mmapedBuffer = MmappedBuffer::openBuffer(path, bufOffset, size,
|
// MmappedBufferWrapper if the instance has the responsibility.
|
||||||
isUpdatable);
|
MmappedBuffer::MmappedBufferPtr mmappedBuffer(MmappedBuffer::openBuffer(path, bufOffset, size,
|
||||||
if (!mmapedBuffer) {
|
isUpdatable));
|
||||||
return 0;
|
if (!mmappedBuffer.get()) {
|
||||||
|
return DictionaryStructureWithBufferPolicy::StructurePoilcyPtr(0);
|
||||||
}
|
}
|
||||||
switch (FormatUtils::detectFormatVersion(mmapedBuffer->getBuffer(),
|
switch (FormatUtils::detectFormatVersion(mmappedBuffer.get()->getBuffer(),
|
||||||
mmapedBuffer->getBufferSize())) {
|
mmappedBuffer.get()->getBufferSize())) {
|
||||||
case FormatUtils::VERSION_2:
|
case FormatUtils::VERSION_2:
|
||||||
return new PatriciaTriePolicy(mmapedBuffer);
|
return DictionaryStructureWithBufferPolicy::StructurePoilcyPtr(
|
||||||
|
new PatriciaTriePolicy(mmappedBuffer));
|
||||||
case FormatUtils::VERSION_3:
|
case FormatUtils::VERSION_3:
|
||||||
return new DynamicPatriciaTriePolicy(mmapedBuffer);
|
return DictionaryStructureWithBufferPolicy::StructurePoilcyPtr(
|
||||||
|
new DynamicPatriciaTriePolicy(mmappedBuffer));
|
||||||
case FormatUtils::VERSION_4:
|
case FormatUtils::VERSION_4:
|
||||||
// TODO: Support version 4 dictionary format.
|
// TODO: Support version 4 dictionary format.
|
||||||
// Fall through.
|
// Fall through.
|
||||||
default:
|
default:
|
||||||
AKLOGE("DICT: dictionary format is unknown, bad magic number");
|
AKLOGE("DICT: dictionary format is unknown, bad magic number");
|
||||||
delete mmapedBuffer;
|
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
return 0;
|
return DictionaryStructureWithBufferPolicy::StructurePoilcyPtr(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,13 +21,15 @@
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "suggest/core/policy/dictionary_structure_with_buffer_policy.h"
|
#include "suggest/core/policy/dictionary_structure_with_buffer_policy.h"
|
||||||
|
#include "utils/exclusive_ownership_pointer.h"
|
||||||
|
|
||||||
namespace latinime {
|
namespace latinime {
|
||||||
|
|
||||||
class DictionaryStructureWithBufferPolicyFactory {
|
class DictionaryStructureWithBufferPolicyFactory {
|
||||||
public:
|
public:
|
||||||
static DictionaryStructureWithBufferPolicy *newDictionaryStructureWithBufferPolicy(
|
static DictionaryStructureWithBufferPolicy::StructurePoilcyPtr
|
||||||
const char *const path, const int bufOffset, const int size, const bool isUpdatable);
|
newDictionaryStructureWithBufferPolicy(const char *const path, const int bufOffset,
|
||||||
|
const int size, const bool isUpdatable);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(DictionaryStructureWithBufferPolicyFactory);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(DictionaryStructureWithBufferPolicyFactory);
|
||||||
|
|
|
@ -34,16 +34,14 @@ class DicNodeVector;
|
||||||
|
|
||||||
class PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
|
class PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
|
||||||
public:
|
public:
|
||||||
PatriciaTriePolicy(const MmappedBuffer *const buffer)
|
PatriciaTriePolicy(const MmappedBuffer::MmappedBufferPtr &mmappedBuffer)
|
||||||
: mBuffer(buffer), mHeaderPolicy(mBuffer->getBuffer(), FormatUtils::VERSION_2),
|
: mMmappedBuffer(mmappedBuffer),
|
||||||
mDictRoot(mBuffer->getBuffer() + mHeaderPolicy.getSize()),
|
mHeaderPolicy(mMmappedBuffer.get()->getBuffer(), FormatUtils::VERSION_2),
|
||||||
mDictBufferSize(mBuffer->getBufferSize() - mHeaderPolicy.getSize()),
|
mDictRoot(mMmappedBuffer.get()->getBuffer() + mHeaderPolicy.getSize()),
|
||||||
|
mDictBufferSize(mMmappedBuffer.get()->getBufferSize()
|
||||||
|
- mHeaderPolicy.getSize()),
|
||||||
mBigramListPolicy(mDictRoot), mShortcutListPolicy(mDictRoot) {}
|
mBigramListPolicy(mDictRoot), mShortcutListPolicy(mDictRoot) {}
|
||||||
|
|
||||||
~PatriciaTriePolicy() {
|
|
||||||
delete mBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
AK_FORCE_INLINE int getRootPosition() const {
|
AK_FORCE_INLINE int getRootPosition() const {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -125,7 +123,7 @@ class PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
|
||||||
private:
|
private:
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(PatriciaTriePolicy);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(PatriciaTriePolicy);
|
||||||
|
|
||||||
const MmappedBuffer *const mBuffer;
|
const MmappedBuffer::MmappedBufferPtr mMmappedBuffer;
|
||||||
const HeaderPolicy mHeaderPolicy;
|
const HeaderPolicy mHeaderPolicy;
|
||||||
const uint8_t *const mDictRoot;
|
const uint8_t *const mDictRoot;
|
||||||
const int mDictBufferSize;
|
const int mDictBufferSize;
|
||||||
|
|
|
@ -216,7 +216,7 @@ int DynamicPatriciaTriePolicy::getBigramsPositionOfPtNode(const int ptNodePos) c
|
||||||
|
|
||||||
bool DynamicPatriciaTriePolicy::addUnigramWord(const int *const word, const int length,
|
bool DynamicPatriciaTriePolicy::addUnigramWord(const int *const word, const int length,
|
||||||
const int probability) {
|
const int probability) {
|
||||||
if (!mBuffer->isUpdatable()) {
|
if (!mMmappedBuffer.get()->isUpdatable()) {
|
||||||
AKLOGI("Warning: addUnigramWord() is called for non-updatable dictionary.");
|
AKLOGI("Warning: addUnigramWord() is called for non-updatable dictionary.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -244,7 +244,7 @@ bool DynamicPatriciaTriePolicy::addUnigramWord(const int *const word, const int
|
||||||
|
|
||||||
bool DynamicPatriciaTriePolicy::addBigramWords(const int *const word0, const int length0,
|
bool DynamicPatriciaTriePolicy::addBigramWords(const int *const word0, const int length0,
|
||||||
const int *const word1, const int length1, const int probability) {
|
const int *const word1, const int length1, const int probability) {
|
||||||
if (!mBuffer->isUpdatable()) {
|
if (!mMmappedBuffer.get()->isUpdatable()) {
|
||||||
AKLOGI("Warning: addBigramWords() is called for non-updatable dictionary.");
|
AKLOGI("Warning: addBigramWords() is called for non-updatable dictionary.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -278,7 +278,7 @@ bool DynamicPatriciaTriePolicy::addBigramWords(const int *const word0, const int
|
||||||
|
|
||||||
bool DynamicPatriciaTriePolicy::removeBigramWords(const int *const word0, const int length0,
|
bool DynamicPatriciaTriePolicy::removeBigramWords(const int *const word0, const int length0,
|
||||||
const int *const word1, const int length1) {
|
const int *const word1, const int length1) {
|
||||||
if (!mBuffer->isUpdatable()) {
|
if (!mMmappedBuffer.get()->isUpdatable()) {
|
||||||
AKLOGI("Warning: removeBigramWords() is called for non-updatable dictionary.");
|
AKLOGI("Warning: removeBigramWords() is called for non-updatable dictionary.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -308,7 +308,7 @@ bool DynamicPatriciaTriePolicy::removeBigramWords(const int *const word0, const
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynamicPatriciaTriePolicy::flush(const char *const filePath) {
|
void DynamicPatriciaTriePolicy::flush(const char *const filePath) {
|
||||||
if (!mBuffer->isUpdatable()) {
|
if (!mMmappedBuffer.get()->isUpdatable()) {
|
||||||
AKLOGI("Warning: flush() is called for non-updatable dictionary.");
|
AKLOGI("Warning: flush() is called for non-updatable dictionary.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -318,7 +318,7 @@ void DynamicPatriciaTriePolicy::flush(const char *const filePath) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynamicPatriciaTriePolicy::flushWithGC(const char *const filePath) {
|
void DynamicPatriciaTriePolicy::flushWithGC(const char *const filePath) {
|
||||||
if (!mBuffer->isUpdatable()) {
|
if (!mMmappedBuffer.get()->isUpdatable()) {
|
||||||
AKLOGI("Warning: flushWithGC() is called for non-updatable dictionary.");
|
AKLOGI("Warning: flushWithGC() is called for non-updatable dictionary.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -334,7 +334,7 @@ void DynamicPatriciaTriePolicy::flushWithGC(const char *const filePath) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DynamicPatriciaTriePolicy::needsToRunGC(const bool mindsBlockByGC) const {
|
bool DynamicPatriciaTriePolicy::needsToRunGC(const bool mindsBlockByGC) const {
|
||||||
if (!mBuffer->isUpdatable()) {
|
if (!mMmappedBuffer.get()->isUpdatable()) {
|
||||||
AKLOGI("Warning: needsToRunGC() is called for non-updatable dictionary.");
|
AKLOGI("Warning: needsToRunGC() is called for non-updatable dictionary.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,21 +33,20 @@ class DicNodeVector;
|
||||||
|
|
||||||
class DynamicPatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
|
class DynamicPatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
|
||||||
public:
|
public:
|
||||||
DynamicPatriciaTriePolicy(const MmappedBuffer *const buffer)
|
DynamicPatriciaTriePolicy(const MmappedBuffer::MmappedBufferPtr &mmappedBuffer)
|
||||||
: mBuffer(buffer), mHeaderPolicy(mBuffer->getBuffer(), FormatUtils::VERSION_3),
|
: mMmappedBuffer(mmappedBuffer),
|
||||||
mBufferWithExtendableBuffer(mBuffer->getBuffer() + mHeaderPolicy.getSize(),
|
mHeaderPolicy(mMmappedBuffer.get()->getBuffer(), FormatUtils::VERSION_3),
|
||||||
mBuffer->getBufferSize() - mHeaderPolicy.getSize(),
|
mBufferWithExtendableBuffer(mMmappedBuffer.get()->getBuffer()
|
||||||
BufferWithExtendableBuffer::DEFAULT_MAX_ADDITIONAL_BUFFER_SIZE),
|
+ mHeaderPolicy.getSize(), mMmappedBuffer.get()->getBufferSize()
|
||||||
|
- mHeaderPolicy.getSize(),
|
||||||
|
BufferWithExtendableBuffer
|
||||||
|
::DEFAULT_MAX_ADDITIONAL_BUFFER_SIZE),
|
||||||
mShortcutListPolicy(&mBufferWithExtendableBuffer),
|
mShortcutListPolicy(&mBufferWithExtendableBuffer),
|
||||||
mBigramListPolicy(&mHeaderPolicy, &mBufferWithExtendableBuffer, &mShortcutListPolicy,
|
mBigramListPolicy(&mHeaderPolicy, &mBufferWithExtendableBuffer, &mShortcutListPolicy,
|
||||||
mHeaderPolicy.isDecayingDict()),
|
mHeaderPolicy.isDecayingDict()),
|
||||||
mUnigramCount(mHeaderPolicy.getUnigramCount()),
|
mUnigramCount(mHeaderPolicy.getUnigramCount()),
|
||||||
mBigramCount(mHeaderPolicy.getBigramCount()), mNeedsToDecayForTesting(false) {}
|
mBigramCount(mHeaderPolicy.getBigramCount()), mNeedsToDecayForTesting(false) {}
|
||||||
|
|
||||||
~DynamicPatriciaTriePolicy() {
|
|
||||||
delete mBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
AK_FORCE_INLINE int getRootPosition() const {
|
AK_FORCE_INLINE int getRootPosition() const {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -110,7 +109,7 @@ class DynamicPatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
|
||||||
static const int MAX_DICT_EXTENDED_REGION_SIZE;
|
static const int MAX_DICT_EXTENDED_REGION_SIZE;
|
||||||
static const int MIN_DICT_SIZE_TO_REFUSE_DYNAMIC_OPERATIONS;
|
static const int MIN_DICT_SIZE_TO_REFUSE_DYNAMIC_OPERATIONS;
|
||||||
|
|
||||||
const MmappedBuffer *const mBuffer;
|
const MmappedBuffer::MmappedBufferPtr mMmappedBuffer;
|
||||||
const HeaderPolicy mHeaderPolicy;
|
const HeaderPolicy mHeaderPolicy;
|
||||||
BufferWithExtendableBuffer mBufferWithExtendableBuffer;
|
BufferWithExtendableBuffer mBufferWithExtendableBuffer;
|
||||||
DynamicShortcutListPolicy mShortcutListPolicy;
|
DynamicShortcutListPolicy mShortcutListPolicy;
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2013, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "suggest/policyimpl/dictionary/utils/mmapped_buffer.h"
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
|
#include <climits>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "suggest/policyimpl/dictionary/utils/file_utils.h"
|
||||||
|
|
||||||
|
namespace latinime {
|
||||||
|
|
||||||
|
/* static */ MmappedBuffer::MmappedBufferPtr MmappedBuffer::openBuffer(
|
||||||
|
const char *const path, const int bufferOffset, const int bufferSize,
|
||||||
|
const bool isUpdatable) {
|
||||||
|
const int openMode = isUpdatable ? O_RDWR : O_RDONLY;
|
||||||
|
const int mmapFd = open(path, openMode);
|
||||||
|
if (mmapFd < 0) {
|
||||||
|
AKLOGE("DICT: Can't open the source. path=%s errno=%d", path, errno);
|
||||||
|
return MmappedBufferPtr(0);
|
||||||
|
}
|
||||||
|
const int pagesize = getpagesize();
|
||||||
|
const int offset = bufferOffset % pagesize;
|
||||||
|
int alignedOffset = bufferOffset - offset;
|
||||||
|
int alignedSize = bufferSize + offset;
|
||||||
|
const int protMode = isUpdatable ? PROT_READ | PROT_WRITE : PROT_READ;
|
||||||
|
void *const mmappedBuffer = mmap(0, alignedSize, protMode, MAP_PRIVATE, mmapFd,
|
||||||
|
alignedOffset);
|
||||||
|
if (mmappedBuffer == MAP_FAILED) {
|
||||||
|
AKLOGE("DICT: Can't mmap dictionary. errno=%d", errno);
|
||||||
|
close(mmapFd);
|
||||||
|
return MmappedBufferPtr(0);
|
||||||
|
}
|
||||||
|
uint8_t *const buffer = static_cast<uint8_t *>(mmappedBuffer) + offset;
|
||||||
|
if (!buffer) {
|
||||||
|
AKLOGE("DICT: buffer is null");
|
||||||
|
close(mmapFd);
|
||||||
|
return MmappedBufferPtr(0);
|
||||||
|
}
|
||||||
|
return MmappedBufferPtr(new MmappedBuffer(buffer, bufferSize, mmappedBuffer, alignedSize,
|
||||||
|
mmapFd, isUpdatable));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ MmappedBuffer::MmappedBufferPtr MmappedBuffer::openBuffer(
|
||||||
|
const char *const path, const bool isUpdatable) {
|
||||||
|
const int fileSize = FileUtils::getFileSize(path);
|
||||||
|
if (fileSize == -1) {
|
||||||
|
return MmappedBufferPtr(0);
|
||||||
|
} else if (fileSize == 0) {
|
||||||
|
return MmappedBufferPtr(new MmappedBuffer(isUpdatable));
|
||||||
|
} else {
|
||||||
|
return openBuffer(path, 0 /* bufferOffset */, fileSize, isUpdatable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ MmappedBuffer::MmappedBufferPtr MmappedBuffer::openBuffer(
|
||||||
|
const char *const dirPath, const char *const fileName, const bool isUpdatable) {
|
||||||
|
const int filePathBufferSize = PATH_MAX + 1 /* terminator */;
|
||||||
|
char filePath[filePathBufferSize];
|
||||||
|
const int filePathLength = snprintf(filePath, filePathBufferSize, "%s%s", dirPath,
|
||||||
|
fileName);
|
||||||
|
if (filePathLength >= filePathBufferSize) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return openBuffer(filePath, isUpdatable);
|
||||||
|
}
|
||||||
|
|
||||||
|
MmappedBuffer::~MmappedBuffer() {
|
||||||
|
if (mAlignedSize == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int ret = munmap(mMmappedBuffer, mAlignedSize);
|
||||||
|
if (ret != 0) {
|
||||||
|
AKLOGE("DICT: Failure in munmap. ret=%d errno=%d", ret, errno);
|
||||||
|
}
|
||||||
|
ret = close(mMmapFd);
|
||||||
|
if (ret != 0) {
|
||||||
|
AKLOGE("DICT: Failure in close. ret=%d errno=%d", ret, errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace latinime
|
|
@ -17,88 +17,27 @@
|
||||||
#ifndef LATINIME_MMAPPED_BUFFER_H
|
#ifndef LATINIME_MMAPPED_BUFFER_H
|
||||||
#define LATINIME_MMAPPED_BUFFER_H
|
#define LATINIME_MMAPPED_BUFFER_H
|
||||||
|
|
||||||
#include <cerrno>
|
|
||||||
#include <climits>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "suggest/policyimpl/dictionary/utils/file_utils.h"
|
#include "utils/exclusive_ownership_pointer.h"
|
||||||
|
|
||||||
namespace latinime {
|
namespace latinime {
|
||||||
|
|
||||||
class MmappedBuffer {
|
class MmappedBuffer {
|
||||||
public:
|
public:
|
||||||
static MmappedBuffer *openBuffer(const char *const path, const int bufferOffset,
|
typedef ExclusiveOwnershipPointer<MmappedBuffer> MmappedBufferPtr;
|
||||||
const int bufferSize, const bool isUpdatable) {
|
|
||||||
const int openMode = isUpdatable ? O_RDWR : O_RDONLY;
|
static MmappedBufferPtr openBuffer(const char *const path,
|
||||||
const int mmapFd = open(path, openMode);
|
const int bufferOffset, const int bufferSize, const bool isUpdatable);
|
||||||
if (mmapFd < 0) {
|
|
||||||
AKLOGE("DICT: Can't open the source. path=%s errno=%d", path, errno);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
const int pagesize = getpagesize();
|
|
||||||
const int offset = bufferOffset % pagesize;
|
|
||||||
int alignedOffset = bufferOffset - offset;
|
|
||||||
int alignedSize = bufferSize + offset;
|
|
||||||
const int protMode = isUpdatable ? PROT_READ | PROT_WRITE : PROT_READ;
|
|
||||||
void *const mmappedBuffer = mmap(0, alignedSize, protMode, MAP_PRIVATE, mmapFd,
|
|
||||||
alignedOffset);
|
|
||||||
if (mmappedBuffer == MAP_FAILED) {
|
|
||||||
AKLOGE("DICT: Can't mmap dictionary. errno=%d", errno);
|
|
||||||
close(mmapFd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
uint8_t *const buffer = static_cast<uint8_t *>(mmappedBuffer) + offset;
|
|
||||||
if (!buffer) {
|
|
||||||
AKLOGE("DICT: buffer is null");
|
|
||||||
close(mmapFd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return new MmappedBuffer(buffer, bufferSize, mmappedBuffer, alignedSize, mmapFd,
|
|
||||||
isUpdatable);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mmap entire file.
|
// Mmap entire file.
|
||||||
static MmappedBuffer *openBuffer(const char *const path, const bool isUpdatable) {
|
static MmappedBufferPtr openBuffer(const char *const path, const bool isUpdatable);
|
||||||
const int fileSize = FileUtils::getFileSize(path);
|
|
||||||
if (fileSize == -1) {
|
|
||||||
return 0;
|
|
||||||
} else if (fileSize == 0) {
|
|
||||||
return new MmappedBuffer(isUpdatable);
|
|
||||||
} else {
|
|
||||||
return openBuffer(path, 0 /* bufferOffset */, fileSize, isUpdatable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static MmappedBuffer *openBuffer(const char *const dirPath, const char *const fileName,
|
static MmappedBufferPtr openBuffer(const char *const dirPath, const char *const fileName,
|
||||||
const bool isUpdatable) {
|
const bool isUpdatable);
|
||||||
const int filePathBufferSize = PATH_MAX + 1 /* terminator */;
|
|
||||||
char filePath[filePathBufferSize];
|
|
||||||
const int filePathLength = snprintf(filePath, filePathBufferSize, "%s%s", dirPath,
|
|
||||||
fileName);
|
|
||||||
if (filePathLength >= filePathBufferSize) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return openBuffer(filePath, isUpdatable);
|
|
||||||
}
|
|
||||||
|
|
||||||
~MmappedBuffer() {
|
~MmappedBuffer();
|
||||||
if (mAlignedSize == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int ret = munmap(mMmappedBuffer, mAlignedSize);
|
|
||||||
if (ret != 0) {
|
|
||||||
AKLOGE("DICT: Failure in munmap. ret=%d errno=%d", ret, errno);
|
|
||||||
}
|
|
||||||
ret = close(mMmapFd);
|
|
||||||
if (ret != 0) {
|
|
||||||
AKLOGE("DICT: Failure in close. ret=%d errno=%d", ret, errno);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AK_FORCE_INLINE uint8_t *getBuffer() const {
|
AK_FORCE_INLINE uint8_t *getBuffer() const {
|
||||||
return mBuffer;
|
return mBuffer;
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2013, 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_EXCLUSIVE_OWNERSHIP_POINTER_H
|
||||||
|
#define LATINIME_EXCLUSIVE_OWNERSHIP_POINTER_H
|
||||||
|
|
||||||
|
#include "defines.h"
|
||||||
|
|
||||||
|
namespace latinime {
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class ExclusiveOwnershipPointer {
|
||||||
|
public:
|
||||||
|
// This instance become an owner of the raw pointer.
|
||||||
|
ExclusiveOwnershipPointer(T *const rawPointer)
|
||||||
|
: mPointer(rawPointer),
|
||||||
|
mSharedOwnerPtr(new (ExclusiveOwnershipPointer<T> *)(this)) {}
|
||||||
|
|
||||||
|
// Move the ownership.
|
||||||
|
ExclusiveOwnershipPointer(const ExclusiveOwnershipPointer<T> &pointer)
|
||||||
|
: mPointer(pointer.mPointer), mSharedOwnerPtr(pointer.mSharedOwnerPtr) {
|
||||||
|
transferOwnership(&pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
~ExclusiveOwnershipPointer() {
|
||||||
|
deletePointersIfHavingOwnership();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the ownership.
|
||||||
|
ExclusiveOwnershipPointer<T> &operator=(const ExclusiveOwnershipPointer<T> &pointer) {
|
||||||
|
// Delete pointers when this is an owner of another pointer.
|
||||||
|
deletePointersIfHavingOwnership();
|
||||||
|
mPointer = pointer.mPointer;
|
||||||
|
mSharedOwnerPtr = pointer.mSharedOwnerPtr;
|
||||||
|
transferOwnership(pointer);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
T *get() const {
|
||||||
|
return mPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// This class allows to copy and assign and ensures only one instance has the ownership of the
|
||||||
|
// managed pointer.
|
||||||
|
|
||||||
|
ExclusiveOwnershipPointer() : mPointer(0), mSharedOwnerPtr(0) {}
|
||||||
|
|
||||||
|
void transferOwnership(const ExclusiveOwnershipPointer<T> *const src) {
|
||||||
|
if (*mSharedOwnerPtr != src) {
|
||||||
|
AKLOGE("Failed to transfer the ownership because src is not the current owner."
|
||||||
|
"src: %p, owner: %p", src, *mSharedOwnerPtr);
|
||||||
|
ASSERT(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Transfer the ownership from src to this instance.
|
||||||
|
*mSharedOwnerPtr = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deletePointersIfHavingOwnership() {
|
||||||
|
if (mSharedOwnerPtr && *mSharedOwnerPtr == this) {
|
||||||
|
if (mPointer) {
|
||||||
|
if (DEBUG_DICT) {
|
||||||
|
AKLOGI("Releasing pointer: %p", mPointer);
|
||||||
|
}
|
||||||
|
delete mPointer;
|
||||||
|
}
|
||||||
|
delete mSharedOwnerPtr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T *mPointer;
|
||||||
|
// mSharedOwnerPtr points a shared memory space where the instance which has the ownership is
|
||||||
|
// stored.
|
||||||
|
ExclusiveOwnershipPointer<T> **mSharedOwnerPtr;
|
||||||
|
};
|
||||||
|
} // namespace latinime
|
||||||
|
#endif /* LATINIME_EXCLUSIVE_OWNERSHIP_POINTER_H */
|
Loading…
Reference in New Issue