Oracle Coherence for C++ API
Release 3.6.0.0

E15728-01

coherence/util/InvocableMap.hpp

00001 /*
00002 * InvocableMap.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_INVOCABLE_MAP_HPP
00017 #define COH_INVOCABLE_MAP_HPP
00018 
00019 #include "coherence/lang.ns"
00020 
00021 #include "coherence/util/Collection.hpp"
00022 #include "coherence/util/Filter.hpp"
00023 #include "coherence/util/Map.hpp"
00024 #include "coherence/util/QueryMap.hpp"
00025 #include "coherence/util/Set.hpp"
00026 #include "coherence/util/ValueUpdater.hpp"
00027 
00028 COH_OPEN_NAMESPACE2(coherence,util)
00029 
00030 
00031 /**
00032 * Map with additional query features.
00033 *
00034 * @author jh  2008.02.27
00035 */
00036 class COH_EXPORT InvocableMap
00037     : public interface_spec<InvocableMap,
00038         implements<Map> >
00039     {
00040     // ----- inner interface: Entry -----------------------------------------
00041 
00042     public:
00043         /**
00044         * An InvocableMap::Entry contains additional information and exposes
00045         * additional operations that the basic Map::Entry does not. It allows
00046         * non-existent entries to be represented, thus allowing their
00047         * optional creation. It allows existent entries to be removed from
00048         * the Map. It supports a number of optimizations that can ultimately
00049         * be mapped through to indexes and other data structures of the
00050         * underlying Map.
00051         */
00052         class COH_EXPORT Entry
00053             : public interface_spec<Entry,
00054                 implements<QueryMap::Entry> >
00055             {
00056             // ----- InvocableMap::Entry interface ----------------------
00057 
00058             public:
00059                 /**
00060                 * Store the value corresponding to this entry. If the entry
00061                 * does not exist, then the entry will be created by invoking
00062                 * this method, even with a NULL value (assuming the Map
00063                 * supports NULL values).
00064                 *
00065                 * Unlike the other form of {@link #setValue(Object::Holder)
00066                 * setValue}, this form does not return the previous value,
00067                 * and as a result may be significantly less expensive (in
00068                 * terms of cost of execution) for certain Map
00069                 * implementations.
00070                 *
00071                 * @param ohValue     the new value for this Entry
00072                 * @param fSynthetic  pass true only if the insertion into or
00073                 *                    modification of the Map should be
00074                 *                    treated as a synthetic event
00075                 *
00076                 * @return the prior value
00077                 */
00078                 virtual Object::Holder setValue(Object::Holder ohValue,
00079                         bool fSynthetic) = 0;
00080 
00081                 /**
00082                 * Update the Entry's value. Calling this method is
00083                 * semantically equivalent to:
00084                 * <pre>
00085                 *   Object::Handle hTarget = cast<Object::Handle>(
00086                 *           hEntry->getValue());
00087                 *   vUpdater->update(hTarget, ohValue);
00088                 *   hEntry->setValue(hTarget, false);
00089                 * </pre>
00090                 * The benefit of using this method is that it may allow the
00091                 * Entry implementation to significantly optimize the
00092                 * operation, such as for purposes of delta updates and backup
00093                 * maintenance.
00094                 *
00095                 * @param vUpdater  a ValueUpdater used to modify the Entry's
00096                 *                  value
00097                 * @param ohValue   the new value to use
00098                 */
00099                 virtual void update(ValueUpdater::View vUpdater,
00100                         Object::Holder ohValue) = 0;
00101 
00102                 /**
00103                 * Determine if this Entry exists in the Map. If the Entry is
00104                 * not present, it can be created by calling {@link
00105                 * #setValue}. If the Entry is present, it can be destroyed by
00106                 * calling {@link #remove}.
00107                 *
00108                 * @return true iff this Entry is existent in the containing
00109                 *         Map
00110                 */
00111                 virtual bool isPresent() const = 0;
00112 
00113                 /**
00114                 * Remove this Entry from the Map if it is present in the Map.
00115                 * This method supports both the operation corresponding to
00116                 * Map#remove as well as synthetic operations such as
00117                 * eviction. If the containing Map does not differentiate
00118                 * between the two, then this method will always be identical
00119                 * to calling <tt>remove(getKey())</tt> on the containing Map.
00120                 *
00121                 * @param fSynthetic  pass true only if the removal from the
00122                 *                    Map should be treated as a synthetic
00123                 *                    event
00124                 */
00125                 virtual void remove(bool fSynthetic) = 0;
00126 
00127             // ----- QueryMap::Entry interface --------------------------
00128 
00129             public:
00130                 /**
00131                 * {@inheritDoc}
00132                 */
00133                 virtual Object::Holder extract(ValueExtractor::View vExtractor) const = 0;
00134 
00135             // ----- Map::Entry interface -------------------------------
00136 
00137             public:
00138                 /**
00139                 * Return the key corresponding to this entry. The resultant
00140                 * key does not necessarily exist within the containing Map,
00141                 * which is to say that calling <tt>containsKey(getKey())</tt>
00142                 * on the containing Map could return false. To test for the
00143                 * presence of this key within the Map, use {@link
00144                 * #isPresent}, and to create the entry for the key, use
00145                 * {@link #setValue}.
00146                 *
00147                 * @return the key corresponding to this entry; may be NULL if
00148                 *         the underlying Map supports NULL keys
00149                 */
00150                 using Map::Entry::getKey;
00151 
00152                 /**
00153                 * Return the value corresponding to this entry. If the entry
00154                 * does not exist, then the value will be NULL. To
00155                 * differentiate between a NULL value and a non-existent
00156                 * entry, use {@link #isPresent}.
00157                 *
00158                 * <b>Note:</b> any modifications to the value retrieved using
00159                 * this method are not guaranteed to persist unless followed
00160                 * by a {@link #setValue} or {@link #update} call.
00161                 *
00162                 * @return the value corresponding to this entry; may be NULL
00163                 *         if the value is NULL or if the Entry does not exist
00164                 *         in the Map
00165                 */
00166                 using Map::Entry::getValue;
00167 
00168                 /**
00169                 * Store the value corresponding to this entry. If the entry
00170                 * does not exist, then the entry will be created by invoking
00171                 * this method, even with a NULL value (assuming the Map
00172                 * supports NULL values).
00173                 *
00174                 * @param ohValue  the new value for this Entry
00175                 *
00176                 * @return the previous value of this Entry, or NULL if the
00177                 *         Entry did not exist
00178                 */
00179                 using Map::Entry::setValue;
00180             };
00181 
00182 
00183     // ----- inner interface: EntryProcessor --------------------------------
00184 
00185     public:
00186         /**
00187         * An invocable agent that operates against the Entry objects within a
00188         * Map.
00189         */
00190         class COH_EXPORT EntryProcessor
00191             : public interface_spec<EntryProcessor>
00192             {
00193             // ----- EntryProcessor interface ---------------------------
00194 
00195             public:
00196                 /**
00197                 * Process a Map::Entry object.
00198                 *
00199                 * @param hEntry  the Entry to process
00200                 *
00201                 * @return the result of the processing, if any
00202                 */
00203                 virtual Object::Holder process(
00204                         Entry::Handle hEntry) const = 0;
00205 
00206                 /**
00207                 * Process a Set of InvocableMap::Entry objects. This method
00208                 * is semantically equivalent to:
00209                 * <pre>
00210                 *   Map::Handle hMapResults = HashMap::create();
00211                 *   for (Iterator::Handle hIter = vSetEntries->iterator();
00212                 *       iter->hasNext; )
00213                 *       {
00214                 *       InvocableMap::Entry::Handle hEntry =
00215                 *               cast<InvocableMap::Entry::Handle>(hIter->next());
00216                 *       hMapResults->put(hEntry->getKey(), process(hEntry));
00217                 *       }
00218                 *   return hMapResults;
00219                 * </pre>
00220                 *
00221                 * @param vSetEntries  a Set of InvocableMap::Entry objects
00222                 *                     to process
00223                 *
00224                 * @return a Map containing the results of the processing, up
00225                 *         to one entry for each InvocableMap::Entry that was
00226                 *         processed, keyed by the keys of the Map that were
00227                 *         processed, with a corresponding value being the
00228                 *         result of the processing for each key
00229                 */
00230                 virtual Map::View processAll(Set::View vSetEntries) const = 0;
00231             };
00232 
00233 
00234     // ----- inner interface: EntryAggregator -------------------------------
00235 
00236     public:
00237         /**
00238         * An EntryAggregator represents processing that can be directed to
00239         * occur against some subset of the entries in an InvocableMap,
00240         * resulting in a aggregated result. Common examples of aggregation
00241         * include functions such as min(), max() and avg(). However, the
00242         * concept of aggregation applies to any process that needs to
00243         * evaluate a group of entries to come up with a single answer.
00244         */
00245         class COH_EXPORT EntryAggregator
00246             : public interface_spec<EntryAggregator>
00247             {
00248             // ----- EntryAggregator interface --------------------------
00249 
00250             public:
00251                 /**
00252                 * Process a set of InvocableMap::Entry objects in order to
00253                 * produce an aggregated result.
00254                 *
00255                 * @param vSetEntries  a Set of read-only InvocableMap::Entry
00256                 *                     objects to aggregate
00257                 *
00258                 * @return the aggregated result from processing the entries
00259                 */
00260                 virtual Object::Holder aggregate(Set::View vSetEntries) = 0;
00261             };
00262 
00263 
00264     // ----- inner interface: ParallelAwareAggregator -----------------------
00265 
00266     public:
00267         /**
00268         * A ParallelAwareAggregator is an advanced extension to
00269         * EntryAggregator that is explicitly capable of being run in
00270         * parallel, for example in a distributed environment.
00271         */
00272         class COH_EXPORT ParallelAwareAggregator
00273             : public interface_spec<ParallelAwareAggregator,
00274                 implements<EntryAggregator> >
00275             {
00276             // ----- ParallelAwareAggregator interface ------------------
00277 
00278             public:
00279                 /**
00280                 * Get an aggregator that can take the place of this
00281                 * aggregator in situations in which the InvocableMap can
00282                 * aggregate in parallel.
00283                 *
00284                 * @return the aggregator that will be run in parallel
00285                 */
00286                 virtual EntryAggregator::Handle getParallelAggregator() = 0;
00287 
00288                 /**
00289                 * Aggregate the results of the parallel aggregations.
00290                 *
00291                 * @param vCollResults  the parallel aggregation results
00292                 *
00293                 * @return the aggregation of the parallel aggregation results
00294                 */
00295                 virtual Object::Holder aggregateResults(
00296                         Collection::View vCollResults) = 0;
00297             };
00298 
00299 
00300     // ----- InvocableMap interface -----------------------------------------
00301 
00302     public:
00303         /**
00304         * Invoke the passed EntryProcessor against the Entry specified by the
00305         * passed key, returning the result of the invocation.
00306         *
00307         * @param vKey    the key to process; it is not required to exist
00308         *                within the Map
00309         * @param hAgent  the EntryProcessor to use to process the specified
00310         *                key
00311         *
00312         * @return the result of the invocation as returned from the
00313         *         EntryProcessor
00314         */
00315         virtual Object::Holder invoke(Object::View vKey,
00316                 EntryProcessor::Handle hAgent) = 0;
00317 
00318         /**
00319         * Invoke the passed EntryProcessor against the entries specified by
00320         * the passed keys, returning the result of the invocation for each.
00321         *
00322         * @param vCollKeys  the keys to process; these keys are not required
00323         *                   to exist within the Map
00324         * @param hAgent     the EntryProcessor to use to process the
00325         *                   specified keys
00326         *
00327         * @return a Map containing the results of invoking the EntryProcessor
00328         *         against each of the specified keys
00329         */
00330         virtual Map::View invokeAll(Collection::View vCollKeys,
00331                 EntryProcessor::Handle hAgent) = 0;
00332 
00333         /**
00334         * Invoke the passed EntryProcessor against the set of entries that
00335         * are selected by the given Filter, returning the result of the
00336         * invocation for each.
00337         *
00338         * Unless specified otherwise, InvocableMap implementations will
00339         * perform this operation in two steps: (1) use the filter to retrieve
00340         * a matching entry set; (2) apply the agent to every filtered entry.
00341         * This algorithm assumes that the agent's processing does not affect
00342         * the result of the specified filter evaluation, since the filtering
00343         * and processing could be performed in parallel on different threads.
00344         * If this assumption does not hold, the processor logic has to be
00345         * idempotent, or at least re-evaluate the filter. This could be
00346         * easily accomplished by wrapping the processor with a
00347         * ConditionalProcessor.
00348         *
00349         * @param vFilter  a Filter that results in the set of keys to be
00350         *                 processed
00351         * @param hAgent   the EntryProcessor to use to process the specified
00352         *                 keys
00353         *
00354         * @return a Map containing the results of invoking the EntryProcessor
00355         *         against the keys that are selected by the given Filter
00356         */
00357         virtual Map::View invokeAll(Filter::View vFilter,
00358                 EntryProcessor::Handle hAgent) = 0;
00359 
00360         /**
00361         * Perform an aggregating operation against the entries specified by
00362         * the passed keys.
00363         *
00364         * @param vCollKeys  the Collection of keys that specify the entries
00365         *                   within this Map to aggregate across
00366         * @param hAgent     the EntryAggregator that is used to aggregate
00367         *                   across the specified entries of this Map
00368         *
00369         * @return the result of the aggregation
00370         */
00371         virtual Object::Holder aggregate(Collection::View vCollKeys,
00372                 EntryAggregator::Handle hAgent) const = 0;
00373 
00374         /**
00375         * Perform an aggregating operation against the set of entries that
00376         * are selected by the given Filter.
00377         *
00378         * @param vFilter  the Filter that is used to select entries within
00379         *                 this Map to aggregate across
00380         * @param hAgent   the EntryAggregator that is used to aggregate
00381         *                 across the selected entries of this Map
00382         *
00383         * @return the result of the aggregation
00384         */
00385         virtual Object::Holder aggregate(Filter::View vFilter,
00386                 EntryAggregator::Handle hAgent) const = 0;
00387     };
00388 
00389 COH_CLOSE_NAMESPACE2
00390 
00391 #endif // COH_INVOCABLE_MAP_HPP
Copyright © 2000, 2010, Oracle and/or its affiliates. All rights reserved.