(file) Return to reg_table.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Server

  1 karl  1.17 //%2006////////////////////////////////////////////////////////////////////////
  2 mday  1.2  //
  3 karl  1.10 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4            // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5            // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6 karl  1.8  // IBM Corp.; EMC Corporation, The Open Group.
  7 karl  1.10 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8            // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9 karl  1.13 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10            // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 karl  1.17 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12            // EMC Corporation; Symantec Corporation; The Open Group.
 13 mday  1.2  //
 14            // Permission is hereby granted, free of charge, to any person obtaining a copy
 15            // of this software and associated documentation files (the "Software"), to
 16            // deal in the Software without restriction, including without limitation the
 17            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 18            // sell copies of the Software, and to permit persons to whom the Software is
 19            // furnished to do so, subject to the following conditions:
 20            // 
 21            // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22            // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 23            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 24            // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 25            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 26            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 27            // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 28            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 29            //
 30            //==============================================================================
 31            //%////////////////////////////////////////////////////////////////////////////
 32            
 33            
 34 mday  1.2  #include <Pegasus/Common/MessageQueueService.h>
 35            #include <Pegasus/Common/HashTable.h>
 36            #include <Pegasus/Common/Sharable.h>
 37            #include <Pegasus/Common/CIMName.h>
 38 joyce.j 1.12 #include <Pegasus/Common/AutoPtr.h>
 39 mday    1.2  #include "reg_table.h"
 40              
 41              
 42              PEGASUS_USING_STD;
 43              
 44              PEGASUS_NAMESPACE_BEGIN
 45              
 46              const DynamicRoutingTable _internal_routing_table;
 47              
 48              class reg_table_record
 49              {
 50                 private:
 51                    reg_table_record(void);
 52 mday    1.6        virtual ~reg_table_record(void);
 53 mday    1.2        
 54 mday    1.6  
 55 mday    1.2        reg_table_record(const CIMName & class_name, 
 56              		       const CIMNamespaceName & namespace_name, 
 57              		       Uint32 type, 
 58              		       Uint32 flags, 
 59              		       const MessageQueueService * destination_service);
 60 mday    1.6        
 61 mday    1.2        reg_table_record(const CIMName & class_name, 
 62              		       const CIMNamespaceName & namespace_name, 
 63              		       Uint32 type, 
 64              		       const Array<Uint8> & extended_type, 
 65              		       Uint32 flags, 
 66              		       const Array<Uint8> & extended_flags,
 67              		       const MessageQueueService * destination_service);
 68 mday    1.6  
 69                    reg_table_record(const CIMName & class_name, 
 70              		       const CIMNamespaceName & namespace_name, 
 71              		       Uint32 type, 
 72              		       Uint32 flags, 
 73              		       const MessageQueueService * destination_service,
 74              		       const String & provider_name, 
 75              		       const String & module_name);
 76              
 77 mday    1.2        reg_table_record(const reg_table_record & );
 78                    reg_table_record & operator =(const reg_table_record & );
 79 mday    1.7  
 80                    void dump(void);
 81 mday    1.2        
 82                    CIMName class_name;
 83                    CIMNamespaceName namespace_name;
 84                    Uint32 type;
 85                    Array<Uint8> extended_key;
 86                    Uint32 flags;
 87                    Array<Uint8> extended_flags;
 88                    MessageQueueService *service;
 89 mday    1.6        String provider_name;
 90                    String module_name;
 91 mday    1.2        
 92                    friend class reg_table_rep;
 93                    friend class DynamicRoutingTable;
 94              };
 95              
 96              reg_table_record::reg_table_record(void)
 97                 : class_name(String::EMPTY),
 98                   namespace_name(String::EMPTY),
 99                   type(0xffffffff),
