diff options
Diffstat (limited to 'TAO/tao/objtable.cpp')
-rw-r--r-- | TAO/tao/objtable.cpp | 691 |
1 files changed, 565 insertions, 126 deletions
diff --git a/TAO/tao/objtable.cpp b/TAO/tao/objtable.cpp index 70ef7aadbcd..eb67f8c8001 100644 --- a/TAO/tao/objtable.cpp +++ b/TAO/tao/objtable.cpp @@ -1,222 +1,661 @@ +// +// $Id$ +// + +#include "ace/Auto_Ptr.h" + #include "tao/corba.h" +#include "tao/objtable.h" -// destructor +TAO_Object_Table_Iterator_Impl::~TAO_Object_Table_Iterator_Impl (void) +{ +} + +TAO_Object_Table_Impl::~TAO_Object_Table_Impl (void) +{ +} + +int +TAO_Object_Table_Impl::find (const PortableServer::Servant servant) +{ + PortableServer::ObjectId* id; + int ret = this->find (servant, id); + if (ret == -1) + return -1; + + // It was found and returned in <id>, we must release it. + delete id; + return 0; +} + +int +TAO_Object_Table_Impl::find (const PortableServer::ObjectId &id) +{ + PortableServer::Servant servant; + return this->find (id, servant); +} + +int +TAO_Object_Table_Impl::find (const PortableServer::Servant servant, + PortableServer::ObjectId_out id) +{ + id.ptr () = 0; + auto_ptr<TAO_Object_Table_Iterator_Impl> end (this->end ()); + for (auto_ptr<TAO_Object_Table_Iterator_Impl> i (this->begin ()); + !i->done (end.get ()); + i->advance ()) + { + const TAO_Object_Table_Entry& item = i->item (); + if (item.int_id_ == servant) + { + if (id != 0) + { + // More than one match return -1. + delete id.ptr (); + return -1; + } + // Store the match.... + id.ptr () = new PortableServer::ObjectId (item.ext_id_); + } + } + return (id.ptr () == 0)?-1:0; +} + + + +TAO_Object_Table_Iterator:: +TAO_Object_Table_Iterator (TAO_Object_Table_Iterator_Impl *impl) + : impl_ (impl) +{ +} + +TAO_Object_Table_Iterator:: +TAO_Object_Table_Iterator (const TAO_Object_Table_Iterator &x) + : impl_ (0) +{ + if (x.impl_ != 0) + { + this->impl_ = x.impl_->clone (); + } +} + +TAO_Object_Table_Iterator& +TAO_Object_Table_Iterator::operator= (const TAO_Object_Table_Iterator &x) +{ + if (this != &x) + { + delete this->impl_; + if (x.impl_ == 0) + { + this->impl_ = 0; + } + else + { + this->impl_ = x.impl_->clone (); + } + } + return *this; +} + +TAO_Object_Table_Iterator::~TAO_Object_Table_Iterator (void) +{ + if (this->impl_ != 0) + { + delete this->impl_; + this->impl_ = 0; + } +} + +const TAO_Object_Table_Entry& +TAO_Object_Table_Iterator::operator* (void) const +{ + return this->impl_->item (); +} + +TAO_Object_Table_Iterator +TAO_Object_Table_Iterator::operator++ (void) +{ + TAO_Object_Table_Iterator tmp = *this; + this->impl_->advance (); + return tmp; +} + +TAO_Object_Table_Iterator +TAO_Object_Table_Iterator::operator++ (int) +{ + this->impl_->advance (); + return *this; +} + +int +operator== (const TAO_Object_Table_Iterator &l, + const TAO_Object_Table_Iterator &r) +{ + return l.impl_->done (r.impl_); +} + +int +operator!= (const TAO_Object_Table_Iterator &l, + const TAO_Object_Table_Iterator &r) +{ + return !(l == r); +} + + + +TAO_Object_Table::TAO_Object_Table (void) +{ + this->impl_ = TAO_ORB_Core_instance ()->server_factory ()->create_object_table (); +} + TAO_Object_Table::~TAO_Object_Table (void) { + delete this->impl_; +} + +int +TAO_Object_Table::find (const PortableServer::ObjectId &id, + PortableServer::Servant &servant) +{ + return this->impl_->find (id, servant); +} + +int +TAO_Object_Table::bind (const PortableServer::ObjectId &id, + PortableServer::Servant servant) +{ + return this->impl_->bind (id, servant); +} + +int +TAO_Object_Table::unbind (const PortableServer::ObjectId &id, + PortableServer::Servant &servant) +{ + return this->impl_->unbind (id, servant); +} + +int +TAO_Object_Table::find (const PortableServer::Servant servant) +{ + return this->impl_->find (servant); +} + +int +TAO_Object_Table::find (const PortableServer::ObjectId &id) +{ + return this->impl_->find (id); } -// Template Specialization for char*. Needed for the dynamic hash lookup int -ACE_Hash_Map_Manager<const char *, CORBA::Object_ptr, ACE_SYNCH_RW_MUTEX>::equal (const char *const &id1, - const char *const &id2) +TAO_Object_Table::find (const PortableServer::Servant servant, + PortableServer::ObjectId_out id) +{ + return this->impl_->find (servant, id); +} + +TAO_Object_Table::iterator +TAO_Object_Table::begin (void) const { - // do a string compare - return ACE_OS::strcmp (id1, id2) == 0; + return TAO_Object_Table::iterator (this->impl_->begin ()); +} + +TAO_Object_Table::iterator +TAO_Object_Table::end (void) const +{ + return TAO_Object_Table::iterator (this->impl_->end ()); +} + + + +/* +int +operator== (const PortableServer::ObjectId &l, + const PortableServer::ObjectId &r) +{ + if (l.length () != r.length ()) + return 0; + + for (CORBA::ULong i = 0; + i < l.length (); + ++i) + { + if (l[i] != r[i]) + return 0; + } + return 1; } +*/ -// Template Specialization for char * +// Template specialization.... u_long -ACE_Hash_Map_Manager<const char *, CORBA::Object_ptr, ACE_SYNCH_RW_MUTEX>::hash (const char *const &ext_id) +ACE_Hash_Map_Manager<PortableServer::ObjectId, PortableServer::Servant, ACE_SYNCH_RW_MUTEX>:: +hash (const PortableServer::ObjectId &ext_id) { - // Use the hash_pjw hash function available in the ACE library - return ACE::hash_pjw (ext_id); + // Based on hash_pjw function on the ACE library. + u_long hash = 0; + + for (CORBA::ULong i = 0; + i < ext_id.length (); + ++i) + { + hash = (hash << 4) + (ext_id[i] * 13); + + u_long g = hash & 0xf0000000; + + if (g) + { + hash ^= (g >> 24); + hash ^= g; + } + } + + return hash; } TAO_Dynamic_Hash_ObjTable::TAO_Dynamic_Hash_ObjTable (CORBA::ULong size) + : hash_map_ (size) +{ +} + +int +TAO_Dynamic_Hash_ObjTable::find (const PortableServer::Servant servant) { - if (size > 0) - this->hash_.open (size); - // else we already have a default hash map + return this->TAO_Object_Table_Impl::find (servant); } -TAO_Dynamic_Hash_ObjTable::~TAO_Dynamic_Hash_ObjTable (void) +int +TAO_Dynamic_Hash_ObjTable::find (const PortableServer::ObjectId &id) { - // we need to go thru each entry and free the space taken up by the strings - OBJ_MAP_MANAGER::ITERATOR iterator (this->hash_); // initialize an iterator + return this->TAO_Object_Table_Impl::find (id); +} - for (OBJ_MAP_MANAGER::ENTRY *entry = 0; - iterator.next (entry) != 0; - iterator.advance ()) +int +TAO_Dynamic_Hash_ObjTable::find (const PortableServer::Servant servant, + PortableServer::ObjectId_out id) +{ + return this->TAO_Object_Table_Impl::find (servant, id); +} + +int +TAO_Dynamic_Hash_ObjTable::find (const PortableServer::ObjectId &id, + PortableServer::Servant &servant) +{ + return this->hash_map_.find (id, servant); +} + +int +TAO_Dynamic_Hash_ObjTable::bind (const PortableServer::ObjectId &id, + PortableServer::Servant servant) +{ + return this->hash_map_.bind (id, servant); +} + +int +TAO_Dynamic_Hash_ObjTable::unbind (const PortableServer::ObjectId &id, + PortableServer::Servant &servant) +{ + return this->hash_map_.unbind (id, servant); +} + +TAO_Object_Table_Iterator_Impl* +TAO_Dynamic_Hash_ObjTable::begin (void) const +{ + TAO_Dynamic_Hash_ObjTable *non_const = + ACE_const_cast(TAO_Dynamic_Hash_ObjTable*, this); + return new TAO_Dynamic_Hash_ObjTable_Iterator (Iterator (non_const->hash_map_)); +} + +TAO_Object_Table_Iterator_Impl* +TAO_Dynamic_Hash_ObjTable::end (void) const +{ + return 0; +} + +TAO_Dynamic_Hash_ObjTable_Iterator:: +TAO_Dynamic_Hash_ObjTable_Iterator (const Impl& impl) + : impl_ (impl) +{ +} + +TAO_Object_Table_Iterator_Impl* +TAO_Dynamic_Hash_ObjTable_Iterator::clone (void) const +{ + return new TAO_Dynamic_Hash_ObjTable_Iterator (*this); +} + +const TAO_Object_Table_Entry& +TAO_Dynamic_Hash_ObjTable_Iterator::item (void) const +{ + static TAO_Object_Table_Entry entry; + + ACE_Hash_Map_Entry<PortableServer::ObjectId,PortableServer::Servant>* tmp; + if (ACE_const_cast(TAO_Dynamic_Hash_ObjTable_Iterator*,this)->impl_.next (tmp) == 1) { - CORBA::string_free ((char *)entry->ext_id_); // we had allocated memory - // and stored the string. So - // we free the memory - entry->ext_id_ = 0; - entry->int_id_ = 0; // we do not own this. So we just set it to 0 + entry.int_id_ = tmp->int_id_; + entry.ext_id_ = tmp->ext_id_; } + return entry; +} - this->hash_.close (); +void +TAO_Dynamic_Hash_ObjTable_Iterator::advance (void) +{ + this->impl_.advance (); } int -TAO_Dynamic_Hash_ObjTable::bind (const TAO_opaque &key, - CORBA::Object_ptr obj) +TAO_Dynamic_Hash_ObjTable_Iterator::done (const TAO_Object_Table_Iterator_Impl *) const +{ + return this->impl_.done (); +} + + + +TAO_Array_ObjTable_Iterator:: +TAO_Array_ObjTable_Iterator (TAO_Object_Table_Entry *pos) + : pos_ (pos) +{ +} + +TAO_Object_Table_Iterator_Impl * +TAO_Array_ObjTable_Iterator::clone (void) const { - // the key is an octet sequence. Hence, we cannot simply cast the buffer to a - // char* as it may result in an arbitrary name. Hence we must first convert - // it to a string and then save a copy of the string in the table. - ACE_CString objkey ((char *)&key[0], key.length ()); - return this->hash_.bind (CORBA::string_dup (objkey.rep ()), obj); + return new TAO_Array_ObjTable_Iterator (*this); +} + +const TAO_Object_Table_Entry& +TAO_Array_ObjTable_Iterator::item (void) const +{ + return *this->pos_; +} + +void +TAO_Array_ObjTable_Iterator::advance (void) +{ + this->pos_++; } int -TAO_Dynamic_Hash_ObjTable::find (const TAO_opaque &key, - CORBA::Object_ptr &obj) +TAO_Array_ObjTable_Iterator::done (const TAO_Object_Table_Iterator_Impl *end) const { - // the key is an octet sequence. Hence, we cannot simply cast the buffer to a - // char* as it may result in an arbitrary name due to absence of a NULL - // terminating character. Hence we must first convert it to a string of the - // specified length. - ACE_CString objkey ((char *)&key[0], key.length ()); - return this->hash_.find (objkey.rep(), obj); // no string_dup necessary here + const TAO_Array_ObjTable_Iterator *tmp = + ACE_dynamic_cast(const TAO_Array_ObjTable_Iterator*, end); + return (this->pos_ == tmp->pos_); } -// Linear search strategy -TAO_Linear_ObjTable::TAO_Linear_ObjTable (CORBA::ULong size) - : next_ (0), - tablesize_ (size), - tbl_ (new TAO_Linear_ObjTable_Entry[size]) + + +TAO_Linear_ObjTable:: +TAO_Linear_ObjTable (CORBA::ULong size) + : next_ (0), + tablesize_ (size) { + ACE_NEW (table_, TAO_Object_Table_Entry[this->tablesize_]); } TAO_Linear_ObjTable::~TAO_Linear_ObjTable (void) { - delete [] this->tbl_; // this will delete each entry + if (this->table_ != 0) + { + delete[] this->table_; + this->table_ = 0; + } +} + +int +TAO_Linear_ObjTable::find (const PortableServer::Servant servant) +{ + return this->TAO_Object_Table_Impl::find (servant); +} + +int +TAO_Linear_ObjTable::find (const PortableServer::ObjectId &id) +{ + return this->TAO_Object_Table_Impl::find (id); } int -TAO_Linear_ObjTable::bind (const TAO_opaque &key, - CORBA::Object_ptr obj) +TAO_Linear_ObjTable::find (const PortableServer::Servant servant, + PortableServer::ObjectId_out id) { - CORBA::ULong i = this->next_; + return this->TAO_Object_Table_Impl::find (servant, id); +} - if (i < this->tablesize_) +int +TAO_Linear_ObjTable::find (const PortableServer::ObjectId &id, + PortableServer::Servant &servant) +{ + for (TAO_Object_Table_Entry *i = this->table_; + i != this->table_ + this->next_; + ++i) { - // store the string and the corresponding object pointer - this->tbl_[i].opname_ = CORBA::string_alloc (key.length ()); // allocates one - // more - ACE_OS::memset (this->tbl_[i].opname_, '\0', key.length () + 1); - ACE_OS::strncpy (this->tbl_[i].opname_, - (char *)&key[0], - key.length ()); - this->tbl_[i].obj_ = obj; - this->next_++; // point to the next available slot - return 0; // success + if ((*i).ext_id_ == id) + { + servant = (*i).int_id_; + return 0; + } } - - return -1; // error, size exceeded + return -1; } -// find if the key exists +const int start_tblsiz = 128; +const int max_exp = 65536; // Grow table exponentially up to 64K +const int lin_chunk = 32768; // afterwards grow in chunks of 32K + int -TAO_Linear_ObjTable::find (const TAO_opaque &key, - CORBA::Object_ptr &obj) +TAO_Linear_ObjTable::bind (const PortableServer::ObjectId &id, + PortableServer::Servant servant) { - ACE_ASSERT (this->next_ <= this->tablesize_); + for (TAO_Object_Table_Entry *i = this->table_; + i != this->table_ + this->next_; + ++i) + { + if ((*i).ext_id_ == id || (*i).int_id_ == 0) + { + (*i).ext_id_ = id; + (*i).int_id_ = servant; + return 0; + } + } + if (this->next_ == this->tablesize_) + { + if (this->next_ == 0) + { + this->tablesize_ = start_tblsiz; + ACE_NEW_RETURN (this->table_, + TAO_Object_Table_Entry[this->tablesize_], + -1); + } + else + { + if (this->tablesize_ < max_exp) + { + this->tablesize_ *= 2; + } + else + { + this->tablesize_ += lin_chunk; + } + TAO_Object_Table_Entry *tmp; + ACE_NEW_RETURN (tmp, + TAO_Object_Table_Entry[this->tablesize_], + -1); + for (TAO_Object_Table_Entry *i = this->table_, *j = tmp; + i != this->table_ + this->next_; + ++i, ++j) + { + *j = *i; + } + delete[] this->table_; + this->table_ = tmp; + } + } + this->table_[this->next_].ext_id_ = id; + this->table_[this->next_].int_id_ = servant; + this->next_++; + return 0; +} - // ACE_CString objkey ((char *)&key[0], key.length ()); - for (CORBA::ULong i = 0; i < this->next_; i++) +int +TAO_Linear_ObjTable::unbind (const PortableServer::ObjectId &id, + PortableServer::Servant &servant) +{ + for (TAO_Object_Table_Entry *i = this->table_; + i != this->table_ + this->next_; + ++i) { - // linearly search thru the table - if (!ACE_OS::strncmp (this->tbl_[i].opname_, (char *)&key[0], - key.length ())) + if ((*i).ext_id_ == id) { - // keys match. Return the object pointer - obj = this->tbl_[i].obj_; - return 0; // success + servant = (*i).int_id_; + (*i).int_id_ = 0; + return 0; } } - return -1; // not found + return -1; } -// constructor -TAO_Linear_ObjTable_Entry::TAO_Linear_ObjTable_Entry (void) +TAO_Object_Table_Iterator_Impl* +TAO_Linear_ObjTable::begin () const { - this->opname_ = 0; - this->obj_ = 0; + return new TAO_Array_ObjTable_Iterator (this->table_); } -TAO_Linear_ObjTable_Entry::~TAO_Linear_ObjTable_Entry (void) +TAO_Object_Table_Iterator_Impl* +TAO_Linear_ObjTable::end () const { - CORBA::string_free (this->opname_); // reclaim space consumed by the string - this->opname_ = 0; - this->obj_ = 0; // cannot delete this as we do not own it + return new TAO_Array_ObjTable_Iterator (this->table_ + this->next_); } + + // Active Demux search strategy // constructor TAO_Active_Demux_ObjTable::TAO_Active_Demux_ObjTable (CORBA::ULong size) - : next_ (0), - tablesize_ (size), - tbl_ (new TAO_Active_Demux_ObjTable_Entry[size]) + : tablesize_ (size) { + ACE_NEW (this->table_, TAO_Object_Table_Entry[size]); + // @@ Maybe a proper constructor for TAO_Object_Table_Entry will + // solve this more cleanly. + for (TAO_Object_Table_Entry *i = this->table_; + i != this->table_ + this->tablesize_; + ++i) + { + (*i).int_id_ = 0; + } } // destructor TAO_Active_Demux_ObjTable::~TAO_Active_Demux_ObjTable () { - delete [] this->tbl_; + delete [] this->table_; } - -// bind the object based on the key int -TAO_Active_Demux_ObjTable::bind (const TAO_opaque &key, - CORBA::Object_ptr obj) +TAO_Active_Demux_ObjTable::index_from_id (const PortableServer::ObjectId & /*id*/) const { - // The active demux strategy works on the assumption that the key is a - // stringified form of an index into the table - ACE_CString objkey ((char *)&key[0], key.length ()); - CORBA::ULong i = ACE_OS::atoi (objkey.rep ()); + // @@ TODO parse id an obtain the index, maybe write a "index" to id + // function or some method to obtain the next "free" id. + return 0; +} - if (i < this->tablesize_) + +int +TAO_Active_Demux_ObjTable::next_free (void) const +{ + for (TAO_Object_Table_Entry *i = this->table_; + i != this->table_ + this->tablesize_; + ++i) { - if (this->tbl_[i].obj_ != 0) + if ((*i).int_id_ == 0) { - // we are trying to overwrite a previous entry - return 1; // duplicate - } - else - { - this->tbl_[i].obj_ = obj; - return 0; + return (i - this->table_); } } - return -1; // error + return -1; } int -TAO_Active_Demux_ObjTable::find (const TAO_opaque &key, - CORBA::Object_ptr& obj) +TAO_Active_Demux_ObjTable::find (const PortableServer::Servant servant) { - ACE_CString objkey ((char *)&key[0], key.length ()); - CORBA::ULong i = ACE_OS::atoi (objkey.rep ()); + return this->TAO_Object_Table_Impl::find (servant); +} - ACE_ASSERT (i < this->tablesize_); // cannot be equal to - obj = this->tbl_[i].obj_; - return 0; // success +int +TAO_Active_Demux_ObjTable::find (const PortableServer::ObjectId &id) +{ + return this->TAO_Object_Table_Impl::find (id); +} + +int +TAO_Active_Demux_ObjTable::find (const PortableServer::Servant servant, + PortableServer::ObjectId_out id) +{ + return this->TAO_Object_Table_Impl::find (servant, id); +} + +int +TAO_Active_Demux_ObjTable::find (const PortableServer::ObjectId &id, + PortableServer::Servant &servant) +{ + int index = this->index_from_id (id); + if (index < 0 || index > this->tablesize_) + { + return -1; + } + servant = this->table_[index].int_id_; + return 0; +} + +int +TAO_Active_Demux_ObjTable::bind (const PortableServer::ObjectId &id, + PortableServer::Servant servant) +{ + int index = this->index_from_id (id); + if (index < 0 || index > this->tablesize_) + { + return -1; + } + this->table_[index].ext_id_ = id; + this->table_[index].int_id_ = servant; + return 0; +} + +int +TAO_Active_Demux_ObjTable::unbind (const PortableServer::ObjectId &id, + PortableServer::Servant &servant) +{ + int index = this->index_from_id (id); + if (index < 0 || index > this->tablesize_) + { + return -1; + } + servant = this->table_[index].int_id_; + this->table_[index].int_id_ = 0; + return 0; } -TAO_Active_Demux_ObjTable_Entry::TAO_Active_Demux_ObjTable_Entry (void) +TAO_Object_Table_Iterator_Impl* +TAO_Active_Demux_ObjTable::begin () const { - this->obj_ = 0; + return new TAO_Array_ObjTable_Iterator (this->table_); } -TAO_Active_Demux_ObjTable_Entry::~TAO_Active_Demux_ObjTable_Entry (void) +TAO_Object_Table_Iterator_Impl* +TAO_Active_Demux_ObjTable::end () const { - this->obj_ = 0; // cannot delete this as we do not own it + return new TAO_Array_ObjTable_Iterator (this->table_ + this->tablesize_); } #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Hash_Map_Iterator_Base<char const*, CORBA::Object_ptr, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Iterator<char const*, CORBA::Object_ptr, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Reverse_Iterator<char const*, CORBA::Object_ptr, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Manager<char const*, CORBA::Object_ptr, ACE_SYNCH_RW_MUTEX>; -template class ACE_Hash_Map_Entry<char const*, CORBA::Object_ptr>; +template class ACE_Hash_Map_Iterator_Base<PortableServer::ObjectId, PortableServer::Servant, ACE_SYNCH_RW_MUTEX>; +template class ACE_Hash_Map_Iterator<PortableServer::ObjectId, PortableServer::Servant, ACE_SYNCH_RW_MUTEX>; +template class ACE_Hash_Map_Reverse_Iterator<PortableServer::ObjectId, PortableServer::Servant, ACE_SYNCH_RW_MUTEX>; +template class ACE_Hash_Map_Manager<PortableServer::ObjectId, PortableServer::Servant, ACE_SYNCH_RW_MUTEX>; +template class ACE_Hash_Map_Entry<PortableServer::ObjectId, PortableServer::Servant>; #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Hash_Map_Iterator_Base<char const*, CORBA::Object_ptr, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Iterator<char const*, CORBA::Object_ptr, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Reverse_Iterator<char const*, CORBA::Object_ptr, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Manager<char const*, CORBA::Object_ptr, ACE_SYNCH_RW_MUTEX> -#pragma instantiate ACE_Hash_Map_Entry<char const*, CORBA::Object_ptr> +#pragma instantiate ACE_Hash_Map_Iterator_Base<PortableServer::ObjectId, PortableServer::Servant, ACE_SYNCH_RW_MUTEX> +#pragma instantiate ACE_Hash_Map_Iterator<PortableServer::ObjectId, PortableServer::Servant, ACE_SYNCH_RW_MUTEX> +#pragma instantiate ACE_Hash_Map_Reverse_Iterator<PortableServer::ObjectId, PortableServer::Servant, ACE_SYNCH_RW_MUTEX> +#pragma instantiate ACE_Hash_Map_Manager<PortableServer::ObjectId, PortableServer::Servant, ACE_SYNCH_RW_MUTEX> +#pragma instantiate ACE_Hash_Map_Entry<PortableServer::ObjectId, PortableServer::Servant> #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ |