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

E80355-01

coherence/util/SafeHashMap.hpp

00001 /*
00002 * SafeHashMap.hpp
00003 *
00004 * Copyright (c) 2000, 2017, 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_SAFE_HASH_MAP_HPP
00017 #define COH_SAFE_HASH_MAP_HPP
00018 
00019 #include "coherence/lang.ns"
00020 
00021 #include "coherence/util/AbstractMap.hpp"
00022 #include "coherence/util/AbstractSet.hpp"
00023 #include "coherence/util/AbstractStableIterator.hpp"
00024 #include "coherence/util/AtomicCounter.hpp"
00025 #include "coherence/util/Iterator.hpp"
00026 #include "coherence/util/Map.hpp"
00027 
00028 
00029 COH_OPEN_NAMESPACE2(coherence,util)
00030 
00031 
00032 /**
00033 * An implementation of coherence::util::Map that is synchronized, but
00034 * minimally so. This class is for use in situation where high concurrency is
00035 * required, but so is data integrity.
00036 *
00037 * All additions and removals are synchronized on the map, so to temporarily
00038 * prevent changes to the map contents, synchronize on the map object.
00039 *
00040 * @author mf  2008.02.25
00041 */
00042 class COH_EXPORT SafeHashMap
00043     : public cloneable_spec<SafeHashMap,
00044         extends<AbstractMap> >
00045     {
00046     friend class factory<SafeHashMap>;
00047 
00048     // ----- handle definitions (needed for nested classes) -----------------
00049 
00050     public:
00051         typedef this_spec::Handle Handle;
00052         typedef this_spec::View   View;
00053         typedef this_spec::Holder Holder;
00054 
00055     // ----- constructors ---------------------------------------------------
00056 
00057     protected:
00058         /**
00059         * Construct a thread-safe hash map using the specified settings.
00060         *
00061         * @param cInitialBuckets  the initial number of hash buckets,
00062         *                         0 &lt; n
00063         * @param flLoadFactor     the acceptable load factor before resizing
00064         *                         occurs, 0 &lt; n, such that a load factor
00065         *                         of 1.0 causes resizing when the number of
00066         *                         entries exceeds the number of buckets
00067         * @param flGrowthRate     the rate of bucket growth when a resize
00068         *                         occurs, 0 &lt; n, such that a growth rate
00069         *                         of 1.0 will double the number of buckets:
00070         *                         bucketcount = bucketcount * (1 + growthrate)
00071         */
00072         SafeHashMap(size32_t cInitialBuckets = 17,
00073                 float32_t flLoadFactor = 1.0F, float32_t flGrowthRate = 3.0F);
00074 
00075         /**
00076         * Copy constructor.
00077         */
00078         SafeHashMap(const SafeHashMap& that);
00079 
00080 
00081     // ----- forward declarations -------------------------------------------
00082 
00083     class Entry;
00084     class EntrySet;
00085     class EntrySetIterator;
00086 
00087 
00088     // ----- Map interface --------------------------------------------------
00089 
00090     public:
00091         /**
00092         * {@inheritDoc}
00093         */
00094         virtual size32_t size() const;
00095 
00096         /**
00097         * {@inheritDoc}
00098         */
00099         virtual bool isEmpty() const;
00100 
00101         /**
00102         * {@inheritDoc}
00103         */
00104         virtual bool containsKey(Object::View vKey) const;
00105 
00106         /**
00107         * {@inheritDoc}
00108         */
00109         virtual Object::Holder get(Object::View vKey) const;
00110 
00111         /**
00112         * {@inheritDoc}
00113         */
00114         using Map::get;
00115 
00116         /**
00117         * {@inheritDoc}
00118         */
00119         virtual Object::Holder put(Object::View vKey, Object::Holder ohValue);
00120 
00121         /**
00122         * {@inheritDoc}
00123         */
00124         virtual Object::Holder remove(Object::View vKey);
00125         using Map::remove;
00126 
00127         /**
00128         * {@inheritDoc}
00129         */
00130         virtual void clear();
00131 
00132         /**
00133         * {@inheritDoc}
00134         */
00135         virtual Set::View entrySet() const;
00136 
00137         /**
00138         * {@inheritDoc}
00139         */
00140         virtual Set::Handle entrySet();
00141 
00142 
00143     // ----- inner class: Entry ---------------------------------------------
00144 
00145     protected:
00146         /**
00147         * A map entry (key-value pair).  The <tt>Map.entrySet</tt> method
00148         * returns a collection-view of the map, whose elements are of this
00149         * class.
00150         */
00151         class COH_EXPORT Entry
00152             : public cloneable_spec<Entry,
00153                 extends<Object>,
00154                 implements<Map::Entry> >
00155             {
00156             friend class factory<Entry>;
00157 
00158             // ----- constructors ---------------------------------------
00159 
00160             protected:
00161                 /**
00162                 * Create a new Map::Entry.
00163                 *
00164                 * @param vKey     the assocaited key
00165                 * @param ohValue  the associated value
00166                 * @param hHash    the associated hash code
00167                 *
00168                 * @return a new Map::Entry
00169                 */
00170                 Entry(Object::View vKey, Object::Holder ohValue,
00171                         size32_t nHash);
00172 
00173                 /**
00174                 * Copy Constructor
00175                 */
00176                 Entry(const Entry& that);
00177 
00178                 /**
00179                 * Instantiate an Entry shallow copying the key and value from
00180                 * the Entry provided.
00181                 *
00182                 * @param vThat  the entry to copy from
00183                 */
00184                 Entry(Entry::View vThat);
00185 
00186             // ----- SafeHashMap::Entry interface -----------------------
00187 
00188             public:
00189                 /**
00190                 * Return true if the supplied key is equal to the entries
00191                 * key.
00192                 */
00193                 virtual bool isKeyEqual(Object::View vKey) const;
00194 
00195             // ----- Map::Entry interface -------------------------------
00196 
00197             public:
00198                 /**
00199                 * {@inheritDoc}
00200                 */
00201                 virtual Object::View getKey() const;
00202 
00203                 /**
00204                 * {@inheritDoc}
00205                 */
00206                 virtual Object::Holder getValue() const;
00207 
00208                 /**
00209                 * {@inheritDoc}
00210                 */
00211                 virtual Object::Holder getValue();
00212 
00213                 /**
00214                 * {@inheritDoc}
00215                 */
00216                 virtual Object::Holder setValue(Object::Holder ohValue);
00217 
00218             // ----- class methods --------------------------------------
00219 
00220                 /**
00221                 * This method is invoked when the containing Map has actually
00222                 * added this Entry to itself.
00223                 */
00224                 virtual void onAdd();
00225 
00226             // ----- Object interface -----------------------------------
00227 
00228             public:
00229                 /**
00230                 * {@inheritDoc}
00231                 */
00232                 virtual bool equals(Object::View vThat) const;
00233 
00234                 /**
00235                 * {@inheritDoc}
00236                 */
00237                 virtual size32_t hashCode() const;
00238 
00239                 /**
00240                 * {@inheritDoc}
00241                 */
00242                 virtual TypedHandle<const String> toString() const;
00243 
00244             // ----- data members ---------------------------------------
00245 
00246             protected:
00247                 /**
00248                 * The key.
00249                 */
00250                 FinalView<Object> f_vKey;
00251 
00252                 /**
00253                 * The value. This object reference can change within the life
00254                 * of the Entry.
00255                 */
00256                 MemberHolder<Object> m_ohValue;
00257 
00258                 /**
00259                 * The key's hash code.  This value will not change for the
00260                 * life of the Entry.
00261                 */
00262                 const size32_t m_nHash;
00263 
00264                 /**
00265                 * The next entry in the linked list (an open hashing
00266                 * implementation).
00267                 */
00268                 MemberHandle<Entry> m_hNext;
00269 
00270             // ----- friends --------------------------------------------
00271 
00272             friend class SafeHashMap;
00273             friend class EntrySet;
00274             friend class EntrySetIterator;
00275             };
00276 
00277         /**
00278         * Factory pattern, initialized with the specified valued
00279         *
00280         * @param vKey     the associated key
00281         * @param ohValue  the assocaited value
00282         * @param nHash    the associated hash code
00283         *
00284         * @return a new instance of the Entry class (or a subclass thereof)
00285         */
00286         virtual Entry::Handle instantiateEntry(Object::View vKey,
00287                 Object::Holder ohValue, size32_t nHash);
00288 
00289         /**
00290         * Factory pattern, instantiate an Entry that is either a deep or
00291         * shalow copy.
00292         *
00293         * @param vEntry  the Entry to copy
00294         * @param fDeep   whether to make a deep copy of the Entry or not
00295         */
00296         virtual Entry::Handle instantiateEntry(Entry::View vEntry);
00297 
00298     // ----- inner class: EntrySet ------------------------------------------
00299 
00300     protected:
00301         /**
00302         * A set of entries backed by this map.
00303         */
00304         class COH_EXPORT EntrySet
00305             : public class_spec<EntrySet,
00306                 extends<AbstractCollection>,
00307                 implements<Set> >
00308             {
00309             friend class factory<EntrySet>;
00310 
00311             // ----- constructors --------------------------------------
00312 
00313             protected:
00314                 /**
00315                 * Return a new EntrySet.
00316                 */
00317                 EntrySet(SafeHashMap::Holder ohMap);
00318 
00319 
00320             // ----- Set interface --------------------------------------
00321 
00322             public:
00323                 /**
00324                 * {@inheritDoc}
00325                 */
00326                 using Collection::add;
00327 
00328                 /**
00329                 * {@inheritDoc}
00330                 */
00331                 virtual Iterator::Handle iterator() const;
00332 
00333                 /**
00334                 * {@inheritDoc}
00335                 */
00336                 virtual Muterator::Handle iterator();
00337 
00338                 /**
00339                 * {@inheritDoc}
00340                 */
00341                 virtual size32_t size() const;
00342 
00343                 /**
00344                 * {@inheritDoc}
00345                 */
00346                 virtual bool contains(Object::View v) const;
00347 
00348                 /**
00349                 * {@inheritDoc}
00350                 */
00351                 virtual bool remove(Object::View v);
00352 
00353                 /**
00354                 * {@inheritDoc}
00355                 */
00356                 virtual void clear();
00357 
00358                 /**
00359                 * {@inheritDoc}
00360                 */
00361                 virtual ObjectArray::Handle toArray(
00362                         ObjectArray::Handle hao = NULL) const;
00363 
00364             // ----- Object interface -----------------------------------
00365 
00366             public:
00367                 /**
00368                 * {@inheritDoc}
00369                 */
00370                 virtual bool equals(Object::View that) const;
00371 
00372                 /**
00373                 * {@inheritDoc}
00374                 */
00375                 virtual size32_t hashCode() const;
00376 
00377             // ----- helper methods --------------------------------------
00378 
00379             protected:
00380                 /**
00381                 * Factory pattern.
00382                 *
00383                 * @return a new instance of an Iterator over the EntrySet
00384                 */
00385                 virtual Iterator::Handle instantiateIterator() const;
00386 
00387                 /**
00388                 * Factory pattern.
00389                 *
00390                 * @return a new instance of an Iterator over the EntrySet
00391                 */
00392                 virtual Muterator::Handle instantiateIterator();
00393 
00394                 /**
00395                 * Return a handle to the assocaited Map.
00396                 */
00397                 virtual SafeHashMap::Handle getDelegate();
00398 
00399                 /**
00400                 * Return a view to the assocaited Map.
00401                 */
00402                 virtual SafeHashMap::View getDelegate() const;
00403 
00404             // ----- data members ---------------------------------------
00405 
00406             protected:
00407                 /**
00408                 * The SafeHashMap associated with the EntrySet.
00409                 */
00410                 FinalHolder<SafeHashMap> f_ohMap;
00411 
00412             // ----- friends --------------------------------------------
00413 
00414             friend class SafeHashMap;
00415             friend class EntrySetIterator;
00416             };
00417 
00418 
00419     // ----- inner class: EntrySetIterator ------------------------------
00420 
00421     protected:
00422         /**
00423         * An Iterator over the EntrySet that is backed by the
00424         * SafeHashMap.
00425         */
00426         class COH_EXPORT EntrySetIterator
00427             : public class_spec<EntrySetIterator,
00428                 extends<AbstractStableIterator> >
00429             {
00430             friend class factory<EntrySetIterator>;
00431 
00432             protected:
00433                 /**
00434                 * Construct an Iterator over the Entries in the
00435                 * SafeHashMap. Special care must be taken to handle
00436                 * the condition in which the SafeHashMap is currently
00437                 * resizing.
00438                 *
00439                 * @param ohMap  the set to iterate
00440                 */
00441                 EntrySetIterator(SafeHashMap::Holder ohMap);
00442 
00443                 /**
00444                 * @internal
00445                 */
00446                 virtual ~EntrySetIterator();
00447 
00448 
00449             // ----- AbstractStableIterator interface -------------------
00450 
00451             public:
00452                 /**
00453                 * {@inheritDoc}
00454                 */
00455                 using Muterator::remove;
00456 
00457             protected:
00458                 /**
00459                 * Advance to the next object.
00460                 */
00461                 virtual void advance();
00462 
00463                 /**
00464                 * Shut down the Iterator. This is done on exhaustion of the
00465                 * contents of the Iterator, or on destruction of the Iterator.
00466                 */
00467                 virtual void deactivate() const;
00468 
00469                 /**
00470                 * {@inheritDoc}
00471                 */
00472                 virtual void remove(Object::Holder oh);
00473 
00474             // ----- data members ---------------------------------------
00475 
00476             private:
00477                 /**
00478                 * The EntrySet's Map being iterated.
00479                 */
00480                 FinalHolder<SafeHashMap> f_ohMap;
00481 
00482                 /**
00483                 * Array of buckets in the hash map. This is a
00484                 * purposeful copy of the hash map's reference to its
00485                 * buckets in order to detect that a resize has
00486                 * occurred.
00487                 */
00488                 MemberView<ObjectArray> m_vaeBucket;
00489 
00490                 /**
00491                 * Current bucket being iterated.
00492                 */
00493                 size32_t m_iBucket;
00494 
00495                 /**
00496                 * The most recent Entry object internally iterated.
00497                 * This is not necessarily the same Entry object that
00498                 * was reported to the stable iterator (via the
00499                 * setNext() method), since when a resize occurs, the
00500                 * entries that are being iterated over internally are
00501                 * the "old" Entry objects (pre-resize) while the
00502                 * entries being returned from the Iterator are the
00503                 * "new" Entry objects (post-resize).
00504                 */
00505                 MemberHandle<Entry> m_hEntryPrev;
00506 
00507                 /**
00508                 * Set to true when a resize has been detected.
00509                 */
00510                 bool m_fResized;
00511 
00512                 /**
00513                 * Set to true when the Iterator is complete.
00514                 */
00515                 mutable bool m_fDeactivated;
00516 
00517                 /**
00518                 * True if the iterator will only return views.
00519                 */
00520                 const bool m_fViewer;
00521             };
00522 
00523 
00524     // ----- helper methods -------------------------------------------------
00525 
00526     public:
00527         /**
00528         * Locate an Entry in the hash map based on its key.
00529         *
00530         * @param vKey  the key object to search for
00531         *
00532         * @return the Entry or NULL
00533         */
00534         virtual Entry::View getEntry(Object::View vKey) const;
00535 
00536         /**
00537         * Locate an Entry in the hash map based on its key.
00538         *
00539         * @param vKey  the key object to search for
00540         *
00541         * @return the Entry or NULL
00542         */
00543         virtual Entry::Handle getEntry(Object::View vKey);
00544 
00545     protected:
00546         /**
00547         * Factory pattern.
00548         *
00549         * @return a new instance of the EntrySet class (or a subclass
00550         * thereof)
00551         */
00552         virtual Set::Handle instantiateEntrySet();
00553 
00554         /**
00555         * Factory pattern.
00556         *
00557         * @return a new instance of the EntrySet class (or a subclass
00558         * thereof)
00559         */
00560         virtual Set::View instantiateEntrySet() const;
00561 
00562         /**
00563         * Resize the bucket array, rehashing all Entries.
00564         */
00565         virtual void grow();
00566 
00567         /**
00568         * Return the hash code to use for the specified key.
00569         *
00570         * @param vKey  the key to hash
00571         *
00572         * @return the hash code to use for the key
00573         */
00574         virtual size32_t getHashCode(Object::View vKey) const;
00575 
00576         /**
00577         * Clone an entire linked list of entries.
00578         *
00579         * This method must be called on the map that will contain the clones,
00580         * to allow the map to be the parent of the entries if the entries are
00581         * not static inner classes.
00582         *
00583         * @param vEntryThat  the entry that is the head of the list to clone
00584         *
00585         * @return NULL if the entry is NULL, otherwise an entry that is a
00586         *         clone of the passed entry, and a linked list of clones for
00587         *         each entry in the linked list that was passed
00588         */
00589         virtual Entry::Handle cloneEntryList(Entry::View vEntryThat) const;
00590 
00591         /**
00592         * Locate an Entry in the hash map based on its key.
00593         *
00594         * Unlike the #getEntry method, there must be no side-effects
00595         * of calling this method.
00596         *
00597         * @param vKey  the key object to search for
00598         *
00599         * @return the Entry or null
00600         */
00601         virtual Entry::Handle getEntryInternal(Object::View vKey) const;
00602 
00603         /**
00604         * Removes the passed Entry from the map.
00605         *
00606         * <b>Note:</b> Unlike calling the "remove" method, which is overriden
00607         * at subclasses, calling this method directly does not generate any
00608         * events.
00609         *
00610         * @param hEntry  the entry to remove from this map
00611         */
00612         virtual void removeEntryInternal(Entry::Handle hEntry);
00613 
00614         /**
00615         * Calculate the bucket number for a particular hash code.
00616         *
00617         * @param nHash     the hash code
00618         * @param cBuckets  the number of buckets
00619         *
00620         * @return the bucket index for the specified hash code
00621         */
00622         virtual size32_t getBucketIndex(size32_t nHash, size32_t cBuckets) const;
00623 
00624         /**
00625         * Get the bucket array, or if a resize is occurring, wait for the
00626         * resize to complete and return the new bucket array.
00627         *
00628         * @return the latest bucket array
00629         */
00630         virtual ObjectArray::View getStableBucketArray() const;
00631 
00632         /**
00633         * Register the activation of an Iterator.
00634         */
00635         virtual void iteratorActivated() const;
00636 
00637         /**
00638         * Unregister the (formerly active) Iterator.
00639         */
00640         virtual void iteratorDeactivated() const;
00641 
00642         /**
00643         * Determine if there are any active Iterators, which may mean that
00644         * they are in the middle of iterating over the Map.
00645         *
00646         * @return true iff there is at least one active Iterator
00647         */
00648         virtual bool isActiveIterator() const;
00649 
00650         /**
00651         * Invaldiate the Map so it's no longer useable
00652         */
00653         virtual void invalidate();
00654 
00655         /**
00656          * Retrun wither the Map is still valid or not
00657          *
00658          * @return whether the Map is still valid or not.
00659          */
00660         virtual bool isValid() const;
00661 
00662     private:
00663         /**
00664         * Copy a list of Entries.
00665         *
00666         * @param vEntry  the Entry to copy
00667         * @param fDeep   whether to deep copy each Entry in the list or not
00668         *
00669         * @return a copy of the list of Entries passed in
00670         */
00671         virtual Entry::Handle copyEntryList(Entry::View vEntry, bool fDeep);
00672 
00673         /**
00674         * Copy an individual Entry.
00675         *
00676         * @param vEntry  the Entry to copy
00677         * @param fDeep   whether to deep copy the Entry or not
00678         *
00679         * @return a copy of the Entry passed in
00680         */
00681         virtual Entry::Handle copyEntry(Entry::View vEntry, bool fDeep);
00682 
00683 
00684     // ----- constants ------------------------------------------------------
00685 
00686     public:
00687         /**
00688         * Default initial size provides a prime modulo and is large enough
00689         * that resize is not immediate.  (A hash map probably uses less than
00690         * 128 bytes initially.)
00691         */
00692         static const size32_t default_initialsize = 17;
00693 
00694         /**
00695         * Biggest possible modulo.
00696         */
00697         static const size32_t biggest_modulo = 2147483647;
00698 
00699 
00700     // ----- data members ---------------------------------------------------
00701 
00702     protected:
00703         /**
00704         * When resizing completes, a notification is issued against this
00705         * object.
00706         */
00707         FinalView<Object> f_vResizing;
00708 
00709         /**
00710         * The number of entries stored in the hash map, 0 <= n.
00711         */
00712         size32_t m_cEntries;
00713 
00714         /**
00715         * The array of hash buckets.  This field is declared volatile in
00716         * order to reduce synchronization.
00717         */
00718         MemberHandle<ObjectArray> m_haeBucket;
00719 
00720         /**
00721         * The capacity of the hash map (the point at which it must resize),
00722         *  1 <= n.
00723         */
00724         size32_t m_cCapacity;
00725 
00726         /**
00727         * The determining factor for the hash map capacity given a certain
00728         * number of buckets, such that capactiy = bucketcount * loadfactor.
00729         */
00730         float32_t m_flLoadFactor;
00731 
00732         /**
00733         * The rate of growth as a fraction of the current number of buckets,
00734         * 0 < n, such that the hash map grows to bucketcount * (1 +
00735         * growthrate)
00736         */
00737         float32_t m_flGrowthRate;
00738 
00739         /**
00740         * A count of the number of active Iterators on this map.
00741         */
00742         mutable NativeAtomic32 m_cIterators;
00743 
00744 
00745     // ----- friends --------------------------------------------------------
00746 
00747     friend class Entry;
00748     friend class EntrySet;
00749     friend class EntrySetIterator;
00750     };
00751 
00752 COH_CLOSE_NAMESPACE2
00753 
00754 #endif // COH_SAFE_HASH_MAP_HPP
Copyright © 2000, 2017, Oracle and/or its affiliates. All rights reserved.