00001
00002
00003 #ifndef TAO_OFFER_DATABASE_CPP
00004 #define TAO_OFFER_DATABASE_CPP
00005
00006 #include "orbsvcs/Trader/Offer_Database.h"
00007 #include "ace/OS_NS_stdio.h"
00008 #include "ace/OS_NS_string.h"
00009
00010 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00011
00012 template <class LOCK_TYPE>
00013 TAO_Offer_Database<LOCK_TYPE>::TAO_Offer_Database (void)
00014 {
00015 }
00016
00017 template <class LOCK_TYPE>
00018 TAO_Offer_Database<LOCK_TYPE>::~TAO_Offer_Database (void)
00019 {
00020 ACE_WRITE_GUARD (LOCK_TYPE, ace_mon, this->db_lock_);
00021
00022 for (ACE_TYPENAME Offer_Database::iterator type_iter (this->offer_db_);
00023 ! type_iter.done ();
00024 type_iter++)
00025 {
00026 Offer_Map_Entry* offer_map_entry = (*type_iter).int_id_;
00027
00028 {
00029
00030
00031 ACE_WRITE_GUARD (LOCK_TYPE, ace_mon, offer_map_entry->lock_);
00032
00033 for (TAO_Offer_Map::iterator offer_iter (*offer_map_entry->offer_map_);
00034 ! offer_iter.done ();
00035 offer_iter++)
00036 {
00037
00038 CosTrading::Offer* offer = (*offer_iter).int_id_;
00039 delete offer;
00040 }
00041
00042 delete offer_map_entry->offer_map_;
00043 }
00044
00045 delete offer_map_entry;
00046 }
00047 }
00048
00049 template <class LOCK_TYPE> CosTrading::OfferId
00050 TAO_Offer_Database<LOCK_TYPE>::
00051 insert_offer (const char* type, CosTrading::Offer* offer)
00052 {
00053 CosTrading::OfferId return_value = 0;
00054 ACE_TYPENAME Offer_Database::ENTRY* database_entry = 0;
00055 CORBA::String_var service_type (type);
00056
00057 ACE_READ_GUARD_RETURN (LOCK_TYPE, ace_mon, this->db_lock_, 0);
00058
00059 if (this->offer_db_.find (service_type, database_entry) == -1)
00060 {
00061
00062
00063 Offer_Map_Entry* new_offer_map_entry = 0;
00064 ACE_NEW_RETURN (new_offer_map_entry, Offer_Map_Entry, 0);
00065 ACE_NEW_RETURN (new_offer_map_entry->offer_map_, TAO_Offer_Map, 0);
00066 new_offer_map_entry->counter_ = 1;
00067
00068 if (this->db_lock_.release () == -1)
00069 return 0;
00070 else
00071 {
00072
00073 ACE_WRITE_GUARD_RETURN (LOCK_TYPE, ace_mon, this->db_lock_, 0);
00074 this->offer_db_.bind (service_type,
00075 new_offer_map_entry,
00076 database_entry);
00077 }
00078
00079 if (this->db_lock_.acquire_read () == -1)
00080 return 0;
00081 }
00082
00083 Offer_Map_Entry* offer_map_entry =
00084 database_entry->int_id_;
00085 ACE_WRITE_GUARD_RETURN (LOCK_TYPE, ace_mon2, offer_map_entry->lock_, 0);
00086
00087
00088 offer_map_entry->offer_map_->bind (offer_map_entry->counter_,
00089 offer);
00090 return_value = this->generate_offer_id (type,
00091 offer_map_entry->counter_);
00092 offer_map_entry->counter_++;
00093
00094 return return_value;
00095 }
00096
00097 template <class LOCK_TYPE> int
00098 TAO_Offer_Database<LOCK_TYPE>::
00099 remove_offer (const char* type, CORBA::ULong id)
00100 {
00101 ACE_READ_GUARD_RETURN (LOCK_TYPE, ace_mon, this->db_lock_, -1);
00102
00103 int return_value = -1;
00104 ACE_TYPENAME Offer_Database::ENTRY* db_entry = 0;
00105 CORBA::String_var service_type (type);
00106
00107 if (this->offer_db_.find (service_type, db_entry) == 0)
00108 {
00109 CosTrading::Offer* offer = 0;
00110 Offer_Map_Entry* offer_map_entry = db_entry->int_id_;
00111
00112 if (offer_map_entry->lock_.acquire_write () == -1)
00113 return -1;
00114
00115 return_value = offer_map_entry->offer_map_->unbind (id, offer);
00116 delete offer;
00117
00118
00119
00120 if (offer_map_entry->offer_map_->current_size () == 0)
00121 {
00122 if (this->db_lock_.release () == -1)
00123 return -1;
00124 else
00125 {
00126
00127
00128 if (this->db_lock_.acquire_write () == -1)
00129 return -1;
00130
00131
00132 this->offer_db_.unbind (service_type);
00133
00134
00135
00136 if (offer_map_entry->lock_.release () == -1)
00137 return -1;
00138
00139
00140 delete offer_map_entry->offer_map_;
00141 delete offer_map_entry;
00142 }
00143 }
00144 else if (offer_map_entry->lock_.release () == -1)
00145 return -1;
00146 }
00147
00148 return return_value;
00149 }
00150
00151 template <class LOCK_TYPE> int
00152 TAO_Offer_Database<LOCK_TYPE>::
00153 remove_offer (const CosTrading::OfferId offer_id
00154 ACE_ENV_ARG_DECL)
00155 ACE_THROW_SPEC ((CosTrading::IllegalOfferId,
00156 CosTrading::UnknownOfferId))
00157 {
00158 char* stype = 0;
00159 CORBA::ULong index;
00160
00161 this->parse_offer_id (offer_id,
00162 stype,
00163 index
00164 ACE_ENV_ARG_PARAMETER);
00165 ACE_CHECK_RETURN (-1);
00166
00167 if (this->remove_offer (stype,
00168 index) == -1)
00169 ACE_THROW_RETURN (CosTrading::UnknownOfferId (offer_id),
00170 -1);
00171
00172 return 0;
00173 }
00174
00175 template <class LOCK_TYPE> CosTrading::Offer*
00176 TAO_Offer_Database<LOCK_TYPE>::
00177 lookup_offer (const CosTrading::OfferId offer_id,
00178 char*& type_name
00179 ACE_ENV_ARG_DECL)
00180 ACE_THROW_SPEC ((CosTrading::IllegalOfferId,
00181 CosTrading::UnknownOfferId))
00182 {
00183 CORBA::ULong index;
00184 CosTrading::Offer* offer = 0;
00185 this->parse_offer_id (offer_id, type_name, index ACE_ENV_ARG_PARAMETER);
00186 ACE_CHECK_RETURN (offer);
00187
00188 if ((offer = this->lookup_offer (type_name, index)) == 0)
00189 ACE_THROW_RETURN (CosTrading::UnknownOfferId (offer_id), offer);
00190
00191 return offer;
00192 }
00193
00194
00195 template <class LOCK_TYPE> CosTrading::Offer*
00196 TAO_Offer_Database<LOCK_TYPE>::
00197 lookup_offer (const CosTrading::OfferId offer_id
00198 ACE_ENV_ARG_DECL)
00199 ACE_THROW_SPEC ((CosTrading::IllegalOfferId,
00200 CosTrading::UnknownOfferId))
00201 {
00202 char* type_name;
00203 CORBA::ULong index;
00204 CosTrading::Offer* offer = 0;
00205
00206 this->parse_offer_id (offer_id, type_name, index ACE_ENV_ARG_PARAMETER);
00207 ACE_CHECK_RETURN (offer);
00208
00209 if ((offer = this->lookup_offer (type_name, index)) == 0)
00210 ACE_THROW_RETURN (CosTrading::UnknownOfferId (offer_id), offer);
00211
00212 return offer;
00213 }
00214
00215 template <class LOCK_TYPE> CosTrading::Offer*
00216 TAO_Offer_Database<LOCK_TYPE>::
00217 lookup_offer (const char* type, CORBA::ULong id)
00218 {
00219 ACE_READ_GUARD_RETURN (LOCK_TYPE, ace_mon, this->db_lock_, 0);
00220
00221 CosTrading::Offer* return_value = 0;
00222 ACE_TYPENAME Offer_Database::ENTRY* db_entry = 0;
00223 CORBA::String_var service_type (type);
00224
00225 if (this->offer_db_.find (service_type, db_entry) == 0)
00226 {
00227 Offer_Map_Entry* offer_map_entry = db_entry->int_id_;
00228 ACE_READ_GUARD_RETURN (LOCK_TYPE, ace_mon, offer_map_entry->lock_, 0);
00229
00230 TAO_Offer_Map::ENTRY* offer_entry_ptr = 0;
00231 if (offer_map_entry->offer_map_->find (id, offer_entry_ptr) == 0)
00232 return_value = offer_entry_ptr->int_id_;
00233 }
00234
00235 return return_value;
00236 }
00237
00238 template <class LOCK_TYPE> TAO_Offer_Id_Iterator*
00239 TAO_Offer_Database<LOCK_TYPE>::retrieve_all_offer_ids (void)
00240 {
00241
00242
00243
00244
00245 TAO_Offer_Id_Iterator* id_iterator;
00246 ACE_NEW_RETURN (id_iterator,
00247 TAO_Offer_Id_Iterator (),
00248 0);
00249 ACE_READ_GUARD_RETURN (LOCK_TYPE, ace_mon, this->db_lock_, 0);
00250
00251 for (ACE_TYPENAME Offer_Database::iterator type_iter (this->offer_db_);
00252 ! type_iter.done ();
00253 type_iter++)
00254 {
00255 const char* type_name = (*type_iter).ext_id_.in ();
00256 Offer_Map_Entry* offer_map_entry = (*type_iter).int_id_;
00257
00258 ACE_READ_GUARD_RETURN (LOCK_TYPE, ace_mon, offer_map_entry->lock_, 0);
00259
00260 for (TAO_Offer_Map::iterator offer_iter (*offer_map_entry->offer_map_);
00261 ! offer_iter.done ();
00262 offer_iter++)
00263 {
00264 CORBA::ULong offer_index = (*offer_iter).ext_id_;
00265 CosTrading::OfferId offer_id =
00266 this->generate_offer_id (type_name, offer_index);
00267
00268 id_iterator->insert_id (offer_id);
00269 }
00270 }
00271
00272 return id_iterator;
00273 }
00274
00275 template <class LOCK_TYPE> void
00276 TAO_Offer_Database<LOCK_TYPE>::
00277 parse_offer_id (const CosTrading::OfferId offer_id,
00278 char*&service_type,
00279 CORBA::ULong& id
00280 ACE_ENV_ARG_DECL)
00281 ACE_THROW_SPEC ((CosTrading::IllegalOfferId))
00282 {
00283
00284 service_type = (char *) offer_id + 16;
00285
00286
00287
00288 char* start_of_type = (char *) (offer_id + 16);
00289 char temp = *start_of_type;
00290 *start_of_type = '\0';
00291 id = ACE_OS::atoi (offer_id);
00292
00293 *start_of_type = temp;
00294
00295 if (! TAO_Trader_Base::is_valid_identifier_name (service_type))
00296 ACE_THROW (CosTrading::IllegalOfferId (offer_id));
00297 }
00298
00299 template <class LOCK_TYPE> CosTrading::OfferId
00300 TAO_Offer_Database<LOCK_TYPE>::
00301 generate_offer_id (const char *service_type_name, CORBA::ULong id)
00302 {
00303
00304 size_t total_size = 16 + ACE_OS::strlen (service_type_name);
00305
00306
00307 CosTrading::OfferId offer_id =
00308 CORBA::string_alloc (static_cast<CORBA::ULong> (total_size));
00309 char* return_value = 0;
00310 ACE_OS::sprintf (offer_id, "%016u%s", id, service_type_name);
00311
00312 return_value = CORBA::string_dup (offer_id);
00313 delete [] offer_id;
00314
00315 return return_value;
00316 }
00317
00318
00319 template <class LOCK_TYPE>
00320 TAO_Service_Offer_Iterator<LOCK_TYPE>::
00321 TAO_Service_Offer_Iterator (const char* type,
00322 TAO_Offer_Database<LOCK_TYPE>& offer_database)
00323 : stm_ (offer_database),
00324 lock_ (0),
00325 offer_iter_ (0),
00326 type_ (type)
00327 {
00328 CORBA::String_var service_type (type);
00329
00330 if (this->stm_.db_lock_.acquire_read () == -1)
00331 return;
00332
00333 ACE_TYPENAME TAO_Offer_Database<LOCK_TYPE>::Offer_Map_Entry* entry = 0;
00334 if (this->stm_.offer_db_.find (service_type, entry) == -1)
00335 return;
00336 else
00337 {
00338 this->lock_ = &entry->lock_;
00339 if (this->lock_->acquire_read () == -1)
00340 return;
00341
00342 ACE_NEW (offer_iter_,
00343 TAO_Offer_Map::iterator (*entry->offer_map_));
00344 }
00345 }
00346
00347 template <class LOCK_TYPE>
00348 TAO_Service_Offer_Iterator<LOCK_TYPE>::~TAO_Service_Offer_Iterator (void)
00349 {
00350 this->stm_.db_lock_.release ();
00351
00352 if (this->lock_ != 0)
00353 {
00354 this->lock_->release ();
00355 delete this->offer_iter_;
00356 }
00357 }
00358
00359 template <class LOCK_TYPE> CosTrading::OfferId
00360 TAO_Service_Offer_Iterator<LOCK_TYPE>::get_id (void)
00361 {
00362 return (this->offer_iter_ != 0)
00363 ? TAO_Offer_Database<LOCK_TYPE>::generate_offer_id (this->type_, (**this->offer_iter_).ext_id_)
00364 : 0;
00365 }
00366
00367 template <class LOCK_TYPE> int
00368 TAO_Service_Offer_Iterator<LOCK_TYPE>::has_more_offers (void)
00369 {
00370 return (this->offer_iter_ != 0) ? ! this->offer_iter_->done () : 0;
00371 }
00372
00373
00374 template <class LOCK_TYPE> CosTrading::Offer*
00375 TAO_Service_Offer_Iterator<LOCK_TYPE>::get_offer (void)
00376 {
00377 return (this->offer_iter_ != 0) ? (**this->offer_iter_).int_id_ : 0;
00378 }
00379
00380 template <class LOCK_TYPE> void
00381 TAO_Service_Offer_Iterator<LOCK_TYPE>::next_offer (void)
00382 {
00383 if (this->offer_iter_ != 0)
00384 this->offer_iter_->advance ();
00385 }
00386
00387 TAO_END_VERSIONED_NAMESPACE_DECL
00388
00389 #endif