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
|