• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2<html>
3<head>
4<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5<title>Customizing Boost.Interprocess</title>
6<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
7<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
8<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
9<link rel="up" href="../interprocess.html" title="Chapter 18. Boost.Interprocess">
10<link rel="prev" href="architecture.html" title="Architecture and internals">
11<link rel="next" href="acknowledgements_notes.html" title="Acknowledgements, notes and links">
12</head>
13<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
14<table cellpadding="2" width="100%"><tr>
15<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
16<td align="center"><a href="../../../index.html">Home</a></td>
17<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
18<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
19<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
20<td align="center"><a href="../../../more/index.htm">More</a></td>
21</tr></table>
22<hr>
23<div class="spirit-nav">
24<a accesskey="p" href="architecture.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../interprocess.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="acknowledgements_notes.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
25</div>
26<div class="section">
27<div class="titlepage"><div><div><h2 class="title" style="clear: both">
28<a name="interprocess.customizing_interprocess"></a><a class="link" href="customizing_interprocess.html" title="Customizing Boost.Interprocess">Customizing Boost.Interprocess</a>
29</h2></div></div></div>
30<div class="toc"><dl class="toc">
31<dt><span class="section"><a href="customizing_interprocess.html#interprocess.customizing_interprocess.custom_interprocess_alloc">Writing
32      a new shared memory allocation algorithm</a></span></dt>
33<dt><span class="section"><a href="customizing_interprocess.html#interprocess.customizing_interprocess.custom_allocators">Building
34      custom STL compatible allocators for Boost.Interprocess</a></span></dt>
35<dt><span class="section"><a href="customizing_interprocess.html#interprocess.customizing_interprocess.custom_indexes">Building
36      custom indexes</a></span></dt>
37</dl></div>
38<div class="section">
39<div class="titlepage"><div><div><h3 class="title">
40<a name="interprocess.customizing_interprocess.custom_interprocess_alloc"></a><a class="link" href="customizing_interprocess.html#interprocess.customizing_interprocess.custom_interprocess_alloc" title="Writing a new shared memory allocation algorithm">Writing
41      a new shared memory allocation algorithm</a>
42</h3></div></div></div>
43<p>
44        If the default algorithm does not satisfy user requirements, it's easy to
45        provide different algorithms like bitmapping or more advanced segregated
46        lists to meet requirements. The class implementing the algorithm must be
47        compatible with shared memory, so it shouldn't have any virtual function
48        or virtual inheritance or any indirect base class with virtual function or
49        inheritance.
50      </p>
51<p>
52        This is the interface to be implemented:
53      </p>
54<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">my_algorithm</span>
55<span class="special">{</span>
56   <span class="keyword">public</span><span class="special">:</span>
57
58   <span class="comment">//!The mutex type to be used by the rest of Interprocess framework</span>
59   <span class="keyword">typedef</span> <span class="identifier">implementation_defined</span>   <span class="identifier">mutex_family</span><span class="special">;</span>
60
61   <span class="comment">//!The pointer type to be used by the rest of Interprocess framework</span>
62   <span class="keyword">typedef</span> <span class="identifier">implementation_defined</span>   <span class="identifier">void_pointer</span><span class="special">;</span>
63
64   <span class="comment">//!Constructor. "size" is the total size of the managed memory segment,</span>
65   <span class="comment">//!"extra_hdr_bytes" indicates the extra bytes after the sizeof(my_algorithm)</span>
66   <span class="comment">//!that the allocator should not use at all.</span>
67   <span class="identifier">my_algorithm</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">extra_hdr_bytes</span><span class="special">);</span>
68
69   <span class="comment">//!Obtains the minimum size needed by the algorithm</span>
70   <span class="keyword">static</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">get_min_size</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">extra_hdr_bytes</span><span class="special">);</span>
71
72   <span class="comment">//!Allocates bytes, returns 0 if there is not more memory</span>
73   <span class="keyword">void</span><span class="special">*</span> <span class="identifier">allocate</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">nbytes</span><span class="special">);</span>
74
75   <span class="comment">//!Deallocates previously allocated bytes</span>
76   <span class="keyword">void</span>  <span class="identifier">deallocate</span> <span class="special">(</span><span class="keyword">void</span> <span class="special">*</span><span class="identifier">adr</span><span class="special">);</span>
77
78   <span class="comment">//!Returns the size of the memory segment</span>
79   <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">get_size</span><span class="special">()</span>  <span class="keyword">const</span><span class="special">;</span>
80
81   <span class="comment">//!Increases managed memory in extra_size bytes more</span>
82   <span class="keyword">void</span> <span class="identifier">grow</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">extra_size</span><span class="special">);</span>
83   <span class="comment">/*...*/</span>
84<span class="special">};</span>
85</pre>
86<p>
87        Let's see the public typedefs to define:
88      </p>
89<pre class="programlisting"><span class="keyword">typedef</span> <span class="comment">/* . . . */</span> <span class="identifier">void_pointer</span><span class="special">;</span>
90<span class="keyword">typedef</span> <span class="comment">/* . . . */</span> <span class="identifier">mutex_family</span><span class="special">;</span>
91</pre>
92<p>
93        The <code class="computeroutput"><span class="identifier">void_pointer</span></code> typedef
94        specifies the pointer type to be used in the <span class="bold"><strong>Boost.Interprocess</strong></span>
95        framework that uses the algorithm. For example, if we define
96      </p>
97<pre class="programlisting"><span class="keyword">typedef</span> <span class="keyword">void</span> <span class="special">*</span> <span class="identifier">void_pointer</span><span class="special">;</span>
98</pre>
99<p>
100        all <span class="bold"><strong>Boost.Interprocess</strong></span> framework using this
101        algorithm will use raw pointers as members. But if we define:
102      </p>
103<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">offset_ptr</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">void_pointer</span><span class="special">;</span>
104</pre>
105<p>
106        then all <span class="bold"><strong>Boost.Interprocess</strong></span> framework will
107        use relative pointers.
108      </p>
109<p>
110        The <code class="computeroutput"><span class="identifier">mutex_family</span></code> is a structure
111        containing typedefs for different interprocess_mutex types to be used in
112        the <span class="bold"><strong>Boost.Interprocess</strong></span> framework. For example
113        the defined
114      </p>
115<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">mutex_family</span>
116<span class="special">{</span>
117   <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">::</span><span class="identifier">interprocess_mutex</span>             <span class="identifier">mutex_type</span><span class="special">;</span>
118   <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">::</span><span class="identifier">interprocess_recursive_mutex</span>   <span class="identifier">recursive_mutex_type</span><span class="special">;</span>
119<span class="special">};</span>
120</pre>
121<p>
122        defines all interprocess_mutex types using boost::interprocess interprocess_mutex
123        types. The user can specify the desired mutex family.
124      </p>
125<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">mutex_family</span> <span class="identifier">mutex_family</span><span class="special">;</span>
126</pre>
127<p>
128        The new algorithm (let's call it <span class="bold"><strong>my_algorithm</strong></span>)
129        must implement all the functions that boost::interprocess::rbtree_best_fit
130        class offers:
131      </p>
132<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
133<li class="listitem">
134            <span class="bold"><strong>my_algorithm</strong></span>'s constructor must take
135            2 arguments:
136            <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
137<li class="listitem">
138                  <span class="bold"><strong>size</strong></span> indicates the total size
139                  of the managed memory segment, and <span class="bold"><strong>my_algorithm</strong></span>
140                  object will be always constructed a at offset 0 of the memory segment.
141                </li>
142<li class="listitem">
143                  The <span class="bold"><strong>extra_hdr_bytes</strong></span> parameter
144                  indicates the number of bytes after the offset <code class="computeroutput"><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">my_algorithm</span><span class="special">)</span></code> that <span class="bold"><strong>my_algorithm</strong></span>
145                  can't use at all. This extra bytes will be used to store additional
146                  data that should not be overwritten. So, <span class="bold"><strong>my_algorithm</strong></span>
147                  will be placed at address XXX of the memory segment, and will manage
148                  the <span class="bold"><strong>[XXX + sizeof(my_algorithm) + extra_hdr_bytes,
149                  XXX + size)</strong></span> range of the segment.
150                </li>
151</ul></div>
152          </li>
153<li class="listitem">
154            The <span class="bold"><strong>get_min_size()</strong></span> function should return
155            the minimum space the algorithm needs to be valid with the passed <span class="bold"><strong>extra_hdr_bytes</strong></span> parameter. This function will
156            be used to check if the memory segment is big enough to place the algorithm
157            there.
158          </li>
159<li class="listitem">
160            The <span class="bold"><strong>allocate()</strong></span> function must return
161            0 if there is no more available memory. The memory returned by <span class="bold"><strong>my_algorithm</strong></span> must be aligned to the most restrictive
162            memory alignment of the system. This function should be executed with
163            the synchronization capabilities offered by <code class="computeroutput"><span class="keyword">typename</span>
164            <span class="identifier">mutex_family</span><span class="special">::</span><span class="identifier">mutex_type</span></code> interprocess_mutex. That
165            means, that if we define <code class="computeroutput"><span class="keyword">typedef</span>
166            <span class="identifier">mutex_family</span> <span class="identifier">mutex_family</span><span class="special">;</span></code> then this function should offer the
167            same synchronization as if it was surrounded by an interprocess_mutex
168            lock/unlock. Normally, this is implemented using a member of type <code class="computeroutput"><span class="identifier">mutex_family</span><span class="special">::</span><span class="identifier">mutex_type</span></code>, but it could be done using
169            atomic instructions or lock free algorithms.
170          </li>
171<li class="listitem">
172            The <span class="bold"><strong>deallocate()</strong></span> function must make
173            the returned buffer available for new allocations. This function should
174            offer the same synchronization as <code class="computeroutput"><span class="identifier">allocate</span><span class="special">()</span></code>.
175          </li>
176<li class="listitem">
177            The <span class="bold"><strong>size()</strong></span> function will return the
178            passed <span class="bold"><strong>size</strong></span> parameter in the constructor.
179            So, <span class="bold"><strong>my_algorithm</strong></span> should store the size
180            internally.
181          </li>
182<li class="listitem">
183            The <span class="bold"><strong>grow()</strong></span> function will expand the
184            managed memory by <span class="bold"><strong>my_algorithm</strong></span> in <span class="bold"><strong>extra_size</strong></span> bytes. So <span class="bold"><strong>size()</strong></span>
185            function should return the updated size, and the new managed memory range
186            will be (if the address where the algorithm is constructed is XXX):
187            <span class="bold"><strong>[XXX + sizeof(my_algorithm) + extra_hdr_bytes,
188            XXX + old_size + extra_size)</strong></span>. This function should offer the
189            same synchronization as <code class="computeroutput"><span class="identifier">allocate</span><span class="special">()</span></code>.
190          </li>
191</ul></div>
192<p>
193        That's it. Now we can create new managed shared memory that uses our new
194        algorithm:
195      </p>
196<pre class="programlisting"><span class="comment">//Managed memory segment to allocate named (c-string) objects</span>
197<span class="comment">//using a user-defined memory allocation algorithm</span>
198<span class="identifier">basic_managed_shared_memory</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">,</span>
199                         <span class="special">,</span><span class="identifier">my_algorithm</span>
200                         <span class="special">,</span><span class="identifier">flat_map_index</span><span class="special">&gt;</span>
201   <span class="identifier">my_managed_shared_memory</span><span class="special">;</span>
202</pre>
203</div>
204<div class="section">
205<div class="titlepage"><div><div><h3 class="title">
206<a name="interprocess.customizing_interprocess.custom_allocators"></a><a class="link" href="customizing_interprocess.html#interprocess.customizing_interprocess.custom_allocators" title="Building custom STL compatible allocators for Boost.Interprocess">Building
207      custom STL compatible allocators for Boost.Interprocess</a>
208</h3></div></div></div>
209<p>
210        If provided STL-like allocators don't satisfy user needs, the user can implement
211        another STL compatible allocator using raw memory allocation and named object
212        construction functions. The user can this way implement more suitable allocation
213        schemes on top of basic shared memory allocation schemes, just like more
214        complex allocators are built on top of new/delete functions.
215      </p>
216<p>
217        When using a managed memory segment, <span class="bold"><strong>get_segment_manager()</strong></span>
218        function returns a pointer to the segment manager. With this pointer, the
219        raw memory allocation and named object construction functions can be called
220        directly:
221      </p>
222<pre class="programlisting"><span class="comment">//Create the managed shared memory and initialize resources</span>
223<span class="identifier">managed_shared_memory</span> <span class="identifier">segment</span>
224   <span class="special">(</span><span class="identifier">create_only</span>
225   <span class="special">,</span><span class="string">"/MySharedMemory"</span>   <span class="comment">//segment name</span>
226   <span class="special">,</span><span class="number">65536</span><span class="special">);</span>             <span class="comment">//segment size in bytes</span>
227
228<span class="comment">//Obtain the segment manager</span>
229<span class="identifier">managed_shared_memory</span><span class="special">::</span><span class="identifier">segment_manager</span> <span class="special">*</span><span class="identifier">segment_mngr</span>
230   <span class="special">=</span> <span class="identifier">segment</span><span class="special">.</span><span class="identifier">get_segment_manager</span><span class="special">();</span>
231
232<span class="comment">//With the segment manager, now we have access to all allocation functions</span>
233<span class="identifier">segment_mngr</span><span class="special">-&gt;</span><span class="identifier">deallocate</span><span class="special">(</span><span class="identifier">segment_mngr</span><span class="special">-&gt;</span><span class="identifier">allocate</span><span class="special">(</span><span class="number">32</span><span class="special">));</span>
234<span class="identifier">segment_mngr</span><span class="special">-&gt;</span><span class="identifier">construct</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="string">"My_Int"</span><span class="special">)[</span><span class="number">32</span><span class="special">](</span><span class="number">0</span><span class="special">);</span>
235<span class="identifier">segment_mngr</span><span class="special">-&gt;</span><span class="identifier">destroy</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="string">"My_Int"</span><span class="special">);</span>
236
237<span class="comment">//Initialize the custom, managed memory segment compatible</span>
238<span class="comment">//allocator with the segment manager.</span>
239<span class="comment">//</span>
240<span class="comment">//MySTLAllocator uses segment_mngr-&gt;xxx functions to</span>
241<span class="comment">//implement its allocation scheme</span>
242<span class="identifier">MySTLAllocator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">stl_alloc</span><span class="special">(</span><span class="identifier">segment_mngr</span><span class="special">);</span>
243
244<span class="comment">//Alias a new vector type that uses the custom STL compatible allocator</span>
245<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">MySTLAllocator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">MyVect</span><span class="special">;</span>
246
247<span class="comment">//Construct the vector in shared memory with the allocator as constructor parameter</span>
248<span class="identifier">segment</span><span class="special">.</span><span class="identifier">construct</span><span class="special">&lt;</span><span class="identifier">MyVect</span><span class="special">&gt;(</span><span class="string">"MyVect_instance"</span><span class="special">)(</span><span class="identifier">stl_alloc</span><span class="special">);</span>
249</pre>
250<p>
251        The user can create new STL compatible allocators that use the segment manager
252        to access to all memory management/object construction functions. All <span class="bold"><strong>Boost.Interprocess</strong></span>' STL compatible allocators are
253        based on this approach. <span class="bold"><strong>Remember</strong></span> that to
254        be compatible with managed memory segments, allocators should define their
255        <span class="bold"><strong>pointer</strong></span> typedef as the same pointer family
256        as <code class="computeroutput"><span class="identifier">segment_manager</span><span class="special">::</span><span class="identifier">void_pointer</span></code> typedef. This means that if
257        <code class="computeroutput"><span class="identifier">segment_manager</span><span class="special">::</span><span class="identifier">void_pointer</span></code> is <code class="computeroutput"><span class="identifier">offset_ptr</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span></code>,
258        <code class="computeroutput"><span class="identifier">MySTLAllocator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code> should
259        define <code class="computeroutput"><span class="identifier">pointer</span></code> as <code class="computeroutput"><span class="identifier">offset_ptr</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code>. The
260        reason for this is that allocators are members of containers, and if we want
261        to put the container in a managed memory segment, the allocator should be
262        ready for that.
263      </p>
264</div>
265<div class="section">
266<div class="titlepage"><div><div><h3 class="title">
267<a name="interprocess.customizing_interprocess.custom_indexes"></a><a class="link" href="customizing_interprocess.html#interprocess.customizing_interprocess.custom_indexes" title="Building custom indexes">Building
268      custom indexes</a>
269</h3></div></div></div>
270<p>
271        The managed memory segment uses a name/object index to speed up object searching
272        and creation. Default specializations of managed memory segments (<code class="computeroutput"><span class="identifier">managed_shared_memory</span></code> for example), use
273        <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">::</span><span class="identifier">flat_map</span></code> as index.
274      </p>
275<p>
276        However, the index type can be chosen via template parameter, so that the
277        user can define its own index type if he needs that. To construct a new index
278        type, the user must create a class with the following guidelines:
279      </p>
280<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
281            The interface of the index must follow the common public interface of
282            std::map and std::tr1::unordered_map including public typedefs. The
283            <code class="computeroutput"><span class="identifier">value_type</span></code> typedef can
284            be of type:
285          </li></ul></div>
286<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">key_type</span><span class="special">,</span> <span class="identifier">mapped_type</span><span class="special">&gt;</span>
287</pre>
288<p>
289        or
290      </p>
291<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="identifier">key_type</span><span class="special">,</span> <span class="identifier">mapped_type</span><span class="special">&gt;</span>
292</pre>
293<p>
294        so that ordered arrays or deques can be used as index types. Some known classes
295        following this basic interface are <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">unordered_map</span></code>,
296        <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">::</span><span class="identifier">flat_map</span></code> and <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">::</span><span class="identifier">map</span></code>.
297      </p>
298<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
299            The class must be a class template taking only a traits struct of this
300            type:
301          </li></ul></div>
302<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">index_traits</span>
303<span class="special">{</span>
304   <span class="keyword">typedef</span> <span class="comment">/*...*/</span>   <span class="identifier">key_type</span><span class="special">;</span>
305   <span class="keyword">typedef</span> <span class="comment">/*...*/</span>   <span class="identifier">mapped_type</span><span class="special">;</span>
306   <span class="keyword">typedef</span> <span class="comment">/*...*/</span>   <span class="identifier">segment_manager</span><span class="special">;</span>
307<span class="special">};</span>
308</pre>
309<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">IndexTraits</span><span class="special">&gt;</span>
310<span class="keyword">class</span> <span class="identifier">my_index_type</span><span class="special">;</span>
311</pre>
312<p>
313        The <code class="computeroutput"><span class="identifier">key_type</span></code> typedef of the
314        passed <code class="computeroutput"><span class="identifier">index_traits</span></code> will
315        be a specialization of the following class:
316      </p>
317<pre class="programlisting"><span class="comment">//!The key of the named allocation information index. Stores a to</span>
318<span class="comment">//!a null string and the length of the string to speed up sorting</span>
319<span class="keyword">template</span><span class="special">&lt;...&gt;</span>
320<span class="keyword">struct</span> <span class="identifier">index_key</span>
321<span class="special">{</span>
322   <span class="keyword">typedef</span> <span class="comment">/*...*/</span>                              <span class="identifier">char_type</span><span class="special">;</span>
323   <span class="keyword">typedef</span> <span class="comment">/*...*/</span>                              <span class="identifier">const_char_ptr_t</span><span class="special">;</span>
324
325   <span class="comment">//Pointer to the object's name (null terminated)</span>
326   <span class="identifier">const_char_ptr_t</span>                             <span class="identifier">mp_str</span><span class="special">;</span>
327
328   <span class="comment">//Length of the name buffer (null NOT included)</span>
329   <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span>                                  <span class="identifier">m_len</span><span class="special">;</span>
330
331   <span class="comment">//!Constructor of the key</span>
332   <span class="identifier">index_key</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">CharT</span> <span class="special">*</span><span class="identifier">name</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">length</span><span class="special">);</span>
333
334   <span class="comment">//!Less than function for index ordering</span>
335   <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">index_key</span> <span class="special">&amp;</span> <span class="identifier">right</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
336
337   <span class="comment">//!Equal to function for index ordering</span>
338   <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">index_key</span> <span class="special">&amp;</span> <span class="identifier">right</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
339<span class="special">};</span>
340</pre>
341<p>
342        The <code class="computeroutput"><span class="identifier">mapped_type</span></code> is not directly
343        modified by the customized index but it is needed to define the index type.
344        The <span class="bold"><strong>segment_manager</strong></span> will be the type of
345        the segment manager that will manage the index. <code class="computeroutput"><span class="identifier">segment_manager</span></code>
346        will define interesting internal types like <code class="computeroutput"><span class="identifier">void_pointer</span></code>
347        or <code class="computeroutput"><span class="identifier">mutex_family</span></code>.
348      </p>
349<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
350            The constructor of the customized index type must take a pointer to segment_manager
351            as constructor argument:
352          </li></ul></div>
353<pre class="programlisting"><span class="identifier">constructor</span><span class="special">(</span><span class="identifier">segment_manager</span> <span class="special">*</span><span class="identifier">segment_mngr</span><span class="special">);</span>
354</pre>
355<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
356            The index must provide a memory reservation function, that optimizes
357            the index if the user knows the number of elements to be inserted in
358            the index:
359          </li></ul></div>
360<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">reserve</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n</span><span class="special">);</span>
361</pre>
362<p>
363        For example, the index type <code class="computeroutput"><span class="identifier">flat_map_index</span></code>
364        based in <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">::</span><span class="identifier">flat_map</span></code> is just defined as:
365      </p>
366<p>
367</p>
368<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">interprocess</span> <span class="special">{</span>
369
370<span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_INTERPROCESS_DOXYGEN_INVOKED</span>
371
372<span class="comment">//!Helper class to define typedefs from IndexTraits</span>
373<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">MapConfig</span><span class="special">&gt;</span>
374<span class="keyword">struct</span> <span class="identifier">flat_map_index_aux</span>
375<span class="special">{</span>
376   <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">MapConfig</span><span class="special">::</span><span class="identifier">key_type</span>            <span class="identifier">key_type</span><span class="special">;</span>
377   <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">MapConfig</span><span class="special">::</span><span class="identifier">mapped_type</span>         <span class="identifier">mapped_type</span><span class="special">;</span>
378   <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">MapConfig</span><span class="special">::</span>
379      <span class="identifier">segment_manager_base</span>                   <span class="identifier">segment_manager_base</span><span class="special">;</span>
380   <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">less</span><span class="special">&lt;</span><span class="identifier">key_type</span><span class="special">&gt;</span>                     <span class="identifier">key_less</span><span class="special">;</span>
381   <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">key_type</span><span class="special">,</span> <span class="identifier">mapped_type</span><span class="special">&gt;</span>        <span class="identifier">value_type</span><span class="special">;</span>
382   <span class="keyword">typedef</span> <span class="identifier">allocator</span><span class="special">&lt;</span><span class="identifier">value_type</span>
383                    <span class="special">,</span><span class="identifier">segment_manager_base</span><span class="special">&gt;</span>   <span class="identifier">allocator_type</span><span class="special">;</span>
384   <span class="keyword">typedef</span> <span class="identifier">flat_map</span><span class="special">&lt;</span><span class="identifier">key_type</span><span class="special">,</span>  <span class="identifier">mapped_type</span><span class="special">,</span>
385                    <span class="identifier">key_less</span><span class="special">,</span> <span class="identifier">allocator_type</span><span class="special">&gt;</span>      <span class="identifier">index_t</span><span class="special">;</span>
386<span class="special">};</span>
387
388<span class="preprocessor">#endif</span>   <span class="comment">//#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED</span>
389
390<span class="comment">//!Index type based in flat_map. Just derives from flat_map and</span>
391<span class="comment">//!defines the interface needed by managed memory segments.</span>
392<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">MapConfig</span><span class="special">&gt;</span>
393<span class="keyword">class</span> <span class="identifier">flat_map_index</span>
394   <span class="comment">//Derive class from flat_map specialization</span>
395   <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">flat_map_index_aux</span><span class="special">&lt;</span><span class="identifier">MapConfig</span><span class="special">&gt;::</span><span class="identifier">index_t</span>
396<span class="special">{</span>
397   <span class="preprocessor">#if</span> <span class="special">!</span><span class="identifier">defined</span><span class="special">(</span><span class="identifier">BOOST_INTERPROCESS_DOXYGEN_INVOKED</span><span class="special">)</span>
398   <span class="keyword">typedef</span> <span class="identifier">flat_map_index_aux</span><span class="special">&lt;</span><span class="identifier">MapConfig</span><span class="special">&gt;</span>  <span class="identifier">index_aux</span><span class="special">;</span>
399   <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">index_aux</span><span class="special">::</span><span class="identifier">index_t</span>    <span class="identifier">base_type</span><span class="special">;</span>
400   <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">index_aux</span><span class="special">::</span>
401      <span class="identifier">segment_manager_base</span>          <span class="identifier">segment_manager_base</span><span class="special">;</span>
402   <span class="preprocessor">#endif</span>   <span class="comment">//#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED</span>
403
404   <span class="keyword">public</span><span class="special">:</span>
405   <span class="comment">//!Constructor. Takes a pointer to the segment manager. Can throw</span>
406   <span class="identifier">flat_map_index</span><span class="special">(</span><span class="identifier">segment_manager_base</span> <span class="special">*</span><span class="identifier">segment_mngr</span><span class="special">)</span>
407      <span class="special">:</span> <span class="identifier">base_type</span><span class="special">(</span><span class="keyword">typename</span> <span class="identifier">index_aux</span><span class="special">::</span><span class="identifier">key_less</span><span class="special">(),</span>
408                  <span class="keyword">typename</span> <span class="identifier">index_aux</span><span class="special">::</span><span class="identifier">allocator_type</span><span class="special">(</span><span class="identifier">segment_mngr</span><span class="special">))</span>
409   <span class="special">{}</span>
410
411   <span class="comment">//!This reserves memory to optimize the insertion of n elements in the index</span>
412   <span class="keyword">void</span> <span class="identifier">reserve</span><span class="special">(</span><span class="keyword">typename</span> <span class="identifier">segment_manager_base</span><span class="special">::</span><span class="identifier">size_type</span> <span class="identifier">n</span><span class="special">)</span>
413   <span class="special">{</span>  <span class="identifier">base_type</span><span class="special">::</span><span class="identifier">reserve</span><span class="special">(</span><span class="identifier">n</span><span class="special">);</span>  <span class="special">}</span>
414
415   <span class="comment">//!This frees all unnecessary memory</span>
416   <span class="keyword">void</span> <span class="identifier">shrink_to_fit</span><span class="special">()</span>
417   <span class="special">{</span>  <span class="identifier">base_type</span><span class="special">::</span><span class="identifier">shrink_to_fit</span><span class="special">();</span>   <span class="special">}</span>
418<span class="special">};</span>
419
420<span class="special">}}</span>   <span class="comment">//namespace boost { namespace interprocess</span>
421</pre>
422<p>
423      </p>
424<p>
425        If the user is defining a node container based index (a container whose iterators
426        are not invalidated when inserting or erasing other elements), <span class="bold"><strong>Boost.Interprocess</strong></span> can optimize named object destruction
427        when destructing via pointer. <span class="bold"><strong>Boost.Interprocess</strong></span>
428        can store an iterator next to the object and instead of using the name of
429        the object to erase the index entry, it uses the iterator, which is a faster
430        operation. So if you are creating a new node container based index (for example,
431        a tree), you should define an specialization of <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">interprocess</span><span class="special">::</span><span class="identifier">is_node_index</span><span class="special">&lt;...&gt;</span></code> defined in <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">interprocess</span><span class="special">/</span><span class="identifier">detail</span><span class="special">/</span><span class="identifier">utilities</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>:
432      </p>
433<pre class="programlisting"><span class="comment">//!Trait classes to detect if an index is a node</span>
434<span class="comment">//!index. This allows more efficient operations</span>
435<span class="comment">//!when deallocating named objects.</span>
436<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">MapConfig</span><span class="special">&gt;</span>
437<span class="keyword">struct</span> <span class="identifier">is_node_index</span>
438   <span class="special">&lt;</span><span class="identifier">my_index</span><span class="special">&lt;</span><span class="identifier">MapConfig</span><span class="special">&gt;</span> <span class="special">&gt;</span>
439<span class="special">{</span>
440   <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
441<span class="special">};</span>
442</pre>
443<p>
444        Interprocess also defines other index types:
445      </p>
446<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
447<li class="listitem">
448            <span class="bold"><strong>boost::map_index</strong></span> uses <span class="bold"><strong>boost::interprocess::map</strong></span>
449            as index type.
450          </li>
451<li class="listitem">
452            <span class="bold"><strong>boost::null_index</strong></span> that uses an dummy
453            index type if the user just needs anonymous allocations and wants to
454            save some space and class instantiations.
455          </li>
456</ul></div>
457<p>
458        Defining a new managed memory segment that uses the new index is easy. For
459        example, a new managed shared memory that uses the new index:
460      </p>
461<pre class="programlisting"><span class="comment">//!Defines a managed shared memory with a c-strings as</span>
462<span class="comment">//!a keys, the red-black tree best fit algorithm (with process-shared mutexes</span>
463<span class="comment">//!and offset_ptr pointers) as raw shared memory management algorithm</span>
464<span class="comment">//!and a custom index</span>
465<span class="keyword">typedef</span>
466   <span class="identifier">basic_managed_shared_memory</span> <span class="special">&lt;</span>
467                              <span class="keyword">char</span><span class="special">,</span>
468                              <span class="identifier">rbtree_best_fit</span><span class="special">&lt;</span><span class="identifier">mutex_family</span><span class="special">&gt;,</span>
469                              <span class="identifier">my_index_type</span>
470                             <span class="special">&gt;</span>
471   <span class="identifier">my_managed_shared_memory</span><span class="special">;</span>
472</pre>
473</div>
474</div>
475<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
476<td align="left"></td>
477<td align="right"><div class="copyright-footer">Copyright © 2005-2015 Ion Gaztanaga<p>
478        Distributed under the Boost Software License, Version 1.0. (See accompanying
479        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
480      </p>
481</div></td>
482</tr></table>
483<hr>
484<div class="spirit-nav">
485<a accesskey="p" href="architecture.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../interprocess.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="acknowledgements_notes.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
486</div>
487</body>
488</html>
489