SequenceNumber.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. // Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @file SequenceNumber.h
  16. */
  17. #ifndef _FASTDDS_RPTS_ELEM_SEQNUM_H_
  18. #define _FASTDDS_RPTS_ELEM_SEQNUM_H_
  19. #include <fastrtps/fastrtps_dll.h>
  20. #include <fastrtps/utils/fixed_size_bitmap.hpp>
  21. #include <fastdds/rtps/common/Types.h>
  22. #include <algorithm>
  23. #include <cassert>
  24. #include <vector>
  25. namespace eprosima {
  26. namespace fastrtps {
  27. namespace rtps {
  28. //!@brief Structure SequenceNumber_t, different for each change in the same writer.
  29. //!@ingroup COMMON_MODULE
  30. struct RTPS_DllAPI SequenceNumber_t
  31. {
  32. //!
  33. int32_t high = 0;
  34. //!
  35. uint32_t low = 0;
  36. //!Default constructor
  37. SequenceNumber_t() noexcept
  38. {
  39. high = 0;
  40. low = 0;
  41. }
  42. /*!
  43. * @param hi
  44. * @param lo
  45. */
  46. SequenceNumber_t(
  47. int32_t hi,
  48. uint32_t lo) noexcept
  49. : high(hi)
  50. , low(lo)
  51. {
  52. }
  53. /*! Convert the number to 64 bit.
  54. * @return 64 bit representation of the SequenceNumber
  55. */
  56. uint64_t to64long() const noexcept
  57. {
  58. return (static_cast<uint64_t>(high) << 32u) + low;
  59. }
  60. //! Increase SequenceNumber in 1.
  61. SequenceNumber_t& operator ++() noexcept
  62. {
  63. ++low;
  64. if (low == 0)
  65. {
  66. ++high;
  67. }
  68. return *this;
  69. }
  70. SequenceNumber_t operator ++(int) noexcept
  71. {
  72. SequenceNumber_t result(*this);
  73. ++(*this);
  74. return result;
  75. }
  76. /**
  77. * Increase SequenceNumber.
  78. * @param inc Number to add to the SequenceNumber
  79. */
  80. SequenceNumber_t& operator +=(
  81. int inc) noexcept
  82. {
  83. uint32_t aux_low = low;
  84. low += inc;
  85. if (low < aux_low)
  86. {
  87. // Being the type of the parameter an 'int', the increment of 'high' will be as much as 1.
  88. ++high;
  89. }
  90. return *this;
  91. }
  92. static SequenceNumber_t unknown() noexcept
  93. {
  94. return { -1, 0 };
  95. }
  96. };
  97. #ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
  98. /**
  99. * Compares two SequenceNumber_t.
  100. * @param sn1 First SequenceNumber_t to compare
  101. * @param sn2 Second SequenceNumber_t to compare
  102. * @return True if equal
  103. */
  104. inline bool operator ==(
  105. const SequenceNumber_t& sn1,
  106. const SequenceNumber_t& sn2) noexcept
  107. {
  108. return (sn1.low == sn2.low) && (sn1.high == sn2.high);
  109. }
  110. /**
  111. * Compares two SequenceNumber_t.
  112. * @param sn1 First SequenceNumber_t to compare
  113. * @param sn2 Second SequenceNumber_t to compare
  114. * @return True if not equal
  115. */
  116. inline bool operator !=(
  117. const SequenceNumber_t& sn1,
  118. const SequenceNumber_t& sn2) noexcept
  119. {
  120. return (sn1.low != sn2.low) || (sn1.high != sn2.high);
  121. }
  122. /**
  123. * Checks if a SequenceNumber_t is greater than other.
  124. * @param seq1 First SequenceNumber_t to compare
  125. * @param seq2 Second SequenceNumber_t to compare
  126. * @return True if the first SequenceNumber_t is greater than the second
  127. */
  128. inline bool operator >(
  129. const SequenceNumber_t& seq1,
  130. const SequenceNumber_t& seq2) noexcept
  131. {
  132. if (seq1.high == seq2.high)
  133. {
  134. return seq1.low > seq2.low;
  135. }
  136. return seq1.high > seq2.high;
  137. }
  138. /**
  139. * Checks if a SequenceNumber_t is less than other.
  140. * @param seq1 First SequenceNumber_t to compare
  141. * @param seq2 Second SequenceNumber_t to compare
  142. * @return True if the first SequenceNumber_t is less than the second
  143. */
  144. inline bool operator <(
  145. const SequenceNumber_t& seq1,
  146. const SequenceNumber_t& seq2) noexcept
  147. {
  148. if (seq1.high == seq2.high)
  149. {
  150. return seq1.low < seq2.low;
  151. }
  152. return seq1.high < seq2.high;
  153. }
  154. /**
  155. * Checks if a SequenceNumber_t is greater or equal than other.
  156. * @param seq1 First SequenceNumber_t to compare
  157. * @param seq2 Second SequenceNumber_t to compare
  158. * @return True if the first SequenceNumber_t is greater or equal than the second
  159. */
  160. inline bool operator >=(
  161. const SequenceNumber_t& seq1,
  162. const SequenceNumber_t& seq2) noexcept
  163. {
  164. if (seq1.high == seq2.high)
  165. {
  166. return seq1.low >= seq2.low;
  167. }
  168. return seq1.high > seq2.high;
  169. }
  170. /**
  171. * Checks if a SequenceNumber_t is less or equal than other.
  172. * @param seq1 First SequenceNumber_t to compare
  173. * @param seq2 Second SequenceNumber_t to compare
  174. * @return True if the first SequenceNumber_t is less or equal than the second
  175. */
  176. inline bool operator <=(
  177. const SequenceNumber_t& seq1,
  178. const SequenceNumber_t& seq2) noexcept
  179. {
  180. if (seq1.high == seq2.high)
  181. {
  182. return seq1.low <= seq2.low;
  183. }
  184. return seq1.high < seq2.high;
  185. }
  186. /**
  187. * Subtract one uint32_t from a SequenceNumber_t
  188. * @param seq Base SequenceNumber_t
  189. * @param inc uint32_t to substract
  190. * @return Result of the substraction
  191. */
  192. inline SequenceNumber_t operator -(
  193. const SequenceNumber_t& seq,
  194. const uint32_t inc) noexcept
  195. {
  196. SequenceNumber_t res(seq.high, seq.low - inc);
  197. if (inc > seq.low)
  198. {
  199. // Being the type of the parameter an 'uint32_t', the decrement of 'high' will be as much as 1.
  200. --res.high;
  201. }
  202. return res;
  203. }
  204. /**
  205. * Add one uint32_t to a SequenceNumber_t
  206. * @param[in] seq Base sequence number
  207. * @param inc value to add to the base
  208. * @return Result of the addition
  209. */
  210. inline SequenceNumber_t operator +(
  211. const SequenceNumber_t& seq,
  212. const uint32_t inc) noexcept
  213. {
  214. SequenceNumber_t res(seq.high, seq.low + inc);
  215. if (res.low < seq.low)
  216. {
  217. // Being the type of the parameter an 'uint32_t', the increment of 'high' will be as much as 1.
  218. ++res.high;
  219. }
  220. return res;
  221. }
  222. /**
  223. * Subtract one SequenceNumber_t to another
  224. * @param minuend Minuend. Has to be greater than or equal to subtrahend.
  225. * @param subtrahend Subtrahend.
  226. * @return Result of the subtraction
  227. */
  228. inline SequenceNumber_t operator -(
  229. const SequenceNumber_t& minuend,
  230. const SequenceNumber_t& subtrahend) noexcept
  231. {
  232. assert(minuend >= subtrahend);
  233. SequenceNumber_t res(minuend.high - subtrahend.high, minuend.low - subtrahend.low);
  234. if (minuend.low < subtrahend.low)
  235. {
  236. --res.high;
  237. }
  238. return res;
  239. }
  240. #endif
  241. const SequenceNumber_t c_SequenceNumber_Unknown(-1,0);
  242. #ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
  243. /**
  244. * Sorts two instances of SequenceNumber_t
  245. * @param s1 First SequenceNumber_t to compare
  246. * @param s2 First SequenceNumber_t to compare
  247. * @return True if s1 is less than s2
  248. */
  249. inline bool sort_seqNum(
  250. const SequenceNumber_t& s1,
  251. const SequenceNumber_t& s2) noexcept
  252. {
  253. return s1 < s2;
  254. }
  255. /**
  256. *
  257. * @param output
  258. * @param seqNum
  259. * @return
  260. */
  261. inline std::ostream& operator <<(
  262. std::ostream& output,
  263. const SequenceNumber_t& seqNum)
  264. {
  265. return output << seqNum.to64long();
  266. }
  267. inline std::ostream& operator <<(
  268. std::ostream& output,
  269. const std::vector<SequenceNumber_t>& seqNumSet)
  270. {
  271. for(const SequenceNumber_t& sn : seqNumSet)
  272. {
  273. output << sn << " ";
  274. }
  275. return output;
  276. }
  277. /*!
  278. * @brief Defines the STL hash function for type SequenceNumber_t.
  279. */
  280. struct SequenceNumberHash
  281. {
  282. std::size_t operator ()(
  283. const SequenceNumber_t& sequence_number) const noexcept
  284. {
  285. return static_cast<std::size_t>(sequence_number.to64long());
  286. }
  287. };
  288. struct SequenceNumberDiff
  289. {
  290. uint32_t operator ()(
  291. const SequenceNumber_t& a,
  292. const SequenceNumber_t& b) const noexcept
  293. {
  294. SequenceNumber_t diff = a - b;
  295. return diff.low;
  296. }
  297. };
  298. #endif
  299. //!Structure SequenceNumberSet_t, contains a group of sequencenumbers.
  300. //!@ingroup COMMON_MODULE
  301. using SequenceNumberSet_t = BitmapRange<SequenceNumber_t, SequenceNumberDiff, 256>;
  302. #ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
  303. /**
  304. * Prints a sequence Number set
  305. * @param output Output Stream
  306. * @param sns SequenceNumber set
  307. * @return OStream.
  308. */
  309. inline std::ostream& operator <<(
  310. std::ostream& output,
  311. const SequenceNumberSet_t& sns)
  312. {
  313. output << sns.base().to64long() << ":";
  314. sns.for_each([&output](
  315. SequenceNumber_t it)
  316. {
  317. output << it.to64long() << "-";
  318. });
  319. return output;
  320. }
  321. #endif
  322. } // namespace rtps
  323. } // namespace fastrtps
  324. } // namespace eprosima
  325. #endif /* _FASTDDS_RTPS_ELEM_SEQNUM_H_ */