OTL 4.0, OTL stream pooling

OTL stream pooling is a mechanism which allows to turn inefficiently managed otl_stream's into something of a greater value as far as performance is concerned. Instances of otl_stream variables get saved in a stream pool, when they get closed, for further reuse in the program. Typically, the program may have a handful of otl_stream variables, defined locally in functions. The streams get instantiated and closed all over again, especially when functions get called repeatedly.

Each instantiation of a stream triggers re-parsing of the stream's SQL statement on the database back end. It is a relatively expensive operation. The stream pooling mechanism alleviates that burden and simplifies coding techniques.

When a stream variable gets closed, the actual instance of the otl_stream gets saved in the stream pool. Then if there is a request to a similar OTL stream, the OTL stream instance can be assigned to the otl_stream variable, which, may be, in its turn, either a local [in function] variable, or allocated on the heap. The similarity of the streams is defined as stream buffer size + SQL statement text + overrides for SELECT output columns (overridden via calls to otl_stream::set_column_type()), meaning that streams with the same SQL statements, buffer sizes, and possibly SELECT output column overrides (in the case if the statement is a SELECT statement and some of its output columns were overridden) will be saved in the same bucket in the stream pool.

Say, three instances of similar streams of <buf_size1+SQLStm1+overrides> were allocated and then all of them were closed. The pool will have one entry point for all the three and the actual bodies of the instances will be placed in the same bucket (see the diagram below). After that, the functions, in which the streams had been created, get called on the second iteration of a loop, and the corresponding otl_stream variables get instantiated again. The second time around, the instances of the similar streams, which were previously saved in the pool, will be pulled out of the pool and re-assigned to the variables, until the variables get closed again.

In some cases, an instance of a stream, if it is, say, used only once, can bypass the pool and be destroyed without saving it in the pool. The otl_stream::close() function has extended functionality to allow the developer to do that.

If the stream pooling is undesirable, then the OTL code, which implements the pooling, can be turned off (not turned on at all). This is controlled by a conditional compilation directive, since OTL is a C++ template as well as macro library with a lot of conditional compilation directives in it, for efficient code generation.

The stream pool has a fixed maximum size, that can be changed by the otl_connect::set_stream_pool_size() function. And, as it already should be obvious from the description above, the stream pool is a property of the otl_connect object.

Stream pooling can be enabled when #define OTL_STL (or #define OTL_ACE if ACE is used, or when #define OTL_UNICODE / #define OTL_UNICODE_STRING_TYPE are used) is defined.

When a new stream is being added to the stream pool but it doesn't have free slots, the least used (as in LRU count based algorithms) entry gets freed up and used for the new stream.

The stream pooling has  a relatively small overhead, compared to the use of otl_stream's, which are kept open always, and don't get closed. This is due to the fact that the std::map<>, as an STL data container, is efficient enough.



Go Home 

Copyright 1996-2017, Sergei Kuchin, email: skuchin@gmail.com, skuchin@gmail.com.

Permission to use, copy, modify and redistribute this document for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.