From 3048022fd7852222bc1b4e7a77bbec67a3df880e Mon Sep 17 00:00:00 2001 From: "Andreas L. Delmelle" Date: Fri, 13 Mar 2009 17:51:45 +0000 Subject: [PATCH] Bugzilla 46828: Activation of the possibility to use CachedRenderPagesModel to conserve memory in case of large documents with a lot of cross-references. (area tree will be serialized to disk to avoid keeping it entirely in memory) Thanks to Dario Laeria for submitting and testing. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@753327 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/apps/FOUserAgent.java | 19 ++++++++++ .../org/apache/fop/area/AreaTreeHandler.java | 7 +++- .../fop/area/CachedRenderPagesModel.java | 2 +- .../apache/fop/area/inline/InlineArea.java | 4 +- .../apache/fop/cli/CommandLineOptions.java | 7 ++++ .../layoutmgr/BlockStackingLayoutManager.java | 37 +++++++++++-------- .../table/TableCellLayoutManager.java | 4 +- status.xml | 17 ++++++--- 8 files changed, 70 insertions(+), 27 deletions(-) diff --git a/src/java/org/apache/fop/apps/FOUserAgent.java b/src/java/org/apache/fop/apps/FOUserAgent.java index ebd2e0594..303967a75 100644 --- a/src/java/org/apache/fop/apps/FOUserAgent.java +++ b/src/java/org/apache/fop/apps/FOUserAgent.java @@ -97,6 +97,7 @@ public class FOUserAgent { private Renderer rendererOverride = null; private FOEventHandler foEventHandlerOverride = null; private boolean locatorEnabled = true; // true by default (for error messages). + private boolean conserveMemoryPolicy = false; private EventBroadcaster eventBroadcaster = new FOPEventBroadcaster(); /** Producer: Metadata element for the system/software that produces @@ -615,5 +616,23 @@ public class FOUserAgent { } + /** + * Check whether memory-conservation is enabled. + * + * @return true if FOP is to conserve as much as possible + */ + public boolean isConserveMemoryPolicyEnabled() { + return this.conserveMemoryPolicy; + } + + /** + * Control whether memory-conservation should be enabled + * + * @param conserveMemoryPolicy the cachingEnabled to set + */ + public void setConserveMemoryPolicy(boolean conserveMemoryPolicy) { + this.conserveMemoryPolicy = conserveMemoryPolicy; + } + } diff --git a/src/java/org/apache/fop/area/AreaTreeHandler.java b/src/java/org/apache/fop/area/AreaTreeHandler.java index 128fc8ce9..298cf263b 100644 --- a/src/java/org/apache/fop/area/AreaTreeHandler.java +++ b/src/java/org/apache/fop/area/AreaTreeHandler.java @@ -124,7 +124,11 @@ public class AreaTreeHandler extends FOEventHandler { */ protected void setupModel(FOUserAgent userAgent, String outputFormat, OutputStream stream) throws FOPException { - this.model = new RenderPagesModel(userAgent, outputFormat, fontInfo, stream); + if (userAgent.isConserveMemoryPolicyEnabled()) { + this.model = new CachedRenderPagesModel(userAgent, outputFormat, fontInfo, stream); + } else { + this.model = new RenderPagesModel(userAgent, outputFormat, fontInfo, stream); + } } /** @@ -442,7 +446,6 @@ public class AreaTreeHandler extends FOEventHandler { /** * Default constructor - * @param areaTreeHandler area tree handler */ protected Statistics() { this.runtime = Runtime.getRuntime(); diff --git a/src/java/org/apache/fop/area/CachedRenderPagesModel.java b/src/java/org/apache/fop/area/CachedRenderPagesModel.java index f522b978b..73c50fa17 100644 --- a/src/java/org/apache/fop/area/CachedRenderPagesModel.java +++ b/src/java/org/apache/fop/area/CachedRenderPagesModel.java @@ -129,7 +129,7 @@ public class CachedRenderPagesModel extends RenderPagesModel { try { // save page to cache ObjectOutputStream tempstream; - String fname = "fop-page-" + page.toString() + ".ser"; + String fname = "fop-page-" + page.getPageIndex() + ".ser"; File tempFile = new File(baseDir, fname); tempFile.deleteOnExit(); tempstream = new ObjectOutputStream(new BufferedOutputStream( diff --git a/src/java/org/apache/fop/area/inline/InlineArea.java b/src/java/org/apache/fop/area/inline/InlineArea.java index 6d5d9ca98..5106fd5bc 100644 --- a/src/java/org/apache/fop/area/inline/InlineArea.java +++ b/src/java/org/apache/fop/area/inline/InlineArea.java @@ -19,6 +19,8 @@ package org.apache.fop.area.inline; +import java.io.Serializable; + import org.apache.fop.area.Area; import org.apache.fop.area.LineArea; import org.apache.fop.area.Trait; @@ -35,7 +37,7 @@ public class InlineArea extends Area { * that can be used in order to re-compute adjustments when a * page-number or a page-number-citation is resolved */ - protected class InlineAdjustingInfo { + protected class InlineAdjustingInfo implements Serializable { /** stretch of the inline area */ protected int availableStretch; /** shrink of the inline area */ diff --git a/src/java/org/apache/fop/cli/CommandLineOptions.java b/src/java/org/apache/fop/cli/CommandLineOptions.java index fef2a1f46..cfab37c95 100644 --- a/src/java/org/apache/fop/cli/CommandLineOptions.java +++ b/src/java/org/apache/fop/cli/CommandLineOptions.java @@ -110,6 +110,8 @@ public class CommandLineOptions { private Map renderingOptions = new java.util.HashMap(); /* target resolution (for the user agent) */ private int targetResolution = 0; + /* control memory-conservation policy */ + private boolean conserveMemoryPolicy = false; private FopFactory factory = FopFactory.newInstance(); private FOUserAgent foUserAgent; @@ -168,6 +170,7 @@ public class CommandLineOptions { } addXSLTParameter("fop-output-format", getOutputFormat()); addXSLTParameter("fop-version", Version.getVersion()); + foUserAgent.setConserveMemoryPolicy(conserveMemoryPolicy); } else { return false; } @@ -268,6 +271,8 @@ public class CommandLineOptions { setLogOption("debug", "debug"); } else if (args[i].equals("-r")) { factory.setStrictValidation(false); + } else if (args[i].equals("-conserve")) { + conserveMemoryPolicy = true; } else if (args[i].equals("-dpi")) { i = i + parseResolution(args, i); } else if (args[i].equals("-q") || args[i].equals("--quiet")) { @@ -1131,6 +1136,8 @@ public class CommandLineOptions { + " -noannotations PDF file will be encrypted without edit annotation permission\n" + " -pdfprofile prof PDF file will be generated with the specified profile\n" + " (Examples for prof: PDF/A-1b or PDF/X-3:2003)\n\n" + + " -conserve Enable memory-conservation policy (trades memory-consumption for disk I/O)" + + " (Note: currently only influences whether the area tree is serialized.)" + " [INPUT] \n" + " infile xsl:fo input file (the same as the next) \n" + " (use '-' for infile to pipe input from stdin)\n" diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java index 64b8bbc0d..1f18a67a0 100644 --- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java @@ -167,6 +167,13 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager addChildToArea(childArea, getCurrentArea()); } + /** {@inheritDoc} */ + protected void notifyEndOfLayout() { + super.notifyEndOfLayout(); + // Free memory of the area tree + //this.parentArea = null; + } + /** * Force current area to be added to parent area. */ @@ -486,7 +493,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager // ? "penalty" : (lastElement.isGlue() ? "glue" : "box" ))); /*LF*/ //log.debug(" position e' " + lastElement.getPosition().getClass().getName()); /*LF*/ //log.debug(" " + (bpUnit > 0 ? "unit" : "")); - Position innerPosition = ((NonLeafPosition) lastElement.getPosition()).getPosition(); + Position innerPosition = lastElement.getPosition().getPosition(); if (innerPosition == null && lastElement.isGlue()) { // this adjustment applies to space-before or space-after of this block @@ -536,7 +543,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager /*LF*/ //log.debug(" BLM.negotiateBPDAdjustment> chiamata passata"); return ((BlockLevelLayoutManager)storedPenalty.getLayoutManager()) .negotiateBPDAdjustment(storedPenalty.getW(), - (KnuthElement)storedPenalty); + storedPenalty); } else { // the original penalty has width = 0 // the adjustment involves only the spaces before and after @@ -787,12 +794,12 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager returnList.add(new KnuthGlue(0, 0, 0, SPACE_AFTER_ADJUSTMENT, new NonLeafPosition(this, null), - (!spaceAfterIsConditional) ? false : true)); + spaceAfterIsConditional)); } else { returnList.add(new KnuthGlue(adjustedSpaceAfter, 0, 0, SPACE_AFTER_ADJUSTMENT, new NonLeafPosition(this, null), - (!spaceAfterIsConditional) ? false : true)); + spaceAfterIsConditional)); } if (!spaceAfterIsConditional) { returnList.add(new KnuthBox(0, @@ -1201,8 +1208,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager totalLength.add(new MinOptMax(element.getW())); //log.debug("box " + element.getW()); } else if (element.isGlue()) { - totalLength.min -= ((KnuthGlue) element).getZ(); - totalLength.max += ((KnuthGlue) element).getY(); + totalLength.min -= element.getZ(); + totalLength.max += element.getY(); //leafValue = ((LeafPosition) element.getPosition()).getLeafPos(); //log.debug("glue " + element.getW() + " + " // + ((KnuthGlue) element).getY() + " - " + ((KnuthGlue) element).getZ()); @@ -1239,10 +1246,10 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager lengthAfterBreak.subtract(new MinOptMax(element.getW())); bPrevIsBox = true; } else if (element.isGlue()) { - lengthBeforeBreak.min -= ((KnuthGlue) element).getZ(); - lengthAfterBreak.min += ((KnuthGlue) element).getZ(); - lengthBeforeBreak.max += ((KnuthGlue) element).getY(); - lengthAfterBreak.max -= ((KnuthGlue) element).getY(); + lengthBeforeBreak.min -= element.getZ(); + lengthAfterBreak.min += element.getZ(); + lengthBeforeBreak.max += element.getY(); + lengthAfterBreak.max -= element.getY(); bPrevIsBox = false; } else { lengthBeforeBreak.add(new MinOptMax(element.getW())); @@ -1250,7 +1257,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager } // create the new elements - if (element.isPenalty() && ((KnuthPenalty) element).getP() < KnuthElement.INFINITE + if (element.isPenalty() && element.getP() < KnuthElement.INFINITE || element.isGlue() && bPrevIsBox || !oldListIterator.hasNext()) { // suppress elements after the breaking point @@ -1260,8 +1267,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager iStepsForward++; if (el.isGlue()) { // suppressed glue - lengthAfterBreak.min += ((KnuthGlue) el).getZ(); - lengthAfterBreak.max -= ((KnuthGlue) el).getY(); + lengthAfterBreak.min += el.getZ(); + lengthAfterBreak.max -= el.getY(); } else if (el.isPenalty()) { // suppressed penalty, do nothing } else { @@ -1281,8 +1288,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager for (int i = 0; i < iStepsForward; i++) { KnuthElement el = (KnuthElement) oldListIterator.previous(); if (el.isGlue()) { - lengthAfterBreak.min -= ((KnuthGlue) el).getZ(); - lengthAfterBreak.max += ((KnuthGlue) el).getY(); + lengthAfterBreak.min -= el.getZ(); + lengthAfterBreak.max += el.getY(); } } diff --git a/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java index ba5e232e9..239a1a88e 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java @@ -201,8 +201,6 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager p.setP(0); } - notifyEndOfLayout(); - setFinished(true); return returnList; } @@ -427,6 +425,8 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager flush(); curBlockArea = null; + + notifyEndOfLayout(); } /** Adds background areas for the column, body and row, if any. */ diff --git a/status.xml b/status.xml index 7e60a7342..825824410 100644 --- a/status.xml +++ b/status.xml @@ -58,19 +58,24 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> + + Added the possibility to use CachedRenderPagesModel, to conserve memory in case + of large documents with a lot of cross-references (area tree will be serialized to + disk to avoid keeping it entirely in memory). + - AFP Fonts: Added support for full URI resolution on configured AFP fonts. + AFP Fonts: Added support for full URI resolution on configured AFP fonts. AFP Output: Tag Logical Element (TLE) is now also allowed on fo:page-sequence - (page group level). + (page group level). Fixed BPD trait and border painting for leaders with leader-pattern="space" - (and similar cases). + (and similar cases). - AFP Output: Added support for Invoke Medium Map (IMM). + AFP Output: Added support for Invoke Medium Map (IMM). Introduced a new, additional intermediate format optimized for performance. Please see @@ -89,11 +94,11 @@ code. - MinOptMaxUtil.toMinOptMax was converting LengthRangeProperty objects into illegal MinOptMax + MinOptMaxUtil.toMinOptMax was converting LengthRangeProperty objects into illegal MinOptMax objects (in some cases opt could be inferior to min). - Added extension to disable column balancing before blocks spanning the whole page, in + Added extension to disable column balancing before blocks spanning the whole page, in multiple-column documents. -- 2.39.5