Previous fileTop of DocumentContentsIndex pageNext file
Apache C++ Standard Library User's Guide

26.9 Improving the Inserter Function

Let's turn here to improving our inserter function. Consider that the country code table might be huge, and access to a country code might turn out to be a time-consuming operation. We can optimize the inserter function's performance by caching the country code table, so that we can access it directly and thus reduce performance overhead.

26.9.1 Primitive Caching

The code below does some primitive caching. It takes the phone facet object from the stream's locale object and copies the country code table into a static variable.

Now consider that the locale object imbued on a stream might change, but the cached static country code table does not. The cache is filled once, and all changes to the stream's locale object have no effect on this inserter function's cache. That's probably not what we want. What we do need is some kind of notification each time a new locale object is imbued, so that we can update the cache.

26.9.2 Registration of a Callback Function

In the following example, notification is provided by a callback function. The iostreams allow registration of callback functions. Class std::ios_base declares:

//1Registered callback functions are called for three events:
  • Destruction of a stream

  • Imbuing a new locale

  • Copying the stream state.

//2The register_callback() function registers a callback function and an index to the stream's parray. During calls to imbue(), copyfmt(), or ~ios_base(), the function fn is called with argument index. Functions registered are called when an event occurs, in opposite order of registration. The parray is an array member defined in class std::ios_base. One can obtain an index to this array via xalloc(), and access the array via pword(index) or iword(index), as shown in Figure 16:

Figure 16: The array parray

In order to install a callback function that updates our cache, we implement a class that retrieves an index to parray and creates the cache, then registers the callback function in its constructor. The procedure is shown in the following code:

//1An index to the array is obtained via xalloc().
//2The pointer to the code table is stored in the array via pword().
//3The callback function and the index are registered.

The actual callback function will later have access to the cache via the index to parray. At this point, we still need a callback function that updates the cache each time the stream's locale is replaced. Such a callback function could look like this:

//1Check whether the event was a change of the imbued locale,
//2retrieve the phone number facet from the stream's locale, and
//3store the country code table in the cache. The cache is accessible via the stream's parray.

26.9.3 Improving the Inserter

We now have everything we need to improve our inserter. It registers a callback function that updates the cache whenever necessary. Registration is done only once, by declaring a static variable of class CallbackRegistrar.

//1The current country code table is cached.
//2The callback function cacheCodesCallback() is registered.

Previous fileTop of DocumentContentsIndex pageNext file