| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN"> | |
| <html> | |
| <head> | |
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | |
| <title>Boost.Flyweight Documentation - Examples</title> | |
| <link rel="stylesheet" href="style.css" type="text/css"> | |
| <link rel="start" href="index.html"> | |
| <link rel="prev" href="performance.html"> | |
| <link rel="up" href="index.html"> | |
| <link rel="next" href="tests.html"> | |
| </head> | |
| <body> | |
| <h1><img src="../../../boost.png" alt="Boost logo" align= | |
| "middle" width="277" height="86">Boost.Flyweight Examples</h1> | |
| <div class="prev_link"><a href="performance.html"><img src="prev.gif" alt="performance" border="0"><br> | |
| Performance | |
| </a></div> | |
| <div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br> | |
| Index | |
| </a></div> | |
| <div class="next_link"><a href="tests.html"><img src="next.gif" alt="tests" border="0"><br> | |
| Tests | |
| </a></div><br clear="all" style="clear: all;"> | |
| <br clear="all" style="clear: all;"> | |
| <hr> | |
| <h2>Contents</h2> | |
| <ul> | |
| <li><a href="#example1">Example 1: basic usage</a></li> | |
| <li><a href="#example2">Example 2: key-value flyweights</a></li> | |
| <li><a href="#example3">Example 3: flyweights and the composite pattern</a></li> | |
| <li><a href="#example4">Example 4: formatted text processing</a></li> | |
| <li><a href="#example5">Example 5: flyweight-based memoization</a></li> | |
| <li><a href="#example6">Example 6: performance comparison</a></li> | |
| <li><a href="#example7">Example 7: custom factory</a></li> | |
| </ul> | |
| <h2><a name="example1">Example 1: basic usage</a></h2> | |
| <p> | |
| See <a href="../example/basic.cpp">source code</a>. | |
| </p> | |
| <p> | |
| Dummy program showing the basic capabilities of <code>flyweight</code> | |
| explained at the <a href="tutorial/basics.html">tutorial</a>. | |
| </p> | |
| <h2><a name="example2">Example 2: key-value flyweights</a></h2> | |
| <p> | |
| See <a href="../example/key_value.cpp">source code</a>. | |
| </p> | |
| <p> | |
| The program simulates the scenario described at the tutorial section on | |
| <a href="tutorial/key_value.html">key-value flyweights</a>: The class | |
| <code>texture</code> manages some texture rendering data stored in | |
| a file whose location is given at construction time. The program | |
| handles large quantities of objects of this class by encapsulating | |
| them into key-value flyweights keyed by filename. Observe how the | |
| execution of the program results in no extra constructions or copies | |
| of objects of type <code>texture</code> except those absolutely | |
| necessary. | |
| </p> | |
| <h2><a name="example3">Example 3: flyweights and the composite pattern</a></h2> | |
| <p> | |
| See <a href="../example/composite.cpp">source code</a>. | |
| </p> | |
| <p> | |
| The <a href="http://c2.com/cgi/wiki?CompositePattern"><i>composite | |
| design pattern</i></a> revolves about the idea that a tree data structure | |
| can be easily constructed and manipulated by defining the tree node type | |
| polymorphically so that either is a leaf node or else contains a list of | |
| pointers to their child nodes. | |
| This way, a tree is the exact same entity as its root node, which allows | |
| for very simple recursive tree-handling algorithms. Large composite trees | |
| having a high degree of duplication of nodes and subtrees (as for instance | |
| those generated when parsing a computer program) are a natural fit for the | |
| flyweight idiom: simply turning the node type into a flyweight | |
| automatically deals with duplication at the node and subtree level. | |
| </p> | |
| <p> | |
| The example program parses Lisp-like lists of the form | |
| <code>(a<sub>1</sub> ... a<sub><i>n</i></sub>)</code> where each | |
| <code>a<sub>i</sub></code> is a terminal string or a list. The parsed | |
| data structure is a composite type defined using Boost.Flyweight in conjunction | |
| with the recursive facilities of | |
| <a href="../../variant/index.html">Boost.Variant</a>. So, given the list | |
| </p> | |
| <blockquote><pre> | |
| (= (tan (+ x y))(/ (+ (tan x)(tan y))(- 1 (* (tan x)(tan y))))) | |
| </pre></blockquote> | |
| <p> | |
| the resulting data structure implicitly detects the duplicated | |
| occurrences of <code>+</code>, <code>x</code>, <code>y</code>, | |
| <code>tan</code>, <code>(tan x)</code> and <code>(tan y)</code>. | |
| </p> | |
| <h2><a name="example4">Example 4: formatted text processing</a></h2> | |
| <p> | |
| See <a href="../example/html.cpp">source code</a>. | |
| </p> | |
| <p> | |
| A classic example of application of the flyweight pattern is that of a | |
| text processor which handles characters with rich formatting information, | |
| like font type, size, color and special options (boldness, italics, etc.) | |
| Coding the formatting information of each character takes considerable | |
| space, but, given the high degree of repetition typical in a document, | |
| maintaining formatted characters as flyweight objects drastically reduces | |
| memory consumption. | |
| </p> | |
| <p> | |
| The example program parses, manipulates and stores HTML documents following | |
| flyweight-based representation techniques. Given the hierarchical nature | |
| of HTML markup, a crude approximation to the formatting options of a given | |
| character is just to equate them with the stack of tag contexts to which | |
| the character belongs, as the figure shows. | |
| </p> | |
| <p align="center"> | |
| <img src="html.png" | |
| alt="formatting contexts of characters in an HTML document" | |
| width="320" height="275"><br> | |
| <b>Fig. 1: Formatting contexts of characters in an HTML document.</b> | |
| </p> | |
| <p> | |
| HTML documents are then parsed as arrays of (character, format) | |
| pairs, where the format is the tag context as described above. The very high | |
| degree of redundancy in formatting information is taken care of by the | |
| use of Boost.Flyweight. This character-based representation makes it | |
| easy to manipulate the document: transposition and elimination of | |
| portions of text are trivial operations. As an example, the program | |
| reverses the text occupying the central portion of the document. | |
| Saving the result in HTML reduces to traversing the array of formatted | |
| characters and emitting opening/closing HTML tags as the context of adjacent | |
| characters varies. | |
| </p> | |
| <p> | |
| For the sake of brevity, the HTML parsing capabilities of this program | |
| are coarse: for instance, elements without end-tag (like <BR>), character | |
| enconding and HTML entities (e.g. "&copy;" for ©) are not properly | |
| handled. Improving the parsing code is left as an exercise to the reader. | |
| </p> | |
| <h2><a name="example5">Example 5: flyweight-based memoization</a></h2> | |
| <p> | |
| See <a href="../example/fibonacci.cpp">source code</a>. | |
| </p> | |
| <p> | |
| <a href="http://en.wikipedia.org/wiki/Memoization">Memoization</a> | |
| is an optimization technique consisting in caching | |
| the results of a computation for later reuse; this can dramatically | |
| improve performance when calculating recursive numerical functions, | |
| for instance. <a href="tutorial/key_value.html">Key-value flyweights</a> | |
| can be used to implement memoization for a numerical function <i>f</i> | |
| by modeling a memoized invocation of the function as a value of | |
| type <code>flyweight<key_value<int,compute_f> ></code>, where | |
| <code>compute_f</code> is a type that does the computation of | |
| <i>f</i>(<i>n</i>) at its <code>compute_f::compute_f(int)</code> constructor. | |
| For instance, the <a href="http://mathworld.wolfram.com/FibonacciNumber.html">Fibonacci | |
| numbers</a> can be computed with memoization like this: | |
| </p> | |
| <blockquote><pre> | |
| <span class=keyword>typedef</span> <span class=identifier>flyweight</span><span class=special><</span><span class=identifier>key_value</span><span class=special><</span><span class=keyword>int</span><span class=special>,</span><span class=identifier>compute_fibonacci</span><span class=special>>,</span><span class=identifier>no_tracking</span><span class=special>></span> <span class=identifier>fibonacci</span><span class=special>;</span> | |
| <span class=keyword>struct</span> <span class=identifier>compute_fibonacci</span> | |
| <span class=special>{</span> | |
| <span class=identifier>compute_fibonacci</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>n</span><span class=special>):</span> | |
| <span class=identifier>result</span><span class=special>(</span><span class=identifier>n</span><span class=special>==</span><span class=number>0</span><span class=special>?</span><span class=number>0</span><span class=special>:</span><span class=identifier>n</span><span class=special>==</span><span class=number>1</span><span class=special>?</span><span class=number>1</span><span class=special>:</span><span class=identifier>fibonacci</span><span class=special>(</span><span class=identifier>n</span><span class=special>-</span><span class=number>2</span><span class=special>).</span><span class=identifier>get</span><span class=special>()+</span><span class=identifier>fibonacci</span><span class=special>(</span><span class=identifier>n</span><span class=special>-</span><span class=number>1</span><span class=special>).</span><span class=identifier>get</span><span class=special>())</span> | |
| <span class=special>{}</span> | |
| <span class=keyword>operator</span> <span class=keyword>int</span><span class=special>()</span><span class=keyword>const</span><span class=special>{</span><span class=keyword>return</span> <span class=identifier>result</span><span class=special>;}</span> | |
| <span class=keyword>int</span> <span class=identifier>result</span><span class=special>;</span> | |
| <span class=special>};</span> | |
| </pre></blockquote> | |
| <p> | |
| The <a href="tutorial/configuration.html#no_tracking"><code>no_tracking</code></a> | |
| policy is used so that the memoized computations persist for future | |
| use throughout the program. The provided program develops this example in full. | |
| </p> | |
| <h2><a name="example6">Example 6: performance comparison</a></h2> | |
| <p> | |
| See <a href="../example/perf.cpp">source code</a>. | |
| </p> | |
| <p> | |
| This program measures the time and space performances of a simple | |
| string type against several differently configured <code>flyweight</code> | |
| instantations as used in a conventional task involving parsing a file and | |
| doing some manipulations on the parsed text. | |
| Memory consumption is computed by instrumenting the relevant | |
| components (the string type itself, flyweight factories, etc.) with custom | |
| allocators that keep track of the allocations and deallocations requested. | |
| The program has been used to produce the experimental results given | |
| at the <a href="performance.html#results">performance section</a>. | |
| </p> | |
| <h2><a name="example7">Example 7: custom factory</a></h2> | |
| <p> | |
| See <a href="../example/custom_factory.cpp">source code</a>. | |
| </p> | |
| <p> | |
| The example shows how to write and use a custom factory class. This | |
| "verbose" factory outputs messages tracing the invocations of its public interface | |
| by Boost.Flyweight, so helping the user visualize factory usage patterns. | |
| </p> | |
| <hr> | |
| <div class="prev_link"><a href="performance.html"><img src="prev.gif" alt="performance" border="0"><br> | |
| Performance | |
| </a></div> | |
| <div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br> | |
| Index | |
| </a></div> | |
| <div class="next_link"><a href="tests.html"><img src="next.gif" alt="tests" border="0"><br> | |
| Tests | |
| </a></div><br clear="all" style="clear: all;"> | |
| <br clear="all" style="clear: all;"> | |
| <br> | |
| <p>Revised December 2nd 2008</p> | |
| <p>© Copyright 2006-2008 Joaquín M López Muñoz. | |
| Distributed under the Boost Software | |
| License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt"> | |
| LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"> | |
| http://www.boost.org/LICENSE_1_0.txt</a>) | |
| </p> | |
| </body> | |
| </html> |