summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornanbor <nanbor@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2002-12-18 23:18:47 +0000
committernanbor <nanbor@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2002-12-18 23:18:47 +0000
commit4e9b6eb39595d4cafe5824b1d16a01c16339c82a (patch)
tree7ebef134b9f941f132e33357553defbe2d2c70f3
parent8aa955b38258f142ee55f9625049596baa1eb907 (diff)
downloadATCD-4e9b6eb39595d4cafe5824b1d16a01c16339c82a.tar.gz
ChangeLogTag:Wed Dec 18 17:12:04 2002 Nanbor Wang <nanbor@cs.wustl.edu>
-rw-r--r--ChangeLog14
-rw-r--r--ChangeLogs/ChangeLog-03a14
-rw-r--r--ace/Hash_Map_Manager_RT_T.cpp765
-rw-r--r--ace/Hash_Map_Manager_RT_T.h772
-rw-r--r--ace/Hash_Map_Manager_RT_T.inl447
-rw-r--r--ace/ace_dll.dsp15
-rw-r--r--ace/ace_lib.dsp29
-rw-r--r--tests/Hash_Map_Manager_RT_Test.cpp396
-rw-r--r--tests/Hash_Map_Manager_RT_Test.dsp158
-rw-r--r--tests/tests.dsw12
10 files changed, 2617 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index fc993dadd49..9515fe3784b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+Wed Dec 18 17:12:04 2002 Nanbor Wang <nanbor@cs.wustl.edu>
+
+ * ace/Hash_Map_Manager_RT.cpp:
+ * ace/Hash_Map_Manager_RT.h:
+ * ace/Hash_Map_Manager_RT_T.cpp:
+ * ace/Hash_Map_Manager_RT_T.h:
+ * ace/Hash_Map_Manager_RT_T.inl:
+ * ace/ace_dll.dsp:
+ * ace/ace_lib.dsp:
+ * tests/Hash_Map_Manager_RT_Test.cpp:
+ * tests/Hash_Map_Manager_RT_Test.dsp:
+ * tests/tests.dsw: Added the new Hash_Map_Manager_RT stuff into
+ the branch RT_Hash.
+
Wed Dec 18 15:03:03 2002 Nanbor Wang <nanbor@cs.wustl.edu>
* ace/Get_Opt.cpp (long_option): For MSVC 7.x compiler, we need to
diff --git a/ChangeLogs/ChangeLog-03a b/ChangeLogs/ChangeLog-03a
index fc993dadd49..9515fe3784b 100644
--- a/ChangeLogs/ChangeLog-03a
+++ b/ChangeLogs/ChangeLog-03a
@@ -1,3 +1,17 @@
+Wed Dec 18 17:12:04 2002 Nanbor Wang <nanbor@cs.wustl.edu>
+
+ * ace/Hash_Map_Manager_RT.cpp:
+ * ace/Hash_Map_Manager_RT.h:
+ * ace/Hash_Map_Manager_RT_T.cpp:
+ * ace/Hash_Map_Manager_RT_T.h:
+ * ace/Hash_Map_Manager_RT_T.inl:
+ * ace/ace_dll.dsp:
+ * ace/ace_lib.dsp:
+ * tests/Hash_Map_Manager_RT_Test.cpp:
+ * tests/Hash_Map_Manager_RT_Test.dsp:
+ * tests/tests.dsw: Added the new Hash_Map_Manager_RT stuff into
+ the branch RT_Hash.
+
Wed Dec 18 15:03:03 2002 Nanbor Wang <nanbor@cs.wustl.edu>
* ace/Get_Opt.cpp (long_option): For MSVC 7.x compiler, we need to
diff --git a/ace/Hash_Map_Manager_RT_T.cpp b/ace/Hash_Map_Manager_RT_T.cpp
new file mode 100644
index 00000000000..62000df2e33
--- /dev/null
+++ b/ace/Hash_Map_Manager_RT_T.cpp
@@ -0,0 +1,765 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Hash_Map_Manager_RT_T.cpp
+ *
+ * $Id$
+ *
+ * @author Jeremy M. Nolle <jmn3@cs.wustl.edu>
+ */
+//=============================================================================
+
+
+#ifndef ACE_HASH_MAP_MANAGER_RT_T_CPP
+#define ACE_HASH_MAP_MANAGER_RT_T_CPP
+
+#include "Hash_Map_Manager_RT_T.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+
+#if !defined (__ACE_INLINE__)
+#include "ace/Hash_Map_Manager_RT_T.inl"
+#endif /* __ACE_INLINE__ */
+
+#include "Synch.h"
+#include "Service_Config.h"
+#include "Malloc.h"
+#include <string.h>
+
+ACE_RCSID(ace, Hash_Map_Manager_RT_T, "$Id$")
+
+//***************************************************************/
+
+ACE_Hash_Map_RT_Coord::ACE_Hash_Map_RT_Coord (int table,
+ int bucket)
+ : table_ (table),
+ bucket_ (bucket)
+{
+}
+
+ACE_Hash_Map_RT_Coord::~ACE_Hash_Map_RT_Coord (void)
+{
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID, class HASH_KEY>
+ACE_Hash_Map_RT_Hash_Function<EXT_ID, INT_ID, HASH_KEY>::ACE_Hash_Map_RT_Hash_Function (int number_of_tables,
+ int buckets_per_table)
+ : max_tables_ (number_of_tables),
+ buckets_per_table_ (buckets_per_table)
+{
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY>
+ACE_Hash_Map_RT_Hash_Function<EXT_ID, INT_ID, HASH_KEY>::~ACE_Hash_Map_RT_Hash_Function (void)
+{
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> int
+ACE_Hash_Map_RT_Hash_Function<EXT_ID, INT_ID, HASH_KEY>::hash (const EXT_ID& ext_id,
+ ACE_Hash_Map_RT_Coord& coord)
+{
+ int hashCode = hash_key_ (ext_id);
+ if ( hashCode < 0 ) hashCode *= -1;
+
+ this->hash_i (hashCode, coord);
+
+ return 0;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> int
+ACE_Hash_Map_RT_Hash_Function<EXT_ID, INT_ID, HASH_KEY>::hash_i (int key,
+ ACE_Hash_Map_RT_Coord& coord)
+{
+ // Have you thought about precisions in all the platforms that
+ // ACE runs on? Will these numbers work?
+
+ double prod = (key * 0.618033988) - (size_t)(key * 0.618033988);
+ size_t u = (int)(this->max_tables_ * this->buckets_per_table_ * prod);
+
+ coord.set_table(u / this->buckets_per_table_);
+ coord.set_bucket(u % this->buckets_per_table_);
+
+ return 0;
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID, class HASH_KEY>
+ACE_Hash_Map_RT_POD<EXT_ID, INT_ID, HASH_KEY>::ACE_Hash_Map_RT_POD (int num_tables,
+ ACE_Hash_Map_RT_Hash_Function<EXT_ID, INT_ID, HASH_KEY>& func)
+ : num_tables_ (num_tables),
+ func_ (func)
+{
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY>
+ACE_Hash_Map_RT_POD<EXT_ID, INT_ID, HASH_KEY>::~ACE_Hash_Map_RT_POD (void)
+{
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID>
+ACE_Hash_Map_RT_ListItem<EXT_ID, INT_ID>::ACE_Hash_Map_RT_ListItem (ENTRY* entry,
+ LITEM* next)
+ : entry_ (entry),
+ next_ (next)
+{
+}
+
+template <class EXT_ID, class INT_ID>
+ACE_Hash_Map_RT_ListItem<EXT_ID, INT_ID>::ACE_Hash_Map_RT_ListItem ()
+ : entry_ (0),
+ next_ (0)
+{
+}
+
+template <class EXT_ID, class INT_ID>
+ACE_Hash_Map_RT_ListItem<EXT_ID, INT_ID>::~ACE_Hash_Map_RT_ListItem (void)
+{
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID>
+ACE_Hash_Map_RT_Entry<EXT_ID, INT_ID>::ACE_Hash_Map_RT_Entry (const EXT_ID& ext_id,
+ const INT_ID& int_id)
+ : ext_id_ (ext_id),
+ int_id_ (int_id)
+{
+}
+
+template <class EXT_ID, class INT_ID>
+ACE_Hash_Map_RT_Entry<EXT_ID, INT_ID>::ACE_Hash_Map_RT_Entry ()
+{
+}
+
+# if ! defined (ACE_HAS_BROKEN_NOOP_DTORS)
+template <class EXT_ID, class INT_ID>
+ACE_Hash_Map_RT_Entry<EXT_ID, INT_ID>::~ACE_Hash_Map_RT_Entry (void)
+{
+}
+# endif /* ! defined (ACE_HAS_BROKEN_NOOP_DTORS) */
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID, class HASH_KEY>
+ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY>::ACE_Hash_Map_RT_Bucket (POD* pod)
+ : curPOD_ (pod)
+{
+ init_bucket_i(pod);
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY>
+ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY>::ACE_Hash_Map_RT_Bucket (void)
+{
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY>
+ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY>::~ACE_Hash_Map_RT_Bucket (void)
+{
+
+ // The "if" second argument results in a no-op instead of deallocation.
+ ACE_DES_FREE_TEMPLATE2 (this->curPOD_,
+ ACE_NOOP,
+ ACE_Hash_Map_RT_POD,
+ EXT_ID,
+ INT_ID);
+ this->curPOD_ = 0;
+
+ // head_ has already been deleted by remove_all at this point, so we need
+ // to clear the bucket's pointer b/c it points to a nonexistant object
+ this->head_ = 0;
+ this->last_ = 0;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> int
+ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY>::init_bucket_i (POD* pod)
+{
+ this->head_ = new LITEM();
+ this->last_ = head_;
+ return 0;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> int
+ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY>::prepend (ENTRY& entry)
+{
+
+ this->head_->next_ = new LITEM((new ENTRY(entry.get_ext_id(),
+ entry.get_int_id())),
+ head_->next_);
+ if (this->last_ == this->head_)
+ this->last_ = this->head_->next_;
+ this->incr_length();
+ return 0;
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID, class HASH_KEY>
+ACE_Hash_Map_RT_Table<EXT_ID, INT_ID, HASH_KEY>::ACE_Hash_Map_RT_Table ()
+{
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY>
+ACE_Hash_Map_RT_Table<EXT_ID, INT_ID, HASH_KEY>::ACE_Hash_Map_RT_Table (ACE_Allocator *allocator,
+ size_t buckets_per_table,
+ POD* pod)
+{
+ init_table_i(allocator, buckets_per_table, pod);
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY>
+ACE_Hash_Map_RT_Table<EXT_ID, INT_ID, HASH_KEY>::~ACE_Hash_Map_RT_Table (void)
+{
+ //
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> int
+ACE_Hash_Map_RT_Table<EXT_ID, INT_ID, HASH_KEY>::init_table_i (ACE_Allocator *allocator,
+ size_t buckets_per_table,
+ POD* pod)
+{
+ size_t bytes = buckets_per_table * sizeof (BUCKET);
+ void *ptr;
+
+ ACE_ALLOCATOR_RETURN (ptr,
+ allocator->malloc (bytes),
+ -1);
+
+ this->buckets_ = (BUCKET *) ptr;
+
+ for (size_t i = 0; i < buckets_per_table; i++)
+ new (&this->buckets_[i]) BUCKET(pod);
+
+ return 0;
+};
+
+//***************************************************************/
+
+ACE_Hash_Map_RT_StatsManager::ACE_Hash_Map_RT_StatsManager (void)
+ : max_chain_ (0),
+ total_elements_ (0)
+{
+}
+
+ACE_Hash_Map_RT_StatsManager::~ACE_Hash_Map_RT_StatsManager (void)
+{
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK>
+ACE_Hash_Map_RT_Clean_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::ACE_Hash_Map_RT_Clean_Manager (ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>* thismanager)
+ : manager_ (thismanager),
+ cur_table_ (0),
+ cur_bucket_(0)
+{
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK>
+ACE_Hash_Map_RT_Clean_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::ACE_Hash_Map_RT_Clean_Visitor (ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>* thismanager)
+{
+ this->manager_ = thismanager;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_Hash_Map_RT_Clean_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>*
+ACE_Hash_Map_RT_Clean_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::incremental_clean (void)
+{
+ if (more_to_do())
+ {
+ BUCKET& bucket = manager_->get_table(cur_table_).get_bucket(cur_bucket_);
+ if (!bucket.is_clean(*manager_->curPOD_))
+ manager_->clean_vis_->process_bucket(bucket);
+
+ ++cur_bucket_;
+ if (cur_bucket_ >= manager_->buckets_per_table_)
+ {
+ ++cur_table_;
+ cur_bucket_ = 0;
+ }
+ }
+ if (cur_table_ < manager_->oldPOD_->get_num_tables())
+ return this;
+ else
+ {
+ this->manager_->oldPOD_ = 0;
+ this->cur_table_ = 0;
+ this->manager_->stats_->reset_max_chain();
+ return 0;
+ }
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
+ACE_Hash_Map_RT_Clean_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::more_to_do (void)
+{
+ return ((manager_->oldPOD_ != 0) && (cur_table_ < manager_->oldPOD_->get_num_tables()));
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK>
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::ACE_Hash_Map_RT_Manager_Ex (size_t bucketsPerTable,
+ size_t newrtl,
+ size_t newMaxTables,
+ ACE_Allocator *alloc,
+ size_t clean_rate)
+: buckets_per_table_ (bucketsPerTable),
+ number_of_tables_ (1),
+ RTL_ (newrtl),
+ max_tables_ (newMaxTables),
+ allocator_ (alloc),
+ cleaning_rate_ (clean_rate)
+{
+ open_i(buckets_per_table_, alloc);
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK>
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::~ACE_Hash_Map_RT_Manager_Ex (void)
+{
+ close_manager();
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::open_i (size_t buckets_per_table,
+ ACE_Allocator *alloc)
+{
+ void *ptr, *ptr2;
+
+ ACE_ALLOCATOR_RETURN (ptr,
+ allocator_->malloc (sizeof(ACE_Hash_Map_RT_POD<EXT_ID, INT_ID, HASH_KEY>)),
+ -1);
+
+ ACE_ALLOCATOR_RETURN (ptr2,
+ allocator_->malloc (sizeof(ACE_Hash_Map_RT_Hash_Function<EXT_ID, INT_ID, HASH_KEY>)),
+ -1);
+
+ this->curPOD_ = new (ptr) ACE_Hash_Map_RT_POD<EXT_ID, INT_ID, HASH_KEY>(1, *(new (ptr2) ACE_Hash_Map_RT_Hash_Function<EXT_ID, INT_ID, HASH_KEY>(1, this->buckets_per_table_)));
+ this->oldPOD_ = 0;
+
+ ACE_ALLOCATOR_RETURN (ptr,
+ allocator_->malloc (sizeof(ACE_Hash_Map_RT_StatsManager)),
+ -1);
+
+ this->stats_ = new (ptr) ACE_Hash_Map_RT_StatsManager();
+
+ ACE_ALLOCATOR_RETURN (ptr,
+ allocator_->malloc (sizeof(ACE_Hash_Map_RT_Clean_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>)),
+ -1);
+
+ this->clean_ = new (ptr) ACE_Hash_Map_RT_Clean_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK> (this);
+
+ ACE_ALLOCATOR_RETURN (ptr,
+ allocator_->malloc (sizeof(ACE_Hash_Map_RT_Clean_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>)),
+ -1);
+
+ this->clean_vis_ = new (ptr) ACE_Hash_Map_RT_Clean_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>(this);
+
+ ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
+
+ if (alloc == 0)
+ alloc = ACE_Allocator::instance ();
+
+ this->allocator_ = alloc;
+
+ size_t bytes = this->max_tables_ * sizeof(TABLE);
+
+ ACE_ALLOCATOR_RETURN (ptr,
+ allocator_->malloc (bytes),
+ -1);
+
+ this->table_ = (TABLE *) ptr;
+
+ for (size_t i = 0; i < max_tables_; i++)
+ new (&this->get_table(i)) TABLE(allocator_, buckets_per_table, this->curPOD_);
+
+ return 0;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::close_manager (void)
+{
+ ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
+
+ return this->close_i ();
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::close_i (void)
+{
+ // Protect against "double-deletion" in case the destructor also
+ // gets called.
+ if (this->table_ != 0)
+ {
+ // Remove all the entries.
+ this->remove_all_i ();
+
+ // Iterate through the buckets
+ for (size_t i = 0; i < this->max_tables_; i++)
+ {
+ for (size_t j = 0; j < this->buckets_per_table_; j++)
+ {
+ BUCKET *temp_bkt = &(this->get_table(i).get_bucket(j));
+
+ // The "if" second argument results in a no-op instead of
+ // deallocation.
+ ACE_DES_FREE_TEMPLATE2 (temp_bkt,
+ ACE_NOOP,
+ ACE_Hash_Map_RT_Bucket,
+ EXT_ID,
+ INT_ID);
+ temp_bkt = 0;
+ }
+
+ TABLE *temp_tbl = &(this->get_table(i));
+ // The "if" second argument results in a no-op instead of
+ // deallocation.
+ ACE_DES_FREE_TEMPLATE2 (temp_tbl,
+ ACE_NOOP,
+ ACE_Hash_Map_RT_Table,
+ EXT_ID,
+ INT_ID);
+ temp_tbl = 0;
+ }
+
+ POD *pod = (this->get_POD());
+
+ ACE_DES_FREE_TEMPLATE2 (pod,
+ ACE_NOOP,
+ ACE_Hash_Map_RT_POD,
+ EXT_ID,
+ INT_ID);
+ pod = 0;
+
+ delete this->oldPOD_;
+ this->oldPOD_ = 0;
+
+ ACE_Hash_Map_RT_StatsManager *stats = (this->stats_);
+ ACE_DES_FREE_TEMPLATE2 (stats,
+ ACE_NOOP,
+ ACE_Hash_Map_RT_StatsManager,
+ EXT_ID,
+ INT_ID);
+ stats = 0;
+
+ CLEAN *clean = (this->clean_);
+ ACE_DES_FREE_TEMPLATE2 (clean,
+ ACE_NOOP,
+ ACE_Hash_Map_RT_Clean_Manager,
+ EXT_ID,
+ INT_ID);
+ clean = 0;
+
+ CLEANV *cleanv = (this->clean_vis_);
+ ACE_DES_FREE_TEMPLATE2 (cleanv,
+ ACE_NOOP,
+ ACE_Hash_Map_RT_Clean_Visitor,
+ EXT_ID,
+ INT_ID);
+ cleanv = 0;
+
+ // Free table memory.
+ this->allocator_->free (this->table_);
+
+ // Should be done last...
+ this->table_ = 0;
+ }
+
+ return 0;
+}
+
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::remove_all_i (void)
+{
+ // Iterate through the entire map calling the destuctor of each <ACE_Hash_Map_ListItem>.
+
+ for (size_t i = 0; i < this->max_tables_; i++)
+ {
+ for (size_t j = 0; j < this->buckets_per_table_; j++)
+ {
+ for (LITEM *temp_ptr = this->get_table(i).get_bucket(j).head_; ((temp_ptr != this->get_table(i).get_bucket(j).last_) && (temp_ptr != 0)); )
+ {
+ LITEM *hold_ptr = temp_ptr;
+ if (temp_ptr->next_ != 0)
+ {
+ temp_ptr = temp_ptr->next_;
+ delete hold_ptr;
+ hold_ptr = 0;
+
+ /// Explicitly call the destructor.
+ ACE_DES_FREE_TEMPLATE2 (hold_ptr,
+ this->allocator_->free,
+ ACE_Hash_Map_RT_ListItem,
+ EXT_ID,
+ INT_ID);
+ }
+ }
+ //done with the bucket
+ this->get_table(i).get_bucket(j).set_length(0);
+ }
+ //done with the table
+ this->get_table(i).set_tablesize(0);
+ }
+
+ //this->cur_size_ = 0;
+
+ return 0;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::locate_i (const EXT_ID &ext_id,
+ ACE_Hash_Map_RT_Searching_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>& visitor,
+ INT_ID& int_id)
+{
+ ACE_Hash_Map_RT_Coord oldcoord = ACE_Hash_Map_RT_Coord(0,0);
+ ACE_Hash_Map_RT_Coord newCoord = ACE_Hash_Map_RT_Coord(0,0);
+
+ BUCKET& new_bucket = find_bucket(this->curPOD_, ext_id);
+
+ if (is_stable() == 1)
+ {
+ int_id = 0;
+
+ size_t num_cleaned = 0;
+ if (!find_bucket(this->oldPOD_, ext_id).is_clean(*this->curPOD_))
+ {
+ clean_vis_->process_bucket(find_bucket(oldPOD_, ext_id));
+ num_cleaned++;
+ }
+ if (!new_bucket.is_clean(*this->curPOD_))
+ {
+ clean_vis_->process_bucket(new_bucket);
+ num_cleaned++;
+ }
+ visitor.process_bucket(new_bucket);
+ while ((clean_ != 0) && (num_cleaned < get_cleaning_rate())) {
+ clean_ = clean_->incremental_clean(); // Incremental clean & Method that ends a rehash
+ num_cleaned++;
+ }
+ if (clean_ == 0)
+ clean_ = new ACE_Hash_Map_RT_Clean_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK> (this);
+ }
+
+ else
+ {
+ visitor.process_bucket(new_bucket);
+ }
+
+ if (visitor.is_found() == 1)
+ {
+ ENTRY& temp = *(visitor.get_found()).entry_;
+ if (temp.get_int_id() != 0)
+ {
+ int_id = temp.get_int_id();
+ return 0;
+ }
+ }
+
+ // we looped without finding the bucket
+ return -1;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_Hash_Map_RT_POD<EXT_ID, INT_ID, HASH_KEY>*
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::create_POD (void)
+{
+ int bucketsPerTable = buckets_per_table_;
+ int currNumTables = number_of_tables_;
+
+ double tuningKnob = 0.000;
+
+ int new_num_of_tables = 0;
+ int currNumBuckets = bucketsPerTable * currNumTables;
+ double new_num_of_buckets = currNumBuckets + (double)(currNumBuckets+1)/(RTL_-1);
+ double idealLoadFactor = RTL_ - 1;
+
+ double currNumElements = (double)(stats_->get_total_elements ());
+ double currentLoadFactor = currNumElements / currNumBuckets;
+ double addPercentage = (idealLoadFactor - currentLoadFactor) / idealLoadFactor;
+
+ new_num_of_tables = (int)(ceil(new_num_of_buckets / (double)bucketsPerTable));
+
+ double extraFraction = addPercentage * new_num_of_buckets;
+ if (extraFraction < 0)
+ extraFraction *= -1;
+
+ new_num_of_buckets = (int)(ceil(new_num_of_buckets + extraFraction * tuningKnob));
+ new_num_of_tables = (int)(ceil(new_num_of_buckets / (double)bucketsPerTable));
+
+ if(new_num_of_tables > this->max_tables_)
+ new_num_of_tables = this->max_tables_;
+
+ if(new_num_of_buckets > this->buckets_per_table_)
+ new_num_of_buckets = this->buckets_per_table_;
+
+ this->number_of_tables_ = new_num_of_tables;
+ this->buckets_per_table_ = new_num_of_buckets;
+
+ return (new ACE_Hash_Map_RT_POD<EXT_ID, INT_ID, HASH_KEY> (new_num_of_tables, *(new ACE_Hash_Map_RT_Hash_Function<EXT_ID, INT_ID, HASH_KEY>(new_num_of_tables, bucketsPerTable))));
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> size_t
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::ceil (double number)
+{
+ if ((int)number != number)
+ ++number;
+ return (size_t)number;
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
+ACE_Hash_Map_RT_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::process_bucket (BUCKET& temp_bucket)
+{
+ BUCKET& bucket = *(start(&temp_bucket));
+
+ LITEM* item = bucket.head_; // head doesnt have an entry
+ this->mtfPrev_ = bucket.head_; // prev is head until we step forward
+
+ while( item != (bucket.last_) ) // all ListItems have a next except last
+ {
+ item = item->next_;
+ visit(item); // so let's visit that next_ ListItem
+
+ if(is_found() == 0) // If we havent found the one we are looking for,
+ this->mtfPrev_ = item; // then save the one we are on (the 'previous').
+ // After we find the one we want, we dont want to overwrite
+ // our mtfPrev_ ptr anymore
+ }
+ done(bucket);
+
+ return 0;
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK>
+ACE_Hash_Map_RT_Searching_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::ACE_Hash_Map_RT_Searching_Visitor (const EXT_ID &ext_id,
+ ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>* manager)
+ : ext_id_ (ext_id),
+ manager_ (manager)
+{
+ this->found_ = 0;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK>
+ACE_Hash_Map_RT_Searching_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::ACE_Hash_Map_RT_Searching_Visitor (void)
+{
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
+ACE_Hash_Map_RT_Searching_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::visit (LITEM* litem)
+{
+ if ((litem != 0) && (strcmp(litem->entry_->get_ext_id(), this->ext_id_) == 0))
+ {
+ found_key (litem);
+ return 0;
+ }
+ return -1;
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK>
+ACE_Hash_Map_RT_Put_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::ACE_Hash_Map_RT_Put_Visitor (const EXT_ID &ext_id,
+ const INT_ID &int_id,
+ ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>* manager)
+ : ACE_Hash_Map_RT_Searching_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK> (ext_id, manager),
+ int_id_ (int_id)
+{
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> void
+ACE_Hash_Map_RT_Put_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::found_key (LITEM* litem)
+{
+ this->found_ = litem;
+
+ // this will overwrite the old value,
+ // we need this in case we insert the same key with a new value
+ litem->entry_->set_int_id(this->int_id_);
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
+ACE_Hash_Map_RT_Put_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::done (BUCKET& bucket)
+{
+ if (is_found() == 0) // if we havent found what we're looking for
+ { // then bind a new one
+ ENTRY entry = ENTRY(this->ext_id_,
+ this->int_id_);
+
+ bucket.prepend(entry);
+
+ LITEM litem = LITEM (&entry,
+ bucket.head_->next_);
+
+ found_key(&litem);
+
+ this->manager_->stats_->incr_total_elements();
+
+ if (manager_->is_stable() == 0)
+ {
+ this->manager_->stats_->compare_max_chain(bucket.get_length());
+ if (bucket.get_length() >= this->manager_->RTL_)
+ {
+ POD* pod = this->manager_->create_POD();
+ if (pod != 0)
+ this->manager_->change_POD(*pod);
+ }
+ }
+ return 0;
+ }
+
+ return -1;
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK>
+ACE_Hash_Map_RT_Get_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::ACE_Hash_Map_RT_Get_Visitor (const EXT_ID &ext_id,
+ INT_ID &int_id,
+ ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>* thismanager)
+ : ACE_Hash_Map_RT_Searching_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK> (ext_id, thismanager),
+ int_id_ (int_id)
+{
+}
+
+
+//***************************************************************/
+
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK>
+ACE_Hash_Map_RT_Remove_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::ACE_Hash_Map_RT_Remove_Visitor (const EXT_ID &ext_id,
+ ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>* thismanager)
+ : ACE_Hash_Map_RT_Searching_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>(ext_id, thismanager)
+{
+}
+
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> int
+ACE_Hash_Map_RT_Remove_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::done (BUCKET& bucket)
+{
+ if(is_found() == 1)
+ {
+ if (this->found_ == bucket.last_)
+ bucket.last_ = this->mtfPrev_;
+
+ this->mtfPrev_->next_ = this->get_found().next_;
+
+ delete this->found_;
+ this->found_ = 0;
+
+ bucket.decr_length();
+ this->manager_->stats_->decr_total_elements();
+ }
+
+ return 0;
+}
+
+
+#endif /* ACE_HASH_MAP_RT_MANAGER_RT_CPP */
diff --git a/ace/Hash_Map_Manager_RT_T.h b/ace/Hash_Map_Manager_RT_T.h
new file mode 100644
index 00000000000..a873d4940f1
--- /dev/null
+++ b/ace/Hash_Map_Manager_RT_T.h
@@ -0,0 +1,772 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Hash_Map_Manager_RT_T.h
+ *
+ * $Id$
+ *
+ * @author Jeremy M. Nolle <jmn3@cs.wustl.edu>
+ */
+//=============================================================================
+
+#ifndef ACE_HASH_MAP_RT_MANAGER_RT_H
+#define ACE_HASH_MAP_RT_MANAGER_RT_H
+#include "pre.h"
+
+#include "config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "Default_Constants.h"
+#include "Functor.h"
+#include "Log_Msg.h"
+
+/**
+ * @class ACE_Hash_Map_RT_Coord
+ *
+ * @brief An int pair for an Entry's (table, bucket) position
+ */
+class ACE_Hash_Map_RT_Coord
+{
+public:
+ // = Initialization and termination methods.
+ /// Constructor
+ ACE_Hash_Map_RT_Coord (int table, int bucket);
+
+ /// Destructor
+ ~ACE_Hash_Map_RT_Coord (void);
+
+ // = Accessor and mutator methods
+ /// Return int table
+ int get_table (void);
+
+ /// Return int bucket
+ int get_bucket (void);
+
+ /// Set int table to new_table_number, return 0 for sucess.
+ int set_table (int new_table_number);
+
+ /// Set int bucket to new_bucket_number, return 0 for sucess.
+ int set_bucket (int new_bucket_number);
+
+private:
+ /// Position relative to the hash_map of which table the ListItem is in.
+ int table_;
+
+ /// Position relative to the table_ of which Bucket the ListItem is in.
+ int bucket_;
+};
+
+/**
+ * @class ACE_Hash_Map_RT_Hash_Function
+ *
+ * @brief A class that holds the templated HASH_KEY and does the actual hashing.
+ */
+template <class EXT_ID, class INT_ID, class HASH_KEY>
+class ACE_Hash_Map_RT_Hash_Function
+{
+public:
+
+ // = Initialization and termination methods.
+ /// Constructor
+ ACE_Hash_Map_RT_Hash_Function (int number_of_tables,
+ int buckets_per_table);
+
+ /// Destructor
+ ~ACE_Hash_Map_RT_Hash_Function (void);
+
+ /// Take an EXT_ID and hash it, returning a ACE_Hash_Map_RT_Coord&
+ int hash (const EXT_ID& ext_id,
+ ACE_Hash_Map_RT_Coord& coord);
+
+private:
+ /// Internal function that does the actual hashing
+ int hash_i (int key,
+ ACE_Hash_Map_RT_Coord& coord);
+
+ /// The number of tables that are available.
+ size_t max_tables_;
+
+ /// Number of buckets in each table.
+ size_t buckets_per_table_;
+
+ /// Function object used for hashing keys.
+ HASH_KEY hash_key_;
+};
+
+/**
+ * @class ACE_Hash_Map_RT_POD
+ *
+ * @brief "Point Of Design" knows when to change Hash_Functions, and how many
+ * tables there are currently. A nre POD is created when the number
+ * of tables is no longer enough.
+ */
+template <class EXT_ID, class INT_ID, class HASH_KEY>
+class ACE_Hash_Map_RT_POD
+{
+
+public:
+ // = Initialization and termination methods.
+ /// Constructor
+ ACE_Hash_Map_RT_POD (int num_of_tables,
+ ACE_Hash_Map_RT_Hash_Function<EXT_ID, INT_ID, HASH_KEY>& func);
+
+ /// Destructor
+ ~ACE_Hash_Map_RT_POD (void);
+
+ /// All hash requests will come through the POD, which will pass them to the
+ /// ACE_Hash_Map_RT_Hash_Function
+ int hash (const EXT_ID& exit_id,
+ ACE_Hash_Map_RT_Coord& coord);
+
+ // = Accessor and mutator methods
+ /// Get the number of available tables of this POD
+ size_t get_num_tables(void);
+
+private:
+ /// The number of available tables
+ int num_tables_;
+
+ /// the ACE_Hash_Map_RT_Hash_Function that does the hashing for this POD
+ ACE_Hash_Map_RT_Hash_Function<EXT_ID, INT_ID, HASH_KEY>& func_;
+
+};
+
+/**
+ * @class ACE_Hash_Map_RT_Entry
+ *
+ * @brief Define an Entry that has a (key, value) pair in the hash table.
+ * Each Entry will be contained inside a ACE_Hash_Map_RT_ListItem, and
+ * a Bucket is a list of ACE_Hash_Map_RT_ListItem s.
+ */
+template <class EXT_ID, class INT_ID>
+class ACE_Hash_Map_RT_Entry
+{
+public:
+ // = Initialization and termination methods.
+ /// Constructor.
+ ACE_Hash_Map_RT_Entry (const EXT_ID& ext_id,
+ const INT_ID& int_id);
+
+ ACE_Hash_Map_RT_Entry (void);
+
+# if ! defined (ACE_HAS_BROKEN_NOOP_DTORS)
+ /// Destructor.
+ ~ACE_Hash_Map_RT_Entry (void);
+#endif /* ! defined (ACE_HAS_BROKEN_NOOP_DTORS) */
+
+ // = Accessor and mutator methods
+ EXT_ID& get_ext_id (void);
+
+ INT_ID& get_int_id (void);
+
+ void set_ext_id (EXT_ID);
+
+ void set_int_id (INT_ID);
+
+ /// Key used to look up an entry.
+ EXT_ID ext_id_;
+
+ /// The contents (value) of the entry.
+ INT_ID int_id_;
+};
+
+/**
+ * @class ACE_Hash_Map_RT_ListItem
+ *
+ * @brief Has an Entry, and a pointer to the next ListItem in the Bucket.
+ * A Bucket stores ListItems. A ListItem has an Entry. Entries have (key, value).
+ */
+template <class EXT_ID, class INT_ID>
+class ACE_Hash_Map_RT_ListItem
+{
+public:
+ typedef ACE_Hash_Map_RT_ListItem<EXT_ID, INT_ID> LITEM;
+ typedef ACE_Hash_Map_RT_Entry<EXT_ID, INT_ID> ENTRY;
+
+ // = Initialization and termination methods.
+ /// Constructors
+ ACE_Hash_Map_RT_ListItem (ENTRY* entry,
+ LITEM* next);
+
+ // Default constructor
+ ACE_Hash_Map_RT_ListItem (void);
+
+ /// Destructor
+ ~ACE_Hash_Map_RT_ListItem (void);
+
+ /// The Entry object
+ ENTRY* entry_;
+
+ /// Pointer to the next item
+ ACE_Hash_Map_RT_ListItem<EXT_ID, INT_ID>* next_;
+
+};
+
+/**
+ * @class ACE_Hash_Map_RT_Bucket
+ *
+ * @brief A Bucket has a list of ListItems.
+ * A ListItem has an Entry. Entries have (key, value).
+ */
+template <class EXT_ID, class INT_ID, class HASH_KEY>
+class ACE_Hash_Map_RT_Bucket
+{
+public:
+
+ typedef ACE_Hash_Map_RT_POD<EXT_ID, INT_ID, HASH_KEY> POD;
+ typedef ACE_Hash_Map_RT_ListItem<EXT_ID, INT_ID> LITEM;
+ typedef ACE_Hash_Map_RT_Entry<EXT_ID, INT_ID> ENTRY;
+
+ // = Initialization and termination methods.
+ /// Constructors
+ ACE_Hash_Map_RT_Bucket (POD* pod);
+
+ ACE_Hash_Map_RT_Bucket (void);
+
+ /// Destructor
+ ~ACE_Hash_Map_RT_Bucket (void);
+
+ // = Accessor and mutator methods
+ /// Get the current length of the Bucket (that is, how many ListItems are present)
+ size_t get_length (void);
+
+ int set_length (int new_length);
+
+ /// Incr the current length by one.
+ int incr_length (void);
+
+ /// Decr the current length by one.
+ int decr_length (void);
+
+ int is_clean (POD& manager_POD);
+
+ /// Add a new ListItem (which will contain the passed Entry) to the front of this
+ /// Bucket's list
+ int prepend (ENTRY& entry);
+
+ /// Return the POD
+ //POD get_POD (void);
+
+ /// Set the POD
+ void set_POD (POD* pod);
+
+ /// Create a new head, and set the POD to the passed one.
+ int empty_bucket (POD* new_POD);
+
+ /// Pointer to the first element in the Bucket.
+ /// This ListItem will never have a key, value.
+ LITEM* head_;
+
+ /// A pointer to the last ListItem in the Bucket.
+ /// Initially this is set to the head_
+ LITEM* last_;
+
+protected:
+ /// Initialises this Bucket, allocating memory
+ int init_bucket_i (POD* pod);
+
+private:
+ /// Int counter of number of ListItems in the Bucket
+ int length_;
+
+ /// This Bucket's POD
+ POD* curPOD_;
+
+};
+
+// forward declare
+class ACE_Allocator;
+
+/**
+ * @class ACE_Hash_Map_RT_Table
+ *
+ * @brief A Table is an array of Buckets.
+ * A hashmap has an array of Tables, a Table has an array of Buckets.
+ * A Bucket stores ListItems. A ListItem has Entries. Entries have (key, value)
+ */
+template <class EXT_ID, class INT_ID, class HASH_KEY>
+class ACE_Hash_Map_RT_Table
+{
+public:
+
+ typedef ACE_Hash_Map_RT_POD<EXT_ID, INT_ID, HASH_KEY> POD;
+ typedef ACE_Hash_Map_RT_ListItem<EXT_ID, INT_ID> LITEM;
+ typedef ACE_Hash_Map_RT_Entry<EXT_ID, INT_ID> ENTRY;
+ typedef ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY> BUCKET;
+
+ friend class ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY>;
+
+ // = Initialization and termination methods.
+ //. Constructor
+ ACE_Hash_Map_RT_Table (ACE_Allocator* allocator,
+ size_t buckets_per_table,
+ POD* pod);
+
+ /// Default constructor
+ ACE_Hash_Map_RT_Table (void);
+
+ /// Destructor
+ ~ACE_Hash_Map_RT_Table(void);
+
+ // = Accessor and mutator methods
+ /// Pass the Bucket at Table[loc] back through the BUCKET& bucket, return 0 for sucess.
+ int get_bucket (int loc,
+ BUCKET& bucket);
+
+ /// Return the Bucket at Table[loc]
+ BUCKET& get_bucket (int loc);
+
+ int get_tablesize (void);
+
+ /// Increase tablesize by one.
+ void incr_tablesize (void);
+
+ /// Decrease tablesize by num_removed
+ void set_tablesize (int num_removed);
+
+ /// Get the array of Buckets
+ BUCKET* get_bucket_array (void);
+
+protected:
+ /// Initialise the Table, allocating memory and calling constructors for the Buckets
+ int init_table_i (ACE_Allocator* allocator,
+ size_t buckets_per_table,
+ POD* pod);
+private:
+ /// The array of Buckets
+ BUCKET *buckets_;
+
+ /// an int counter of the number of Buckets
+ int numBuckets;
+};
+
+// forward decl the manager
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> class ACE_Hash_Map_RT_Manager_Ex;
+
+/**
+ * @class ACE_Hash_Map_RT_Visitor
+ *
+ * @brief Parent class of all visitors that will traverse the Tables and Buckets. The visitors walk through the buckets looking for
+ * a certain key, and when (if) it is found, the appropritate visitor takes action (by returning the value, or deleting for example.).
+ * The Visitors are responsible for the actual inserting or deleting that bind() or unbind() do.
+ * These are not iterators, the simply perform their respective function at the appropriate place in the map.
+ */
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK>
+class ACE_Hash_Map_RT_Visitor
+{
+public:
+ typedef ACE_Hash_Map_RT_POD<EXT_ID, INT_ID, HASH_KEY> POD;
+ typedef ACE_Hash_Map_RT_ListItem<EXT_ID, INT_ID>LITEM;
+ typedef ACE_Hash_Map_RT_Entry<EXT_ID, INT_ID>ENTRY;
+ typedef ACE_Hash_Map_RT_Table<EXT_ID, INT_ID, HASH_KEY> TABLE;
+ typedef ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY> BUCKET;
+
+ virtual BUCKET* start(BUCKET* bucket) = 0;
+
+ virtual int visit(LITEM* litem) = 0;
+
+ virtual int done(BUCKET& bucket) = 0;
+
+ virtual void found_key (LITEM* litem);
+
+ /// Walks through the bucket, calling start() (then visit() only if the appropriate key has been found)
+ /// then done() on each ListItem. start and done only modify the map if is_found() is true, indicating
+ /// that the key has been found.
+ int process_bucket(BUCKET& bucket);
+
+ /// Returns 0 for false, 1 for true by comparing found_ to '0'
+ int is_found (void);
+
+ /// return found_
+ LITEM& get_found (void);
+
+protected:
+ /// A pointer to the last ListItem we touched.
+ /// As we search for the element we are looking for, this pointer is incremented accordingly.
+ /// Its used for removing ListItems from the Bucket without keeping
+ /// backward pointers to every ListItem
+ LITEM* mtfPrev_;
+
+ /// Pointer to the ListItem we are looking for (or null)
+ LITEM* found_;
+
+ ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>* manager_;
+};
+
+/**
+ * @class ACE_Hash_Map_RT_Clean_Visitor
+ *
+ * @brief Takes care of cleaning the buckets, to make sure the ListItems are in the right Table and Bucket according to the
+ * current POD and Hash_Function. If it encounters a ListItem that is not, it removes it then inserts it in the correct
+ * place.
+ */
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK>
+class ACE_Hash_Map_RT_Clean_Visitor : public ACE_Hash_Map_RT_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>
+{
+public:
+ ACE_Hash_Map_RT_Clean_Visitor (ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>* thismanager);
+
+ /// Returns a copy of the contents of that Bucket right before it empties the Bucket.
+ BUCKET* start (BUCKET* bucket);
+
+ /// the ListItem to 'visit' and inspect its location compared to where the POD says it should be.
+ int visit (LITEM* litem);
+
+ /// Sets the POD of the bucket to be the Table's current POD.
+ int done (BUCKET& bucket);
+
+ /// a copy of the contents of a bucket before we just cleared it out
+ BUCKET dead_bucket;
+};
+
+/**
+ * @class ACE_Hash_Map_RT_Searching_Visitor
+ *
+ * @brief Handles the searching through the Tables and Buckets while looking for a certain EXT_ID.
+ */
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK>
+class ACE_Hash_Map_RT_Searching_Visitor : public ACE_Hash_Map_RT_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>
+{
+public:
+
+ // = Initialization and termination methods.
+ /// Constructor
+ ACE_Hash_Map_RT_Searching_Visitor (const EXT_ID& entry,
+ ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>* manager);
+
+ /// Default constructor
+ ACE_Hash_Map_RT_Searching_Visitor (void);
+
+ /// Does nothing.
+ BUCKET* start (BUCKET* bucket);
+
+ /// Looks at the ListItem to see if its the one we are looking for.
+ int visit (LITEM* litem);
+
+ /// Does nothing.
+ int done (BUCKET& bucket);
+
+ /// the key that we're looking for
+ const EXT_ID& ext_id_;
+
+ ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>* manager_;
+};
+
+/**
+ * @class ACE_Hash_Map_RT_Put_Visitor
+ *
+ * @brief Adds a new ListItem (with Entry) to the Bucket where Searching_Visitor says it should go.
+ */
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK>
+class ACE_Hash_Map_RT_Put_Visitor : public ACE_Hash_Map_RT_Searching_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>
+{
+public:
+
+ // = Initialization and termination methods.
+ /// Constructor
+ ACE_Hash_Map_RT_Put_Visitor(const EXT_ID& ext_id,
+ const INT_ID& int_id,
+ ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>* thismanager);
+
+ virtual void found_key (LITEM* litem);
+
+ /// Prepends the Entry that we want to insert onto the Bucket
+ int done (BUCKET& bucket);
+
+private:
+
+ const INT_ID& int_id_;
+};
+
+/**
+ * @class ACE_Hash_Map_RT_Put_Visitor
+ *
+ * @brief Gets the INT_ID from the Bucket where Searching_Visitor finds it.
+ */
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK>
+class ACE_Hash_Map_RT_Get_Visitor : public ACE_Hash_Map_RT_Searching_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>
+{
+public:
+
+ // = Initialization and termination methods.
+ /// Constructor
+ ACE_Hash_Map_RT_Get_Visitor(const EXT_ID& ext_id,
+ INT_ID& int_id,
+ ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>* thismanager);
+
+ /// Calls compareMaxChain
+ int done (BUCKET& bucket);
+
+private:
+ INT_ID& int_id_;
+};
+
+/**
+ * @class ACE_Hash_Map_RT_Remove_Visitor
+ *
+ * @brief Removes the ListItem from the Bucket where Searching_Visitor finds it.
+ */
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK>
+class ACE_Hash_Map_RT_Remove_Visitor : public ACE_Hash_Map_RT_Searching_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>
+{
+public:
+
+ // = Initialization and termination methods.
+ /// Constructor
+ ACE_Hash_Map_RT_Remove_Visitor(const EXT_ID& ext_id,
+ ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>* thismanager);
+
+ /// Deletes the ListItem that we are looking for from the Bucket
+ int done (BUCKET& bucket);
+
+};
+
+class ACE_Hash_Map_RT_StatsManager
+{
+public:
+
+ // = Initialization and termination methods.
+ /// Constructor
+ ACE_Hash_Map_RT_StatsManager (void);
+
+ /// Destructor
+ ~ACE_Hash_Map_RT_StatsManager (void);
+
+ int get_total_elements (void);
+
+ int get_max_chain (void);
+
+ /// Stores the greater of chain_size and the stats_manager's max_chain_ in the stats_manager's max_chain_
+ void compare_max_chain (int chain_size);
+
+ /// max_chain_ = 0;
+ void reset_max_chain (void);
+
+ int incr_total_elements (void);
+
+ int decr_total_elements (void);
+
+private:
+ /// the longest list (which translates to the biggest Bucket's size)
+ int max_chain_;
+
+ /// the Sum of all the elements in all the Buckets (not including any Bucket->head_ because they dont hold an Entry)
+ int total_elements_;
+};
+
+
+ /*
+ * @class ACE_Hash_Map_RT_Clean_Manager
+ *
+ * @brief This class walks through the tables, and buckets looking for ListItems that are in the wrong
+ * position according to the current POD. When it reaches the end (more_to_do() = false) it is
+ * killed, and another one is created which starts from the beginning all over again.
+ *
+ */
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK>
+class ACE_Hash_Map_RT_Clean_Manager
+{
+ typedef ACE_Hash_Map_RT_Table<EXT_ID, INT_ID, HASH_KEY> TABLE;
+ typedef ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY> BUCKET;
+
+public:
+
+ ///Constructor
+ ACE_Hash_Map_RT_Clean_Manager (ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>* thismanager);
+
+ /// calls clean visitor.process_bucket on the next bucket in the current table. then goes to the next table, and
+ /// continues until more_to_do() == false
+ ACE_Hash_Map_RT_Clean_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>* incremental_clean (void);
+
+private:
+ /// if we havent retired the old POD and we're not done with the last table, then there is more to do.
+ int more_to_do (void);
+
+ /// A reference to the ACE_Hash_Map_RT_Manager_Ex
+ ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>* manager_;
+
+ /// the current table which is being cleaned
+ size_t cur_table_;
+
+ /// the current bucket in cur_table_ that is being cleaned.
+ size_t cur_bucket_;
+};
+
+// Forward decl.
+class ACE_Allocator;
+
+/**
+ * @class ACE_Hash_Map_RT_Manager_Ex
+ *
+ * @brief Define a map abstraction that efficiently associates
+ * <EXT_ID>s with <INT_ID>s.
+ *
+ * This implementation of a map uses a hash table. Key hashing
+ * is achieved through the HASH_KEY object.
+ * This class uses an <ACE_Allocator> to allocate memory. The
+ * user can make this a persistent class by providing an
+ * <ACE_Allocator> with a persistable memory pool.
+ */
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK>
+class ACE_Hash_Map_RT_Manager_Ex
+{
+public:
+ typedef EXT_ID KEY;
+ typedef INT_ID VALUE;
+ typedef ACE_Hash_Map_RT_Coord COORD;
+ typedef ACE_Hash_Map_RT_POD<EXT_ID, INT_ID, HASH_KEY> POD;
+ typedef ACE_Hash_Map_RT_Entry<EXT_ID, INT_ID> ENTRY;
+ typedef ACE_Hash_Map_RT_Table<EXT_ID, INT_ID, HASH_KEY> TABLE;
+ typedef ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY> BUCKET;
+ typedef ACE_Hash_Map_RT_ListItem<EXT_ID, INT_ID> LITEM;
+ typedef ACE_Hash_Map_RT_Clean_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK> CLEAN;
+ typedef ACE_Hash_Map_RT_Clean_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK> CLEANV;
+
+ friend class ACE_Hash_Map_RT_Clean_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>;
+ friend class ACE_Hash_Map_RT_Get_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>;
+ friend class ACE_Hash_Map_RT_Put_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>;
+ friend class ACE_Hash_Map_RT_Remove_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>;
+ friend class ACE_Hash_Map_RT_Clean_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>;
+
+ // = Initialization and termination methods.
+
+ /// Initialize a <Hash_Map_Manager_Ex> with default size.
+ ACE_Hash_Map_RT_Manager_Ex (size_t buckets_per_table,
+ size_t RTL,
+ size_t max_tables,
+ ACE_Allocator *alloc = 0,
+ size_t clean_rate = 3);
+
+ /// Cleanup the <Hash_Map_Manager_Ex>.
+ ~ACE_Hash_Map_RT_Manager_Ex (void);
+
+ /**
+ * Associate <ext_id> with <int_id>. If <ext_id> is already in the
+ * map then the <ACE_Hash_Map_RT_Entry> is not changed. Returns 0 if a
+ * new entry is bound successfully, returns 1 if an attempt is made
+ * to bind an existing entry, and returns -1 if failures occur.
+ */
+ int bind (const EXT_ID &item,
+ const INT_ID &int_id);
+
+ /// Return the value associated with the key.
+ int find (const EXT_ID &ext_id,
+ INT_ID &int_id);
+
+ /// Remove a key, value pair from the map
+ int unbind (const EXT_ID &ext_id);
+
+ /// find a the coord of the bucket where item is located according to this POD
+ int find_bucket (POD* pod,
+ const EXT_ID &item,
+ COORD& coord);
+
+ /// Return the bucket where the item is located according to this POD
+ BUCKET& find_bucket (POD* pod,
+ const EXT_ID &item);
+
+ POD* get_POD (void);
+
+ /// True if this->oldPOD_ != 0
+ int is_stable (void);
+
+ /// Return table at table_[loc]
+ TABLE& get_table (size_t loc);
+
+ size_t get_cleaning_rate (void);
+
+protected:
+ /// Retire the POD to old_POD and make this new_POD be the current POD for the hashmap
+ int change_POD (POD& new_POD);
+
+ /// Calls close_i while holding a write lock
+ int close_manager (void);
+
+ ///Iterate through the entire map calling the destuctor of each <ACE_Hash_Map_ListItem>.
+ int remove_all_i (void);
+
+ /// returns the coord where the key is located according to the current POD
+ int hash (const KEY& key,
+ ACE_Hash_Map_RT_Coord& coord);
+
+ /// find where entry should go according to the current POD and prepend it there
+ int rehash (ENTRY& entry);
+
+ /// makes a new POD based on the current table size and max_tables variables
+ POD* create_POD (void);
+
+ ///total number of elements
+ int size (void);
+
+ ///de allocates the buckets and the table array
+ int close_i (void);
+
+ ///finds the item, then lets the visitor do its thing (bind, unbind, find)
+ int locate_i (const EXT_ID& item,
+ ACE_Hash_Map_RT_Searching_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>& visitor,
+ INT_ID& id);
+
+ /// allocates memory and creates all tables and local variables.
+ int open_i (size_t buckets_per_table,
+ ACE_Allocator *alloc);
+
+ /// Pointer to a memory allocator.
+ ACE_Allocator *allocator_;
+
+ ACE_Hash_Map_RT_StatsManager* stats_;
+
+private:
+ /// a math function that gets the smallest size_t larger than the double
+ size_t ceil (double number);
+
+ /// array of tables
+ TABLE* table_;
+
+ size_t buckets_per_table_;
+
+ /// Current number of tables, always < max_tables_
+ size_t number_of_tables_;
+
+ /// Rehash Trigger Length
+ size_t RTL_;
+
+ /// how many tables we have room for
+ size_t max_tables_;
+
+ POD* curPOD_;
+
+ POD* oldPOD_;
+
+ ACE_Hash_Map_RT_Clean_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>* clean_vis_;
+
+ ACE_Hash_Map_RT_Clean_Manager<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>* clean_;
+
+ /// If the user is willing to put up with increased overhead in order
+ /// to clean the table in fewer operations, this will tell the
+ /// CleanManager to rehash additional buckets on each operation.
+ size_t cleaning_rate_;
+
+ /// Synchronization variable for the MT_SAFE <ACE_Hash_Map_Manager_Ex>.
+ ACE_LOCK lock_;
+
+};
+
+#if defined (__ACE_INLINE__)
+# include "ace/Hash_Map_Manager_RT_T.inl"
+#endif /* __ACE_INLINE__ */
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "Hash_Map_Manager_RT_T.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("Hash_Map_Manager_RT_T.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#include "post.h"
+#endif /* ACE_HASH_MAP_RT_MANAGER_RT_H */
diff --git a/ace/Hash_Map_Manager_RT_T.inl b/ace/Hash_Map_Manager_RT_T.inl
new file mode 100644
index 00000000000..befcc8ce428
--- /dev/null
+++ b/ace/Hash_Map_Manager_RT_T.inl
@@ -0,0 +1,447 @@
+// $Id$
+
+#ifndef ACE_HASH_MAP_MANAGER_RT_T_INL
+#define ACE_HASH_MAP_MANAGER_RT_T_INL
+
+#include "Synch.h"
+
+
+ACE_INLINE
+int
+ACE_Hash_Map_RT_Coord::get_table (void)
+{
+ return this->table_;
+}
+
+ACE_INLINE
+int
+ACE_Hash_Map_RT_Coord::get_bucket (void)
+{
+ return this->bucket_;
+}
+
+ACE_INLINE
+int
+ACE_Hash_Map_RT_Coord::set_table (int newtables)
+{
+ this->table_ = newtables;
+ return 0;
+}
+
+ACE_INLINE
+int
+ACE_Hash_Map_RT_Coord::set_bucket (int newbuckets)
+{
+ this->bucket_ = newbuckets;
+ return 0;
+}
+
+//***************************************************************/
+
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> ACE_INLINE
+int
+ACE_Hash_Map_RT_POD<EXT_ID, INT_ID, HASH_KEY>::hash (const EXT_ID& ext_id, ACE_Hash_Map_RT_Coord& coord)
+{
+ return this->func_.hash(ext_id, coord);
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> ACE_INLINE
+size_t
+ACE_Hash_Map_RT_POD<EXT_ID, INT_ID, HASH_KEY>::get_num_tables()
+{
+ return this->num_tables_;
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID> ACE_INLINE
+void
+ACE_Hash_Map_RT_Entry<EXT_ID, INT_ID>::set_ext_id (EXT_ID id)
+{
+ this->ext_id_ = id;
+}
+
+template <class EXT_ID, class INT_ID> ACE_INLINE
+void
+ACE_Hash_Map_RT_Entry<EXT_ID, INT_ID>::set_int_id (INT_ID id)
+{
+ this->int_id_ = id;
+}
+
+template <class EXT_ID, class INT_ID> ACE_INLINE
+EXT_ID&
+ACE_Hash_Map_RT_Entry<EXT_ID, INT_ID>::get_ext_id ()
+{
+ return this->ext_id_;
+}
+
+template <class EXT_ID, class INT_ID> ACE_INLINE
+INT_ID&
+ACE_Hash_Map_RT_Entry<EXT_ID, INT_ID>::get_int_id ()
+{
+ return this->int_id_;
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> ACE_INLINE
+size_t
+ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY>::get_length (void)
+{
+ return this->length_;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> ACE_INLINE
+int
+ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY>::set_length (int new_length)
+{
+ this->length_ = new_length;
+ return 0;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> ACE_INLINE
+int
+ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY>::incr_length (void)
+{
+ return ++this->length_;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> ACE_INLINE
+int
+ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY>::decr_length (void)
+{
+ return --this->length_;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> ACE_INLINE
+int
+ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY>::is_clean (POD& manager_POD)
+{
+ return curPOD_ == &manager_POD;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> ACE_INLINE
+int
+ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY>::empty_bucket (POD* newPOD)
+{
+ this->head_ = new LITEM();
+ this->last_ = this->head_;
+ this->length_ = 0;
+
+ curPOD_ = newPOD;
+
+ return 0;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> ACE_INLINE
+void
+ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY>::set_POD (POD* pod)
+{
+ curPOD_ = pod;
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> ACE_INLINE
+int
+ACE_Hash_Map_RT_Table<EXT_ID, INT_ID, HASH_KEY>::get_bucket (int loc,
+ BUCKET& bucket)
+{
+ bucket = get_bucket(loc);
+ return 0;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> ACE_INLINE
+void
+ACE_Hash_Map_RT_Table<EXT_ID, INT_ID, HASH_KEY>::incr_tablesize (void)
+{
+ ++this->numBuckets;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> ACE_INLINE
+int
+ACE_Hash_Map_RT_Table<EXT_ID, INT_ID, HASH_KEY>::get_tablesize (void)
+{
+ return this->numBuckets;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> ACE_INLINE
+void
+ACE_Hash_Map_RT_Table<EXT_ID, INT_ID, HASH_KEY>::set_tablesize (int numRemoved)
+{
+ this->numBuckets = numRemoved;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> ACE_INLINE
+ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY>&
+ACE_Hash_Map_RT_Table<EXT_ID, INT_ID, HASH_KEY>::get_bucket (int loc)
+{
+ return this->buckets_[loc];
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY> ACE_INLINE
+ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY>*
+ACE_Hash_Map_RT_Table<EXT_ID, INT_ID, HASH_KEY>::get_bucket_array (void)
+{
+ return this->buckets_;
+}
+
+
+//***************************************************************/
+
+ACE_INLINE
+int
+ACE_Hash_Map_RT_StatsManager::get_total_elements (void)
+{
+ return this->total_elements_;
+}
+
+ACE_INLINE
+int
+ACE_Hash_Map_RT_StatsManager::get_max_chain (void)
+{
+ return this->max_chain_;
+}
+
+ACE_INLINE
+void
+ACE_Hash_Map_RT_StatsManager::compare_max_chain (int chainSize)
+{
+ if (chainSize > this->max_chain_)
+ this->max_chain_ = chainSize;
+}
+
+ACE_INLINE
+void
+ACE_Hash_Map_RT_StatsManager::reset_max_chain (void)
+{
+ this->max_chain_ = 0;
+}
+
+ACE_INLINE
+int
+ACE_Hash_Map_RT_StatsManager::incr_total_elements (void)
+{
+ compare_max_chain (++this->total_elements_);
+ return this->total_elements_;
+}
+
+ACE_INLINE
+int
+ACE_Hash_Map_RT_StatsManager::decr_total_elements (void)
+{
+ return --this->total_elements_;
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+int
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::size (void)
+{
+ return this->stats.getTotalElements();
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+int
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::bind (const EXT_ID &ext_id,
+ const INT_ID &int_id)
+{
+ ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
+
+ INT_ID dummy = int_id;
+
+ ACE_Hash_Map_RT_Put_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK> visitor (ext_id,
+ int_id,
+ this);
+ return locate_i(ext_id,
+ visitor,
+ dummy);
+ return 0;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+ACE_Hash_Map_RT_Table<EXT_ID, INT_ID, HASH_KEY>&
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::get_table (size_t loc)
+{
+ return table_[loc];
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+int
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::find (const EXT_ID &ext_id,
+ INT_ID &int_id)
+{
+
+ ACE_READ_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
+
+ ACE_Hash_Map_RT_Get_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK> visitor (ext_id,
+ int_id,
+ this);
+ return locate_i(ext_id,
+ visitor,
+ int_id);
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+int
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::unbind (const EXT_ID &ext_id)
+{
+ ACE_WRITE_GUARD_RETURN (ACE_LOCK, ace_mon, this->lock_, -1);
+
+ INT_ID dummy;
+
+ ACE_Hash_Map_RT_Remove_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK> visitor (ext_id,
+ this);
+ return locate_i(ext_id,
+ visitor,
+ dummy);
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+int
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::find_bucket (POD* pod,
+ const EXT_ID &ext_id,
+ ACE_Hash_Map_RT_Coord& coord)
+{
+ pod->hash(ext_id, coord);
+ return 1;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY>&
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::find_bucket (POD* pod,
+ const EXT_ID &ext_id)
+{
+ ACE_Hash_Map_RT_Coord coord = ACE_Hash_Map_RT_Coord(0,0);
+ pod->hash(ext_id, coord);
+ return get_table(coord.get_table()).get_bucket(coord.get_bucket());
+}
+
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+int
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::change_POD (ACE_Hash_Map_RT_POD<EXT_ID, INT_ID, HASH_KEY>& newPOD)
+{
+ this->oldPOD_ = this->curPOD_;
+ this->curPOD_ = &newPOD;
+ return 0;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+ACE_Hash_Map_RT_POD<EXT_ID, INT_ID, HASH_KEY>*
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::get_POD (void)
+{
+ return curPOD_;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+int
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::is_stable (void)
+{
+ return (this->oldPOD_ != 0);
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+int
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::hash (const KEY& key, ACE_Hash_Map_RT_Coord& coord)
+{
+ this->curPOD_->hash(key, coord);
+ return 0;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+int
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::rehash (ENTRY& entry)
+{
+ find_bucket(curPOD_, entry.get_ext_id()).prepend(entry);
+ return 0;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+size_t
+ACE_Hash_Map_RT_Manager_Ex<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::get_cleaning_rate (void)
+{
+ return cleaning_rate_;
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+int
+ACE_Hash_Map_RT_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::is_found (void)
+{
+ return (this->found_ != 0);
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+void
+ACE_Hash_Map_RT_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::found_key (LITEM* litem)
+{
+ this->found_ = litem;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+ACE_Hash_Map_RT_ListItem<EXT_ID, INT_ID>&
+ACE_Hash_Map_RT_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::get_found (void)
+{
+ return *this->found_;
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+int
+ACE_Hash_Map_RT_Clean_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::visit (LITEM* litem)
+{
+ manager_->rehash(*litem->entry_);
+ return 0;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY>*
+ACE_Hash_Map_RT_Clean_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::start (BUCKET* bucket)
+{
+ dead_bucket = *bucket;
+
+ (*bucket).empty_bucket(this->manager_->get_POD());
+
+ return &dead_bucket;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+int
+ACE_Hash_Map_RT_Clean_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::done (BUCKET& bucket)
+{
+ bucket.set_POD(manager_->get_POD());
+ return 0;
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+ACE_Hash_Map_RT_Bucket<EXT_ID, INT_ID, HASH_KEY>*
+ACE_Hash_Map_RT_Searching_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::start (BUCKET* bucket)
+{
+ return bucket;
+}
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+int
+ACE_Hash_Map_RT_Searching_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::done (BUCKET&)
+{
+ return 0;
+}
+
+//***************************************************************/
+
+template <class EXT_ID, class INT_ID, class HASH_KEY, class COMPARE_KEYS, class ACE_LOCK> ACE_INLINE
+int
+ACE_Hash_Map_RT_Get_Visitor<EXT_ID, INT_ID, HASH_KEY, COMPARE_KEYS, ACE_LOCK>::done (BUCKET& bucket)
+{
+ this->manager_->stats_->compare_max_chain(bucket.get_length());
+ return 0;
+}
+
+#endif
diff --git a/ace/ace_dll.dsp b/ace/ace_dll.dsp
index 7c4e92d3a8f..88ac1d56519 100644
--- a/ace/ace_dll.dsp
+++ b/ace/ace_dll.dsp
@@ -414,6 +414,10 @@ SOURCE=.\Hash_Map_Manager.cpp
# End Source File
# Begin Source File
+SOURCE=.\Hash_Map_Manager_RT.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\Hashable.cpp
# End Source File
# Begin Source File
@@ -1462,6 +1466,10 @@ SOURCE=.\Hash_Map_Manager_rt.h
# End Source File
# Begin Source File
+SOURCE=.\Hash_Map_Manager_RT_T.h
+# End Source File
+# Begin Source File
+
SOURCE=.\Hash_Map_Manager_T.h
# End Source File
# Begin Source File
@@ -2570,7 +2578,7 @@ SOURCE=.\Hash_Map_Manager.i
# End Source File
# Begin Source File
-SOURCE=.\Hash_Map_Manager_rt.i
+SOURCE=.\Hash_Map_Manager_RT_T.inl
# End Source File
# Begin Source File
@@ -3261,6 +3269,11 @@ SOURCE=.\Hash_Cache_Map_Manager_T.cpp
# End Source File
# Begin Source File
+SOURCE=.\Hash_Map_Manager_RT_T.cpp
+# PROP Exclude_From_Build 1
+# End Source File
+# Begin Source File
+
SOURCE=.\Hash_Map_Manager_T.cpp
# PROP Exclude_From_Build 1
# End Source File
diff --git a/ace/ace_lib.dsp b/ace/ace_lib.dsp
index 756cc88dc6f..e5a590da308 100644
--- a/ace/ace_lib.dsp
+++ b/ace/ace_lib.dsp
@@ -42,8 +42,8 @@ RSC=rc.exe
# PROP Output_Dir ""
# PROP Intermediate_Dir ".\LIB\Release"
# PROP Target_Dir ""
-MTL=midl.exe
LINK32=link.exe -lib
+MTL=midl.exe
# ADD BASE CPP /nologo /MD /W3 /GX /O1 /I "../" /D ACE_HAS_DLL=0 /D "ACE_NO_INLINE" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /FD /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MT /W3 /GX /O1 /I "../" /I "../PACE" /D ACE_OS_HAS_DLL=0 /D ACE_HAS_DLL=0 /D "ACE_NO_INLINE" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /FD /c
@@ -69,8 +69,8 @@ LIB32=link.exe -lib
# PROP Output_Dir ""
# PROP Intermediate_Dir ".\LIB\Debug"
# PROP Target_Dir ""
-MTL=midl.exe
LINK32=link.exe -lib
+MTL=midl.exe
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /Gy /I "../" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D ACE_HAS_DLL=0 /FD /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /Gy /I "../" /I "../PACE" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D ACE_HAS_DLL=0 /D ACE_OS_HAS_DLL=0 /FD /c
@@ -96,8 +96,8 @@ LIB32=link.exe -lib
# PROP Output_Dir ""
# PROP Intermediate_Dir ".\LIB\Release"
# PROP Target_Dir ""
-MTL=midl.exe
LINK32=link.exe -lib
+MTL=midl.exe
# ADD BASE CPP /nologo /G5 /MT /W3 /GX /O1 /I "../" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D ACE_HAS_DLL=0 /D "ACE_NO_INLINE" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /Zi /O1 /I "../" /I "../PACE" /D "_WINDOWS" /D "NDEBUG" /D "ACE_AS_STATIC_LIBS" /D "WIN32" /FD /c
# SUBTRACT CPP /YX
@@ -122,8 +122,8 @@ LIB32=link.exe -lib
# PROP Output_Dir ""
# PROP Intermediate_Dir ".\LIB\Debug"
# PROP Target_Dir ""
-MTL=midl.exe
LINK32=link.exe -lib
+MTL=midl.exe
# ADD BASE CPP /nologo /G5 /MTd /W3 /Gm /GX /Zi /Od /Gy /I "../" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D ACE_HAS_DLL=0 /D "ACE_NO_INLINE" /YX /FD /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /Gy /I "../" /I "../PACE" /D "_WINDOWS" /D "_DEBUG" /D "ACE_AS_STATIC_LIBS" /D "WIN32" /FD /c
# SUBTRACT CPP /YX
@@ -405,6 +405,10 @@ SOURCE=.\Hash_Map_Manager.cpp
# End Source File
# Begin Source File
+SOURCE=.\Hash_Map_Manager_RT.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\Hashable.cpp
# End Source File
# Begin Source File
@@ -1449,6 +1453,14 @@ SOURCE=.\Hash_Map_Manager.h
# End Source File
# Begin Source File
+SOURCE=.\Hash_Map_Manager_rt.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Hash_Map_Manager_RT_T.h
+# End Source File
+# Begin Source File
+
SOURCE=.\Hash_Map_Manager_T.h
# End Source File
# Begin Source File
@@ -2565,6 +2577,10 @@ SOURCE=.\Hash_Map_Manager.i
# End Source File
# Begin Source File
+SOURCE=.\Hash_Map_Manager_RT_T.inl
+# End Source File
+# Begin Source File
+
SOURCE=.\Hash_Map_Manager_T.i
# End Source File
# Begin Source File
@@ -3248,6 +3264,11 @@ SOURCE=.\Hash_Cache_Map_Manager_T.cpp
# End Source File
# Begin Source File
+SOURCE=.\Hash_Map_Manager_RT_T.cpp
+# PROP Exclude_From_Build 1
+# End Source File
+# Begin Source File
+
SOURCE=.\Hash_Map_Manager_T.cpp
# PROP Exclude_From_Build 1
# End Source File
diff --git a/tests/Hash_Map_Manager_RT_Test.cpp b/tests/Hash_Map_Manager_RT_Test.cpp
new file mode 100644
index 00000000000..35af0786d91
--- /dev/null
+++ b/tests/Hash_Map_Manager_RT_Test.cpp
@@ -0,0 +1,396 @@
+
+//=============================================================================
+/**
+ * @file Hash_Map_Manager_RT_Test.cpp
+ *
+ * $Id$
+ *
+ * @author Jeremy M. Nolle <jmn3@cs.wustl.edu>
+ */
+//=============================================================================
+
+#include "test_config.h"
+#include "ace/Hash_Map_Manager_RT.h"
+#include "ace/Malloc_T.h"
+#include "ace/Synch.h"
+
+ACE_RCSID(tests, Hash_Map_Manager_Test, "$Id$")
+
+static const size_t STRING_TABLE_ENTRIES = 18;
+static const size_t MAX_HASH = 18;
+
+typedef ACE_Hash_Map_RT_Table<const ACE_TCHAR *,
+ const ACE_TCHAR *,
+ const ACE_TCHAR *> HASH_STRING_TABLE;
+
+typedef ACE_Hash_Map_RT_Bucket<const ACE_TCHAR *,
+ const ACE_TCHAR *,
+ const ACE_TCHAR *> HASH_STRING_BUCKET;
+
+// This allows us enough for 4 tables and 8 buckets in each table
+// regardless of the number of entries
+static const size_t STRING_TABLE_SIZE =
+ (6 * (sizeof (HASH_STRING_TABLE))) + 48 * (sizeof(HASH_STRING_BUCKET)) ;
+
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Hash_Map_RT_Entry<const ACE_TCHAR *, const ACE_TCHAR *>;
+template class ACE_Hash_Map_RT_Manager_Ex<const ACE_TCHAR *, const ACE_TCHAR *, ACE_Hash<const ACE_TCHAR *>, ACE_Equal_To<const ACE_TCHAR *>, ACE_Null_Mutex>;
+template class ACE_Static_Allocator<STRING_TABLE_SIZE>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Hash_Map_RT_Entry<const ACE_TCHAR *, const ACE_TCHAR *>
+#pragma instantiate ACE_Hash_Map_RT_Manager_Ex<const ACE_TCHAR *, const ACE_TCHAR *, ACE_Hash<const ACE_TCHAR *>, ACE_Equal_To<const ACE_TCHAR *>, ACE_Null_Mutex>
+#pragma instantiate ACE_Static_Allocator<STRING_TABLE_SIZE>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
+
+static ACE_Static_Allocator<STRING_TABLE_SIZE> ace_test_allocator;
+
+typedef ACE_Hash_Map_RT_Manager_Ex<const ACE_TCHAR *,
+ const ACE_TCHAR *,
+ ACE_Hash<const ACE_TCHAR *>,
+ ACE_Equal_To<const ACE_TCHAR *>,
+ ACE_Null_Mutex> HASH_STRING_MAP;
+
+struct String_Table
+{
+ const ACE_TCHAR *key_;
+ const ACE_TCHAR *value_;
+};
+
+static String_Table string_table[] =
+{
+ {
+ ACE_TEXT ("hello "),
+ ACE_TEXT ("guten Tag")
+ },
+ {
+ ACE_TEXT ("one "),
+ ACE_TEXT ("111111")
+ },
+ {
+ ACE_TEXT ("two "),
+ ACE_TEXT ("222222")
+ },
+ {
+ ACE_TEXT ("three "),
+ ACE_TEXT ("333333")
+ },
+ {
+ ACE_TEXT ("four "),
+ ACE_TEXT ("444444")
+ },
+ {
+ ACE_TEXT ("five "),
+ ACE_TEXT ("555555")
+ },
+ {
+ ACE_TEXT ("six "),
+ ACE_TEXT ("666666")
+ },
+ {
+ ACE_TEXT ("seven "),
+ ACE_TEXT ("777777")
+ },
+ {
+ ACE_TEXT ("eight "),
+ ACE_TEXT ("888888")
+ },
+ {
+ ACE_TEXT ("nine "),
+ ACE_TEXT ("999999")
+ },
+ {
+ ACE_TEXT ("ten "),
+ ACE_TEXT ("101010")
+ },
+ {
+ ACE_TEXT ("eleven "),
+ ACE_TEXT ("111111")
+ },
+ {
+ ACE_TEXT ("twelve "),
+ ACE_TEXT ("121212")
+ },
+ {
+ ACE_TEXT ("thirteen"),
+ ACE_TEXT ("131313")
+ },
+ {
+ ACE_TEXT ("fourteen"),
+ ACE_TEXT ("141414")
+ },
+ {
+ ACE_TEXT ("fifteen "),
+ ACE_TEXT ("151515")
+ },
+ {
+ ACE_TEXT ("sixteen "),
+ ACE_TEXT ("161616")
+ },
+ {
+ ACE_TEXT ("seventen"),
+ ACE_TEXT ("171717")
+ },
+ {
+ ACE_TEXT ("eighteen"),
+ ACE_TEXT ("181818")
+ },
+ {
+ ACE_TEXT ("nineteen"),
+ ACE_TEXT ("191919")
+ },
+ {
+ ACE_TEXT ("twenty "),
+ ACE_TEXT ("202020")
+ },
+ {
+ ACE_TEXT ("twentyon"),
+ ACE_TEXT ("212121")
+ },
+ {
+ ACE_TEXT ("twentytw"),
+ ACE_TEXT ("222222")
+ },
+ {
+ ACE_TEXT ("twenthre"),
+ ACE_TEXT ("232323")
+ },
+ {
+ ACE_TEXT ("twenfour"),
+ ACE_TEXT ("242424")
+ },
+ {
+ ACE_TEXT ("twenfive"),
+ ACE_TEXT ("252525")
+ },
+ {
+ ACE_TEXT ("twnsix "),
+ ACE_TEXT ("262626")
+ },
+ {
+ ACE_TEXT ("twensevn"),
+ ACE_TEXT ("272727")
+ },
+ {
+ ACE_TEXT ("tweneigt"),
+ ACE_TEXT ("282828")
+ },
+ {
+ ACE_TEXT ("twennine"),
+ ACE_TEXT ("292929")
+ },
+ {
+ ACE_TEXT ("thirty "),
+ ACE_TEXT ("303030")
+ },
+ {
+ ACE_TEXT ("thirtyon"),
+ ACE_TEXT ("313131")
+ },
+ {
+ ACE_TEXT ("thirtytw"),
+ ACE_TEXT ("323232")
+ },
+ {
+ ACE_TEXT ("thirthre"),
+ ACE_TEXT ("333333")
+ },
+ {
+ ACE_TEXT ("thirfour"),
+ ACE_TEXT ("343434")
+ },
+ {
+ ACE_TEXT ("thirfive"),
+ ACE_TEXT ("353535")
+ },
+ {
+ ACE_TEXT ("thirsix "),
+ ACE_TEXT ("363636")
+ },
+ {
+ ACE_TEXT ("thirsevn"),
+ ACE_TEXT ("373737")
+ },
+ {
+ ACE_TEXT ("colours "),
+ ACE_TEXT ("Farben")
+ },
+ {
+ ACE_TEXT ("hello "),
+ ACE_TEXT ("not so, hello")
+ },
+ {
+ ACE_TEXT ("ja whol "),
+ ACE_TEXT ("sure thing")
+ },
+ {
+ ACE_TEXT ("no idea "),
+ ACE_TEXT ("keine Idee")
+ },
+ {
+ ACE_TEXT ("cheese "),
+ ACE_TEXT ("Kase")
+ },
+ {
+ ACE_TEXT ("mensch "),
+ ACE_TEXT ("bummer")
+ },
+ {
+ ACE_TEXT ("mustard "),
+ ACE_TEXT ("yellow")
+ },
+ {
+ ACE_TEXT ("ketchup "),
+ ACE_TEXT ("red")
+ },
+ {
+ ACE_TEXT ("grapes "),
+ ACE_TEXT ("purpurot")
+ },
+ {
+ ACE_TEXT ("kartofel"),
+ ACE_TEXT ("potato")
+ },
+ {
+ ACE_TEXT ("brot "),
+ ACE_TEXT ("bread")
+ },
+ {
+ ACE_TEXT ("0"),
+ ACE_TEXT ("zilch")
+ },
+ {
+ ACE_TEXT ("goodbye "),
+ ACE_TEXT ("auf wiedersehen")
+ },
+ {
+ 0,
+ 0
+ }
+};
+
+
+static int
+run_test (void)
+{
+ HASH_STRING_MAP hash (2,
+ 3,
+ 4,
+ &ace_test_allocator);
+
+ int i;
+ // Check the <bind> operation.
+ for (i = 0; string_table[i].key_ != 0; i++)
+ if (hash.bind (string_table[i].key_,
+ string_table[i].value_) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("bind failed for %s \n"),
+ string_table[i].key_), -1);
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("just put %s\n"),
+ string_table[i]));
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("\n just put a bunch of stuff\n\n")));
+
+
+ const ACE_TCHAR *id;
+
+ // Check the <find> operation.
+ for (i = 0; string_table[i].key_ != 0; i++)
+ if (hash.find (string_table[i].key_,
+ id) == 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("`%s' found `%s'\n"),
+ string_table[i].key_,
+ id));
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("`%s' _________NOT_________ found \n"),
+ string_table[i].key_));
+
+ id = NULL;
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("\n\n")));
+
+ // now remove the 6th element
+ hash.unbind (string_table[5].key_);
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("removing `%s'\n"),
+ string_table[5].key_));
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("\n")));
+
+ // remove the first element
+ hash.unbind (string_table[0].key_);
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("removing `%s'\n"),
+ string_table[0].key_));
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("\n\n")));
+
+ // Check the <find> operation again with missing elements
+ for (i = 0; string_table[i].key_ != 0; i++)
+ {
+ if (hash.find (string_table[i].key_,
+ id) == 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("`%s' found `%s'\n"),
+ string_table[i].key_,
+ id));
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("`%s' _________NOT_________ found \n"),
+ string_table[i].key_));
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("\n\n")));
+
+ // now put the 6th element back in
+ if (hash.bind (string_table[5].key_,
+ string_table[5].value_) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p failed for %s \n"),
+ ACE_TEXT ("bind"),
+ string_table[5].key_), -1);
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("putting five back \n\n")));
+
+ // Check the <find> operation. now only the first element is missing (twice)
+ for (i = 0; string_table[i].key_ != 0; i++)
+ {
+ if (hash.find (string_table[i].key_,
+ id) == 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("`%s' found `%s'\n"),
+ string_table[i].key_,
+ id));
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("`%s' _________NOT_________ found \n"),
+ string_table[i].key_));
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("dump\n")));
+ ace_test_allocator.dump ();
+ return 0;
+}
+
+int
+ACE_TMAIN (int, ACE_TCHAR *[])
+{
+ ACE_START_TEST (ACE_TEXT ("Hash_Map_Manager_Test"));
+
+ run_test ();
+
+ ACE_END_TEST;
+
+ return 0;
+}
diff --git a/tests/Hash_Map_Manager_RT_Test.dsp b/tests/Hash_Map_Manager_RT_Test.dsp
new file mode 100644
index 00000000000..25636a8ef68
--- /dev/null
+++ b/tests/Hash_Map_Manager_RT_Test.dsp
@@ -0,0 +1,158 @@
+# Microsoft Developer Studio Project File - Name="Hash_Map_Manager_RT_Test" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=Hash_Map_Manager_RT_Test - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Hash_Map_Manager_RT_Test.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Hash_Map_Manager_RT_Test.mak" CFG="Hash_Map_Manager_RT_Test - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Hash_Map_Manager_RT_Test - Win32 Static Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "Hash_Map_Manager_RT_Test - Win32 Static Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "Hash_Map_Manager_RT_Test - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "Hash_Map_Manager_RT_Test - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "Hash_Map_Manager_RT_Test - Win32 Static Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Static_Debug"
+# PROP BASE Intermediate_Dir "Static_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Static_Debug"
+# PROP Intermediate_Dir "Static_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "../" /D "_DEBUG" /D ACE_AS_STATIC_LIBS /D "WIN32" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
+# ADD LINK32 acesd.lib advapi32.lib user32.lib /nologo /subsystem:console /debug /machine:I386 /libpath:"..\ace"
+
+!ELSEIF "$(CFG)" == "Hash_Map_Manager_RT_Test - Win32 Static Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Static_Release"
+# PROP BASE Intermediate_Dir "Static_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Static_Release"
+# PROP Intermediate_Dir "Static_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../" /D "NDEBUG" /D ACE_AS_STATIC_LIBS /D "WIN32" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 aces.lib advapi32.lib user32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\ace"
+
+!ELSEIF "$(CFG)" == "Hash_Map_Manager_RT_Test - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\ace"
+
+!ELSEIF "$(CFG)" == "Hash_Map_Manager_RT_Test - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ""
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "../" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\ace"
+
+!ENDIF
+
+# Begin Target
+
+# Name "Hash_Map_Manager_RT_Test - Win32 Static Debug"
+# Name "Hash_Map_Manager_RT_Test - Win32 Static Release"
+# Name "Hash_Map_Manager_RT_Test - Win32 Release"
+# Name "Hash_Map_Manager_RT_Test - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter ".cpp"
+# Begin Source File
+
+SOURCE=.\Hash_Map_Manager_RT_Test.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter ".h"
+# Begin Source File
+
+SOURCE=.\test_config.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/tests/tests.dsw b/tests/tests.dsw
index 47a6f8d263e..c07d7cd4ec4 100644
--- a/tests/tests.dsw
+++ b/tests/tests.dsw
@@ -453,6 +453,18 @@ Package=<4>
###############################################################################
+Project: "Hash_Map_Manager_RT_Test"=".\Hash_Map_Manager_RT_Test.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
Project: "High_Res_Timer_Test"=".\High_Res_Timer_Test.dsp" - Package Owner=<4>
Package=<5>