00001 /* 00002 * 00003 * 00004 * Distributed under the OpenDDS License. 00005 * See: http://www.opendds.org/license.html 00006 */ 00007 00008 #ifndef REPOIDGENERATOR_H 00009 #define REPOIDGENERATOR_H 00010 00011 #include "tao/Basic_Types.h" 00012 00013 #include "dds/DdsDcpsInfoUtilsC.h" 00014 #include "dds/DdsDcpsGuidC.h" 00015 00016 #include "dds/DCPS/GuidUtils.h" 00017 00018 #include "dcps_export.h" 00019 00020 /** 00021 * @class RepoIdGenerator 00022 * 00023 * @brief Create RepoId values for use within DDS. 00024 * 00025 * Internal to the OpenDDS repository, the Repository Identifiers that 00026 * uniquely identify all DDS Entities within the service managed by this 00027 * (and other federated) repositories consist of GUID values. 00028 * 00029 * These GUID (Global Unique IDentifiers) values are based on the RTPS 00030 * specification (formal/08-04-09) GUID_t values. They use the same 00031 * structure. The VendorId value is applied in the first 2 bytes of the 00032 * prefix. The remainder of the Participant Id value is composed of the 00033 * OpenDDS specific Federation Id value (the identifier of the repository 00034 * where the Entity was created) and a DomainParticipant identifier within 00035 * that repository. In addition to the standard EntityKind values, 00036 * the EntityKind byte has an added value of ENTITYKIND_OPENDDS_TOPIC 00037 * allowed to permit the use of GUID values for Topic entities as well. 00038 * This is an OpenDDS specific extension. 00039 * 00040 * The EntityKey field is used to distinguish Topics, Publications and 00041 * Subscriptions within a single Participant. Each of these is within 00042 * its own number (address) space. The EntityKind byte will ensure that 00043 * identical EntityKey values of these different types will not conflict 00044 * in the final GUID value. 00045 * 00046 * Values are generated using the specified FederationId and 00047 * DomainParticipant identifiers. The EntityKey for a type is 00048 * incremented each time a value is generated. 00049 * 00050 * The ability to reset the last used value is provided to allow the 00051 * reloading of Entities from persistent storage without inducing 00052 * conflicts with newly created Entities. This is a simplistic mechanism 00053 * and requires that all information from the persistent storage be 00054 * processed *prior* to any new Entities being created within the 00055 * repository. After this processing is complete, the last used value 00056 * should be reset to ensure that any new values will not conflict with 00057 * the restored values. 00058 * 00059 * NOTE: This mechanism does not work well for values that have wrapped 00060 * around the 24 bit EntityKey space. It is possible to extend the 00061 * current mapping to overflow into the two '0' bytes (2 and 3) 00062 * with the Key value number (address) space to increase the 00063 * possible unique identifiers if this becomes an issue. Doing 00064 * that would alleviate the need to manage an arena of Key values. 00065 * 00066 * Even though each Domain could have a separate GUID (address) space, 00067 * since we do not currently include the domain value within the GUID 00068 * mapping, all domains within a repository will use the same generator 00069 * instance to ensure no conflicting GUID values. This will restrict the 00070 * total number of DomainParticipants within *all* domains of a 00071 * repository to be within the 32 bit (2**32) DomainParticipant address 00072 * space. It is likely that other limits will be exceeded before this 00073 * one is approached. 00074 * 00075 * The current mapping of meanings to the GUID component values is: 00076 * 00077 * Content: 00078 * | VendorId| 0 | 0 | FederationId | DomainParticpant | EntityKey |Kind| 00079 * GUID_t bytes: 00080 * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 00081 * GuidPrefix_t GUID_t.guidPrefix bytes: 00082 * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 00083 * EntityId_t GUID_t.entityId bytes: | 0 | 1 | 2 | 3 | 00084 * EntityKey_t GUID_t.entityId.entityKey bytes: | 0 | 1 | 2 | 00085 * 00086 * Where the VendorId value used for OpenDDS is defined in GuidUtils.h 00087 */ 00088 class OpenDDS_Dcps_Export RepoIdGenerator { 00089 public: 00090 static const unsigned KeyBits; 00091 00092 static const unsigned KeyMask; 00093 00094 /** 00095 * @brief construct with at least a FederationId value. 00096 * 00097 * @param federation identifier for the repository. 00098 * @param participant identifier for the participant. 00099 * @param kind type of Entities to generate Id values for. 00100 * @return GUID_t generated unique identifier value. 00101 * 00102 * If the @c kind is KIND_PARTICIPANT then the generator will generate 00103 * Participant RepoId values. Otherwise it will generate the specified 00104 * type of Entity values within the specified Participant. 00105 */ 00106 RepoIdGenerator( 00107 long federation, 00108 long participant = 0, 00109 OpenDDS::DCPS::EntityKind kind = OpenDDS::DCPS::KIND_PARTICIPANT); 00110 00111 /// Virtual destructor. 00112 virtual ~RepoIdGenerator(); 00113 00114 /// Obtain the next RepoId value. 00115 OpenDDS::DCPS::RepoId next(); 00116 00117 /** 00118 * Set the minimum of the last key (or participant) value used. 00119 * 00120 * @param key the smallest value that the last generated key can be 00121 * 00122 * If the supplied @c key value is larger than the actual last 00123 * generated key value, the new key value replaces the old one. 00124 */ 00125 void last(long key); 00126 00127 private: 00128 /// Type of Entity to generate GUID values for. 00129 OpenDDS::DCPS::EntityKind kind_; 00130 00131 /// Unique identifier for the repository. 00132 long federation_; 00133 00134 /// Unique identifier for the DomainParticipant. 00135 long participant_; 00136 00137 /// Unique value for the EntityKey. 00138 long lastKey_; 00139 }; 00140 00141 #endif /* REPOIDGENERATOR_H */