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