DisjointSequence.h

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * Distributed under the OpenDDS License.
00005  * See: http://www.opendds.org/license.html
00006  */
00007 
00008 #ifndef DCPS_DISJOINTSEQUENCE_H
00009 #define DCPS_DISJOINTSEQUENCE_H
00010 
00011 #include "dcps_export.h"
00012 #include "Definitions.h"
00013 
00014 #include "PoolAllocator.h"
00015 
00016 namespace OpenDDS {
00017 namespace DCPS {
00018 
00019 /// Data structure for a set of SequenceNumbers.
00020 /// Sequence numbers can be inserted as single numbers, ranges,
00021 /// or RTPS-style bitmaps.  The DisjointSequence can then be queried for
00022 /// contiguous ranges and internal gaps.
00023 class OpenDDS_Dcps_Export DisjointSequence {
00024 public:
00025 
00026   DisjointSequence();
00027   void reset();
00028 
00029   bool empty() const;
00030 
00031   /// Lowest SequenceNumber in the set.
00032   /// Precondition: !empty()
00033   SequenceNumber low() const;
00034 
00035   /// Highest SequenceNumber in the set.
00036   /// Precondition: !empty()
00037   SequenceNumber high() const;
00038 
00039   /// Gets the high end of the lowest contiguous range.
00040   /// Named after the use case of tracking received messages (which may be
00041   /// received out-of-order) and then determining the largest value that the
00042   /// receiver is allowed to acknowledge (under a cumulative-acking protocol).
00043   /// If empty(), returns SEQUENCENUMBER_UNKNOWN.
00044   SequenceNumber cumulative_ack() const;
00045 
00046   /// Gets the low end of the highest contiguous range, may be thought of as
00047   /// the inverse of cumulative_ack().
00048   /// If empty(), returns SEQUENCENUMBER_UNKNOWN.
00049   SequenceNumber last_ack() const;
00050 
00051   /// Objects with the disjoint() property have an internal gap in the inserted
00052   /// SequenceNumbers.
00053   bool disjoint() const;
00054 
00055   bool contains(SequenceNumber value) const;
00056 
00057   /// All insert() methods return true upon modifying the set and false if
00058   /// the set already contained the SequenceNumber(s) that were to be inserted.
00059   /// This is the general form of insert() whereby the caller receives a list of
00060   /// sub-ranges of 'range' that were not already in the DisjointSequence.
00061   /// For example, given a DisjointSequence 'seq' containing (1, 2, 5, 9),
00062   /// calling seq.insert(SequenceRange(4, 12), v) returns true
00063   /// and yields v = [(4, 4), (6, 8), (10, 12)] and seq = (1, 2, 4, ..., 12).
00064   bool insert(const SequenceRange& range, OPENDDS_VECTOR(SequenceRange)& added);
00065 
00066   /// Insert all numbers between range.first and range.second (both inclusive).
00067   bool insert(const SequenceRange& range);
00068 
00069   /// Shorthand for "insert(SequenceRange(value, value))"
00070   bool insert(SequenceNumber value);
00071 
00072   /// Insert using the RTPS compact representation of a set.  The three
00073   /// parameters, taken together, describe a set with each 1 bit starting
00074   /// at the msb of bits[0] and extending through num_bits (which are located at
00075   /// the next least significant bits of bits[0] followed by the msb of bits[1],
00076   /// etc.) indicating presence of the number (value + bit_index) in the set.
00077   /// bit_index is 0-based.
00078   /// Precondition: the array 'bits' has at least ceil(num_bits / 32) entries.
00079   bool insert(SequenceNumber value,
00080               CORBA::ULong num_bits,
00081               const CORBA::Long bits[]);
00082 
00083   /// Inverse of insert(value, num_bits, bits).  Populates array of
00084   /// bitmap[length] with the bitmap of ranges above the cumulative_ack() value.
00085   /// Sets the number of significant (used) bits in num_bits.  The 'base' of the
00086   /// bitmap is one larger than cumulative_ack().  Returns true if the entire
00087   /// DisjointSequence was able to fit in bitmap[].  Returning false is not an
00088   /// error, it's just that the higher-valued ranges didn't fit.  If invert is
00089   /// true, the 1's in the bitmap represent the missing_sequence_ranges()
00090   /// instead of the present_sequence_ranges().
00091   /// Precondition: the array 'bits' has 'length' entries allocated.
00092   bool to_bitmap(CORBA::Long bitmap[],
00093                  CORBA::ULong length,
00094                  CORBA::ULong& num_bits,
00095                  bool invert = false) const;
00096 
00097   /// Returns missing ranges of SequenceNumbers (internal gaps in the sequence)
00098   OPENDDS_VECTOR(SequenceRange) missing_sequence_ranges() const;
00099 
00100   /// Returns a representation of the members of the sequence as a list of
00101   /// contiguous ranges (each Range is inclusive on both sides).
00102   OPENDDS_VECTOR(SequenceRange) present_sequence_ranges() const;
00103 
00104   void dump() const;
00105 
00106 private:
00107   static void validate(const SequenceRange& range);
00108 
00109   static bool SequenceRange_LessThan(const SequenceRange& lhs,
00110                                      const SequenceRange& rhs)
00111   {
00112     return lhs.second < rhs.second;
00113   }
00114 
00115   typedef bool (*SRCompare)(const SequenceRange&, const SequenceRange&);
00116   typedef OPENDDS_SET_CMP(SequenceRange, SRCompare) RangeSet;
00117   RangeSet sequences_;
00118 
00119 
00120   // helper methods:
00121 
00122   bool insert_i(const SequenceRange& range,
00123                 OPENDDS_VECTOR(SequenceRange)* gaps = 0);
00124 
00125   bool insert_bitmap_range(RangeSet::iterator& iter, const SequenceRange& sr);
00126 
00127 public:
00128   /// Set the bits in range [low, high] in the bitmap, updating num_bits.
00129   static bool fill_bitmap_range(CORBA::ULong low, CORBA::ULong high,
00130                                 CORBA::Long bitmap[], CORBA::ULong length,
00131                                 CORBA::ULong& num_bits);
00132 };
00133 
00134 
00135 } // namespace DCPS
00136 } // namespace OpenDDS
00137 
00138 #ifdef __ACE_INLINE__
00139 # include "DisjointSequence.inl"
00140 #endif /* __ACE_INLINE__ */
00141 
00142 #endif  /* DCPS_DISJOINTSEQUENCE_H */

Generated on Fri Feb 12 20:05:22 2016 for OpenDDS by  doxygen 1.4.7