Re-call getBuffer after writing in bigram/shortcut policy.

Bug: 6669677
Change-Id: I35dc290aa9582e019681b8aae49db3f8d37c90d4
main
Keisuke Kuroyanagi 2013-09-10 12:12:42 +09:00
parent e7ac900340
commit c987120cbc
4 changed files with 24 additions and 12 deletions

View File

@ -20,12 +20,13 @@ namespace latinime {
bool DynamicBigramListPolicy::copyAllBigrams(int *const fromPos, int *const toPos) { bool DynamicBigramListPolicy::copyAllBigrams(int *const fromPos, int *const toPos) {
const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(*fromPos); const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(*fromPos);
const uint8_t *const buffer = mBuffer->getBuffer(usesAdditionalBuffer);
if (usesAdditionalBuffer) { if (usesAdditionalBuffer) {
*fromPos -= mBuffer->getOriginalBufferSize(); *fromPos -= mBuffer->getOriginalBufferSize();
} }
BigramListReadWriteUtils::BigramFlags flags; BigramListReadWriteUtils::BigramFlags flags;
do { do {
// The buffer address can be changed after calling buffer writing methods.
const uint8_t *const buffer = mBuffer->getBuffer(usesAdditionalBuffer);
flags = BigramListReadWriteUtils::getFlagsAndForwardPointer(buffer, fromPos); flags = BigramListReadWriteUtils::getFlagsAndForwardPointer(buffer, fromPos);
int bigramPos = BigramListReadWriteUtils::getBigramAddressAndForwardPointer( int bigramPos = BigramListReadWriteUtils::getBigramAddressAndForwardPointer(
buffer, flags, fromPos); buffer, flags, fromPos);
@ -63,7 +64,6 @@ bool DynamicBigramListPolicy::copyAllBigrams(int *const fromPos, int *const toPo
bool DynamicBigramListPolicy::addBigramEntry(const int bigramPos, const int probability, bool DynamicBigramListPolicy::addBigramEntry(const int bigramPos, const int probability,
int *const pos) { int *const pos) {
const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(*pos); const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(*pos);
const uint8_t *const buffer = mBuffer->getBuffer(usesAdditionalBuffer);
if (usesAdditionalBuffer) { if (usesAdditionalBuffer) {
*pos -= mBuffer->getOriginalBufferSize(); *pos -= mBuffer->getOriginalBufferSize();
} }
@ -73,6 +73,8 @@ bool DynamicBigramListPolicy::addBigramEntry(const int bigramPos, const int prob
if (usesAdditionalBuffer) { if (usesAdditionalBuffer) {
entryPos += mBuffer->getOriginalBufferSize(); entryPos += mBuffer->getOriginalBufferSize();
} }
// The buffer address can be changed after calling buffer writing methods.
const uint8_t *const buffer = mBuffer->getBuffer(usesAdditionalBuffer);
flags = BigramListReadWriteUtils::getFlagsAndForwardPointer(buffer, pos); flags = BigramListReadWriteUtils::getFlagsAndForwardPointer(buffer, pos);
BigramListReadWriteUtils::getBigramAddressAndForwardPointer(buffer, flags, pos); BigramListReadWriteUtils::getBigramAddressAndForwardPointer(buffer, flags, pos);
if (BigramListReadWriteUtils::hasNext(flags)) { if (BigramListReadWriteUtils::hasNext(flags)) {
@ -118,13 +120,14 @@ bool DynamicBigramListPolicy::addBigramEntry(const int bigramPos, const int prob
bool DynamicBigramListPolicy::removeBigram(const int bigramListPos, const int targetBigramPos) { bool DynamicBigramListPolicy::removeBigram(const int bigramListPos, const int targetBigramPos) {
const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(bigramListPos); const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(bigramListPos);
const uint8_t *const buffer = mBuffer->getBuffer(usesAdditionalBuffer);
int pos = bigramListPos; int pos = bigramListPos;
if (usesAdditionalBuffer) { if (usesAdditionalBuffer) {
pos -= mBuffer->getOriginalBufferSize(); pos -= mBuffer->getOriginalBufferSize();
} }
BigramListReadWriteUtils::BigramFlags flags; BigramListReadWriteUtils::BigramFlags flags;
do { do {
// The buffer address can be changed after calling buffer writing methods.
const uint8_t *const buffer = mBuffer->getBuffer(usesAdditionalBuffer);
flags = BigramListReadWriteUtils::getFlagsAndForwardPointer(buffer, &pos); flags = BigramListReadWriteUtils::getFlagsAndForwardPointer(buffer, &pos);
int bigramOffsetFieldPos = pos; int bigramOffsetFieldPos = pos;
if (usesAdditionalBuffer) { if (usesAdditionalBuffer) {
@ -139,8 +142,7 @@ bool DynamicBigramListPolicy::removeBigram(const int bigramListPos, const int ta
continue; continue;
} }
// Target entry is found. Write 0 into the bigram pos field to mark the bigram invalid. // Target entry is found. Write 0 into the bigram pos field to mark the bigram invalid.
const int bigramOffsetFieldSize = const int bigramOffsetFieldSize = BigramListReadWriteUtils::attributeAddressSize(flags);
BigramListReadWriteUtils::attributeAddressSize(flags);
if (!mBuffer->writeUintAndAdvancePosition(0 /* data */, bigramOffsetFieldSize, if (!mBuffer->writeUintAndAdvancePosition(0 /* data */, bigramOffsetFieldSize,
&bigramOffsetFieldPos)) { &bigramOffsetFieldPos)) {
return false; return false;

View File

@ -176,7 +176,9 @@ bool DynamicPatriciaTrieWritingHelper::writeNodeToBuffer(const bool isBlackliste
// Copy shortcut list when the originalShortcutListPos is valid dictionary position. // Copy shortcut list when the originalShortcutListPos is valid dictionary position.
if (originalShortcutListPos != NOT_A_DICT_POS) { if (originalShortcutListPos != NOT_A_DICT_POS) {
int fromPos = originalShortcutListPos; int fromPos = originalShortcutListPos;
mShortcutPolicy->copyAllShortcuts(&fromPos, writingPos); if (!mShortcutPolicy->copyAllShortcutsAndReturnIfSucceededOrNot(&fromPos, writingPos)) {
return false;
}
} }
// Copy bigram list when the originalBigramListPos is valid dictionary position. // Copy bigram list when the originalBigramListPos is valid dictionary position.
if (originalBigramListPos != NOT_A_DICT_POS) { if (originalBigramListPos != NOT_A_DICT_POS) {

View File

@ -83,8 +83,8 @@ class DynamicShortcutListPolicy : public DictionaryShortcutsStructurePolicy {
} }
// Copy shortcuts from the shortcut list that starts at fromPos to toPos and advance these // Copy shortcuts from the shortcut list that starts at fromPos to toPos and advance these
// positions after the shortcut lists. // positions after the shortcut lists. This returns whether the copy was succeeded or not.
void copyAllShortcuts(int *const fromPos, int *const toPos) { bool copyAllShortcutsAndReturnIfSucceededOrNot(int *const fromPos, int *const toPos) {
const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(*fromPos); const bool usesAdditionalBuffer = mBuffer->isInAdditionalBuffer(*fromPos);
const uint8_t *const buffer = mBuffer->getBuffer(usesAdditionalBuffer); const uint8_t *const buffer = mBuffer->getBuffer(usesAdditionalBuffer);
if (usesAdditionalBuffer) { if (usesAdditionalBuffer) {
@ -93,16 +93,23 @@ class DynamicShortcutListPolicy : public DictionaryShortcutsStructurePolicy {
const int shortcutListSize = ShortcutListReadingUtils const int shortcutListSize = ShortcutListReadingUtils
::getShortcutListSizeAndForwardPointer(buffer, fromPos); ::getShortcutListSizeAndForwardPointer(buffer, fromPos);
// Copy shortcut list size. // Copy shortcut list size.
mBuffer->writeUintAndAdvancePosition( if (!mBuffer->writeUintAndAdvancePosition(
shortcutListSize + ShortcutListReadingUtils::getShortcutListSizeFieldSize(), shortcutListSize + ShortcutListReadingUtils::getShortcutListSizeFieldSize(),
ShortcutListReadingUtils::getShortcutListSizeFieldSize(), toPos); ShortcutListReadingUtils::getShortcutListSizeFieldSize(), toPos)) {
return false;
}
// Copy shortcut list.
for (int i = 0; i < shortcutListSize; ++i) { for (int i = 0; i < shortcutListSize; ++i) {
const uint8_t data = ByteArrayUtils::readUint8AndAdvancePosition(buffer, fromPos); const uint8_t data = ByteArrayUtils::readUint8AndAdvancePosition(
mBuffer->writeUintAndAdvancePosition(data, 1 /* size */, toPos); mBuffer->getBuffer(usesAdditionalBuffer), fromPos);
if (!mBuffer->writeUintAndAdvancePosition(data, 1 /* size */, toPos)) {
return false;
}
} }
if (usesAdditionalBuffer) { if (usesAdditionalBuffer) {
*fromPos += mBuffer->getOriginalBufferSize(); *fromPos += mBuffer->getOriginalBufferSize();
} }
return true;
} }
private: private:

View File

@ -47,6 +47,7 @@ class BufferWithExtendableBuffer {
return position >= mOriginalBufferSize; return position >= mOriginalBufferSize;
} }
// TODO: Resolve the issue that the address can be changed when the vector is resized.
// CAVEAT!: Be careful about array out of bound access with buffers // CAVEAT!: Be careful about array out of bound access with buffers
AK_FORCE_INLINE const uint8_t *getBuffer(const bool usesAdditionalBuffer) const { AK_FORCE_INLINE const uint8_t *getBuffer(const bool usesAdditionalBuffer) const {
if (usesAdditionalBuffer) { if (usesAdditionalBuffer) {