[FD3] Split stackNodes into two methods.

In the future we need to have a method that computes only
from the size, as we used to have, to initialize the cached
addresses, and a much simpler and faster method to copy
the cached sizes.

Bug: 8526576
Change-Id: I6a5a790303ab8f3bf957c7ca266eb12da7c1ad9e
main
Jean Chalard 2013-07-11 13:48:27 +09:00
parent 5526d138fe
commit 429db8d61e
1 changed files with 37 additions and 16 deletions

View File

@ -384,13 +384,12 @@ public final class BinaryDictInputOutput {
/** /**
* Compute the maximum size of a node, assuming 3-byte addresses for everything, and caches * Compute the maximum size of a node, assuming 3-byte addresses for everything, and caches
* it in the 'actualSize' member of the node, then returns it. * it in the 'actualSize' member of the node.
* *
* @param node the node to compute the maximum size of. * @param node the node to compute the maximum size of.
* @param options file format options. * @param options file format options.
* @return the size of the node.
*/ */
private static int calculateNodeMaximumSize(final Node node, final FormatOptions options) { private static void calculateNodeMaximumSize(final Node node, final FormatOptions options) {
int size = getGroupCountSize(node); int size = getGroupCountSize(node);
for (CharGroup g : node.mData) { for (CharGroup g : node.mData) {
final int groupSize = getCharGroupMaximumSize(g, options); final int groupSize = getCharGroupMaximumSize(g, options);
@ -401,7 +400,6 @@ public final class BinaryDictInputOutput {
size += FormatSpec.FORWARD_LINK_ADDRESS_SIZE; size += FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
} }
node.mCachedSize = size; node.mCachedSize = size;
return size;
} }
/** /**
@ -591,22 +589,48 @@ public final class BinaryDictInputOutput {
} }
/** /**
* Computes the byte size of a list of nodes and updates each node cached position. * Initializes the cached addresses of nodes from their size.
* *
* @param flatNodes the array of nodes. * @param flatNodes the array of nodes.
* @param formatOptions file format options. * @param formatOptions file format options.
* @return the byte size of the entire stack. * @return the byte size of the entire stack.
*/ */
// TODO: rename this method when all it does is fill back the cached addresses before update private static int initializeNodesCachedAddresses(final ArrayList<Node> flatNodes,
// with cached addresses after update. final FormatOptions formatOptions) {
private static int stackNodes(final ArrayList<Node> flatNodes, int nodeOffset = 0;
for (final Node n : flatNodes) {
n.mCachedAddressBeforeUpdate = nodeOffset;
int groupCountSize = getGroupCountSize(n);
int groupOffset = 0;
for (final CharGroup g : n.mData) {
g.mCachedAddress = groupCountSize + nodeOffset + groupOffset;
groupOffset += g.mCachedSize;
}
final int nodeSize = groupCountSize + groupOffset
+ (formatOptions.mSupportsDynamicUpdate
? FormatSpec.FORWARD_LINK_ADDRESS_SIZE : 0);
nodeOffset += n.mCachedSize;
}
return nodeOffset;
}
/**
* Updates the cached addresses of nodes after recomputing their new positions.
*
* @param flatNodes the array of nodes.
* @param formatOptions file format options.
* @return the byte size of the entire stack.
*/
private static int updateNodeCachedAddresses(final ArrayList<Node> flatNodes,
final FormatOptions formatOptions) { final FormatOptions formatOptions) {
int nodeOffset = 0; int nodeOffset = 0;
for (final Node n : flatNodes) { for (final Node n : flatNodes) {
n.mCachedAddressBeforeUpdate = n.mCachedAddressAfterUpdate; n.mCachedAddressBeforeUpdate = n.mCachedAddressAfterUpdate;
int groupCountSize = getGroupCountSize(n); int groupCountSize = getGroupCountSize(n);
int groupOffset = 0; int groupOffset = 0;
for (CharGroup g : n.mData) { for (final CharGroup g : n.mData) {
// TODO: just copy cached address after update into cached address before update
// when the two fields are separated.
g.mCachedAddress = groupCountSize + nodeOffset + groupOffset; g.mCachedAddress = groupCountSize + nodeOffset + groupOffset;
groupOffset += g.mCachedSize; groupOffset += g.mCachedSize;
} }
@ -614,6 +638,7 @@ public final class BinaryDictInputOutput {
+ (formatOptions.mSupportsDynamicUpdate + (formatOptions.mSupportsDynamicUpdate
? FormatSpec.FORWARD_LINK_ADDRESS_SIZE : 0); ? FormatSpec.FORWARD_LINK_ADDRESS_SIZE : 0);
if (nodeSize != n.mCachedSize) { if (nodeSize != n.mCachedSize) {
// TODO: remove this test when the addresses are separated
throw new RuntimeException("Bug : Stored and computed node size differ"); throw new RuntimeException("Bug : Stored and computed node size differ");
} }
if (nodeOffset != n.mCachedAddressAfterUpdate) { if (nodeOffset != n.mCachedAddressAfterUpdate) {
@ -665,12 +690,8 @@ public final class BinaryDictInputOutput {
private static ArrayList<Node> computeAddresses(final FusionDictionary dict, private static ArrayList<Node> computeAddresses(final FusionDictionary dict,
final ArrayList<Node> flatNodes, final FormatOptions formatOptions) { final ArrayList<Node> flatNodes, final FormatOptions formatOptions) {
// First get the worst possible sizes and offsets // First get the worst possible sizes and offsets
int offset = 0; for (final Node n : flatNodes) calculateNodeMaximumSize(n, formatOptions);
for (final Node n : flatNodes) { final int offset = initializeNodesCachedAddresses(flatNodes, formatOptions);
n.mCachedAddressAfterUpdate = offset;
offset += calculateNodeMaximumSize(n, formatOptions);
}
offset = stackNodes(flatNodes, formatOptions);
MakedictLog.i("Compressing the array addresses. Original size : " + offset); MakedictLog.i("Compressing the array addresses. Original size : " + offset);
MakedictLog.i("(Recursively seen size : " + offset + ")"); MakedictLog.i("(Recursively seen size : " + offset + ")");
@ -689,7 +710,7 @@ public final class BinaryDictInputOutput {
nodeStartOffset += newNodeSize; nodeStartOffset += newNodeSize;
changesDone |= changed; changesDone |= changed;
} }
stackNodes(flatNodes, formatOptions); updateNodeCachedAddresses(flatNodes, formatOptions);
++passes; ++passes;
if (passes > MAX_PASSES) throw new RuntimeException("Too many passes - probably a bug"); if (passes > MAX_PASSES) throw new RuntimeException("Too many passes - probably a bug");
} while (changesDone); } while (changesDone);