xmlgraphics-fop-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Xmlgraphics-fop Wiki] Update of "PropertyHandling/PropertyCache" by AndreasDelmelle
Date Thu, 08 May 2008 16:59:02 GMT
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Xmlgraphics-fop Wiki" for change notification.

The following page has been changed by AndreasDelmelle:

  Still, this type of streamlining of the stylesheet is not always possible. In contexts where
the stylesheet is generated by a third-party tool, there are likely to be many XML attribute
specifications that, from the point of view of the formatter would be redundant. On another
note, there are also many {{{<enum>}}} properties that share the same possible values,
but are not inherited.
- The initial idea for further optimization in that area was given to FOP by Richard Wheeldon
in a Bugzilla patch (see: https://issues.apache.org/bugzilla/show_bug.cgi?id=41044).
+ The initial idea for further optimization in that area was given to FOP by Richard Wheeldon
in a Bugzilla patch (see: https://issues.apache.org/bugzilla/show_bug.cgi?id=41044). 
+ In its most basic form, some {{{Property}}} subclasses that did not require a layout context
for resolution were equipped with a private static {{{WeakHashMap}}} that retained all created
instances to which other objects held hard references, and accompanying implementations for
{{{equals()}}} and {{{hashCode()}}}. Their constructors were made inaccessible from outside
the package, and instead new instances were created via a public static {{{getInstance()}}}
method. That method creates a new instance, performs a {{{get()}}} on the {{{HashMap}}}, adds
it if it does not exist yet, and returns either the result of the {{{get()}}} or the newly
created instance.
+ Since all the related constructors are simple parameter assignment constructors, like: 
+ {{{
+ public MyProperty(int someInt, Object someObj) {
+     this.primitiveValue = someInt; 
+     this.referenceValue = someObj;
+ }
+ }}}
+ and the generated instances only have to be moved from the stack to the heap if they are
really ''new'' instances to be added to the map, the involved overhead should be minimal in
a language like Java, especially with modern VMs. The well-known warning about instantiation
rates in the early days now more apply to circumstances where one would trigger a chain of
constructors with every instantion (e.g. if the second assignment would be {{{this.referenceValue
= new OtherClass();}}}).
+ == Structure ==
+ As the number of properties to which this approach was applied, began to grow, the decision
was made to implement a dedicated class that could be used by any of the {{{Property}}} classes.
The concern for multi-session environments was first taken into account by wrapping the {{{WeakHashMap}}}
in a standard synchronized map. The {{{PropertyCache}}} itself would only have one or more
{{{fetch(Object obj)}}} methods as public access points, that took care of the operations
that were initially performed within the {{{Property}}} subclasses (see above), so the idiom
had become simply: 
+ {{{
+ public static Property getInstance(int someInt, Object someObj) {
+   return myPropertyCache.fetch(new MyProperty(someInt, someObj));
+ }
+ }}}
+ The newly created instance would either be returned from this method, or disappear into
oblivion and be replaced by the corresponding entry in the map.
+ After fixing some errors in the added {{{hashCode()}}} and {{{equals()}}} implementations,
the first version of the {{{PropertyCache}}} was silently released to the public with FOP
0.94. No big commotion was made back then. As this was still restricted to only a handful
of properties, the assumed effect would be only minimal.
+ In the meantime development went further on the trunk. After reading some more documentation
on multi-threading in Java and studying the concepts of concurrency and contention, it became
obvious that there was a possible performance bottleneck involved in using {{{Collections.synchronizedMap();}}}.
Java 1.5 has its own {{{java.util.concurrent}}} package, but FOP still targets 1.4 environments,
so those could not be used. Even then, the {{{util.concurrent}}} package only offers a {{{ConcurrentHashMap}}},
no variant using {{{WeakReference}}}s, which would be needed to implement a cache that is
shared by many threads. Besides that, a {{{Map}}} always contains ''mappings''. That is: every
entry has a key ''and'' a value. But FOP needed only a weakly referenced key...
+ The following article at IBM gave a starting point for building our very own cache: 
+ http://www.ibm.com/developerworks/java/library/j-jtp08223/index.html

To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org

View raw message