Oracle Coherence for C++ API
Release 3.6.0.0

E15728-01

coherence/util/ConcurrentMap.hpp

00001 /*
00002 * ConcurrentMap.hpp
00003 *
00004 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
00005 *
00006 * Oracle is a registered trademarks of Oracle Corporation and/or its
00007 * affiliates.
00008 *
00009 * This software is the confidential and proprietary information of Oracle
00010 * Corporation. You shall not disclose such confidential and proprietary
00011 * information and shall use it only in accordance with the terms of the
00012 * license agreement you entered into with Oracle.
00013 *
00014 * This notice may not be removed or altered.
00015 */
00016 #ifndef COH_CONCURRENT_MAP_HPP
00017 #define COH_CONCURRENT_MAP_HPP
00018 
00019 #include "coherence/lang.ns"
00020 
00021 #include "coherence/util/Map.hpp"
00022 
00023 COH_OPEN_NAMESPACE2(coherence,util)
00024 
00025 
00026 /**
00027 * Map with additional concurrency features.
00028 *
00029 * @author jh  2008.03.05
00030 */
00031 class COH_EXPORT ConcurrentMap
00032     : public interface_spec<ConcurrentMap,
00033         implements<Map> >
00034     {
00035     // ----- handle definitions (needed for nested classes) -----------------
00036 
00037     public:
00038         typedef this_spec::Handle Handle;
00039         typedef this_spec::View   View;
00040         typedef this_spec::Holder Holder;
00041 
00042 
00043     // ----- ConcurrentMap interface ----------------------------------------
00044 
00045     public:
00046         /**
00047         * Attempt to lock the specified item within the specified period of
00048         * time.
00049         *
00050         * The item doesn't have to exist to be <i>locked</i>. While the item
00051         * is locked there is known to be a <i>lock holder</i> which has an
00052         * exclusive right to modify (calling put and remove methods) that
00053         * item.
00054         *
00055         * Lock holder is an abstract concept that depends on the
00056         * ConcurrentMap implementation. For example, holder could be a
00057         * process or a thread (or both).
00058         *
00059         * Locking strategy may vary for concrete implementations as well.
00060         * Lock could have an expiration time (this lock is sometimes called a
00061         * "lease") or be held indefinitely (until the lock holder
00062         * terminates).
00063         *
00064         * Some implementations may allow the entire map to be locked. If the
00065         * map is locked in such a way, then only a lock holder is allowed to
00066         * perform any of the "put" or "remove" operations. Pass the special
00067         * constant {@link #getLockAll()} as the <i>vKey</i> parameter to
00068         * indicate the map lock.
00069         *
00070         * @param vKey  key being locked
00071         * @param cWait the number of milliseconds to continue trying to
00072         *              obtain a lock; pass zero to return immediately; pass
00073         *              -1 to block the calling thread until the lock could be
00074         *              obtained
00075         *
00076         * @return true if the item was successfully locked within the
00077         *         specified time; false otherwise
00078         */
00079         virtual bool lock(Object::View vKey, int64_t cWait) const = 0;
00080 
00081         /**
00082         * Attempt to lock the specified item and return immediately.
00083         *
00084         * This method behaves exactly as if it simply performs the call
00085         * <tt>lock(vKey, 0)</tt>.
00086         *
00087         * @param vKey key being locked
00088         *
00089         * @return true if the item was successfully locked; false otherwise
00090         */
00091         virtual bool lock(Object::View vKey) const = 0;
00092 
00093         /**
00094         * Unlock the specified item. The item doesn't have to exist to be
00095         * <i>unlocked</i>. If the item is currently locked, only the
00096         * <i>holder</i> of the lock could successfully unlock it.
00097         *
00098         * @param vKey key being unlocked
00099         *
00100         * @return true if the item was successfully unlocked; false otherwise
00101         */
00102         virtual bool unlock(Object::View vKey) const = 0;
00103 
00104 
00105     // ----- inner class: LockBlock -----------------------------------------
00106 
00107     public:
00108         /**
00109         * The LockBlock allows for easy creation of ConcurrentMap::lock code.
00110         * It's used on conjunction with the COH_CACHE_LOCK macros.
00111         */
00112         class LockBlock
00113             {
00114             // ----- constructors ---------------------------------------
00115 
00116             public:
00117                 /**
00118                 * Construct a LockBlock that will lock the supplied map.
00119                 *
00120                 * @param hMap   the map to lock
00121                 * @param vKey   the Key to lock int he map
00122                 * @param cWait  the number of milliseconds to continue trying
00123                 *               to obtain a lock; pass zero to return
00124                 *               immediately; pass -1 to block the calling
00125                 *               thread until the lock could be obtained
00126                 */
00127                 LockBlock(ConcurrentMap::Handle hMap, Object::View vKey,
00128                         bool fTryLock, int64_t cWait = -1L);
00129 
00130                 /**
00131                 * Copy constructor used by the COH_CACHE_LOCK macros
00132                 */
00133                 LockBlock(const LockBlock& that);
00134 
00135                 /**
00136                 * Destroy an LockBlock object, exiting the associated map
00137                 */
00138                 ~LockBlock();
00139 
00140             // ----- LockBlock interface ---------------------------------
00141 
00142             public:
00143                 /**
00144                 * Boolean conversion for the COH_CACHE_LOCK macros
00145                 *
00146                 * @return true if it's a time based lock and false if no
00147                 */
00148                 operator bool() const;
00149 
00150             private:
00151                 /**
00152                 * Blocked assignment operator
00153                 */
00154                 const LockBlock& operator=(const LockBlock&);
00155 
00156                 /**
00157                 * Blocked dynamic allocation.
00158                 */
00159                 static void* operator new(size_t);
00160 
00161             // ----- data members ---------------------------------------
00162 
00163             protected:
00164                 /**
00165                 * Map to lock and unlock
00166                 */
00167                 mutable ConcurrentMap::Handle m_hMap; // on stack
00168 
00169                 /**
00170                 * Key to lock and unlock in the associated Map
00171                 */
00172                 const Object::View m_vKey; // on stack
00173 
00174                 /**
00175                 * Flag describing the type of lock being used
00176                 */
00177                 const bool m_fTryLock;
00178             };
00179 
00180 
00181     // ----- constants ------------------------------------------------------
00182 
00183     public:
00184         /**
00185         * Special key value indicating an intent to lock the entire map.
00186         */
00187         static Object::View getLockAll();
00188     };
00189 
00190 
00191 // ----- non-member operators and functions ---------------------------------
00192 
00193 
00194 /**
00195 * Macro for more readable cache locking blocks. See the ConcurrentMap docs
00196 * for more details.
00197 */
00198 #define COH_CACHE_LOCK(MAP, KEY) \
00199     if (coherence::util::ConcurrentMap::LockBlock COH_UNIQUE_IDENTIFIER(_coh_cache_lock_) \
00200         = coherence::util::ConcurrentMap::LockBlock(MAP, KEY, false, -1L)) \
00201         { \
00202         COH_THROW(coherence::lang::IllegalStateException::create()); \
00203         } \
00204         else
00205 
00206 
00207 #define COH_CACHE_TRYLOCK(MAP, KEY, TIME) \
00208     if (coherence::util::ConcurrentMap::LockBlock COH_UNIQUE_IDENTIFIER(_coh_cache_trylock_) \
00209             = coherence::util::ConcurrentMap::LockBlock( \
00210                 coherence::util::ConcurrentMap::LockBlock(MAP, KEY, true, TIME)))
00211 
00212 COH_CLOSE_NAMESPACE2
00213 
00214 #endif // COH_CONCURRENT_MAP_HPP
Copyright © 2000, 2010, Oracle and/or its affiliates. All rights reserved.