100                   extended_key(),
101                   flags(0xffffffff),
102                   extended_flags(),
103                   service(0)
104              {
105              }
106              
107              reg_table_record::reg_table_record(
108                 const CIMName &_name, 
109                 const CIMNamespaceName &_ns, 
110                 Uint32 _type, 
111                 Uint32 _flags,
112 mday    1.2     const MessageQueueService * _svce)
113                 : class_name(_name),
114                   namespace_name(_ns),
115                   type(_type),
116                   extended_key(),
117                   flags(_flags),
118                   extended_flags(),
119                   service(const_cast<MessageQueueService *>(_svce))
120              {
121              
122              }
123              
124              reg_table_record::reg_table_record(
125                 const CIMName &_name, 
126                 const CIMNamespaceName &_ns, 
127                 Uint32 _type, 
128 mday    1.6     Uint32 _flags,
129                 const MessageQueueService * _svce,
130                 const String & _provider_name, 
131                 const String & _module_name)
132                 : class_name(_name),
133                   namespace_name(_ns),
134                   type(_type),
135                   extended_key(),
136                   flags(_flags),
137                   extended_flags(),
138                   service(const_cast<MessageQueueService *>(_svce)),
139                   provider_name(_provider_name),
140                   module_name(_module_name)
141              {
142              
143              }
144              
145 mday    1.2  reg_table_record::reg_table_record(const reg_table_record & rtr)
146              {
147                 class_name = rtr.class_name;
148                 namespace_name = rtr.namespace_name;
149                 type = rtr.type;
150                 extended_key = rtr.extended_key;
151                 flags = rtr.flags;
152                 extended_flags = rtr.extended_flags;
153                 service = rtr.service;
154 mday    1.6     provider_name = rtr.provider_name;
155                 module_name = rtr.module_name;
156 mday    1.2  }
157              
158 mday    1.6  reg_table_record:: ~reg_table_record(void)
159              {
160              }
161              
162              
163 mday    1.2  reg_table_record & 
164              reg_table_record::operator =(const reg_table_record & other)
165              {
166 mday    1.6     if(this != &other)
167                 {
168                    class_name = other.class_name;
169                    namespace_name = other.namespace_name;
170                    type = other.type;
171                    extended_key = other.extended_key;
172                    flags = other.flags;
173                    extended_flags = other.extended_flags;
174                    service = other.service;
175                    provider_name = other.provider_name;
176                    module_name = other.module_name;
177                 }
178                 return *this;
179 mday    1.2  }
180              
181 mday    1.7  
182              void 
183              reg_table_record::dump(void)
184              {
185                 PEGASUS_STD(cout) << "----Dumping Reg Table Record:----" << PEGASUS_STD(endl);
186                 PEGASUS_STD(cout) << class_name.getString() << PEGASUS_STD(endl);
187                 PEGASUS_STD(cout) << namespace_name.getString() << PEGASUS_STD(endl);
188                 PEGASUS_STD(cout) << type << PEGASUS_STD(endl);
189                 PEGASUS_STD(cout) << "---------------------------------" << PEGASUS_STD(endl);
190              }
191              
192              
193 mday    1.2  // instead of concatenating class, namespace, type into a single key, use a 3-level set-associative cache 
194              // implemented with hash tables for namespace, class, and type. Because key composition is not 
195              // necessary it should be faster than a fully associative cache. 
196              
197 mday    1.7  struct RegTableEqual
198              {
199                  static Boolean equal(const String & x, const String & y)
200                  {
201                      if (0 == String::compareNoCase(x, y))
202                          return true;
203                      return false;
204                  }
205              };
206              
207              struct RegTableHash
208              {
209                  static Uint32 hash(const String & str)
210                  {
211                      String cpy(str);
212                      cpy.toLower();
213                      Uint32 h = 0;
214                      for(Uint32 i = 0, n = cpy.size(); i < n; i++)
215                          h = 5 * h + cpy[i];
216                      return h;
217                  }
218 mday    1.7  };
219              
220 david.dillard 1.11 typedef HashTable<String,  reg_table_record *, RegTableEqual, RegTableHash > routing_table;
221 mday          1.2  
222                    typedef HashTable<Uint32, routing_table *, EqualFunc<Uint32>, HashFunc<Uint32> > type_table;
223                    
224 mday          1.7  typedef HashTable<String, type_table *, RegTableEqual, RegTableHash  > namespace_table;
225 mday          1.2  
226                    class reg_table_rep : public Sharable
227                    {
228                       public:
229                          reg_table_rep(void) 
230                          {
231                          }
232 konrad.r      1.16       ~reg_table_rep(void); 
233 mday          1.2     private:
234                    
235                          // store a record 
236                          Boolean _insert(const reg_table_record & rec);
237                    
238                          // retrieve a pointer to the stored record
239                          const reg_table_record * find(const reg_table_record& rec);
240                          void find(const reg_table_record& rec, Array<reg_table_record *> *results);
241                          
242                          // remove the record and retrieve a pointer to it 
243 mday          1.6        reg_table_record * release(const reg_table_record& rec);
244                    
245 karl          1.19       //void release(const reg_table_record& rec, Array<reg_table_record *> *results);
246 mday          1.2        
247                          // remove and destroy a record or records
248                          void destroy(const reg_table_record& rec);
249                          
250                          void destroy_all(void);
251                    
252 mday          1.6        Uint32 remove_by_router(const reg_table_record& rec);
253 mday          1.2        
254                          static const Uint32 FIND;
255                          static const Uint32 REMOVE;
256                          static const Uint32 MULTIPLE;
257                          static const Uint32 DESTROY;
258                          static const Uint32 EXTENDED;
259                          static const Uint32 SERVICE;
260 mday          1.6        static const Uint32 STRINGS;
261 mday          1.2        
262                          reg_table_record * _find(const reg_table_record & rec, 
263                    			       Uint32 flags, 
264                    			       Array<reg_table_record *> *arr_ptr = 0);
265                    
266                          // "wildcard" routines that use iterators
267                          // ns.isNull() == true means enumerate for all name spaces
268                          // cls.isNull() == true means enumerate for all classes
269                          // type == 0xffffffff means enumerate for all types
270                          void _enumerate(const reg_table_record & rec,
271                    		      Uint32 flags, 
272                    		      Array<reg_table_record *> *arr_ptr = 0);
273                          
274 mday          1.7        void _dump_table();
275 mday          1.2        namespace_table _table;
276                          Mutex _mutex;
277                    
278                          friend class DynamicRoutingTable;
279                    };
280                    
281 karl          1.19 
282 mday          1.2  const Uint32 reg_table_rep::FIND =         0x00000001;
283                    const Uint32 reg_table_rep::REMOVE =       0x00000002;
284                    const Uint32 reg_table_rep::MULTIPLE =     0x00000004;
285                    const Uint32 reg_table_rep::DESTROY =      0x00000008;
286                    const Uint32 reg_table_rep::EXTENDED =     0x00000010;
287                    const Uint32 reg_table_rep::SERVICE  =     0x00000020;
288 mday          1.6  const Uint32 reg_table_rep::STRINGS  =     0x00000020;
289 mday          1.2  
290 konrad.r      1.16 reg_table_rep::~reg_table_rep(void)
291                    {
292                       type_table *tt;
293                       routing_table *rt;
294                       reg_table_record *record  = 0;
295                    
296                       try { 
297                        for(namespace_table::Iterator _table_i = _table.start(); _table_i; _table_i++)
298                        {
299                          tt = _table_i.value();
300                          for(type_table::Iterator _tt_i = tt->start(); _tt_i  ;_tt_i++)
301                           {
302                             rt = _tt_i.value();
303                             for (routing_table::Iterator _rt_i = rt->start(); _rt_i; _rt_i++)
304                              {
305                                 delete _rt_i.value();
306                              }
307                             delete rt;
308                           }
309                         delete tt;
310                        }
311 konrad.r      1.16    } catch (... ) 
312                       {
313                         // Just ignore them. The worst that can happend is that we have a memory leak.
314                       }
315                    }
316 mday          1.2  // insert optimized for simplicity, not speed 
317                    Boolean
318                    reg_table_rep::_insert(const reg_table_record &rec)
319                    {
320                       // ipc synchronization 
321 kumpf         1.9     AutoMutex monitor(_mutex);
322 mday          1.2     
323 mday          1.6     type_table *tt = 0;
324 mday          1.7     
325 david         1.5     if(false ==  _table.lookup(rec.namespace_name.getString(), tt))
326 mday          1.2     {
327 joyce.j       1.12       AutoPtr<type_table> temp(new type_table()); 
328                          _table.insert(rec.namespace_name.getString(), temp.get());
329                          temp.release();
330 mday          1.6        if(false ==  _table.lookup(rec.namespace_name.getString(), tt))
331                    	 return false;
332 mday          1.2     }
333                       
334 mday          1.6     routing_table *rt = 0;
335 karl          1.19 
336                       // if not found in type_table, insert new entry.
337 mday          1.2     if(false == tt->lookup(rec.type, rt))
338                       {
339 joyce.j       1.12       AutoPtr<routing_table> temp(new routing_table()); 
340                          tt->insert(rec.type, temp.get());
341                          temp.release();
342 mday          1.6        if(false == tt->lookup(rec.type, rt))
343                    	 return false;
344 mday          1.2     }
345                       
346 david         1.4     Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
347                    	       "reg_table_rep::_insert - Inserting provider $0 into the provider reqistration table,",
348                    	       rec.class_name.getString());	
349                    
350 karl          1.19    // Insert the new record into the routing table
351 mday          1.2     return rt->insert(rec.class_name.getString(), new reg_table_record(rec));
352                    }
353                    
354                    const reg_table_record *
355                    reg_table_rep::find(const reg_table_record & rec)
356                    {
357                       return _find(rec, FIND);
358                    }
359                    
360                    void 
361                    reg_table_rep::find(const reg_table_record & rec, 
362                    		    Array<reg_table_record *> *results)
363                    {
364                       _find(rec, (FIND | MULTIPLE), results);
365                    }
366                    
367                    void 
368                    reg_table_rep::destroy(const reg_table_record & rec)
369                    {
370                       _find(rec, (FIND | REMOVE | DESTROY));
371                    }
372 mday          1.2  
373                    void 
374                    reg_table_rep::destroy_all(void)
375                    {
376                       reg_table_record rec;
377                       _find(rec, (FIND | REMOVE | DESTROY | MULTIPLE ));
378                    }
379                    
380                    reg_table_record * 
381                    reg_table_rep::_find(const reg_table_record &rec, 
382                    		     Uint32 flags, 
383                    		     Array<reg_table_record *> *arr_ptr)
384                    {
385                       // ipc synchronization 
386 kumpf         1.9     AutoMutex monitor(_mutex);
387 mday          1.6     type_table *tt = 0;
388                       Boolean try_again = true;
389                       
390                       if(flags & MULTIPLE )
391 mday          1.2     {
392                          
393                          _enumerate(rec,
394                    		 flags, 
395                    		 arr_ptr);
396                          return 0;
397                       }
398                       else 
399                       {
400                          // find the type entry
401                          if(true == _table.lookup(rec.namespace_name.getString(), tt))
402                          {
403 mday          1.6  	try_again_wild_namespace:
404 mday          1.2  	 routing_table *rt;
405                    	 if(true == tt->lookup(rec.type, rt))
406                    	 {
407                    	    reg_table_record *record ;
408 mday          1.6  
409 mday          1.2  	    while(true == rt->lookup(rec.class_name.getString(), record))
410                    	    {
411                    	       // flags value of all foxes always matches 
412                    	       if(rec.flags != 0xffffffff)
413                    		  if(record->flags != rec.flags)
414                    		     continue;
415 karl          1.19 
416 mday          1.2  	       if(flags & REMOVE || flags & DESTROY)
417                    	       {
418                    		  rt->remove(rec.class_name.getString());
419 mday          1.6  		  if(flags & DESTROY)
420 mday          1.2  		  {
421                    		     delete record;
422                    		     record = 0;
423                    		  }
424                    	       }
425                    	       return record;
426                    	    }
427                    	 }
428                          }
429                       }
430 mday          1.6  
431 karl          1.19     // now try again using the special wildcard namespace table
432 mday          1.6     CIMNamespaceName _wild;
433                       _wild.clear();
434                       if(true == try_again && true == _table.lookup(_wild.getString(), tt))
435                       {
436                          try_again = false;
437                          goto try_again_wild_namespace;
438                       }
439                       
440 mday          1.2     return 0;
441                    }
442                    
443 mday          1.6  // do not call directly - does not lock the reg table mutex !!
444 mday          1.2  void 
445                    reg_table_rep::_enumerate(const reg_table_record & rec,
446                    			  Uint32 flags, 
447                    			  Array<reg_table_record *> *results)
448                    {
449 mday          1.6  
450 karl          1.19   _enumerate_start:
451 mday          1.6  
452 mday          1.2     if(flags & MULTIPLE)
453                       {
454                          if(results == 0 && ! (flags & DESTROY))
455                    	 return;
456                          
457                          for(namespace_table::Iterator i = _table.start(); i; i++)
458                          {
459                    	 // null namespace_name is a wildcard
460                    	 if(false == rec.namespace_name.isNull())
461                    	 {
462                    	    if(rec.namespace_name.getString() != i.key())
463                    	       continue;
464                    	 }
465                          
466 mday          1.6  	 for(type_table::Iterator y = i.value()->start(); y != 0 ; y++)
467 mday          1.2  	 {
468                    	    // type of -1 is a wildcard
469 mday          1.6  	    if(rec.type != 0xffffffff)
470 mday          1.2  	    {
471                    	       if(rec.type != y.key())
472                    		  continue;
473                    	    }
474                    	 
475 mday          1.6  	    for(routing_table::Iterator x = y.value()->start(); x != 0; x++)
476 mday          1.2  	    {
477                    	       // null class_name is a wildcard
478                    	       if(false == rec.class_name.isNull())
479                    	       {
480 david         1.5  		  if(!rec.class_name.equal(x.value()->class_name))
481 mday          1.2  		     continue;
482                    	       }
483                    	       reg_table_record *tmp = x.value();
484                    	       // flags value of all foxes always matches 
485                    	       if(rec.flags != 0xffffffff)
486                    		  if(tmp->flags != rec.flags)
487                    		     continue;
488                    
489 karl          1.19                if(flags & SERVICE)
490 mday          1.2  	       {
491                    		  if(rec.service != tmp->service)
492                    		     continue;
493                    	       }
494                    	       
495                    	       if(flags & REMOVE || flags & DESTROY)
496                    	       {
497                    		  y.value()->remove(x.key());
498                    		  if(flags & DESTROY)
499                    		  {
500                    		     delete tmp;
501                    		  }
502 karl          1.19 		  goto _enumerate_start;
503 mday          1.2  	       }
504                    	       else
505                    	       {
506                    		  results->append(tmp);
507                    	       }
508                    	    }
509                    	 }
510                          }
511                       }
512                    }
513                    
514 mday          1.7  void 
515                    reg_table_rep::_dump_table()
516                    {
517                       PEGASUS_STD(cout) <<"******** Dumping Reg Table ********"  << PEGASUS_STD(endl);
518 kumpf         1.9     AutoMutex monitor(_mutex);
519 mday          1.7     for(namespace_table::Iterator i = _table.start(); i; i++)
520                       {
521                          PEGASUS_STD(cout) << "Namespace: "  << i.key() << PEGASUS_STD(endl);
522                          
523                          for(type_table::Iterator y = i.value()->start(); y != 0 ; y++)
524                          {
525                    
526                    	 PEGASUS_STD(cout) << "Type: " << y.key()  << PEGASUS_STD(endl);
527                    	 
528                    	 for(routing_table::Iterator x = y.value()->start(); x != 0; x++)
529                    	 {
530                    	       reg_table_record *tmp = x.value();
531                    	       tmp->dump();
532                    	 }
533                          }
534                       }
535                    }
536 mday          1.6  
537                    const Uint32 DynamicRoutingTable:: INTERNAL       = 0x00000001;
538                    const Uint32 DynamicRoutingTable:: INSTANCE       = 0x00000002;
539                    const Uint32 DynamicRoutingTable:: CLASS          = 0x00000003;
540                    const Uint32 DynamicRoutingTable:: METHOD         = 0x00000004;
541                    
542 mday          1.2  DynamicRoutingTable::DynamicRoutingTable(void)
543                    {
544                       _rep = new reg_table_rep();
545                    }
546                    
547                    DynamicRoutingTable::~DynamicRoutingTable(void)
548                    {
549                       Dec(_rep);
550                    }
551                    
552                    DynamicRoutingTable::DynamicRoutingTable(const DynamicRoutingTable & table)
553                    {
554                       if(this != &table)
555                       {
556                          Inc(_rep = table._rep);
557                       }
558                    }
559                    
560                    DynamicRoutingTable & 
561                    DynamicRoutingTable::operator =(const DynamicRoutingTable & table)
562                    {
563 mday          1.2     if(this != &table)
564                       {
565 konrad.r      1.15      // De-allocate the _rep we have internally
566 joyce.j       1.14       Dec(_rep);
567 mday          1.2        Inc(_rep = table._rep);
568                       }
569                       return *this;
570                    }
571                    
572                    
573                    DynamicRoutingTable
574                    DynamicRoutingTable::get_rw_routing_table(void)
575                    {
576                       return DynamicRoutingTable(_internal_routing_table);
577                    }
578                    
579 mday          1.6  MessageQueueService *
580                    DynamicRoutingTable::get_routing(const CIMName & classname, 
581                    				 const CIMNamespaceName & ns, 
582                    				 Uint32 type,
583                    				 Uint32 flags, 
584                    				 String & provider,
585                    				 String & module) const
586                    {
587                       reg_table_record rec(classname, ns, type, flags, 0, provider, module);
588                       const reg_table_record *ret = _rep->find(rec);
589                       if(ret)
590                       {
591                          provider = ret->provider_name;
592                          module = ret->module_name;
593                          return ret->service;
594                       }
595                       
596                       return 0;
597                       
598                    }
599                    
600 mday          1.2  Boolean 
601                    DynamicRoutingTable::insert_record(const CIMName& classname, 
602                    				   const CIMNamespaceName& ns, 
603                    				   Uint32 type,
604                    				   Uint32 flags,
605                    				   MessageQueueService* svce) 
606                    {
607                       reg_table_record rec(classname, ns, type, flags, svce);
608                       return (_rep->_insert(rec));
609                    }
610                    
611 mday          1.6  Boolean 
612                    DynamicRoutingTable::insert_record(const CIMName& classname, 
613                    				   const CIMNamespaceName& ns, 
614                    				   Uint32 type,
615                    				   Uint32 flags,
616                    				   MessageQueueService* svce, 
617                    				   const String& provider, 
618                    				   const String& module) 
619                    {
620                       reg_table_record rec(classname, ns, type, flags, svce, provider, module);
621                       return (_rep->_insert(rec));
622                    }
623                    
624 mday          1.7  void
625                    DynamicRoutingTable::dump_table(void)
626                    {
627                       _rep->_dump_table();
628                    }
629 mday          1.2  
630                    
631                    PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2