diff options
author | nanbor <nanbor@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2002-12-18 23:18:47 +0000 |
---|---|---|
committer | nanbor <nanbor@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2002-12-18 23:18:47 +0000 |
commit | 4e9b6eb39595d4cafe5824b1d16a01c16339c82a (patch) | |
tree | 7ebef134b9f941f132e33357553defbe2d2c70f3 | |
parent | 8aa955b38258f142ee55f9625049596baa1eb907 (diff) | |
download | ATCD-4e9b6eb39595d4cafe5824b1d16a01c16339c82a.tar.gz |
ChangeLogTag:Wed Dec 18 17:12:04 2002 Nanbor Wang <nanbor@cs.wustl.edu>
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | ChangeLogs/ChangeLog-03a | 14 | ||||
-rw-r--r-- | ace/Hash_Map_Manager_RT_T.cpp | 765 | ||||
-rw-r--r-- | ace/Hash_Map_Manager_RT_T.h | 772 | ||||
-rw-r--r-- | ace/Hash_Map_Manager_RT_T.inl | 447 | ||||
-rw-r--r-- | ace/ace_dll.dsp | 15 | ||||
-rw-r--r-- | ace/ace_lib.dsp | 29 | ||||
-rw-r--r-- | tests/Hash_Map_Manager_RT_Test.cpp | 396 | ||||
-rw-r--r-- | tests/Hash_Map_Manager_RT_Test.dsp | 158 | ||||
-rw-r--r-- | tests/tests.dsw | 12 |
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>
|