Merge "Combine mHasParentAddress with mHasLinkedListNode into mSupportsDynamicUpdate." into jb-mr1-dev

main
Ken Wakasa 2012-09-23 21:19:30 -07:00 committed by Android (Google) Code Review
commit 5274a4a630
4 changed files with 42 additions and 68 deletions

View File

@ -92,7 +92,7 @@ public class BinaryDictIOUtils {
} }
if (p.mPosition == p.mNumOfCharGroup) { if (p.mPosition == p.mNumOfCharGroup) {
if (formatOptions.mHasLinkedListNode) { if (formatOptions.mSupportsDynamicUpdate) {
final int forwardLinkAddress = buffer.readUnsignedInt24(); final int forwardLinkAddress = buffer.readUnsignedInt24();
if (forwardLinkAddress != FormatSpec.NO_FORWARD_LINK_ADDRESS) { if (forwardLinkAddress != FormatSpec.NO_FORWARD_LINK_ADDRESS) {
// the node has a forward link. // the node has a forward link.

View File

@ -376,7 +376,7 @@ public class BinaryDictInputOutput {
g.mCachedSize = groupSize; g.mCachedSize = groupSize;
size += groupSize; size += groupSize;
} }
if (options.mHasLinkedListNode) { if (options.mSupportsDynamicUpdate) {
size += FormatSpec.FORWARD_LINK_ADDRESS_SIZE; size += FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
} }
node.mCachedSize = size; node.mCachedSize = size;
@ -390,11 +390,11 @@ public class BinaryDictInputOutput {
} }
/** /**
* Helper method to check whether the CharGroup has a parent address. * Helper method to check whether the dictionary can be updated dynamically.
*/ */
public static boolean hasParentAddress(final FormatOptions options) { public static boolean supportsDynamicUpdate(final FormatOptions options) {
return options.mVersion >= FormatSpec.FIRST_VERSION_WITH_PARENT_ADDRESS return options.mVersion >= FormatSpec.FIRST_VERSION_WITH_DYNAMIC_UPDATE
&& options.mHasParentAddress; && options.mSupportsDynamicUpdate;
} }
/** /**
@ -404,7 +404,7 @@ public class BinaryDictInputOutput {
* @param options file format options. * @param options file format options.
*/ */
private static int getGroupHeaderSize(final CharGroup group, final FormatOptions options) { private static int getGroupHeaderSize(final CharGroup group, final FormatOptions options) {
if (hasParentAddress(options)) { if (supportsDynamicUpdate(options)) {
return FormatSpec.GROUP_FLAGS_SIZE + FormatSpec.PARENT_ADDRESS_SIZE return FormatSpec.GROUP_FLAGS_SIZE + FormatSpec.PARENT_ADDRESS_SIZE
+ getGroupCharactersSize(group); + getGroupCharactersSize(group);
} else { } else {
@ -530,7 +530,7 @@ public class BinaryDictInputOutput {
group.mCachedSize = groupSize; group.mCachedSize = groupSize;
size += groupSize; size += groupSize;
} }
if (formatOptions.mHasLinkedListNode) { if (formatOptions.mSupportsDynamicUpdate) {
size += FormatSpec.FORWARD_LINK_ADDRESS_SIZE; size += FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
} }
if (node.mCachedSize != size) { if (node.mCachedSize != size) {
@ -559,7 +559,8 @@ public class BinaryDictInputOutput {
groupOffset += g.mCachedSize; groupOffset += g.mCachedSize;
} }
final int nodeSize = groupCountSize + groupOffset final int nodeSize = groupCountSize + groupOffset
+ (formatOptions.mHasLinkedListNode ? FormatSpec.FORWARD_LINK_ADDRESS_SIZE : 0); + (formatOptions.mSupportsDynamicUpdate
? FormatSpec.FORWARD_LINK_ADDRESS_SIZE : 0);
if (nodeSize != n.mCachedSize) { if (nodeSize != n.mCachedSize) {
throw new RuntimeException("Bug : Stored and computed node size differ"); throw new RuntimeException("Bug : Stored and computed node size differ");
} }
@ -792,8 +793,7 @@ public class BinaryDictInputOutput {
return (options.mFrenchLigatureProcessing ? FormatSpec.FRENCH_LIGATURE_PROCESSING_FLAG : 0) return (options.mFrenchLigatureProcessing ? FormatSpec.FRENCH_LIGATURE_PROCESSING_FLAG : 0)
+ (options.mGermanUmlautProcessing ? FormatSpec.GERMAN_UMLAUT_PROCESSING_FLAG : 0) + (options.mGermanUmlautProcessing ? FormatSpec.GERMAN_UMLAUT_PROCESSING_FLAG : 0)
+ (hasBigrams ? FormatSpec.CONTAINS_BIGRAMS_FLAG : 0) + (hasBigrams ? FormatSpec.CONTAINS_BIGRAMS_FLAG : 0)
+ (formatOptions.mHasParentAddress ? FormatSpec.HAS_PARENT_ADDRESS : 0) + (formatOptions.mSupportsDynamicUpdate ? FormatSpec.SUPPORTS_DYNAMIC_UPDATE : 0);
+ (formatOptions.mHasLinkedListNode ? FormatSpec.HAS_LINKEDLIST_NODE : 0);
} }
/** /**
@ -857,7 +857,7 @@ public class BinaryDictInputOutput {
byte flags = makeCharGroupFlags(group, groupAddress, childrenOffset); byte flags = makeCharGroupFlags(group, groupAddress, childrenOffset);
buffer[index++] = flags; buffer[index++] = flags;
if (hasParentAddress(formatOptions)) { if (supportsDynamicUpdate(formatOptions)) {
if (parentAddress == FormatSpec.NO_PARENT_ADDRESS) { if (parentAddress == FormatSpec.NO_PARENT_ADDRESS) {
// this node is the root node. // this node is the root node.
buffer[index] = buffer[index + 1] = buffer[index + 2] = 0; buffer[index] = buffer[index + 1] = buffer[index + 2] = 0;
@ -927,7 +927,7 @@ public class BinaryDictInputOutput {
} }
} }
if (formatOptions.mHasLinkedListNode) { if (formatOptions.mSupportsDynamicUpdate) {
buffer[index] = buffer[index + 1] = buffer[index + 2] buffer[index] = buffer[index + 1] = buffer[index + 2]
= FormatSpec.NO_FORWARD_LINK_ADDRESS; = FormatSpec.NO_FORWARD_LINK_ADDRESS;
index += FormatSpec.FORWARD_LINK_ADDRESS_SIZE; index += FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
@ -1112,7 +1112,7 @@ public class BinaryDictInputOutput {
++addressPointer; ++addressPointer;
final int parentAddress; final int parentAddress;
if (hasParentAddress(options)) { if (supportsDynamicUpdate(options)) {
// read the parent address. (version 3) // read the parent address. (version 3)
parentAddress = -buffer.readUnsignedInt24(); parentAddress = -buffer.readUnsignedInt24();
addressPointer += 3; addressPointer += 3;
@ -1251,7 +1251,7 @@ public class BinaryDictInputOutput {
final String result; final String result;
final int originalPointer = buffer.position(); final int originalPointer = buffer.position();
if (hasParentAddress(formatOptions)) { if (supportsDynamicUpdate(formatOptions)) {
result = getWordAtAddressWithParentAddress(buffer, headerSize, address, formatOptions); result = getWordAtAddressWithParentAddress(buffer, headerSize, address, formatOptions);
} else { } else {
result = getWordAtAddressWithoutParentAddress(buffer, headerSize, address, result = getWordAtAddressWithoutParentAddress(buffer, headerSize, address,
@ -1392,7 +1392,7 @@ public class BinaryDictInputOutput {
} }
// reach the end of the array. // reach the end of the array.
if (options.mHasLinkedListNode) { if (options.mSupportsDynamicUpdate) {
final int nextAddress = buffer.readUnsignedInt24(); final int nextAddress = buffer.readUnsignedInt24();
if (nextAddress >= 0 && nextAddress < buffer.limit()) { if (nextAddress >= 0 && nextAddress < buffer.limit()) {
buffer.position(nextAddress); buffer.position(nextAddress);
@ -1400,7 +1400,7 @@ public class BinaryDictInputOutput {
break; break;
} }
} }
} while (options.mHasLinkedListNode && } while (options.mSupportsDynamicUpdate &&
buffer.position() != FormatSpec.NO_FORWARD_LINK_ADDRESS); buffer.position() != FormatSpec.NO_FORWARD_LINK_ADDRESS);
final Node node = new Node(nodeContents); final Node node = new Node(nodeContents);
@ -1469,8 +1469,7 @@ public class BinaryDictInputOutput {
0 != (optionsFlags & FormatSpec.GERMAN_UMLAUT_PROCESSING_FLAG), 0 != (optionsFlags & FormatSpec.GERMAN_UMLAUT_PROCESSING_FLAG),
0 != (optionsFlags & FormatSpec.FRENCH_LIGATURE_PROCESSING_FLAG)), 0 != (optionsFlags & FormatSpec.FRENCH_LIGATURE_PROCESSING_FLAG)),
new FormatOptions(version, new FormatOptions(version,
0 != (optionsFlags & FormatSpec.HAS_PARENT_ADDRESS), 0 != (optionsFlags & FormatSpec.SUPPORTS_DYNAMIC_UPDATE)));
0 != (optionsFlags & FormatSpec.HAS_LINKEDLIST_NODE)));
return header; return header;
} }

View File

@ -145,17 +145,14 @@ public final class FormatSpec {
static final int MAXIMUM_SUPPORTED_VERSION = 3; static final int MAXIMUM_SUPPORTED_VERSION = 3;
static final int NOT_A_VERSION_NUMBER = -1; static final int NOT_A_VERSION_NUMBER = -1;
static final int FIRST_VERSION_WITH_HEADER_SIZE = 2; static final int FIRST_VERSION_WITH_HEADER_SIZE = 2;
static final int FIRST_VERSION_WITH_PARENT_ADDRESS = 3; static final int FIRST_VERSION_WITH_DYNAMIC_UPDATE = 3;
static final int FIRST_VERSION_WITH_LINKEDLIST_NODE = 3;
// These options need to be the same numeric values as the one in the native reading code. // These options need to be the same numeric values as the one in the native reading code.
static final int GERMAN_UMLAUT_PROCESSING_FLAG = 0x1; static final int GERMAN_UMLAUT_PROCESSING_FLAG = 0x1;
// TODO: Make the native reading code read this variable. // TODO: Make the native reading code read this variable.
static final int HAS_PARENT_ADDRESS = 0x2; static final int SUPPORTS_DYNAMIC_UPDATE = 0x2;
static final int FRENCH_LIGATURE_PROCESSING_FLAG = 0x4; static final int FRENCH_LIGATURE_PROCESSING_FLAG = 0x4;
static final int CONTAINS_BIGRAMS_FLAG = 0x8; static final int CONTAINS_BIGRAMS_FLAG = 0x8;
// TODO: Make the native reading code read this variable.
static final int HAS_LINKEDLIST_NODE = 0x10;
// TODO: Make this value adaptative to content data, store it in the header, and // TODO: Make this value adaptative to content data, store it in the header, and
// use it in the reading code. // use it in the reading code.
@ -215,31 +212,17 @@ public final class FormatSpec {
*/ */
public static class FormatOptions { public static class FormatOptions {
public final int mVersion; public final int mVersion;
public final boolean mHasParentAddress; public final boolean mSupportsDynamicUpdate;
public final boolean mHasLinkedListNode;
public FormatOptions(final int version) { public FormatOptions(final int version) {
this(version, false); this(version, false);
} }
public FormatOptions(final int version, final boolean hasParentAddress) { public FormatOptions(final int version, final boolean supportsDynamicUpdate) {
this(version, hasParentAddress, false);
}
public FormatOptions(final int version, final boolean hasParentAddress,
final boolean hasLinkedListNode) {
mVersion = version; mVersion = version;
if (version < FIRST_VERSION_WITH_PARENT_ADDRESS && hasParentAddress) { if (version < FIRST_VERSION_WITH_DYNAMIC_UPDATE && supportsDynamicUpdate) {
throw new RuntimeException("Parent addresses are only supported with versions " throw new RuntimeException("Dynamic updates are only supported with versions "
+ FIRST_VERSION_WITH_PARENT_ADDRESS + " and ulterior."); + FIRST_VERSION_WITH_DYNAMIC_UPDATE + " and ulterior.");
} }
mHasParentAddress = hasParentAddress; mSupportsDynamicUpdate = supportsDynamicUpdate;
if (version < FIRST_VERSION_WITH_LINKEDLIST_NODE && hasLinkedListNode) {
throw new RuntimeException("Linked list nodes are only supported with versions "
+ FIRST_VERSION_WITH_LINKEDLIST_NODE + " and ulterior.");
}
if (!hasParentAddress && hasLinkedListNode) {
throw new RuntimeException("Linked list nodes need parent addresses.");
}
mHasLinkedListNode = hasLinkedListNode;
} }
} }

View File

@ -65,13 +65,10 @@ public class BinaryDictIOTests extends AndroidTestCase {
CollectionUtils.newSparseArray(); CollectionUtils.newSparseArray();
private static final FormatSpec.FormatOptions VERSION2 = new FormatSpec.FormatOptions(2); private static final FormatSpec.FormatOptions VERSION2 = new FormatSpec.FormatOptions(2);
private static final FormatSpec.FormatOptions VERSION3_WITHOUT_PARENTADDRESS = private static final FormatSpec.FormatOptions VERSION3_WITHOUT_DYNAMIC_UPDATE =
new FormatSpec.FormatOptions(3, false /* hasParentAddress */); new FormatSpec.FormatOptions(3, false /* supportsDynamicUpdate */);
private static final FormatSpec.FormatOptions VERSION3_WITH_PARENTADDRESS = private static final FormatSpec.FormatOptions VERSION3_WITH_DYNAMIC_UPDATE =
new FormatSpec.FormatOptions(3, true /* hasParentAddress */); new FormatSpec.FormatOptions(3, true /* supportsDynamicUpdate */);
private static final FormatSpec.FormatOptions VERSION3_WITH_LINKEDLIST_NODE =
new FormatSpec.FormatOptions(3, true /* hasParentAddress */,
true /* hasLinkedListNode */);
private static final String[] CHARACTERS = { private static final String[] CHARACTERS = {
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
@ -240,8 +237,7 @@ public class BinaryDictIOTests extends AndroidTestCase {
String result = " : buffer type = " String result = " : buffer type = "
+ ((bufferType == USE_BYTE_BUFFER) ? "byte buffer" : "byte array"); + ((bufferType == USE_BYTE_BUFFER) ? "byte buffer" : "byte array");
result += " : version = " + formatOptions.mVersion; result += " : version = " + formatOptions.mVersion;
return result + ", hasParentAddress = " + formatOptions.mHasParentAddress return result + ", supportsDynamicUpdate = " + formatOptions.mSupportsDynamicUpdate;
+ ", hasLinkedListNode = " + formatOptions.mHasLinkedListNode;
} }
// Tests for readDictionaryBinary and writeDictionaryBinary // Tests for readDictionaryBinary and writeDictionaryBinary
@ -308,9 +304,8 @@ public class BinaryDictIOTests extends AndroidTestCase {
final List<String> results = CollectionUtils.newArrayList(); final List<String> results = CollectionUtils.newArrayList();
runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION2); runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION2);
runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION3_WITHOUT_PARENTADDRESS); runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION3_WITHOUT_DYNAMIC_UPDATE);
runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION3_WITH_PARENTADDRESS); runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION3_WITH_DYNAMIC_UPDATE);
runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION3_WITH_LINKEDLIST_NODE);
for (final String result : results) { for (final String result : results) {
Log.d(TAG, result); Log.d(TAG, result);
@ -321,9 +316,8 @@ public class BinaryDictIOTests extends AndroidTestCase {
final List<String> results = CollectionUtils.newArrayList(); final List<String> results = CollectionUtils.newArrayList();
runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION2); runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION2);
runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION3_WITHOUT_PARENTADDRESS); runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION3_WITHOUT_DYNAMIC_UPDATE);
runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION3_WITH_PARENTADDRESS); runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION3_WITH_DYNAMIC_UPDATE);
runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION3_WITH_LINKEDLIST_NODE);
for (final String result : results) { for (final String result : results) {
Log.d(TAG, result); Log.d(TAG, result);
@ -455,9 +449,8 @@ public class BinaryDictIOTests extends AndroidTestCase {
final List<String> results = CollectionUtils.newArrayList(); final List<String> results = CollectionUtils.newArrayList();
runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION2); runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION2);
runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION3_WITHOUT_PARENTADDRESS); runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION3_WITHOUT_DYNAMIC_UPDATE);
runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION3_WITH_PARENTADDRESS); runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION3_WITH_DYNAMIC_UPDATE);
runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION3_WITH_LINKEDLIST_NODE);
for (final String result : results) { for (final String result : results) {
Log.d(TAG, result); Log.d(TAG, result);
@ -468,9 +461,8 @@ public class BinaryDictIOTests extends AndroidTestCase {
final List<String> results = CollectionUtils.newArrayList(); final List<String> results = CollectionUtils.newArrayList();
runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION2); runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION2);
runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION3_WITHOUT_PARENTADDRESS); runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION3_WITHOUT_DYNAMIC_UPDATE);
runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION3_WITH_PARENTADDRESS); runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION3_WITH_DYNAMIC_UPDATE);
runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION3_WITH_LINKEDLIST_NODE);
for (final String result : results) { for (final String result : results) {
Log.d(TAG, result); Log.d(TAG, result);
@ -528,7 +520,7 @@ public class BinaryDictIOTests extends AndroidTestCase {
new FusionDictionary.DictionaryOptions( new FusionDictionary.DictionaryOptions(
new HashMap<String, String>(), false, false)); new HashMap<String, String>(), false, false));
addUnigrams(sWords.size(), dict, sWords, null /* shortcutMap */); addUnigrams(sWords.size(), dict, sWords, null /* shortcutMap */);
timeWritingDictToFile(file, dict, VERSION3_WITH_LINKEDLIST_NODE); timeWritingDictToFile(file, dict, VERSION3_WITH_DYNAMIC_UPDATE);
final FusionDictionaryBufferInterface buffer = getBuffer(file, USE_BYTE_ARRAY); final FusionDictionaryBufferInterface buffer = getBuffer(file, USE_BYTE_ARRAY);
@ -569,7 +561,7 @@ public class BinaryDictIOTests extends AndroidTestCase {
public void testDeleteWord() { public void testDeleteWord() {
File file = null; File file = null;
try { try {
file = File.createTempFile("testGetTerminalPosition", ".dict"); file = File.createTempFile("testDeleteWord", ".dict");
} catch (IOException e) { } catch (IOException e) {
// do nothing // do nothing
} }
@ -579,7 +571,7 @@ public class BinaryDictIOTests extends AndroidTestCase {
new FusionDictionary.DictionaryOptions( new FusionDictionary.DictionaryOptions(
new HashMap<String, String>(), false, false)); new HashMap<String, String>(), false, false));
addUnigrams(sWords.size(), dict, sWords, null /* shortcutMap */); addUnigrams(sWords.size(), dict, sWords, null /* shortcutMap */);
timeWritingDictToFile(file, dict, VERSION3_WITH_LINKEDLIST_NODE); timeWritingDictToFile(file, dict, VERSION3_WITH_DYNAMIC_UPDATE);
final FusionDictionaryBufferInterface buffer = getBuffer(file, USE_BYTE_ARRAY); final FusionDictionaryBufferInterface buffer = getBuffer(file, USE_BYTE_ARRAY);