am be470f06: Hide DictBuffer from BinaryDictDecoderUtils.

* commit 'be470f06e48e40a0def32e0f34e3ca48113937b5':
  Hide DictBuffer from BinaryDictDecoderUtils.
main
Yuichiro Hanada 2013-09-12 09:15:20 -07:00 committed by Android Git Automerger
commit a3be38ebc7
4 changed files with 98 additions and 53 deletions

View File

@ -342,13 +342,11 @@ public final class BinaryDictDecoderUtils {
* @param formatOptions file format options. * @param formatOptions file format options.
* @return the word with its frequency, as a weighted string. * @return the word with its frequency, as a weighted string.
*/ */
/* package for tests */ static WeightedString getWordAtPosition( /* package for tests */ static WeightedString getWordAtPosition(final DictDecoder dictDecoder,
final Ver3DictDecoder dictDecoder, final int headerSize, final int pos, final int headerSize, final int pos, final FormatOptions formatOptions) {
final FormatOptions formatOptions) {
final DictBuffer dictBuffer = dictDecoder.getDictBuffer();
final WeightedString result; final WeightedString result;
final int originalPos = dictBuffer.position(); final int originalPos = dictDecoder.getPosition();
dictBuffer.position(pos); dictDecoder.setPosition(pos);
if (BinaryDictIOUtils.supportsDynamicUpdate(formatOptions)) { if (BinaryDictIOUtils.supportsDynamicUpdate(formatOptions)) {
result = getWordAtPositionWithParentAddress(dictDecoder, pos, formatOptions); result = getWordAtPositionWithParentAddress(dictDecoder, pos, formatOptions);
@ -357,14 +355,13 @@ public final class BinaryDictDecoderUtils {
formatOptions); formatOptions);
} }
dictBuffer.position(originalPos); dictDecoder.setPosition(originalPos);
return result; return result;
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
private static WeightedString getWordAtPositionWithParentAddress( private static WeightedString getWordAtPositionWithParentAddress(final DictDecoder dictDecoder,
final Ver3DictDecoder dictDecoder, final int pos, final FormatOptions options) { final int pos, final FormatOptions options) {
final DictBuffer dictBuffer = dictDecoder.getDictBuffer();
int currentPos = pos; int currentPos = pos;
int frequency = Integer.MIN_VALUE; int frequency = Integer.MIN_VALUE;
final StringBuilder builder = new StringBuilder(); final StringBuilder builder = new StringBuilder();
@ -373,7 +370,7 @@ public final class BinaryDictDecoderUtils {
PtNodeInfo currentInfo; PtNodeInfo currentInfo;
int loopCounter = 0; int loopCounter = 0;
do { do {
dictBuffer.position(currentPos); dictDecoder.setPosition(currentPos);
currentInfo = dictDecoder.readPtNode(currentPos, options); currentInfo = dictDecoder.readPtNode(currentPos, options);
if (BinaryDictIOUtils.isMovedPtNode(currentInfo.mFlags, options)) { if (BinaryDictIOUtils.isMovedPtNode(currentInfo.mFlags, options)) {
currentPos = currentInfo.mParentAddress + currentInfo.mOriginalAddress; currentPos = currentInfo.mParentAddress + currentInfo.mOriginalAddress;
@ -392,11 +389,10 @@ public final class BinaryDictDecoderUtils {
} }
private static WeightedString getWordAtPositionWithoutParentAddress( private static WeightedString getWordAtPositionWithoutParentAddress(
final Ver3DictDecoder dictDecoder, final int headerSize, final int pos, final DictDecoder dictDecoder, final int headerSize, final int pos,
final FormatOptions options) { final FormatOptions options) {
final DictBuffer dictBuffer = dictDecoder.getDictBuffer(); dictDecoder.setPosition(headerSize);
dictBuffer.position(headerSize); final int count = dictDecoder.readPtNodeCount();
final int count = readPtNodeCount(dictBuffer);
int groupPos = headerSize + BinaryDictIOUtils.getPtNodeCountSize(count); int groupPos = headerSize + BinaryDictIOUtils.getPtNodeCountSize(count);
final StringBuilder builder = new StringBuilder(); final StringBuilder builder = new StringBuilder();
WeightedString result = null; WeightedString result = null;
@ -414,8 +410,8 @@ public final class BinaryDictDecoderUtils {
if (info.mChildrenAddress > pos) { if (info.mChildrenAddress > pos) {
if (null == last) continue; if (null == last) continue;
builder.append(new String(last.mCharacters, 0, last.mCharacters.length)); builder.append(new String(last.mCharacters, 0, last.mCharacters.length));
dictBuffer.position(last.mChildrenAddress); dictDecoder.setPosition(last.mChildrenAddress);
i = readPtNodeCount(dictBuffer); i = dictDecoder.readPtNodeCount();
groupPos = last.mChildrenAddress + BinaryDictIOUtils.getPtNodeCountSize(i); groupPos = last.mChildrenAddress + BinaryDictIOUtils.getPtNodeCountSize(i);
last = null; last = null;
continue; continue;
@ -424,8 +420,8 @@ public final class BinaryDictDecoderUtils {
} }
if (0 == i && BinaryDictIOUtils.hasChildrenAddress(last.mChildrenAddress)) { if (0 == i && BinaryDictIOUtils.hasChildrenAddress(last.mChildrenAddress)) {
builder.append(new String(last.mCharacters, 0, last.mCharacters.length)); builder.append(new String(last.mCharacters, 0, last.mCharacters.length));
dictBuffer.position(last.mChildrenAddress); dictDecoder.setPosition(last.mChildrenAddress);
i = readPtNodeCount(dictBuffer); i = dictDecoder.readPtNodeCount();
groupPos = last.mChildrenAddress + BinaryDictIOUtils.getPtNodeCountSize(i); groupPos = last.mChildrenAddress + BinaryDictIOUtils.getPtNodeCountSize(i);
last = null; last = null;
continue; continue;
@ -449,17 +445,16 @@ public final class BinaryDictDecoderUtils {
* @param options file format options. * @param options file format options.
* @return the read node array with all his children already read. * @return the read node array with all his children already read.
*/ */
private static PtNodeArray readNodeArray(final Ver3DictDecoder dictDecoder, private static PtNodeArray readNodeArray(final DictDecoder dictDecoder,
final int headerSize, final Map<Integer, PtNodeArray> reverseNodeArrayMap, final int headerSize, final Map<Integer, PtNodeArray> reverseNodeArrayMap,
final Map<Integer, PtNode> reversePtNodeMap, final FormatOptions options) final Map<Integer, PtNode> reversePtNodeMap, final FormatOptions options)
throws IOException { throws IOException {
final DictBuffer dictBuffer = dictDecoder.getDictBuffer();
final ArrayList<PtNode> nodeArrayContents = new ArrayList<PtNode>(); final ArrayList<PtNode> nodeArrayContents = new ArrayList<PtNode>();
final int nodeArrayOriginPos = dictBuffer.position(); final int nodeArrayOriginPos = dictDecoder.getPosition();
do { // Scan the linked-list node. do { // Scan the linked-list node.
final int nodeArrayHeadPos = dictBuffer.position(); final int nodeArrayHeadPos = dictDecoder.getPosition();
final int count = readPtNodeCount(dictBuffer); final int count = dictDecoder.readPtNodeCount();
int groupOffsetPos = nodeArrayHeadPos + BinaryDictIOUtils.getPtNodeCountSize(count); int groupOffsetPos = nodeArrayHeadPos + BinaryDictIOUtils.getPtNodeCountSize(count);
for (int i = count; i > 0; --i) { // Scan the array of PtNode. for (int i = count; i > 0; --i) { // Scan the array of PtNode.
PtNodeInfo info = dictDecoder.readPtNode(groupOffsetPos, options); PtNodeInfo info = dictDecoder.readPtNode(groupOffsetPos, options);
@ -480,11 +475,11 @@ public final class BinaryDictDecoderUtils {
if (BinaryDictIOUtils.hasChildrenAddress(info.mChildrenAddress)) { if (BinaryDictIOUtils.hasChildrenAddress(info.mChildrenAddress)) {
PtNodeArray children = reverseNodeArrayMap.get(info.mChildrenAddress); PtNodeArray children = reverseNodeArrayMap.get(info.mChildrenAddress);
if (null == children) { if (null == children) {
final int currentPosition = dictBuffer.position(); final int currentPosition = dictDecoder.getPosition();
dictBuffer.position(info.mChildrenAddress); dictDecoder.setPosition(info.mChildrenAddress);
children = readNodeArray(dictDecoder, headerSize, reverseNodeArrayMap, children = readNodeArray(dictDecoder, headerSize, reverseNodeArrayMap,
reversePtNodeMap, options); reversePtNodeMap, options);
dictBuffer.position(currentPosition); dictDecoder.setPosition(currentPosition);
} }
nodeArrayContents.add( nodeArrayContents.add(
new PtNode(info.mCharacters, shortcutTargets, bigrams, new PtNode(info.mCharacters, shortcutTargets, bigrams,
@ -503,15 +498,10 @@ public final class BinaryDictDecoderUtils {
// reach the end of the array. // reach the end of the array.
if (options.mSupportsDynamicUpdate) { if (options.mSupportsDynamicUpdate) {
final int nextAddress = dictBuffer.readUnsignedInt24(); final boolean hasValidForwardLink = dictDecoder.readForwardLinkAndAdvancePosition();
if (nextAddress >= 0 && nextAddress < dictBuffer.limit()) { if (!hasValidForwardLink) break;
dictBuffer.position(nextAddress);
} else {
break;
}
} }
} while (options.mSupportsDynamicUpdate && } while (options.mSupportsDynamicUpdate && dictDecoder.hasNextPtNodeArray());
dictBuffer.position() != FormatSpec.NO_FORWARD_LINK_ADDRESS);
final PtNodeArray nodeArray = new PtNodeArray(nodeArrayContents); final PtNodeArray nodeArray = new PtNodeArray(nodeArrayContents);
nodeArray.mCachedAddressBeforeUpdate = nodeArrayOriginPos; nodeArray.mCachedAddressBeforeUpdate = nodeArrayOriginPos;

View File

@ -61,12 +61,11 @@ public final class BinaryDictIOUtils {
/** /**
* Retrieves all node arrays without recursive call. * Retrieves all node arrays without recursive call.
*/ */
private static void readUnigramsAndBigramsBinaryInner( private static void readUnigramsAndBigramsBinaryInner(final DictDecoder dictDecoder,
final Ver3DictDecoder dictDecoder, final int headerSize, final int headerSize, final Map<Integer, String> words,
final Map<Integer, String> words, final Map<Integer, Integer> frequencies, final Map<Integer, Integer> frequencies,
final Map<Integer, ArrayList<PendingAttribute>> bigrams, final Map<Integer, ArrayList<PendingAttribute>> bigrams,
final FormatOptions formatOptions) { final FormatOptions formatOptions) {
final DictBuffer dictBuffer = dictDecoder.getDictBuffer();
int[] pushedChars = new int[FormatSpec.MAX_WORD_LENGTH + 1]; int[] pushedChars = new int[FormatSpec.MAX_WORD_LENGTH + 1];
Stack<Position> stack = new Stack<Position>(); Stack<Position> stack = new Stack<Position>();
@ -83,11 +82,11 @@ public final class BinaryDictIOUtils {
p.mNumOfPtNode + ", position=" + p.mPosition + ", length=" + p.mLength); p.mNumOfPtNode + ", position=" + p.mPosition + ", length=" + p.mLength);
} }
if (dictBuffer.position() != p.mAddress) dictBuffer.position(p.mAddress); if (dictDecoder.getPosition() != p.mAddress) dictDecoder.setPosition(p.mAddress);
if (index != p.mLength) index = p.mLength; if (index != p.mLength) index = p.mLength;
if (p.mNumOfPtNode == Position.NOT_READ_PTNODE_COUNT) { if (p.mNumOfPtNode == Position.NOT_READ_PTNODE_COUNT) {
p.mNumOfPtNode = BinaryDictDecoderUtils.readPtNodeCount(dictBuffer); p.mNumOfPtNode = dictDecoder.readPtNodeCount();
p.mAddress += getPtNodeCountSize(p.mNumOfPtNode); p.mAddress += getPtNodeCountSize(p.mNumOfPtNode);
p.mPosition = 0; p.mPosition = 0;
} }
@ -114,11 +113,12 @@ public final class BinaryDictIOUtils {
if (p.mPosition == p.mNumOfPtNode) { if (p.mPosition == p.mNumOfPtNode) {
if (formatOptions.mSupportsDynamicUpdate) { if (formatOptions.mSupportsDynamicUpdate) {
final int forwardLinkAddress = dictBuffer.readUnsignedInt24(); final boolean hasValidForwardLinkAddress =
if (forwardLinkAddress != FormatSpec.NO_FORWARD_LINK_ADDRESS) { dictDecoder.readForwardLinkAndAdvancePosition();
if (hasValidForwardLinkAddress && dictDecoder.hasNextPtNodeArray()) {
// The node array has a forward link. // The node array has a forward link.
p.mNumOfPtNode = Position.NOT_READ_PTNODE_COUNT; p.mNumOfPtNode = Position.NOT_READ_PTNODE_COUNT;
p.mAddress = forwardLinkAddress; p.mAddress = dictDecoder.getPosition();
} else { } else {
stack.pop(); stack.pop();
} }
@ -127,7 +127,7 @@ public final class BinaryDictIOUtils {
} }
} else { } else {
// The Ptnode array has more PtNodes. // The Ptnode array has more PtNodes.
p.mAddress = dictBuffer.position(); p.mAddress = dictDecoder.getPosition();
} }
if (!isMovedPtNode && hasChildrenAddress(info.mChildrenAddress)) { if (!isMovedPtNode && hasChildrenAddress(info.mChildrenAddress)) {
@ -171,9 +171,8 @@ public final class BinaryDictIOUtils {
@UsedForTesting @UsedForTesting
/* package */ static int getTerminalPosition(final Ver3DictDecoder dictDecoder, /* package */ static int getTerminalPosition(final Ver3DictDecoder dictDecoder,
final String word) throws IOException, UnsupportedFormatException { final String word) throws IOException, UnsupportedFormatException {
final DictBuffer dictBuffer = dictDecoder.getDictBuffer();
if (word == null) return FormatSpec.NOT_VALID_WORD; if (word == null) return FormatSpec.NOT_VALID_WORD;
if (dictBuffer.position() != 0) dictBuffer.position(0); dictDecoder.setPosition(0);
final FileHeader header = dictDecoder.readHeader(); final FileHeader header = dictDecoder.readHeader();
int wordPos = 0; int wordPos = 0;
@ -182,10 +181,10 @@ public final class BinaryDictIOUtils {
if (wordPos >= wordLen) return FormatSpec.NOT_VALID_WORD; if (wordPos >= wordLen) return FormatSpec.NOT_VALID_WORD;
do { do {
final int ptNodeCount = BinaryDictDecoderUtils.readPtNodeCount(dictBuffer); final int ptNodeCount = dictDecoder.readPtNodeCount();
boolean foundNextPtNode = false; boolean foundNextPtNode = false;
for (int i = 0; i < ptNodeCount; ++i) { for (int i = 0; i < ptNodeCount; ++i) {
final int ptNodePos = dictBuffer.position(); final int ptNodePos = dictDecoder.getPosition();
final PtNodeInfo currentInfo = dictDecoder.readPtNode(ptNodePos, final PtNodeInfo currentInfo = dictDecoder.readPtNode(ptNodePos,
header.mFormatOptions); header.mFormatOptions);
final boolean isMovedNode = isMovedPtNode(currentInfo.mFlags, final boolean isMovedNode = isMovedPtNode(currentInfo.mFlags,
@ -219,7 +218,7 @@ public final class BinaryDictIOUtils {
return FormatSpec.NOT_VALID_WORD; return FormatSpec.NOT_VALID_WORD;
} }
foundNextPtNode = true; foundNextPtNode = true;
dictBuffer.position(currentInfo.mChildrenAddress); dictDecoder.setPosition(currentInfo.mChildrenAddress);
break; break;
} }
} }
@ -233,11 +232,11 @@ public final class BinaryDictIOUtils {
return FormatSpec.NOT_VALID_WORD; return FormatSpec.NOT_VALID_WORD;
} }
final int forwardLinkAddress = dictBuffer.readUnsignedInt24(); final boolean hasValidForwardLinkAddress =
if (forwardLinkAddress == FormatSpec.NO_FORWARD_LINK_ADDRESS) { dictDecoder.readForwardLinkAndAdvancePosition();
if (!hasValidForwardLinkAddress || !dictDecoder.hasNextPtNodeArray()) {
return FormatSpec.NOT_VALID_WORD; return FormatSpec.NOT_VALID_WORD;
} }
dictBuffer.position(forwardLinkAddress);
} while(true); } while(true);
} }
return FormatSpec.NOT_VALID_WORD; return FormatSpec.NOT_VALID_WORD;

View File

@ -91,6 +91,33 @@ public interface DictDecoder {
final TreeMap<Integer, ArrayList<PendingAttribute>> bigrams) final TreeMap<Integer, ArrayList<PendingAttribute>> bigrams)
throws IOException, UnsupportedFormatException; throws IOException, UnsupportedFormatException;
/**
* Sets the position of the buffer to the given value.
*
* @param newPos the new position
*/
public void setPosition(final int newPos);
/**
* Gets the position of the buffer.
*
* @return the position
*/
public int getPosition();
/**
* Reads and returns the PtNode count out of a buffer and forwards the pointer.
*/
public int readPtNodeCount();
/**
* Reads the forward link and advances the position.
*
* @return if this method advances the position then true else false.
*/
public boolean readForwardLinkAndAdvancePosition();
public boolean hasNextPtNodeArray();
// Flags for DictionaryBufferFactory. // Flags for DictionaryBufferFactory.
public static final int USE_READONLY_BYTEBUFFER = 0x01000000; public static final int USE_READONLY_BYTEBUFFER = 0x01000000;
public static final int USE_BYTEARRAY = 0x02000000; public static final int USE_BYTEARRAY = 0x02000000;

View File

@ -348,4 +348,33 @@ public class Ver3DictDecoder implements DictDecoder {
BinaryDictIOUtils.readUnigramsAndBigramsBinary(this, words, frequencies, bigrams); BinaryDictIOUtils.readUnigramsAndBigramsBinary(this, words, frequencies, bigrams);
} }
@Override
public void setPosition(int newPos) {
mDictBuffer.position(newPos);
}
@Override
public int getPosition() {
return mDictBuffer.position();
}
@Override
public int readPtNodeCount() {
return BinaryDictDecoderUtils.readPtNodeCount(mDictBuffer);
}
@Override
public boolean readForwardLinkAndAdvancePosition() {
final int nextAddress = mDictBuffer.readUnsignedInt24();
if (nextAddress >= 0 && nextAddress < mDictBuffer.limit()) {
mDictBuffer.position(nextAddress);
return true;
}
return false;
}
@Override
public boolean hasNextPtNodeArray() {
return mDictBuffer.position() != FormatSpec.NO_FORWARD_LINK_ADDRESS;
}
} }