// -*- Mode: C++; -*-
//                              File      : RDITypeMap.h
//                              Package   : omniNotify-Library
//                              Created on: 1-Jan-1998
//                              Authors   : gruber&panagos
//
//    Copyright (C) 1998-2001 AT&T Laboratories -- Research
//
//    This file is part of the omniNotify library
//    and is distributed with the omniNotify release.
//
//    The omniNotify library is free software; you can redistribute it and/or
//    modify it under the terms of the GNU Library General Public
//    License as published by the Free Software Foundation; either
//    version 2 of the License, or (at your option) any later version.
//
//    This library is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//    Library General Public License for more details.
//
//    You should have received a copy of the GNU Library General Public
//    License along with this library; if not, write to the Free
//    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
//    02111-1307, USA
//
//
// Description:
//    proprietary interface
//
 
/*
$Log: RDITypeMap.h,v $
Revision 1.16  2001/08/03 17:54:15  alcfp
added support for AttNotification

Revision 1.15  2001/06/26 20:01:11  alcfp
updated copyright notices, added support for omniORB4, switched default to POA

Revision 1.14  2001/06/22 07:00:29  alcfp
moved to new logging scheme

Revision 1.13  2000/11/15 21:18:17  alcfp
large number of changes to switch to use of RDIOplocks for safe object disposal support.  also reduced code duplication a little, and tried hard to make all the proxy code consistent

Revision 1.12  2000/10/30 05:41:46  alcfp
renamed CosNotify.h to CosNotifyShorthands.h and placed CosNotifyShorthands.h in omniNotify/include rather than src/services/include

Revision 1.11  2000/10/30 04:39:24  alcfp
extensive changes in preparation for 1.1 release.  will add notes about changes to update.log

Revision 1.10  2000/08/22 18:23:52  alcfp
added description to each file

Revision 1.9  2000/08/16 20:19:20  alcfp
Added licensing notice to each .h and .cc file where library files get GLPL notice and daemon file gets GPL notice -- examples do not claim any license but point out that the library and daemon code does have a license notice

*/
 
#ifndef _RDI_TYPE_MAP_H_
#define _RDI_TYPE_MAP_H_

#include "RDIMutex.h"
#include "RDIHash.h"
#include "CosNotifyShorthands.h"
#include "CosNotifyFilter_i.h"
#include "CosNotifyChannelAdmin_i.h"

/** RDI_TypeMap
  *
  * This object is responsible for maintaining the mapping between
  * filters, which are registered with ConsumerAdmin/ProxySupplier
  * objects, and the event types present in the constraints of the
  * filters.
  */

class RDI_TypeMap {
public:
  // Support data structures required for implementing the mapping

  struct FNode_t {
    Filter_i* _fltr;
    FNode_t*  _next;
    FNode_t(Filter_i* fltr=0) : _fltr(fltr), _next(0) {;}
  };

  struct FList_t {
    FNode_t* _star_star;
    FNode_t* _domn_star;
    FNode_t* _star_type;
    FNode_t* _domn_type;
    FList_t() : _star_star(0),_domn_star(0),_star_type(0),_domn_type(0) {;}
  };

  RDI_TypeMap(EventChannel_i* channel, unsigned int init_hash_size=128);
  ~RDI_TypeMap();

  CORBA::Boolean update(const CosN::EventTypeSeq& added,
			const CosN::EventTypeSeq& deled,
			ConsumerAdmin_i* admin, Filter_i* filter,
			CORBA::Boolean chan_lock_held);
  CORBA::Boolean update(const CosN::EventTypeSeq& added,
			const CosN::EventTypeSeq& deled,
			RDIProxySupplier* proxy, Filter_i* filter,
			CORBA::Boolean chan_lock_held);

  // Locate all filters for a given event type and a ConsumerAdmin
  // or ProxySupplier object -- returning a consistent snapshot of
  // all filters is achieved by either using locking or creating a
  // separate copy.  We chose locking and, hence,  the caller MUST
  // call 'lookup_end' when done with the filters.

  void lookup_begin(const char* domain_name, const char* type_name, 
		    ConsumerAdmin_i* admin, FList_t& filters);
  void lookup_begin(const CosN::EventType& type, 
		    ConsumerAdmin_i* admin, FList_t& filters); 
  void lookup_begin(const char* domain_name, const char* type_name,
		    RDIProxySupplier* proxy, FList_t& filters);
  void lookup_begin(const CosN::EventType& type, 
		    RDIProxySupplier* proxy, FList_t& filters);
  void lookup_end()	{ _lock.unlock(); }

  // Retrieve the list of all event types registered with the map

  CosN::EventTypeSeq* obtain_subscription_types();
  CosN::EventTypeSeq* pxy_obtain_subscription_types(RDIProxyConsumer* pxy, CosNA::ObtainInfoMode mode);

public:
  struct ANode_t {
    ConsumerAdmin_i* _admn;
    FNode_t*         _fltr;
    ANode_t*         _next;
    ANode_t(ConsumerAdmin_i* admn=0, FNode_t* fltr=0) :
      _admn(admn), _fltr(fltr), _next(0) {;}
  };
  struct PNode_t {
    RDIProxySupplier* _prxy;
    FNode_t*          _fltr;
    PNode_t*          _next;
    PNode_t(RDIProxySupplier* prxy=0, FNode_t* fltr=0) :
      _prxy(prxy), _fltr(fltr), _next(0) {;}
  };
  struct VNode_t {
    ANode_t* _admn;
    PNode_t* _prxy;
    VNode_t(ANode_t* admn=0, PNode_t* prxy=0) : 
      _admn(admn), _prxy(prxy) {;}
  };

  RDIstrstream& log_output(RDIstrstream& str);
private:
  RDI_RWMutex _lock;
  EventChannel_i* _channel;
  RDI_Hash<CosN::EventType, VNode_t> _tmap;
};

////////////////////////////////////////
// Logging

inline RDIstrstream& operator<< (RDIstrstream& str, RDI_TypeMap& map) { return map.log_output(str); }

#endif
