Routing_Slip_Persistence_Manager.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    Routing_Slip_Persistence_Manager.h
00006  *
00007  *  Routing_Slip_Persistence_Manager.h,v 1.6 2006/03/14 06:14:34 jtc Exp
00008  *
00009  *  A Routing_Slip_Persistence manager controls the actual allocation of
00010  *  blocks through a Persistent_Storage_Allocator and can persist an
00011  *  event and its routing slip.
00012  *
00013  *  @author Jonathan Pollack <pollack_j@ociweb.com>
00014  */
00015 //=============================================================================
00016 
00017 #ifndef ROUTING_SLIP_PERSISTENCE_MANAGER_H
00018 #define ROUTING_SLIP_PERSISTENCE_MANAGER_H
00019 #include /**/ "ace/pre.h"
00020 
00021 #include "orbsvcs/Notify/notify_serv_export.h"
00022 
00023 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00024 #pragma once
00025 #endif /* ACE_LACKS_PRAGMA_ONCE */
00026 
00027 #include "tao/Versioned_Namespace.h"
00028 #include "ace/Message_Block.h"
00029 #include "ace/Synch_T.h"
00030 #include "ace/Containers_T.h"
00031 
00032 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00033 
00034 namespace TAO_Notify
00035 {
00036 // Some forward declarations.
00037 class Standard_Event_Persistence_Factory;
00038 class Persistent_File_Allocator;
00039 class Persistent_Storage_Block;
00040 class Persistent_Callback;
00041 
00042 /**
00043  * \brief Manage interaction between Routing_Slip and persistent storage.
00044  *
00045  * todo: to complete the strategization of event persistent storage this
00046  * should become an interface that is implemented differently by different
00047  * strategies.  For now it interacts with Standard_Event_Persistence.
00048  */
00049 class TAO_Notify_Serv_Export Routing_Slip_Persistence_Manager
00050 {
00051 public:
00052   /// A unique identifier for logical blocks in persistent storage.
00053   typedef ACE_UINT64 Block_Serial_Number;
00054   /// The physical address of a block in persistent storage.
00055   typedef ACE_UINT32 Block_Number;
00056   /// The size of a block in persistent storage.
00057   typedef ACE_UINT16 Block_Size;
00058   /// A code to indicate the type of block in persistent storage.
00059   typedef ACE_UINT16 Block_Type;
00060 
00061   /// The constructor.
00062   Routing_Slip_Persistence_Manager(Standard_Event_Persistence_Factory* factory);
00063 
00064   /// The destructor.
00065   ~Routing_Slip_Persistence_Manager();
00066 
00067   /// Set up callbacks
00068   void set_callback(Persistent_Callback* callback);
00069 
00070 
00071   /// Store an event + routing slip.
00072   bool store(const ACE_Message_Block& event,
00073     const ACE_Message_Block& routing_slip);
00074 
00075   /// \brief Update the routing slip.
00076   ///
00077   /// We must always overwrite the first block
00078   /// last, and it may not chance.  Other blocks should be freed and
00079   /// reallocated.
00080   bool update(const ACE_Message_Block& routing_slip);
00081 
00082   /// \brief Remove our associated event and routing slip from the
00083   /// Persistent_File_Allocator.
00084   bool remove();
00085 
00086   /////////////////////////////////////////
00087   // Methods to be used during reload only.
00088 
00089   /// \brief Call this method to recover data during event reload.
00090   ///
00091   /// It should not fail under normal circumstances.
00092   /// Caller owns the resulting message blocks and is responsible
00093   /// for deleting them.
00094   /// Reload the event and routing_slip from the Persistent_File_Allocator.
00095   bool reload(ACE_Message_Block*& event, ACE_Message_Block*&routing_slip);
00096 
00097   /// \brief Get next RSPM during reload.
00098   ///
00099   /// After using the data from the reload method, call this
00100   /// method to get the next RSPM.  It returns a null pointer
00101   /// when all persistent events have been reloaded.
00102   Routing_Slip_Persistence_Manager * load_next ();
00103 
00104   /////////////////////////
00105   // Implementation methods.
00106   // Should not be called by Routing_Slip
00107 
00108   /// \brief Commit root data to disk, which should only be done for a root node.
00109   bool store_root();
00110 
00111   /// \brief Reload data into this RSPM from the given block/serial#
00112   ///
00113   /// \return false if the reload is not successful.
00114   bool load(Block_Number block_number, Block_Serial_Number expected_serial_number);
00115 
00116   /// \brief Is this RSPM attached to the root block?
00117   bool is_root () const;
00118 
00119   /// \brief During cleanup for shut down, release all chained RSPMs.
00120   void release_all ();
00121 
00122 private:
00123   /**
00124    * \brief private: Storage for header information of all persistent block.
00125    */
00126   class Block_Header
00127   {
00128   public:
00129     enum Header_Type {
00130       BT_Routing_Slip,
00131       BT_Event,
00132       BT_Overflow
00133       };
00134 
00135     Block_Header(Header_Type type);
00136     virtual ~Block_Header (void);
00137     virtual size_t extract_header(Persistent_Storage_Block& psb,
00138       size_t offset = 0);
00139     virtual size_t put_header(Persistent_Storage_Block& psb,
00140       size_t offset = 0);
00141 
00142   public:
00143     /// Our serial number
00144     Block_Serial_Number serial_number;
00145     /// Address of the overflow record (if any)
00146     Block_Number next_overflow;
00147     /// How much extra header data is in this block (not including this header)
00148     Block_Type header_type;
00149     /// How much actual data is in this block? (not including headers)
00150     Block_Size data_size;
00151   };
00152 
00153   /**
00154    * \brief private: Storage for header information for Routing_Slip blocks.
00155    */
00156   class Routing_Slip_Header : public Block_Header
00157   {
00158   public:
00159     Routing_Slip_Header();
00160     virtual size_t extract_header(Persistent_Storage_Block& psb,
00161       size_t offset = 0);
00162     virtual size_t put_header(Persistent_Storage_Block& psb,
00163       size_t offset = 0);
00164 
00165   public:
00166     /// The next event in the system
00167     Block_Number next_routing_slip_block;
00168     /// The next expected serial number
00169     Block_Serial_Number next_serial_number;
00170     Block_Number event_block;
00171   };
00172 
00173   /// \brief An Event block header.
00174   ///
00175   /// is just a Block_Header with no extra data
00176   class Event_Header : public Block_Header
00177   {
00178   public:
00179     Event_Header ();
00180   };
00181 
00182   /// \brief An overflow block header.
00183   ///
00184   /// is just a Block_Header with no extra data
00185   /// The same record type is used for both Routing_Slip
00186   /// and Event overflows.
00187   class Overflow_Header : public Block_Header
00188   {
00189   public:
00190     Overflow_Header ();
00191   };
00192 
00193   bool store_i(const ACE_Message_Block& event,
00194     const ACE_Message_Block& routing_slip);
00195 
00196   bool update_i(const ACE_Message_Block& routing_slip);
00197 
00198   bool store_event(const ACE_Message_Block& event);
00199 
00200   /// Fill in a block with data, and return the number of bytes
00201   /// of data remaining to be written.
00202   size_t fill_block(Persistent_Storage_Block& psb,
00203     size_t offset_into_block, const ACE_Message_Block* data,
00204     size_t offset_into_msg);
00205   size_t fill_block(Persistent_Storage_Block& psb,
00206     size_t offset_into_block, unsigned char* data,
00207     size_t data_size);
00208 
00209   /// Build a chain of Persistent_Storage_Blocks
00210   bool build_chain(
00211     Persistent_Storage_Block* first_block,
00212     Block_Header& first_header,
00213     ACE_Unbounded_Stack<size_t>& allocated_blocks,
00214     const ACE_Message_Block& data);
00215 
00216   /// Reload a chain from persistent store.
00217   bool reload_chain(Persistent_Storage_Block* first_block,
00218     Block_Header& first_header,
00219     ACE_Unbounded_Stack<size_t>& allocated_blocks,
00220     ACE_Message_Block* amb,
00221     ACE_UINT64 expected_serial_number);
00222 
00223   /// Locked method to do the work of setting the next_manager_.
00224   bool update_next_manager(Routing_Slip_Persistence_Manager* next);
00225 
00226   /// Have we been persisted yet?
00227   bool persisted();
00228 
00229   /// Write out our first event block.
00230   size_t write_first_routing_slip_block(bool prepare_only = false);
00231 
00232   /// Insert ourselves into a linked list of Routing_Slip_Persistnce_Managers
00233   void dllist_push_back();
00234 
00235   void insert_before (Routing_Slip_Persistence_Manager * node);
00236 
00237   /// Remove ourselves from a linked list of Routing_Slip_Persistence_Managers
00238   void remove_from_dllist();
00239 
00240 private:
00241   ACE_SYNCH_MUTEX lock_;
00242   bool removed_;
00243   ACE_UINT64 serial_number_;
00244   Persistent_File_Allocator* allocator_;
00245   Standard_Event_Persistence_Factory* factory_;
00246   Event_Header event_header_;
00247   Routing_Slip_Header routing_slip_header_;
00248   Persistent_Storage_Block* first_event_block_;
00249   Persistent_Storage_Block* first_routing_slip_block_;
00250   /// We are part of a doubly-linked list
00251   Routing_Slip_Persistence_Manager* prev_manager_;
00252   Routing_Slip_Persistence_Manager* next_manager_;
00253   ACE_Unbounded_Stack<size_t> allocated_event_blocks_;
00254   ACE_Unbounded_Stack<size_t> allocated_routing_slip_blocks_;
00255   Persistent_Callback* callback_;
00256 
00257   /// if these are non-zero we own 'em
00258   ACE_Message_Block * event_mb_;
00259   ACE_Message_Block * routing_slip_mb_;
00260 };
00261 
00262 } /* namespace TAO_Notify */
00263 
00264 TAO_END_VERSIONED_NAMESPACE_DECL
00265 
00266 #include /**/ "ace/post.h"
00267 #endif /* ROUTING_SLIP_PERSISTENCE_MANAGER_H */

Generated on Thu Nov 9 13:24:15 2006 for TAO_CosNotification by doxygen 1.3.6