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

E77779-01

coherence/util/MapListenerSupport.hpp

00001 /*
00002 * MapListenerSupport.hpp
00003 *
00004 * Copyright (c) 2000, 2016, 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_MAP_LISTENER_SUPPORT_HPP
00017 #define COH_MAP_LISTENER_SUPPORT_HPP
00018 
00019 #include "coherence/lang.ns"
00020 
00021 #include "coherence/net/cache/CacheEvent.hpp"
00022 #include "coherence/util/Converter.hpp"
00023 #include "coherence/util/Filter.hpp"
00024 #include "coherence/util/Listeners.hpp"
00025 #include "coherence/util/MapEvent.hpp"
00026 #include "coherence/util/MapListener.hpp"
00027 #include "coherence/util/MultiplexingMapListener.hpp"
00028 #include "coherence/util/Set.hpp"
00029 #include "coherence/util/SynchronousListener.hpp"
00030 
00031 COH_OPEN_NAMESPACE2(coherence,util)
00032 
00033 using coherence::net::cache::CacheEvent;
00034 
00035 
00036 /**
00037 * This class provides support for advanced MapListener functionality.
00038 *
00039 * @author js  2008.06.10
00040 */
00041 class COH_EXPORT MapListenerSupport
00042     : public class_spec<MapListenerSupport>
00043     {
00044     friend class factory<MapListenerSupport>;
00045 
00046     // ----- constructors ---------------------------------------------------
00047 
00048     protected:
00049         /**
00050         * Create a new MapListenerSupport.
00051         */
00052         MapListenerSupport();
00053 
00054 
00055     // ----- MapListenerSupport interface -----------------------------------
00056 
00057     public:
00058         /**
00059         * Add a map listener that receives events based on a filter
00060         * evaluation.
00061         *
00062         * @param hListener  the listener to add
00063         * @param vFilter    a filter that will be passed MapEvent objects to
00064         *                   select from; a MapEvent will be delivered to the
00065         *                   listener only if the filter evaluates to true for
00066         *                   that MapEvent; NULL is equivalent to a filter
00067         *                   that alway returns true
00068         * @param fLite      true to indicate that the MapEvent objects do not
00069         *                   have to include the OldValue and NewValue
00070         *                   property values in order to allow optimizations
00071         */
00072         virtual void addListener(MapListener::Handle hListener,
00073                 Filter::View vFilter, bool fLite);
00074 
00075         /**
00076         * Add a map listener for a specific key.
00077         *
00078         * @param hListener  the listener to add
00079         * @param vKey       the key that identifies the entry for which to
00080         *                   raise events
00081         * @param fLite      true to indicate that the MapEvent objects do not
00082         *                   have to include the OldValue and NewValue
00083         *                   property values in order to allow optimizations
00084         *
00085         */
00086         virtual void addListener(MapListener::Handle hListener,
00087                 Object::View vKey, bool fLite);
00088 
00089         /**
00090         * Remove a map listener that previously signed up for events based on
00091         * a filter evaluation.
00092         *
00093         * @param vListener  the listener to remove
00094         * @param vFilter    a filter used to evaluate events
00095         */
00096         virtual void removeListener(MapListener::View vListener,
00097                 Filter::View vFilter);
00098 
00099         /**
00100         * Remove a map listener that previously signed up for events about a
00101         * specific key.
00102         *
00103         * @param vListener  the listener to remove
00104         * @param vKey       the key that identifies the entry for which to
00105         *                   raise events
00106         */
00107         virtual void removeListener(MapListener::View vListener,
00108                 Object::View vKey);
00109 
00110         /**
00111         * Remove all signed up listeners.
00112         */
00113         virtual void clear();
00114 
00115         /**
00116         * Checks whether or not this MapListenerSupport object contains
00117         * any listeners.
00118         *
00119         * @return true iff there are no listeners encapsulated by this
00120         *         MapListenerSupport object
00121         */
00122         virtual bool isEmpty() const;
00123 
00124         /**
00125         * Checks whether or not this MapListenerSupport object contains
00126         * any listeners for a given filter.
00127         *
00128         * @param vFilter  the filter
00129         *
00130         * @return true iff there are no listeners for the specified filter
00131         *              encapsulated by this MapListenerSupport object
00132         */
00133         virtual bool isEmpty(Filter::View vFilter) const;
00134 
00135         /**
00136         * Checks whether or not this MapListenerSupport object contains
00137         * any listeners for a given key.
00138         *
00139         * @param vKey  the key
00140         *
00141         * @return true iff there are no listeners for the specified filter
00142         *              encapsulated by this MapListenerSupport object
00143         */
00144         virtual bool isEmpty(Object::View vKey) const;
00145 
00146         /**
00147         * Checks whether or not this MapListenerSupport object contains
00148         * any standard (not lite) listeners for a given filter.
00149         *
00150         * @param vFilter  the filter
00151         *
00152         * @return true iff there are no standard listeners for the specified
00153         *              filter encapsulated by this MapListenerSupport object
00154         */
00155         virtual bool containsStandardListeners(
00156                 Filter::View vFilter) const;
00157 
00158         /**
00159         * Checks whether or not this MapListenerSupport object contains
00160         * any standard (not lite) listeners for a given key.
00161         *
00162         * @param vKey  the key
00163         *
00164         * @return true iff there are no standard listeners for the specified
00165         *              filter encapsulated by this MapListenerSupport object
00166         */
00167         virtual bool containsStandardListeners(Object::View vKey) const;
00168 
00169         /**
00170         * Obtain a set of all filters that have assosiated global listeners.
00171         * <p>
00172         * <b>Note</b>: The returned value must be treated as an immutable.
00173         *
00174         * @return a set of all filters that have assosiated global listeners
00175         */
00176         virtual Set::View getFilterSet() const;
00177 
00178         /**
00179         * Obtain a set of all keys that have assosiated key listeners.
00180         * <p>
00181         * <b>Note</b>: The returned value must be treated as an immutable.
00182         *
00183         * @return a set of all keys that have assosiated key listeners
00184         */
00185         virtual Set::View getKeySet() const;
00186 
00187         /**
00188         * Obtain the Listeners object for a given filter.
00189         *
00190         * @param vFilter  the filter
00191         *
00192         * @return the Listeners object for the filter; NULL if none exists
00193         */
00194         virtual Listeners::View getListeners(Filter::View vFilter) const;
00195 
00196         /**
00197         * Obtain the Listeners object for a given key.
00198         *
00199         * @param vKey  the key
00200         *
00201         * @return the Listeners object for the key; NULL if none exists
00202         */
00203         virtual Listeners::View getListeners(Object::View vKey) const;
00204 
00205         /**
00206         * Collect all Listeners that should be notified for a given event.
00207         * <p>
00208         * <b>Note</b>: The returned value must be treated as an immutable.
00209         *
00210         * @param vEvent the MapEvent object
00211         *
00212         * @return the Listeners object containing the relevant listeners
00213         */
00214         virtual Listeners::View collectListeners(MapEvent::View vEvent);
00215 
00216         /**
00217         * Fire the specified map event.
00218         *
00219         * @param hEvent    the map event
00220         * @param fStrict   if true then any RuntimeException thrown by event
00221         *                  handlers stops all further event processing and
00222         *                  the exception is re-thrown; if false then all
00223         *                  exceptions are logged and the process continues
00224         */
00225         virtual void fireEvent(MapEvent::Handle hEvent, bool fStrict);
00226 
00227         /**
00228         * Convert the specified map event into another MapEvent that ensures
00229         * the lazy event data conversion using the specified converters.
00230         *
00231         * @param vEvent    the map event
00232         * @param hmapConv  the source for the converted event
00233         * @param vConvKey  (optional) the key Converter
00234         * @param vConvVal  (optional) the value converter
00235         *
00236         * @return the converted MapEvent object
00237         */
00238         static MapEvent::Handle convertEvent(MapEvent::View vEvent,
00239                 ObservableMap::Handle hmapConv,
00240                 Converter::View vConvKey = NULL,
00241                 Converter::View vConvVal = NULL);
00242 
00243         /**
00244         * Transform the given MapEvent into a FilterEvent if it is not already a
00245         * FilterEvent and there are matching filters associated with the
00246         * specified Listeners object.
00247         *
00248         * @param hEvent      the MapEvent to transform, if necessary
00249         * @param vListeners  the Listeners object
00250         *
00251         * @return a FilterEvent if the given MapEvent is not a FilterEvent and
00252         *         the specified Listeners object has associated filters;
00253         *         otherwise, the given MapEvent
00254         * @since  Coherence 3.7.1.8
00255         */
00256         static MapEvent::Handle enrichEvent(MapEvent::Handle hEvent,
00257                 Listeners::View vListeners);
00258 
00259         /**
00260         * Unwrap the specified map event and return the underlying source event.
00261         *
00262         * @param vEvent  the event to unwrap
00263         *
00264         * @return the unwrapped event
00265         */
00266         static MapEvent::View unwrapEvent(MapEvent::View vEvent);
00267 
00268         /**
00269         * Check if the given listener is a PrimingListener or if it wraps one.
00270         *
00271         * @param listener  Map listener to check
00272         *
00273         * @return true iff the listener is a PrimingListener or wraps one
00274         *
00275         * @since 12.2.1
00276         */
00277         static bool isPrimingListener(MapListener::Handle listener);
00278 
00279 
00280     // ----- helper methods -------------------------------------------------
00281 
00282     protected:
00283         /**
00284         * Evaluate whether or not the specified event should be delivered to the
00285         * listener associated with the specified filter.
00286         *
00287         * @param vFilter  the filter
00288         * @param vEvent   the event
00289         *
00290         * @return true iff the event should be delivered to the corresponding listener
00291         */
00292         static bool evaluateEvent(Filter::View vFilter, MapEvent::View vEvent);
00293 
00294         /**
00295         * Return true iff the specified event represents a transformed CacheEvent.
00296         *
00297         * @param vEvent  the event to test
00298         *
00299         * @return true iff the event has been transformed
00300         */
00301         static bool isTransformedEvent(MapEvent::View vEvent);
00302 
00303         /**
00304         * Ensure that the specified map has a Listeners object assosiated
00305         * with the specified key and add the specified listener to it.
00306         *
00307         * @param hmapListeners  map of listeners
00308         * @param vKey           key of the listener
00309         * @param hListener      the listener to add
00310         */
00311         static void addSafeListener(Map::Handle hmapListeners,
00312                 Object::View vKey, MapListener::Handle hListener);
00313 
00314         /**
00315         * Ensure that the specified map has a Listeners object associated
00316         * with the specified Filter and add the specified listener to it.
00317         *
00318         * @param hmapListeners  map of listeners
00319         * @param vFilter        filter of the listener
00320         * @param hListener      the listener to add
00321         * @since Coherence 3.7.1.8
00322         */
00323         static void addSafeListener(Map::Handle hMapListeners,
00324                 Filter::View vAnyFilter, MapListener::Handle hListener);
00325 
00326         /**
00327         * Remove the specified listener from the Listeners object assosiated
00328         * with the specified key.
00329         *
00330         * @param hmapListeners  map of listeners
00331         * @param vKey           key of the listener
00332         * @param vListener      the listener to remove
00333         */
00334         static void removeSafeListener(Map::Handle hmapListeners,
00335                 Object::View vKey, MapListener::View vListener);
00336 
00337         /**
00338         * Add a state information (lite or standard) associated with
00339         * specified key and listener.
00340         *
00341         * @param hmapStandardListeners  map of standard listeners
00342         * @param vKey                   key of the listener
00343         * @param hListener              the listener to add
00344         * @param fLite                  true to indicate that the MapEvent
00345         *                               objects do not have to include the
00346         *                               OldValue and NewValue property values
00347         */
00348         static void addListenerState(Map::Handle hmapStandardListeners,
00349                 Object::View vKey, MapListener::Handle hListener,
00350                 bool fLite);
00351 
00352         /**
00353         * Remove a state information (lite or standard) assosiated with
00354         * specified key and listener.
00355         *
00356         * @param hmapStandardListeners  map of standard listeners
00357         * @param vKey                   key of the listener
00358         * @param vListener              the listener to remove
00359         */
00360         static void removeListenerState(Map::Handle hmapStandardListeners,
00361                 Object::View vKey, MapListener::View vListener);
00362 
00363         /**
00364         * Unwrap the specified map listener and return the underlying map listener.
00365         *
00366         * @param hL istener  the listener to unwrap
00367         *
00368         * @return the unwrapped listener
00369         *
00370         * @since 12.2.1
00371         */
00372         static MapListener::Handle unwrapListener(MapListener::Handle hListener);
00373 
00374     // ----- Object interface -----------------------------------------------
00375 
00376     public:
00377         /**
00378         * {@inheritDoc}
00379         */
00380         virtual TypedHandle<const String> toString() const;
00381 
00382 
00383     // ----- inner class: FilterEvent ---------------------------------------
00384 
00385     public:
00386         /**
00387         * An extension of the CacheEvent which may carry no values (old or
00388         * new), but instead holds an array of Filter objects being the
00389         * "cause" of the event.
00390         */
00391         class COH_EXPORT FilterEvent
00392             : public class_spec<FilterEvent,
00393                 extends<CacheEvent> >
00394             {
00395             friend class factory<FilterEvent>;
00396 
00397             // ----- constructors ---------------------------------------
00398 
00399             protected:
00400                 /**
00401                 * Create a new FilterEvent with no old and new values.
00402                 *
00403                 * @param hMap        the map on which the Event initially
00404                 *                    occurred
00405                 * @param nId         the events id (entry_inserted |
00406                 *                    entry_updated | entry_deleted)
00407                 * @param vKey        the key into the map
00408                 * @param fSynthetic  true iff the event is caused by internal
00409                 *                    cache processing such as eviction or
00410                 *                    loading
00411                 * @param vaFilters   an array of Filters that caused this event.
00412                 */
00413                 FilterEvent(ObservableMap::Handle hMap, int32_t nId,
00414                         Object::View vKey, Object::View vValueOld,
00415                         Object::View vValueNew, bool fSynthetic,
00416                         ObjectArray::View vaFilters);
00417 
00418                 /**
00419                 * Create a new FilterEvent with no old and new values.
00420                 *
00421                 * @param hMap             the map on which the Event initially
00422                 *                         occurred
00423                 * @param nId              the events id (entry_inserted |
00424                 *                         entry_updated | entry_deleted)
00425                 * @param vKey             the key into the map
00426                 * @param fSynthetic       true iff the event is caused by internal
00427                 *                         cache processing such as eviction or
00428                 *                         loading
00429                 * @param nTransformState  the state describing how this event has 
00430                 *                         been or should be transformed
00431                 * @param vaFilters   an array of Filters that caused this event.
00432                 */
00433                 FilterEvent(ObservableMap::Handle hMap, int32_t nId,
00434                         Object::View vKey, Object::View vValueOld,
00435                         Object::View vValueNew, bool fSynthetic,
00436                         TransformationState nTransformState,
00437                         ObjectArray::View vaFilters);
00438 
00439             // ----- FilterEvent interface ------------------------------
00440 
00441             public:
00442                 /**
00443                 * Return an array of filters that are the cause of this
00444                 * event.
00445                 *
00446                 * @return an array of filters
00447                 */
00448                 virtual ObjectArray::View getFilter() const;
00449 
00450                 /**
00451                 * Set the event that this FilterEvent wraps.
00452                 *
00453                 * @param vEvent  the wrapped event
00454                 * @since Coherence 3.7.1.8
00455                 */
00456                 virtual void setEvent(MapEvent::View vEvent);
00457 
00458             // ----- Describable interface ------------------------------
00459 
00460             public:
00461                 /**
00462                 * {@inheritDoc}
00463                 */
00464                 virtual String::View getDescription() const;
00465 
00466             // ----- MapEvent methods -----------------------------------
00467 
00468             public:
00469                 /**
00470                 * {@inheritDoc}
00471                 */
00472                 virtual Object::View getKey() const;
00473 
00474                 /**
00475                 * {@inheritDoc}
00476                 */
00477                 virtual Object::View getOldValue() const;
00478 
00479                 /**
00480                 * {@inheritDoc}
00481                 */
00482                 virtual Object::View getNewValue() const;
00483 
00484             // ----- helper methods -------------------------------------
00485 
00486             public:
00487                 /**
00488                 * Determine if this filter event contains a specified filter.
00489                 *
00490                 * @param vFilter  the filter to search for
00491                 *
00492                 * @return true if the event contained the specified filter,
00493                 *         false otherwise
00494                 */
00495                 virtual bool containsFilter(Filter::View vFilter) const;
00496 
00497             // ----- data members ---------------------------------------
00498 
00499             protected:
00500                 /**
00501                 * Filters which caused the event.
00502                 */
00503                 FinalView<ObjectArray> f_vaFilters;
00504 
00505                 /**
00506                 * Optional wrapped MapEvent.
00507                 * @since Coherence 3.7.1.8
00508                 */
00509                 FinalView<MapEvent> f_vEvent;
00510             };
00511 
00512 
00513     // ----- inner class: SynchronousListener -------------------------------
00514 
00515     public:
00516         /**
00517         * A tag interface indicating that tagged MapListener implementation
00518         * has to receive the MapEvent notifications in a synchronous manner.
00519         * <p>
00520         * Consider a MapListener that subscribes to receive notifications for
00521         * distributed (partitioned) cache. All events notifications are
00522         * received by the service thread and immediately queued to be
00523         * processed by the dedicated event dispatcher thread. This makes it
00524         * impossible to differentiate between the event caused by the updates
00525         * made by this thread and any other thread (possibly in a different
00526         * VM). Forcing the events to be processed on the service thread
00527         * guarantees that by the time "put" or "remove" requests return to
00528         * the caller all relevant MapEvent notification have been processed
00529         * (due to the "in order delivery" rule enforced by the TCMP).
00530         * <p>
00531         * This interface should be considered as a very advanced feature, so
00532         * a MapListener implementation that is tagged as a
00533         * SynchronousListener must exercise extreme caution during event
00534         * processing since any delay with return or unhandled exception will
00535         * cause a delay or complete shutdown of the corresponding cache
00536         * service.
00537         * <p>
00538         * <b>Note:</b> The contract by the event producer in respect to the
00539         * SynchronousListener is somewhat weaker then the general one.
00540         * First, the SynchronousListener implementaion should make no
00541         * assumptions about the event source obtained by {MapEvent#getMap()}.
00542         * Second, in the event of [automatic] service restart, the listener
00543         * has to be re-registered manually (for example, in response to the
00544         * {com::tangosol::net::MemberEvent#member_joined member_joined}
00545         * event). Third, and the most important, no calls against the
00546         * NamedCache are allowed during the synchronous event processing (the
00547         * only exception being a call to remove the listener itself).
00548         */
00549         class COH_EXPORT SynchronousListener
00550             : public interface_spec<SynchronousListener,
00551                 implements<coherence::util::SynchronousListener, MapListener> >
00552             {
00553             };
00554 
00555     // ----- inner class: PrimingListener ----------------------------------
00556 
00557     public:
00558         /**
00559          * A tag interface indicating that tagged MapListener implementation
00560          * has to receive the MapEvent notifications in a synchronous manner
00561          * for lite events (carrying only a key).
00562          * Additionally a "priming" event is generated when registering this listener.
00563          *
00564          * @since 12.2.1
00565          */
00566         class COH_EXPORT PrimingListener
00567             : public interface_spec<PrimingListener,
00568                 implements<SynchronousListener> >
00569             {
00570             };
00571 
00572 
00573     // ----- inner class: WrapperSynchronousListener ------------------------
00574 
00575     public:
00576         /**
00577         * A wrapper class that turns the specified MapListener into
00578         * a synchronous listener.
00579         */
00580         class COH_EXPORT WrapperSynchronousListener
00581             : public class_spec<WrapperSynchronousListener,
00582                 extends<MultiplexingMapListener>,
00583                 implements<SynchronousListener> >
00584             {
00585             friend class factory<WrapperSynchronousListener>;
00586 
00587             // ----- constructors ---------------------------------------
00588 
00589             protected:
00590                 /**
00591                 * Create a new WrapperSynchronousListener.
00592                 *
00593                 * @param hListener  the listener to be wrapped
00594                 *
00595                 * @return the new WrapperSynchronousListener instance
00596                 */
00597                 WrapperSynchronousListener(MapListener::Handle hListener);
00598 
00599             // ----- accessors ------------------------------------------
00600 
00601             public:
00602                 /**
00603                 * Get the underlying MapListener.
00604                 *
00605                 * @return the underlying listener
00606                 */
00607                 virtual MapListener::Handle getMapListener();
00608 
00609             // ----- MultiplexingMapListener interface ------------------
00610 
00611             public:
00612                 /**
00613                 * {@inheritDoc}
00614                 */
00615                 virtual void onMapEvent(MapEvent::View vEvent);
00616 
00617             // ----- Object interface -----------------------------------
00618 
00619             public:
00620                 /**
00621                 * {@inheritDoc}
00622                 */
00623                 virtual size32_t hashCode() const;
00624 
00625                 /**
00626                 * {@inheritDoc}
00627                 */
00628                 virtual bool equals(Object::View v) const;
00629 
00630             // ----- data members ---------------------------------------
00631 
00632             protected:
00633                 /**
00634                 * Wrapped MapListener.
00635                 */
00636                 MemberHandle<MapListener> m_hListener;
00637             };
00638 
00639     // ----- inner class: WrapperPrimingListener ------------------------
00640 
00641     public:
00642         /**
00643          * A wrapper class that turns the specified MapListener into
00644          * a Priminglistener.
00645          *
00646          * @since 12.2.1
00647          */
00648         class COH_EXPORT WrapperPrimingListener
00649             : public class_spec<WrapperPrimingListener,
00650                 extends<WrapperSynchronousListener>,
00651                 implements<PrimingListener> >
00652         {
00653         friend class factory<WrapperPrimingListener>;
00654 
00655         // ----- constructors ---------------------------------------
00656 
00657         protected:
00658             /**
00659              * Create a new WrapperPrimingListener.
00660              *
00661              * @param hListener  the listener to be wrapped
00662              *
00663              * @return the new WrapperPrimingListener instance
00664              */
00665             WrapperPrimingListener(MapListener::Handle hListener);
00666 
00667         private:
00668             /**
00669              * Blocked copy constructor.
00670              */
00671             WrapperPrimingListener(const WrapperPrimingListener&);
00672         };
00673 
00674     // ----- enums ----------------------------------------------------------
00675 
00676     protected:
00677         /**
00678         * Optimization Plan enum.
00679         */
00680         enum Plan
00681             {
00682             none,          // A plan has not yet been formed
00683             no_listeners,  // There are no listeners
00684             all_listener,  // There is one all-keys non-filtered listener
00685             key_listener,  // One key listener (even if for multiple keys)
00686             no_optimize    // No optimized plan, use the default approach
00687             };
00688 
00689 
00690     // ----- data members ---------------------------------------------------
00691 
00692     protected:
00693          /**
00694         * The collections of MapListener objects that have signed up for
00695         * notifications from an ObservableMap implementation keyed by the
00696         * corresponding Filter objects.
00697         */
00698         MemberHandle<Map> m_hmapListeners;
00699 
00700         /**
00701         * The collections of MapListener objects that have signed up for key
00702         * based notifications from an ObservableMap implementation keyed by
00703         * the corresponding key objects.
00704         */
00705         MemberHandle<Map> m_hmapKeyListeners;
00706 
00707         // consider adding listener tag support to Listeners class, which
00708         // would allow getting rid of the following data structures ...
00709         /**
00710         * The subset of standard (not lite) global listeners. The keys are
00711         * the Filter objects, the values are sets of corresponding standard
00712         * listeners.
00713         */
00714         MemberHandle<Map> m_hmapStandardListeners;
00715 
00716         /**
00717         * The subset of standard (not lite) key listeners. The keys are the
00718         * key objects, the values are sets of corresponding standard
00719         * listeners.
00720         */
00721         MemberHandle<Map> m_hmapStandardKeyListeners;
00722 
00723         /**
00724         * The optimization plan which indicates the fastest way to put
00725         * together a set of listeners.
00726         */
00727         Plan m_optimizationPlan;
00728 
00729         /**
00730         * A cached set of Listeners.
00731         */
00732         MemberView<Listeners> m_vListenersCached;
00733     };
00734 
00735 COH_CLOSE_NAMESPACE2
00736 
00737 #endif // COH_MAP_LISTENER_SUPPORT_HPP
00738 
Copyright © 2000, 2016, Oracle and/or its affiliates. All rights reserved.