]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/flyweight/doc/tutorial/basics.html
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / flyweight / doc / tutorial / basics.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
2
3 <html>
4 <head>
5 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
6 <title>Boost.Flyweight Documentation - Tutorial - Basics</title>
7 <link rel="stylesheet" href="../style.css" type="text/css">
8 <link rel="start" href="../index.html">
9 <link rel="prev" href="index.html">
10 <link rel="up" href="index.html">
11 <link rel="next" href="key_value.html">
12 </head>
13
14 <body>
15 <h1><img src="../../../../boost.png" alt="Boost logo" align=
16 "middle" width="277" height="86">Boost.Flyweight Tutorial: Basics</h1>
17
18 <div class="prev_link"><a href="index.html"><img src="../prev.gif" alt="Boost.Flyweight tutorial" border="0"><br>
19 Boost.Flyweight tutorial
20 </a></div>
21 <div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.Flyweight tutorial" border="0"><br>
22 Boost.Flyweight tutorial
23 </a></div>
24 <div class="next_link"><a href="key_value.html"><img src="../next.gif" alt="key-value flyweights" border="0"><br>
25 Key-value flyweights
26 </a></div><br clear="all" style="clear: all;">
27
28 <hr>
29
30 <h2>Contents</h2>
31
32 <ul>
33 <li><a href="#intro">Introduction</a>
34 <ul>
35 <li><a href="#serialization">Serialization</a></li>
36 </ul>
37 </li>
38 <li><a href="#requirements">Flyweight requirements</a></li>
39 </ul>
40
41 <h2><a name="intro">Introduction</a></h2>
42
43 <p>
44 Suppose we are writing a massive multiplayer online game
45 which has to maintain hundreds of thousands or millions of instances
46 of the following class in memory:
47 </p>
48
49 <blockquote><pre>
50 <span class=keyword>struct</span> <span class=identifier>user_entry</span>
51 <span class=special>{</span>
52 <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>first_name</span><span class=special>;</span>
53 <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>last_name</span><span class=special>;</span>
54 <span class=keyword>int</span> <span class=identifier>age</span><span class=special>;</span>
55 <span class=special>...</span>
56 <span class=special>};</span>
57 </pre></blockquote>
58
59 <p>
60 In this kind of environments memory resources are precious, so we are seeking
61 ways to make <code>user_entry</code> as compact as possible. Typically, there
62 exists a very high level of repetition of first and last names among
63 the community users, so an obvious optimization consists in moving
64 <code>user_entry::first_name</code> and <code>user_entry::last_name</code>
65 objects to a common repository where duplicates are avoided, and leaving
66 references to these inside <code>user_entry</code>. This is precisely what
67 Boost.Flyweight does in the simplest possible way for the programmer:
68 </p>
69
70 <blockquote><pre>
71 <span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>flyweight</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
72
73 <span class=keyword>struct</span> <span class=identifier>user_entry</span>
74 <span class=special>{</span>
75 <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;</span> <span class=identifier>first_name</span><span class=special>;</span>
76 <span class=identifier>flyweight</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;</span> <span class=identifier>last_name</span><span class=special>;</span>
77 <span class=keyword>int</span> <span class=identifier>age</span><span class=special>;</span>
78 <span class=special>...</span>
79 <span class=special>};</span>
80 </pre></blockquote>
81
82 <p>
83 Boost.Flyweight automatically performs the optimization just described behind
84 the scenes, so that the net effect of this change is that the memory
85 usage of the program decreases by a factor proportional to the level of
86 redundancy among user names.
87 </p>
88
89 <p>
90 <code>flyweight&lt;std::string&gt;</code> behaves in many ways like
91 <code>std::string</code>; for instance, the following code works
92 unchanged after the redefinition of <code>user_entry</code>:
93 </p>
94
95 <blockquote><pre>
96 <span class=comment>// flyweight&lt;T&gt; can be constructed in the same way as T objects can,
97 // even with multiple argument constructors</span>
98
99 <span class=identifier>user_entry</span><span class=special>::</span><span class=identifier>user_entry</span><span class=special>(</span><span class=keyword>const</span> <span class=keyword>char</span><span class=special>*</span> <span class=identifier>f</span><span class=special>,</span><span class=keyword>const</span> <span class=keyword>char</span><span class=special>*</span> <span class=identifier>l</span><span class=special>,</span><span class=keyword>int</span> <span class=identifier>a</span><span class=special>,...):</span>
100 <span class=identifier>first_name</span><span class=special>(</span><span class=identifier>f</span><span class=special>),</span>
101 <span class=identifier>last_name</span><span class=special>(</span><span class=identifier>l</span><span class=special>),</span>
102 <span class=identifier>age</span><span class=special>(</span><span class=identifier>a</span><span class=special>),</span>
103 <span class=special>...</span>
104 <span class=special>{}</span>
105
106 <span class=comment>// flyweight classes have relational operators replicating the
107 // semantics of the underyling type</span>
108
109 <span class=keyword>bool</span> <span class=identifier>same_name</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>user_entry</span><span class=special>&amp;</span> <span class=identifier>user1</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>user_entry</span><span class=special>&amp;</span> <span class=identifier>user2</span><span class=special>)</span>
110 <span class=special>{</span>
111 <span class=keyword>return</span> <span class=identifier>user1</span><span class=special>.</span><span class=identifier>first_name</span><span class=special>==</span><span class=identifier>user2</span><span class=special>.</span><span class=identifier>first_name</span> <span class=special>&amp;&amp;</span>
112 <span class=identifier>user1</span><span class=special>.</span><span class=identifier>last_name</span><span class=special>==</span><span class=identifier>user2</span><span class=special>.</span><span class=identifier>last_name</span><span class=special>;</span>
113 <span class=special>}</span>
114
115 <span class=comment>// flyweight&lt;T&gt; provides operator&lt;&lt; and operator&gt;&gt; internally
116 // forwarding to T::operator&lt;&lt; and T::operator&gt;&gt;</span>
117
118 <span class=identifier>std</span><span class=special>::</span><span class=identifier>ostream</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>&lt;&lt;(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>ostream</span><span class=special>&amp;</span> <span class=identifier>os</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>user_entry</span><span class=special>&amp;</span> <span class=identifier>user</span><span class=special>)</span>
119 <span class=special>{</span>
120 <span class=keyword>return</span> <span class=identifier>os</span><span class=special>&lt;&lt;</span><span class=identifier>user</span><span class=special>.</span><span class=identifier>first_name</span><span class=special>&lt;&lt;</span><span class=string>&quot; &quot;</span><span class=special>&lt;&lt;</span><span class=identifier>user</span><span class=special>.</span><span class=identifier>last_name</span><span class=special>&lt;&lt;</span><span class=string>&quot; &quot;</span><span class=special>&lt;&lt;</span><span class=identifier>user</span><span class=special>.</span><span class=identifier>age</span><span class=special>;</span>
121 <span class=special>}</span>
122
123 <span class=identifier>std</span><span class=special>::</span><span class=identifier>istream</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>&gt;&gt;(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>istream</span><span class=special>&amp;</span> <span class=identifier>is</span><span class=special>,</span><span class=identifier>user_entry</span><span class=special>&amp;</span> <span class=identifier>user</span><span class=special>)</span>
124 <span class=special>{</span>
125 <span class=keyword>return</span> <span class=identifier>is</span><span class=special>&gt;&gt;</span><span class=identifier>user</span><span class=special>.</span><span class=identifier>first_name</span><span class=special>&gt;&gt;</span><span class=identifier>user</span><span class=special>.</span><span class=identifier>last_name</span><span class=special>&gt;&gt;</span><span class=identifier>user</span><span class=special>.</span><span class=identifier>age</span><span class=special>;</span>
126 <span class=special>}</span>
127 </pre></blockquote>
128
129 <p>
130 Besides, <code>flyweight&lt;T&gt;</code> is convertible to
131 <code>const T&amp;</code>, either implicitly or through the <code>get</code>
132 member function:
133 </p>
134
135 <blockquote><pre>
136 <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>full_name</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>user_entry</span><span class=special>&amp;</span> <span class=identifier>user</span><span class=special>)</span>
137 <span class=special>{</span>
138 <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>full</span><span class=special>;</span>
139
140 <span class=identifier>full</span><span class=special>.</span><span class=identifier>reserve</span><span class=special>(</span>
141 <span class=identifier>user</span><span class=special>.</span><span class=identifier>first_name</span><span class=special>.</span><span class=identifier>get</span><span class=special>().</span><span class=identifier>size</span><span class=special>()+</span> <span class=comment>// get() returns the underlying</span>
142 <span class=identifier>user</span><span class=special>.</span><span class=identifier>last_name</span><span class=special>.</span><span class=identifier>get</span><span class=special>().</span><span class=identifier>size</span><span class=special>()+</span><span class=number>1</span><span class=special>);</span> <span class=comment>// const std::string&amp;</span>
143
144 <span class=identifier>full</span><span class=special>+=</span><span class=identifier>user</span><span class=special>.</span><span class=identifier>first_name</span><span class=special>;</span> <span class=comment>// implicit conversion is used here</span>
145 <span class=identifier>full</span><span class=special>+=</span><span class=string>&quot; &quot;</span><span class=special>;</span>
146 <span class=identifier>full</span><span class=special>+=</span><span class=identifier>user</span><span class=special>.</span><span class=identifier>last_name</span><span class=special>;</span>
147
148 <span class=keyword>return</span> <span class=identifier>full</span><span class=special>;</span>
149 <span class=special>}</span>
150 </pre></blockquote>
151
152 <p>
153 The most important restriction to take into account when replacing a class
154 with an equivalent flyweight is the fact that flyweights are not
155 mutable: since several flyweight objects can share the same representation
156 value, modifying this value is not admissible. On the other hand, flyweight
157 objects can be assigned new values:
158 </p>
159
160 <blockquote><pre>
161 <span class=keyword>void</span> <span class=identifier>change_name</span><span class=special>(</span>
162 <span class=identifier>user_entry</span><span class=special>&amp;</span> <span class=identifier>user</span><span class=special>,</span>
163 <span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&amp;</span> <span class=identifier>f</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&amp;</span> <span class=identifier>l</span><span class=special>)</span>
164 <span class=special>{</span>
165 <span class=identifier>user</span><span class=special>.</span><span class=identifier>first_name</span><span class=special>=</span><span class=identifier>f</span><span class=special>;</span>
166 <span class=identifier>user</span><span class=special>.</span><span class=identifier>last_name</span><span class=special>=</span><span class=identifier>l</span><span class=special>;</span>
167 <span class=special>}</span>
168 </pre></blockquote>
169
170 <p>
171 In general, <code>flyweight&lt;T&gt;</code> interface is designed to make
172 the transition from plain <code>T</code> as straightforward as possible.
173 Check the <a href="../reference/flyweight.html#flyweight">reference</a> for
174 further details on the interface of the class template <code>flyweight</code>.
175 The <a href="../examples.html">examples section</a> explores
176 some common usage scenarios of Boost.Flyweight.
177 </p>
178
179 <h4><a name="serialization">Serialization</a></h4>
180
181 <p>
182 <code>flyweight&lt;T&gt;</code> can be serialized by means of the
183 <a href="../../../serialization/index.html">Boost Serialization Library</a>
184 as long as the underlying <code>T</code> is serializable. Both regular and
185 XML archives are supported. In order to
186 use Boost.Flyweight serialization capabilities, the specific
187 header <a href="../reference/flyweight.html#serialize_synopsis"><code>"boost/flyweight/serialize.hpp"</code></a>
188 must be included.
189 </p>
190
191 <blockquote><pre><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">flyweight</span><span class="special">/</span><span class="identifier">serialize</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
192
193 <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Archive</span><span class="special">&gt;</span>
194 <span class="keyword">void</span> <span class="identifier">serialize</span><span class="special">(</span><span class="identifier">Archive</span><span class="special">&amp;</span> <span class="identifier">ar</span><span class="special">,</span><span class="identifier">user_entry</span><span class="special">&amp;</span> <span class="identifier">user</span><span class="special">,</span><span class="keyword">const</span> <span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">)</span>
195 <span class="special">{</span>
196 <span class="identifier">ar</span><span class="special">&amp;</span><span class="identifier">user</span><span class="special">.</span><span class="identifier">first_name</span><span class="special">;</span>
197 <span class="identifier">ar</span><span class="special">&amp;</span><span class="identifier">user</span><span class="special">.</span><span class="identifier">last_name</span><span class="special">;</span>
198 <span class="identifier">ar</span><span class="special">&amp;</span><span class="identifier">user</span><span class="special">.</span><span class="identifier">age</span><span class="special">;</span>
199 <span class="special">...</span>
200 <span class="special">}</span>
201 </pre></blockquote>
202
203 <p>
204 Much as using Boost.Flyweight reduces memory consumption due to the internal
205 sharing of duplicate values, serializing <code>flyweight</code>s can also
206 result in smaller archive files, as a common value is only stored
207 once and their associated <code>flyweight</code>s get saved as references to it.
208 This policy is observed even if <code>flyweight</code> underlying type is
209 not <a href="../../../serialization/doc/traits.html#tracking">tracked</a>
210 by Boost.Serialization.
211 </p>
212
213 <p>
214 See <a href="../examples.html#example6">example 6</a> at the examples section
215 for an illustration of use of Boost.Flyweight serialization capabilities.
216 </p>
217
218 <h3><a name="requirements">Flyweight requirements</a></h3>
219
220 <p>
221 For <code>flyweight&lt;T&gt;</code> to be instantiable, <code>T</code> must
222 be <a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>,
223 <a href="http://www.sgi.com/tech/stl/EqualityComparable.html"><code>Equality
224 Comparable</code></a> and must interoperate with
225 <a href="../../../functional/hash/index.html">Boost.Hash</a>.
226 The first requirement is probably met without any extra effort by the user,
227 not so the other two, except for the most common basic types of C++
228 and the standard library. Equality and hashing of <code>T</code> are used
229 internally by <code>flyweight&lt;T&gt;</code> internal factory to maintain the
230 common repository of unique <code>T</code> values referred to by the flyweight
231 objects. Consult the Boost.Hash documentation
232 <a href="../../../../doc/html/hash/custom.html">section</a> on extending
233 that library for custom data types.
234 </p>
235
236 <p>
237 As we have seen, equality and hash requirements on <code>T</code> are
238 imposed by the particular type of <i>flyweight factory</i> internally used by
239 <code>flyweight&lt;T&gt;</code>. We will see later how the user can customize
240 this factory to use equality and hash predicates other than the default,
241 or even switch to an entirely different kind of factory which may impose
242 another requirements on <code>T</code>, as described in the section on
243 <a href="configuration.html">configuring Boost.Flyweight</a>.
244 </p>
245
246 <hr>
247
248 <div class="prev_link"><a href="index.html"><img src="../prev.gif" alt="Boost.Flyweight tutorial" border="0"><br>
249 Boost.Flyweight tutorial
250 </a></div>
251 <div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.Flyweight tutorial" border="0"><br>
252 Boost.Flyweight tutorial
253 </a></div>
254 <div class="next_link"><a href="key_value.html"><img src="../next.gif" alt="key-value flyweights" border="0"><br>
255 Key-value flyweights
256 </a></div><br clear="all" style="clear: all;">
257
258 <br>
259
260 <p>Revised September 1st 2014</p>
261
262 <p>&copy; Copyright 2006-2014 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
263 Distributed under the Boost Software
264 License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
265 LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
266 http://www.boost.org/LICENSE_1_0.txt</a>)
267 </p>
268
269 </body>
270 </html>