Coverage Report

Created: 2022-08-24 06:19

/src/Fast-DDS/include/fastdds/rtps/common/SequenceNumber.h
Line
Count
Source (jump to first uncovered line)
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
/**
16
 * @file SequenceNumber.h
17
 */
18
19
#ifndef _FASTDDS_RPTS_ELEM_SEQNUM_H_
20
#define _FASTDDS_RPTS_ELEM_SEQNUM_H_
21
22
#include <algorithm>
23
#include <cassert>
24
#include <limits>
25
#include <vector>
26
27
#include <fastrtps/fastrtps_dll.h>
28
#include <fastrtps/utils/fixed_size_bitmap.hpp>
29
#include <fastdds/rtps/common/Types.h>
30
31
namespace eprosima {
32
namespace fastrtps {
33
namespace rtps {
34
35
36
//!@brief Structure SequenceNumber_t, different for each change in the same writer.
37
//!@ingroup COMMON_MODULE
38
struct RTPS_DllAPI SequenceNumber_t
39
{
40
    //!
41
    int32_t high = 0;
42
    //!
43
    uint32_t low = 0;
44
45
    //!Default constructor
46
    SequenceNumber_t() noexcept
47
46.7k
    {
48
46.7k
        high = 0;
49
46.7k
        low = 0;
50
46.7k
    }
51
52
    /*!
53
     * @param hi
54
     * @param lo
55
     */
56
    SequenceNumber_t(
57
            int32_t hi,
58
            uint32_t lo) noexcept
59
        : high(hi)
60
        , low(lo)
61
30.8k
    {
62
30.8k
    }
63
64
    /*!
65
     * @param u
66
     */
67
    explicit
68
    SequenceNumber_t(
69
            uint64_t u) noexcept
70
        : high(static_cast<int32_t>(u >> 32u))
71
        , low(static_cast<uint32_t>(u))
72
0
    {
73
0
    }
74
75
    /*! Convert the number to 64 bit.
76
     * @return 64 bit representation of the SequenceNumber
77
     */
78
    uint64_t to64long() const noexcept
79
0
    {
80
0
        return (static_cast<uint64_t>(high) << 32u) + low;
81
0
    }
82
83
    //! Increase SequenceNumber in 1.
84
    SequenceNumber_t& operator ++() noexcept
85
0
    {
86
0
        ++low;
87
0
        if (low == 0)
88
0
        {
89
0
            assert(std::numeric_limits<decltype(high)>::max() > high);
90
0
            ++high;
91
0
        }
92
0
93
0
        return *this;
94
0
    }
95
96
    SequenceNumber_t operator ++(
97
            int) noexcept
98
0
    {
99
0
        SequenceNumber_t result(*this);
100
0
        ++(*this);
101
0
        return result;
102
0
    }
103
104
    /**
105
     * Increase SequenceNumber.
106
     * @param inc Number to add to the SequenceNumber
107
     */
108
    SequenceNumber_t& operator +=(
109
            int inc) noexcept
110
0
    {
111
0
        assert(inc >= 0);
112
0
        uint32_t aux_low = low;
113
0
        low +=  static_cast<uint32_t>(inc);
114
0
115
0
        if (low < aux_low)
116
0
        {
117
0
            // Being the type of the parameter an 'int', the increment of 'high' will be as much as 1.
118
0
            assert(std::numeric_limits<decltype(high)>::max() > high);
119
0
            ++high;
120
0
        }
121
0
122
0
        return *this;
123
0
    }
124
125
    static SequenceNumber_t unknown() noexcept
126
6
    {
127
6
        return { -1, 0 };
128
6
    }
129
130
};
131
132
#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
133
134
/**
135
 * Compares two SequenceNumber_t.
136
 * @param sn1 First SequenceNumber_t to compare
137
 * @param sn2 Second SequenceNumber_t to compare
138
 * @return True if equal
139
 */
140
inline bool operator ==(
141
        const SequenceNumber_t& sn1,
142
        const SequenceNumber_t& sn2) noexcept
143
0
{
144
0
    return (sn1.low == sn2.low) && (sn1.high == sn2.high);
145
0
}
146
147
/**
148
 * Compares two SequenceNumber_t.
149
 * @param sn1 First SequenceNumber_t to compare
150
 * @param sn2 Second SequenceNumber_t to compare
151
 * @return True if not equal
152
 */
153
inline bool operator !=(
154
        const SequenceNumber_t& sn1,
155
        const SequenceNumber_t& sn2) noexcept
156
1.18k
{
157
1.18k
    return (sn1.low != sn2.low) || (sn1.high != sn2.high);
158
1.18k
}
159
160
/**
161
 * Checks if a SequenceNumber_t is greater than other.
162
 * @param seq1 First SequenceNumber_t to compare
163
 * @param seq2 Second SequenceNumber_t to compare
164
 * @return True if the first SequenceNumber_t is greater than the second
165
 */
166
inline bool operator >(
167
        const SequenceNumber_t& seq1,
168
        const SequenceNumber_t& seq2) noexcept
169
0
{
170
0
    if (seq1.high == seq2.high)
171
0
    {
172
0
        return seq1.low > seq2.low;
173
0
    }
174
0
175
0
    return seq1.high > seq2.high;
176
0
}
177
178
/**
179
 * Checks if a SequenceNumber_t is less than other.
180
 * @param seq1 First SequenceNumber_t to compare
181
 * @param seq2 Second SequenceNumber_t to compare
182
 * @return True if the first SequenceNumber_t is less than the second
183
 */
184
inline bool operator <(
185
        const SequenceNumber_t& seq1,
186
        const SequenceNumber_t& seq2) noexcept
187
5.15k
{
188
5.15k
    if (seq1.high == seq2.high)
189
2.43k
    {
190
2.43k
        return seq1.low < seq2.low;
191
2.43k
    }
192
193
2.71k
    return seq1.high < seq2.high;
194
5.15k
}
195
196
/**
197
 * Checks if a SequenceNumber_t is greater or equal than other.
198
 * @param seq1 First SequenceNumber_t to compare
199
 * @param seq2 Second SequenceNumber_t to compare
200
 * @return True if the first SequenceNumber_t is greater or equal than the second
201
 */
202
inline bool operator >=(
203
        const SequenceNumber_t& seq1,
204
        const SequenceNumber_t& seq2) noexcept
205
0
{
206
0
    if (seq1.high == seq2.high)
207
0
    {
208
0
        return seq1.low >= seq2.low;
209
0
    }
210
0
211
0
    return seq1.high > seq2.high;
212
0
}
213
214
/**
215
 * Checks if a SequenceNumber_t is less or equal than other.
216
 * @param seq1 First SequenceNumber_t to compare
217
 * @param seq2 Second SequenceNumber_t to compare
218
 * @return True if the first SequenceNumber_t is less or equal than the second
219
 */
220
inline bool operator <=(
221
        const SequenceNumber_t& seq1,
222
        const SequenceNumber_t& seq2) noexcept
223
14.5k
{
224
14.5k
    if (seq1.high == seq2.high)
225
1.50k
    {
226
1.50k
        return seq1.low <= seq2.low;
227
1.50k
    }
228
229
13.0k
    return seq1.high < seq2.high;
230
14.5k
}
231
232
/**
233
 * Subtract one uint32_t from a SequenceNumber_t
234
 * @param seq Base SequenceNumber_t
235
 * @param inc uint32_t to subtract
236
 * @return Result of the subtraction
237
 */
238
inline SequenceNumber_t operator -(
239
        const SequenceNumber_t& seq,
240
        const uint32_t inc) noexcept
241
1.18k
{
242
1.18k
    SequenceNumber_t res(seq.high, seq.low - inc);
243
244
1.18k
    if (inc > seq.low)
245
413
    {
246
        // Being the type of the parameter an 'uint32_t', the decrement of 'high' will be as much as 1.
247
413
        assert(0 < res.high);
248
413
        --res.high;
249
413
    }
250
251
1.18k
    return res;
252
1.18k
}
253
254
/**
255
 * Add one uint32_t to a SequenceNumber_t
256
 * @param[in] seq Base sequence number
257
 * @param inc value to add to the base
258
 * @return Result of the addition
259
 */
260
inline SequenceNumber_t operator +(
261
        const SequenceNumber_t& seq,
262
        const uint32_t inc) noexcept
263
14.7k
{
264
14.7k
    SequenceNumber_t res(seq.high, seq.low + inc);
265
266
14.7k
    if (res.low < seq.low)
267
200
    {
268
        // Being the type of the parameter an 'uint32_t', the increment of 'high' will be as much as 1.
269
200
        assert(std::numeric_limits<decltype(res.high)>::max() > res.high);
270
200
        ++res.high;
271
200
    }
272
273
14.7k
    return res;
274
14.7k
}
275
276
/**
277
 * Subtract one SequenceNumber_t to another
278
 * @param minuend Minuend. Has to be greater than or equal to subtrahend.
279
 * @param subtrahend Subtrahend.
280
 * @return Result of the subtraction
281
 */
282
inline SequenceNumber_t operator -(
283
        const SequenceNumber_t& minuend,
284
        const SequenceNumber_t& subtrahend) noexcept
285
0
{
286
0
    assert(minuend >= subtrahend);
287
0
    SequenceNumber_t res(minuend.high - subtrahend.high, minuend.low - subtrahend.low);
288
0
289
0
    if (minuend.low < subtrahend.low)
290
0
    {
291
0
        assert(0 < res.high);
292
0
        --res.high;
293
0
    }
294
0
295
0
    return res;
296
0
}
297
298
#endif // ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
299
300
const SequenceNumber_t c_SequenceNumber_Unknown{-1, 0};
301
302
#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
303
304
/**
305
 * Sorts two instances of SequenceNumber_t
306
 * @param s1 First SequenceNumber_t to compare
307
 * @param s2 First SequenceNumber_t to compare
308
 * @return True if s1 is less than s2
309
 */
310
inline bool sort_seqNum(
311
        const SequenceNumber_t& s1,
312
        const SequenceNumber_t& s2) noexcept
313
0
{
314
0
    return s1 < s2;
315
0
}
316
317
/**
318
 *
319
 * @param output
320
 * @param seqNum
321
 * @return
322
 */
323
inline std::ostream& operator <<(
324
        std::ostream& output,
325
        const SequenceNumber_t& seqNum)
326
0
{
327
0
    return output << seqNum.to64long();
328
0
}
329
330
inline std::ostream& operator <<(
331
        std::ostream& output,
332
        const std::vector<SequenceNumber_t>& seqNumSet)
333
0
{
334
0
    for (const SequenceNumber_t& sn : seqNumSet)
335
0
    {
336
0
        output << sn << " ";
337
0
    }
338
0
339
0
    return output;
340
0
}
341
342
/*!
343
 * @brief Defines the STL hash function for type SequenceNumber_t.
344
 */
345
struct SequenceNumberHash
346
{
347
    std::size_t operator ()(
348
            const SequenceNumber_t& sequence_number) const noexcept
349
0
    {
350
0
        return static_cast<std::size_t>(sequence_number.to64long());
351
0
    }
352
353
};
354
355
struct SequenceNumberDiff
356
{
357
    uint32_t operator ()(
358
            const SequenceNumber_t& a,
359
            const SequenceNumber_t& b) const noexcept
360
0
    {
361
0
        SequenceNumber_t diff = a - b;
362
0
        return diff.low;
363
0
    }
364
365
};
366
367
#endif // ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
368
369
//!Structure SequenceNumberSet_t, contains a group of sequencenumbers.
370
//!@ingroup COMMON_MODULE
371
using SequenceNumberSet_t = BitmapRange<SequenceNumber_t, SequenceNumberDiff, 256>;
372
373
#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
374
375
/**
376
 * Prints a sequence Number set
377
 * @param output Output Stream
378
 * @param sns SequenceNumber set
379
 * @return OStream.
380
 */
381
inline std::ostream& operator <<(
382
        std::ostream& output,
383
        const SequenceNumberSet_t& sns)
384
0
{
385
0
    output << sns.base().to64long() << ":";
386
0
    sns.for_each([&output](
387
0
                SequenceNumber_t it)
388
0
            {
389
0
                output << it.to64long() << "-";
390
0
            });
391
0
392
0
    return output;
393
0
}
394
395
/**
396
 *
397
 * @param input
398
 * @param seqNum
399
 * @return
400
 */
401
inline std::istream& operator >>(
402
        std::istream& input,
403
        SequenceNumber_t& seqNum)
404
0
{
405
0
    uint64_t aux;
406
0
407
0
    if (input >> aux)
408
0
    {
409
0
        seqNum = SequenceNumber_t(aux);
410
0
    }
411
0
412
0
    return input;
413
0
}
414
415
#endif // DOXYGEN_SHOULD_SKIP_THIS_PUBLIC
416
417
} // namespace rtps
418
} // namespace fastrtps
419
} // namespace eprosima
420
421
#endif /* _FASTDDS_RTPS_ELEM_SEQNUM_H_ */