searchengine/util/cpixtools/inc/public/cpixsyncpool.h
changeset 0 671dee74050a
equal deleted inserted replaced
-1:000000000000 0:671dee74050a
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 #ifndef CPIXTOOLS_CPIXSYNCPOOL_H_
       
    18 #define CPIXTOOLS_CPIXSYNCPOOL_H_
       
    19 
       
    20 #include <list>
       
    21 #include <set>
       
    22 
       
    23 #include "cpixsynctools.h"
       
    24 
       
    25 
       
    26 namespace Cpt
       
    27 {
       
    28 
       
    29     /**
       
    30      * A template class for pooling items. There is always a given
       
    31      * number of items kept around (either free or used), and clients
       
    32      * can ask for more items, in which case those items are created
       
    33      * on demand.
       
    34      *
       
    35      * NOTE: clients should always release the items back to the pool
       
    36      * the moment they don't need them anymore, otherwise it will
       
    37      * behave like a memory leak (even if it is technically not a
       
    38      * memory leak).
       
    39      *
       
    40      * ITEM: must be default constructible and must have a public
       
    41      * destructor.
       
    42      */
       
    43     template<typename ITEM>
       
    44     class SyncPool
       
    45     {
       
    46     private:
       
    47         //
       
    48         // private members
       
    49         //
       
    50         /**
       
    51          * Stores the items that are free (at most minItemCount_ of
       
    52          * them).
       
    53          */
       
    54         std::list<ITEM*>     freeItems_;
       
    55 
       
    56         /**
       
    57          * Stores the items that are used by clients.
       
    58          */
       
    59         std::set<ITEM*>     usedItems_;
       
    60 
       
    61         const size_t       minItemCount_;
       
    62 
       
    63         /**
       
    64          * Protects freeItems_ and usedItems_ both.
       
    65          */
       
    66         Mutex              mutex_;
       
    67 
       
    68     public:
       
    69         //
       
    70         // public operators
       
    71         //
       
    72         /**
       
    73          * Gets an item from the pool (either an existing unused one
       
    74          * or a newly created one). Must be release()-ed
       
    75          * eventually. Thread-safe implementation.
       
    76          */
       
    77         ITEM * acquire();
       
    78 
       
    79 
       
    80         /**
       
    81          * Releases an item back to the pool. The item itself may
       
    82          * actually be destroyed, or just stored for future use, but
       
    83          * the releasing client must not use it anymore. Thread-safe
       
    84          * implementation. If the item being released has already been
       
    85          * released or is unknown to the SyncPool, an exception is
       
    86          * thrown (SyncExc).
       
    87          */
       
    88         void release(ITEM * item);
       
    89 
       
    90 
       
    91         //
       
    92         // lifetime management
       
    93         //
       
    94         /**
       
    95          * Constructs this item pool.
       
    96          *
       
    97          * @param minItemCount the number of items that will be kept
       
    98          * around. This constructor does not actually create that many
       
    99          * items up front, only on demand.
       
   100          */
       
   101         SyncPool(size_t minItemCount);
       
   102 
       
   103 
       
   104         /**
       
   105          * Destructor.
       
   106          */
       
   107         ~SyncPool();
       
   108     };
       
   109 
       
   110 }
       
   111 
       
   112 
       
   113 
       
   114 
       
   115 //////////////////////////////////////////////////
       
   116 //
       
   117 //
       
   118 //  I M P L E M E N T A T I O N
       
   119 //
       
   120 //
       
   121 namespace Cpt
       
   122 {
       
   123 
       
   124     template<typename ITEM>
       
   125     ITEM * SyncPool<ITEM>::acquire()
       
   126     {
       
   127         SyncRegion
       
   128             sr(mutex_);
       
   129 
       
   130         ITEM
       
   131             * rv = NULL;
       
   132 
       
   133         if (!freeItems_.empty())
       
   134             {
       
   135                 rv = freeItems_.front();
       
   136                 freeItems_.pop_front();
       
   137             }
       
   138         else
       
   139             {
       
   140                 rv = new ITEM;
       
   141             }
       
   142 
       
   143         usedItems_.insert(rv);
       
   144 
       
   145         return rv;
       
   146     }
       
   147 
       
   148 
       
   149 
       
   150     template<typename ITEM>
       
   151     void SyncPool<ITEM>::release(ITEM * item)
       
   152     {
       
   153         SyncRegion
       
   154             sr(mutex_);
       
   155 
       
   156         if (usedItems_.find(item) == usedItems_.end())
       
   157             {
       
   158                 throw SyncExc("Releasing unknown item to SyncPool");
       
   159             }
       
   160 
       
   161         usedItems_.erase(item);
       
   162 
       
   163         if (freeItems_.size() == minItemCount_)
       
   164             {
       
   165                 delete item;
       
   166             }
       
   167         else
       
   168             {
       
   169                 freeItems_.push_back(item);
       
   170             }
       
   171     }
       
   172 
       
   173 
       
   174 
       
   175     template<typename ITEM>
       
   176     SyncPool<ITEM>::SyncPool(size_t minItemCount)
       
   177         : minItemCount_(minItemCount)
       
   178     {
       
   179         ;
       
   180     }
       
   181 
       
   182     
       
   183 
       
   184     template<typename ITEM>
       
   185     SyncPool<ITEM>::~SyncPool()
       
   186     {
       
   187         using namespace std;
       
   188 
       
   189         SyncRegion
       
   190             sr(mutex_);
       
   191 
       
   192         // AR: Used on shutdown to test, whether pool items usages have leaked
       
   193         if (!usedItems_.empty())
       
   194             {
       
   195                 throw SyncExc("Destroying SyncPool that has used items still");
       
   196             }
       
   197 
       
   198         { // free items
       
   199             typename list<ITEM*>::iterator
       
   200                 i = freeItems_.begin(),
       
   201                 end = freeItems_.end();
       
   202             
       
   203             for (; i != end; ++i)
       
   204                 {
       
   205                     ITEM
       
   206                         * tmp = *i;
       
   207                     delete tmp;
       
   208                 }
       
   209 
       
   210             freeItems_.clear();
       
   211         }
       
   212 
       
   213  
       
   214         { // used items
       
   215             typename set<ITEM*>::iterator
       
   216                 i = usedItems_.begin(),
       
   217                 end = usedItems_.end();
       
   218             
       
   219             for (; i != end; ++i)
       
   220                 {
       
   221                     ITEM
       
   222                         * tmp = *i;
       
   223                     delete tmp;
       
   224                 }
       
   225 
       
   226             usedItems_.clear();
       
   227         }
       
   228            
       
   229     }
       
   230 
       
   231 
       
   232 }
       
   233 
       
   234 
       
   235 #endif CPIXTOOLS_CPIXSYNCPOOL_H_