Oracle Fusion Middleware C++ API Reference for Oracle Coherence
12c (12.1.2)

E26041-01

coherence/net/cache/CachingMap.hpp

00001 /*
00002 * CachingMap.hpp
00003 *
00004 * Copyright (c) 2000, 2013, 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_CACHING_MAP_HPP
00017 #define COH_CACHING_MAP_HPP
00018 
00019 #include "coherence/lang.ns"
00020 
00021 #include "coherence/net/cache/CacheMap.hpp"
00022 #include "coherence/net/cache/SimpleCacheStatistics.hpp"
00023 
00024 #include "coherence/util/AbstractMapListener.hpp"
00025 #include "coherence/util/Collection.hpp"
00026 #include "coherence/util/ConcurrentMap.hpp"
00027 #include "coherence/util/Filter.hpp"
00028 #include "coherence/util/List.hpp"
00029 #include "coherence/util/Map.hpp"
00030 #include "coherence/util/MapListener.hpp"
00031 #include "coherence/util/MapListenerSupport.hpp"
00032 #include "coherence/util/MultiplexingMapListener.hpp"
00033 #include "coherence/util/Set.hpp"
00034 
00035 #include "coherence/util/filter/CacheEventFilter.hpp"
00036 #include "coherence/util/filter/MapEventFilter.hpp"
00037 
00038 COH_OPEN_NAMESPACE3(coherence,net,cache)
00039 
00040 using coherence::util::AbstractMapListener;
00041 using coherence::util::Collection;
00042 using coherence::util::ConcurrentMap;
00043 using coherence::util::Filter;
00044 using coherence::util::List;
00045 using coherence::util::Map;
00046 using coherence::util::MapListener;
00047 using coherence::util::MapListenerSupport;
00048 using coherence::util::MultiplexingMapListener;
00049 using coherence::util::Set;
00050 using coherence::util::filter::CacheEventFilter;
00051 using coherence::util::filter::MapEventFilter;
00052 
00053 
00054 /**
00055 * Map implementation that wraps two maps - a front map (assumed to be
00056 * "inexpensive" and probably "incomplete") and a back map (assumed to
00057 * be "complete" and "correct", but more "expensive") - using a
00058 * read-through/write-through approach.
00059 *
00060 * If the back map implements ObservableMap interface, the CachingMap provides
00061 * four different strategies of invalidating the front map entries that have
00062 * changed by other processes in the back map:
00063 *
00064 * listen_none strategy instructs the cache not to listen for invalidation
00065 *     events at all. This is the best choice for raw performance and
00066 *     scalability when business requirements permit the use of data which
00067 *     might not be absolutely current.  Freshness of data can be guaranteed
00068 *     by use of a sufficiently brief eviction policy for the front map;
00069 * listen_present strategy instructs the CachingMap to listen to the
00070 *     back map events related <b>only</b> to the items currently present in
00071 *     the front map. This strategy works best when each instance of a front
00072 *     map contains distinct subset of data relative to the other front map
00073 *     instances (e.g. sticky data access patterns);
00074 * listen_all strategy instructs the CachingMap to listen to <b>all</b>
00075 *     back map events. This strategy is optimal for read-heavy tiered access
00076 *     patterns where there is significant overlap between the different
00077 *     instances of front maps;
00078 * listen_auto strategy instructs the CachingMap implementation to switch
00079 *     automatically between listen_present and listen_all strategies based
00080 *     on the cache statistics.
00081 * listen_logical strategy instructs the CachingMap to listen to <b>all</b>
00082 *     back map events that are <b>not synthetic</b>. A synthetic event could
00083 *     be emitted as a result of eviction or expiration. With this
00084 *     invalidation strategy, it is possible for the front map to contain
00085 *     cache entries that have been synthetically removed from the back
00086 *     (though any subsequent re-insertion will cause the corresponding
00087 *     entries in the front map to be invalidated).
00088 *
00089 * The front map implementation is assumed to be thread safe; additionally
00090 * any modifications to the front map are allowed only after the corresponding
00091 * lock is acquired against the ControlMap.
00092 *
00093 * <b>Note:</b> NULL values are not cached in the front map and therefore this
00094 * implementation is not optimized for maps that allow NULL values to be
00095 * stored.
00096 *
00097 * @author tb  2008.06.12
00098 */
00099 class COH_EXPORT CachingMap
00100     : public class_spec<CachingMap,
00101         extends<Object>,
00102         implements<Map> >
00103     {
00104     friend class factory<CachingMap>;
00105 
00106     // ----- handle definitions (needed for nested classes) -----------------
00107 
00108     public:
00109         typedef this_spec::Handle Handle;
00110         typedef this_spec::View   View;
00111         typedef this_spec::Holder Holder;
00112 
00113 
00114     // ----- enums ----------------------------------------------------------
00115 
00116     public:
00117         /**
00118         * Enum for invalidation strategies
00119         */
00120         enum InvalidationStrategy
00121             {
00122             /**
00123             * No invalidation strategy.
00124             */
00125             listen_none,
00126 
00127             /**
00128             * Invalidation strategy that instructs the CachingMap to listen
00129             * to the back map events related <b>only</b> to the items
00130             * currently present in the front map; this strategy serves best
00131             * when the changes to the back map come mostly from the
00132             * CachingMap itself.
00133             */
00134             listen_present,
00135 
00136             /**
00137             * Invalidation strategy that instructs the CachingMap to listen
00138             * to <b>all</b> back map events; this strategy is preferred when
00139             * updates to the back map are frequent and with high probability
00140             * come from the outside of this CachingMap; for example multiple
00141             * CachingMap instances using the same back map with a large
00142             * degree of key set overlap between front maps.
00143             */
00144             listen_all,
00145 
00146             /**
00147             * Invalidation strategy that instructs the CachingMap
00148             * implementation to switch automatically between listen_present
00149             * and listen_all strategies based on the cache statistics.
00150             */
00151             listen_auto,
00152 
00153             /**
00154             * Invalidation strategy that instructs the CachingMap to listen
00155             * to <b>all</b> back map events that are <b>not synthetic</b>. A
00156             * synthetic event could be emitted as a result of eviction or
00157             * expiration. With this invalidation strategy, it is possible
00158             * for the front map to contain cache entries that have been
00159             * synthetically removed from the back (though any subsequent
00160             * re-insertion will cause the corresponding entries in the front
00161             * map to be invalidated).
00162             */
00163             listen_logical
00164             };
00165 
00166 
00167     // ----- constructors ---------------------------------------------------
00168 
00169     protected:
00170         /**
00171         * Construct a CachingMap using two specified maps:
00172         * <i>FrontMap</i> (aka "cache", "near" or "shallow") and
00173         * <i>BackMap</i>  (aka "actual", "real" or "deep").
00174         *
00175         * If the BackMap implements the ObservableMap interface a listener
00176         * will be added to the BackMap to invalidate FrontMap items updated
00177         * [externally] in the back map using the listen_auto strategy.
00178         *
00179         * If no MapControl is specified then a new one is created.
00180         *
00181         * @param hMapFront    front map
00182         * @param hMapBack     back map
00183         * @param strategy     specifies the strategy used for the front map
00184         *                     invalidation; valid values are LISTEN_*
00185         *                     constants
00186         * @param hMapControl  the ConcurrentMap to keep track of front map
00187         *                     updates; may be NULL
00188         */
00189         CachingMap(CacheMap::Handle hMapFront, CacheMap::Handle hMapBack,
00190                 InvalidationStrategy strategy = listen_auto,
00191                 ConcurrentMap::Handle hMapControl = NULL);
00192 
00193 
00194     // ----- life-cycle -----------------------------------------------------
00195 
00196     public:
00197         /**
00198         * Release the CachingMap. If the BackMap implements an ObservableMap
00199         * calling this method is necessary to remove the BackMap listener.
00200         * Any access to the CachingMap which has been released will cause
00201         * IllegalStateException.
00202         *
00203         * @throws IllegalStateException if accessing the CachingMap
00204         *         which has been released
00205         */
00206         virtual void release();
00207 
00208 
00209     // ----- accessors ------------------------------------------------------
00210 
00211     public:
00212         /**
00213         * Obtain the front map reference.
00214         *
00215         * <b>Note:</b> direct modifications of the returned map may cause an
00216         * unpredictable behavior of the CachingMap.
00217         *
00218         * @return the front Map
00219         */
00220         virtual CacheMap::Handle getFrontMap() const;
00221 
00222         /**
00223         * Obtain the back map reference.
00224         *
00225         * <b>Note:</b> direct modifications of the returned map may cause an
00226         * unpredictable behavior of the CachingMap.
00227         *
00228         * @return the back Map
00229         */
00230         virtual CacheMap::Handle getBackMap() const;
00231 
00232         /**
00233         * Obtain the invalidation strategy used by this CachingMap.
00234         *
00235         * @return one of LISTEN_* values
00236         */
00237         virtual InvalidationStrategy getInvalidationStrategy() const;
00238 
00239         /**
00240         * Obtain the ConcurrentMap that should be used to synchronize
00241         * the front map modification access.
00242         *
00243         * @return a ConcurrentMap controlling the front map modifications
00244         */
00245         virtual ConcurrentMap::Handle getControlMap() const;
00246 
00247         /**
00248         * Obtain the CacheStatistics for this cache.
00249         *
00250         * @return a CacheStatistics object
00251         */
00252         virtual CacheStatistics::Handle getCacheStatistics() const;
00253 
00254         /**
00255         * Determine the rough number of front map invalidation hits since
00256         * the cache statistics were last reset.
00257         *
00258         * An invalidation hit is an externally induced map event for an entry
00259         * that exists in the front map.
00260         *
00261         * @return the number of cache invalidation hits
00262         */
00263         virtual int64_t getInvalidationHits() const;
00264 
00265         /**
00266         * Determine the rough number of front map invalidation misses since
00267         * the cache statistics were last reset.
00268         *
00269         * An invalidation miss is an externally induced map event for an
00270         * entry that does not exists in the front map.
00271         *
00272         * @return the number of cache invalidation misses
00273         */
00274         virtual int64_t getInvalidationMisses() const;
00275 
00276         /**
00277         * Determine the total number of registerListener(Object::View vKey)
00278         * operations since the cache statistics were last reset.
00279         *
00280         * @return the total number of listener registrations
00281         */
00282         virtual int64_t getTotalRegisterListener() const;
00283 
00284     protected:
00285         /**
00286         * Determine if changes to the back map affect the front map so that
00287         * data in the front map stays in sync.
00288         *
00289         * @return true if the front map has a means to stay in sync with the
00290         *         back map so that it does not contain stale data
00291         */
00292         virtual bool isCoherent() const;
00293 
00294 
00295     // ----- CachingMap interface -------------------------------------------
00296 
00297     protected:
00298         /**
00299         * Invalidate the key from the front.  The caller must have the key
00300         * locked.
00301         *
00302         * @param vKey  the key to invalidate
00303         */
00304         virtual void invalidateFront(Object::View vKey) const;
00305 
00306         /**
00307         * Helper method used by put() and putAll() to perform common
00308         * maintanence tasks after completing an operation against the back.
00309         * This includes removing the keys from the control map, and
00310         * evaluating if it is safe to update the front with the "new" value.
00311         * The implementation makes use of the following assumption: if
00312         * listEvents == IGNORE_LIST then oKey does not exist in the
00313         * front, and there is no key based listener for it.  Any key passed
00314         * to this method must be locked in the control map by the caller.
00315         *
00316         * @param vKey        the key
00317         * @param ohValue     the new value
00318         * @param hlistEvents the event list associated with the key
00319         * @param cMillis     the number of milliseconds until the cache entry
00320         *                    will expire
00321         */
00322         virtual void finalizePut(Object::View vKey, Object::Holder ohValue,
00323                 List::Handle hlistEvents, int64_t cMillis);
00324 
00325     public:
00326         /**
00327         * Implementation of put method that optionally skips the return value
00328         * retrieval and allows to specify an expiry for the cache entry.
00329         *
00330         * @param vKey     the key
00331         * @param ohValue  the value
00332         * @param fReturn  if true, the return value is required; otherwise
00333         *                 the return value will be ignored
00334         * @param cMillis  the number of milliseconds until the cache entry
00335         *                 will expire
00336         * @return previous value (if required)
00337         *
00338         * @throws UnsupportedOperationException if the requested expiry is a
00339         *         positive value and either the front map or the back map
00340         *         implementations do not support the expiration functionality
00341         */
00342         virtual Object::Holder put(Object::View vKey, Object::Holder ohValue,
00343                 bool fReturn, int64_t cMillis);
00344 
00345         /**
00346         * Get all the specified keys, if they are in the cache. For each key
00347         * that is in the cache, that key and its corresponding value will be
00348         * placed in the map that is returned by this method. The absence of
00349         * a key in the returned map indicates that it was not in the cache,
00350         * which may imply (for caches that can load behind the scenes) that
00351         * the requested data could not be loaded.
00352         *
00353         * <b>Note:</b> this implementation does not differentiate between
00354         * missing keys or NULL values stored in the back map; in both cases
00355         * the returned map will not contain the corresponding entry.
00356         *
00357         * @param vColKeys  a collection of keys that may be in the named
00358         *                  cache
00359         *
00360         * @return a Map of keys to values for the specified keys passed in
00361         *         <tt>col</tt>
00362         */
00363         virtual Map::View getAll(Collection::View vColKeys) const;
00364 
00365 
00366     // ----- Map interface --------------------------------------------------
00367 
00368     public:
00369         /**
00370         * {@inheritDoc}
00371         */
00372         virtual size32_t size() const;
00373 
00374         /**
00375         * {@inheritDoc}
00376         */
00377         virtual bool isEmpty() const;
00378 
00379         /**
00380         * {@inheritDoc}
00381         */
00382         virtual bool containsKey(Object::View vKey) const;
00383 
00384         /**
00385         * {@inheritDoc}
00386         */
00387         virtual bool containsValue(Object::View vValue) const;
00388 
00389         /**
00390         * {@inheritDoc}
00391         */
00392         virtual Object::Holder get(Object::View vKey) const;
00393 
00394         /**
00395         * {@inheritDoc}
00396         */
00397         virtual Object::Holder get(Object::View vKey);
00398 
00399         /**
00400         * {@inheritDoc}
00401         */
00402         virtual Object::Holder put(Object::View vKey, Object::Holder ohValue);
00403 
00404         /**
00405         * {@inheritDoc}
00406         */
00407         virtual Object::Holder remove(Object::View vKey);
00408 
00409         /**
00410         * {@inheritDoc}
00411         */
00412         virtual void putAll(Map::View vMap);
00413 
00414         /**
00415         * {@inheritDoc}
00416         */
00417         virtual void clear();
00418 
00419         /**
00420         * {@inheritDoc}
00421         */
00422         virtual Set::View keySet() const;
00423 
00424         /**
00425         * {@inheritDoc}
00426         */
00427         virtual Set::Handle keySet();
00428 
00429         /**
00430         * {@inheritDoc}
00431         */
00432         virtual Collection::View values() const;
00433 
00434         /**
00435         * {@inheritDoc}
00436         */
00437         virtual Collection::Handle values();
00438 
00439         /**
00440         * {@inheritDoc}
00441         */
00442         virtual Set::View entrySet() const;
00443 
00444         /**
00445         * {@inheritDoc}
00446         */
00447         virtual Set::Handle entrySet();
00448 
00449 
00450     // ----- Object interface -----------------------------------------------
00451 
00452     public:
00453         /**
00454         * {@inheritDoc}
00455         */
00456         virtual void toStream(std::ostream& out) const;
00457 
00458     protected:
00459         /**
00460         * {@inheritDoc}
00461         */
00462         virtual void onInit();
00463 
00464 
00465     // ----- back map listener support --------------------------------------
00466 
00467     public:
00468         /**
00469         * Register the global back map listener.
00470         */
00471         virtual void registerListener() const;
00472 
00473         /**
00474         * Unregister the global back map listener.
00475         */
00476         virtual void unregisterListener() const;
00477 
00478         /**
00479         * Register the back map listener for the specified key.
00480         *
00481         * @param vKey  the key
00482         */
00483         virtual void registerListener(Object::View vKey) const;
00484 
00485         /**
00486         * Unregister the back map listener for the specified key.
00487         *
00488         * @param vKey  the key
00489         */
00490         virtual void unregisterListener(Object::View vKey) const;
00491 
00492         /**
00493         * Register the global front map listener.
00494         */
00495         virtual void registerFrontListener() const;
00496 
00497         /**
00498         * Unregister the global front map listener.
00499         */
00500         virtual void unregisterFrontListener() const;
00501 
00502         /**
00503         * Ensure that a strategy has been choosen and that any appropriate
00504         * global listeners have been registered.
00505         *
00506         * @return the current strategy
00507         */
00508         virtual InvalidationStrategy ensureInvalidationStrategy() const;
00509 
00510         /**
00511         * Reset the "current invalidation strategy" flag.
00512         *
00513         * This method should be called <b>only</b> while the access to the
00514         * front map is fully synchronzied and the front map is empty to
00515         * prevent stalled data.
00516         */
00517         virtual void resetInvalidationStrategy();
00518 
00519 
00520     // ----- inner class: BackMapListener -----------------------------------
00521 
00522     protected:
00523         /**
00524         * MapListener for back map responsible for keeping the front map
00525         * coherent with the back map. This listener is registered as a
00526         * synchronous listener for lite events (carrying only a key).
00527         */
00528         class BackMapListener
00529            : public class_spec<BackMapListener,
00530                extends<MultiplexingMapListener>,
00531                implements<MapListenerSupport::SynchronousListener> >
00532             {
00533             friend class factory<BackMapListener>;
00534 
00535             // ----- constructors ---------------------------------------
00536 
00537             protected:
00538                 /**
00539                 * Construct a BackMapListener
00540                 *
00541                 * @param hMap  the map associated with this listener
00542                 */
00543                 BackMapListener(CachingMap::Handle hMap);
00544 
00545             // ----- MultiplexingMapListener interface ------------------
00546 
00547                 /**
00548                 * {@inheritDoc}
00549                 */
00550                 virtual void onMapEvent(MapEvent::View vEvent);
00551 
00552             // ---- data members ----------------------------------------
00553 
00554             protected:
00555                 /**
00556                 * The map associated with this listener.
00557                 */
00558                 WeakHandle<CachingMap> m_whMap;
00559             };
00560 
00561 
00562     // ----- inner class: FrontMapListener ----------------------------------
00563 
00564     protected:
00565         /**
00566         * MapListener for back map responsible for keeping the front map
00567         * coherent with the back map. This listener is registered as a
00568         * synchronous listener for lite events (carrying only a key).
00569         */
00570         class FrontMapListener
00571             : public class_spec<FrontMapListener,
00572                 extends<AbstractMapListener>,
00573                 implements<MapListenerSupport::SynchronousListener> >
00574             {
00575             friend class factory<FrontMapListener>;
00576 
00577             // ----- constructors ---------------------------------------
00578 
00579             protected:
00580                 /**
00581                 * Construct a FrontMapListener
00582                 *
00583                 * @param hMap  the map associated with this listener
00584                 */
00585                 FrontMapListener(CachingMap::Handle hMap);
00586 
00587             // ----- MapListener interface ------------------------------
00588 
00589             public:
00590                 /**
00591                 * {@inheritDoc}
00592                 */
00593                 virtual void entryDeleted(MapEvent::View vEvent);
00594 
00595             // ---- helper registration methods -------------------------
00596 
00597             public:
00598                 /**
00599                 * Register this listener with the "front" map.
00600                 */
00601                 virtual void registerWithMap();
00602 
00603                 /**
00604                 * Unregister this listener with the "front" map.
00605                 */
00606                 virtual void unregisterFromMap();
00607 
00608             // ---- data members ----------------------------------------
00609 
00610             protected:
00611                 /**
00612                 * The filter associated with this listener.
00613                 */
00614                 FinalView<Filter> f_vFilter;
00615 
00616                 /**
00617                 * The map associated with this listener.
00618                 */
00619                 WeakHandle<CachingMap> m_whMap;
00620             };
00621 
00622 
00623     // ----- listener support -----------------------------------------------
00624 
00625     protected:
00626         /**
00627         * Factory pattern: instantiate back map listener.
00628         *
00629         * @return an instance of back map listener responsible for keeping
00630         *         the front map coherent with the back map
00631         */
00632         virtual MapListener::Handle instantiateBackMapListener();
00633 
00634         /**
00635         * Factory pattern: instantiate front map listener.
00636         *
00637         * @return an instance of front map listener
00638         */
00639         virtual FrontMapListener::Handle instantiateFrontMapListener();
00640 
00641         /**
00642         * Validate the front map entry for the specified back map event.
00643         *
00644         * @param vEvent  the MapEvent from the back map
00645         */
00646         virtual void validate(MapEvent::View vEvent);
00647 
00648 
00649     // ----- constants and data fields  -------------------------------------
00650 
00651     protected :
00652         /**
00653         * The "back" map, considered to be "complete" yet "expensive" to
00654         * access.
00655         */
00656         mutable FinalHandle<CacheMap> f_hMapBack;
00657 
00658         /**
00659         * The "front" map, considered to be "incomplete" yet "inexpensive" to
00660         * access.
00661         */
00662         mutable FinalHandle<CacheMap> f_hMapFront;
00663 
00664         /**
00665         * The invalidation strategy that this map is to use.
00666         */
00667         mutable InvalidationStrategy m_strategyTarget;
00668 
00669         /**
00670         * The current invalidation strategy, which at times could be different
00671         * from the target strategy.
00672         */
00673         mutable InvalidationStrategy m_strategyCurrent;
00674 
00675         /**
00676         * An optional listener for the "back" map.
00677         */
00678         mutable MemberHandle<MapListener> m_hListener;
00679 
00680         /**
00681         * An optional listener for the "front" map.
00682         */
00683         mutable FinalHandle<FrontMapListener> f_hListenerFront;
00684 
00685         /**
00686         * A filter that selects events for the back-map listener.
00687         */
00688         mutable MemberHandle<Filter> m_hFilterListener;
00689 
00690         /**
00691         * The ConcurrentMap to keep track of front map updates.
00692         * Values are list of events received by the listener while the
00693         * corresponding key was locked.  Use of LOCK_ALL is restricited to
00694         * non-blocking operations to prevent deadlock with the service thread.
00695         */
00696         mutable FinalHandle<ConcurrentMap> f_hMapControl;
00697 
00698         /**
00699         * The CacheStatistics object maintained by this cache.
00700         */
00701         mutable FinalHandle<SimpleCacheStatistics> f_hStats;
00702 
00703         /**
00704         * The rough (ie unsynchronized) number of times the front map entries
00705         * that were present in the front map were invalidated by the listener.
00706         */
00707         mutable /*volatile stat*/ int64_t m_cInvalidationHits;
00708 
00709         /**
00710         * The rough (ie unsynchronized) number of times the front map entries
00711         * that were absent in the front map received invalidation event.
00712         */
00713         mutable /*volatile stat*/ int64_t m_cInvalidationMisses;
00714 
00715         /**
00716         * The total number of registerListener(oKey) operations.
00717         */
00718         mutable /*volatile stat*/ int64_t m_cRegisterListener;
00719 
00720         /**
00721         * True if the cache has been released.
00722         */
00723         bool m_fReleased;
00724 
00725     // ----- constants ------------------------------------------------------
00726 
00727     protected :
00728         /**
00729         * A unique Object that serves as a control key for global operations
00730         * such as clear and release and synchronization point for the current
00731         * strategy change.
00732         */
00733         FinalView<Object> f_vKeyGlobal;
00734     };
00735 
00736 COH_CLOSE_NAMESPACE3
00737 
00738 #endif // COH_CACHING_MAP_HPP
Copyright © 2000, 2013, Oracle and/or its affiliates. All rights reserved.