searchengine/util/cpixtools/inc/public/cpixsyncpool.h
changeset 0 671dee74050a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/searchengine/util/cpixtools/inc/public/cpixsyncpool.h	Mon Apr 19 14:40:16 2010 +0300
@@ -0,0 +1,235 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+#ifndef CPIXTOOLS_CPIXSYNCPOOL_H_
+#define CPIXTOOLS_CPIXSYNCPOOL_H_
+
+#include <list>
+#include <set>
+
+#include "cpixsynctools.h"
+
+
+namespace Cpt
+{
+
+    /**
+     * A template class for pooling items. There is always a given
+     * number of items kept around (either free or used), and clients
+     * can ask for more items, in which case those items are created
+     * on demand.
+     *
+     * NOTE: clients should always release the items back to the pool
+     * the moment they don't need them anymore, otherwise it will
+     * behave like a memory leak (even if it is technically not a
+     * memory leak).
+     *
+     * ITEM: must be default constructible and must have a public
+     * destructor.
+     */
+    template<typename ITEM>
+    class SyncPool
+    {
+    private:
+        //
+        // private members
+        //
+        /**
+         * Stores the items that are free (at most minItemCount_ of
+         * them).
+         */
+        std::list<ITEM*>     freeItems_;
+
+        /**
+         * Stores the items that are used by clients.
+         */
+        std::set<ITEM*>     usedItems_;
+
+        const size_t       minItemCount_;
+
+        /**
+         * Protects freeItems_ and usedItems_ both.
+         */
+        Mutex              mutex_;
+
+    public:
+        //
+        // public operators
+        //
+        /**
+         * Gets an item from the pool (either an existing unused one
+         * or a newly created one). Must be release()-ed
+         * eventually. Thread-safe implementation.
+         */
+        ITEM * acquire();
+
+
+        /**
+         * Releases an item back to the pool. The item itself may
+         * actually be destroyed, or just stored for future use, but
+         * the releasing client must not use it anymore. Thread-safe
+         * implementation. If the item being released has already been
+         * released or is unknown to the SyncPool, an exception is
+         * thrown (SyncExc).
+         */
+        void release(ITEM * item);
+
+
+        //
+        // lifetime management
+        //
+        /**
+         * Constructs this item pool.
+         *
+         * @param minItemCount the number of items that will be kept
+         * around. This constructor does not actually create that many
+         * items up front, only on demand.
+         */
+        SyncPool(size_t minItemCount);
+
+
+        /**
+         * Destructor.
+         */
+        ~SyncPool();
+    };
+
+}
+
+
+
+
+//////////////////////////////////////////////////
+//
+//
+//  I M P L E M E N T A T I O N
+//
+//
+namespace Cpt
+{
+
+    template<typename ITEM>
+    ITEM * SyncPool<ITEM>::acquire()
+    {
+        SyncRegion
+            sr(mutex_);
+
+        ITEM
+            * rv = NULL;
+
+        if (!freeItems_.empty())
+            {
+                rv = freeItems_.front();
+                freeItems_.pop_front();
+            }
+        else
+            {
+                rv = new ITEM;
+            }
+
+        usedItems_.insert(rv);
+
+        return rv;
+    }
+
+
+
+    template<typename ITEM>
+    void SyncPool<ITEM>::release(ITEM * item)
+    {
+        SyncRegion
+            sr(mutex_);
+
+        if (usedItems_.find(item) == usedItems_.end())
+            {
+                throw SyncExc("Releasing unknown item to SyncPool");
+            }
+
+        usedItems_.erase(item);
+
+        if (freeItems_.size() == minItemCount_)
+            {
+                delete item;
+            }
+        else
+            {
+                freeItems_.push_back(item);
+            }
+    }
+
+
+
+    template<typename ITEM>
+    SyncPool<ITEM>::SyncPool(size_t minItemCount)
+        : minItemCount_(minItemCount)
+    {
+        ;
+    }
+
+    
+
+    template<typename ITEM>
+    SyncPool<ITEM>::~SyncPool()
+    {
+        using namespace std;
+
+        SyncRegion
+            sr(mutex_);
+
+        // AR: Used on shutdown to test, whether pool items usages have leaked
+        if (!usedItems_.empty())
+            {
+                throw SyncExc("Destroying SyncPool that has used items still");
+            }
+
+        { // free items
+            typename list<ITEM*>::iterator
+                i = freeItems_.begin(),
+                end = freeItems_.end();
+            
+            for (; i != end; ++i)
+                {
+                    ITEM
+                        * tmp = *i;
+                    delete tmp;
+                }
+
+            freeItems_.clear();
+        }
+
+ 
+        { // used items
+            typename set<ITEM*>::iterator
+                i = usedItems_.begin(),
+                end = usedItems_.end();
+            
+            for (; i != end; ++i)
+                {
+                    ITEM
+                        * tmp = *i;
+                    delete tmp;
+                }
+
+            usedItems_.clear();
+        }
+           
+    }
+
+
+}
+
+
+#endif CPIXTOOLS_CPIXSYNCPOOL_H_