#include <DisjointSequence.h>
Public Member Functions | |
DisjointSequence () | |
void | reset () |
bool | empty () const |
SequenceNumber | low () const |
SequenceNumber | high () const |
SequenceNumber | cumulative_ack () const |
SequenceNumber | last_ack () const |
bool | disjoint () const |
bool | contains (SequenceNumber value) const |
bool | insert (const SequenceRange &range, OPENDDS_VECTOR(SequenceRange)&added) |
bool | insert (const SequenceRange &range) |
Insert all numbers between range.first and range.second (both inclusive). | |
bool | insert (SequenceNumber value) |
Shorthand for "insert(SequenceRange(value, value))". | |
bool | insert (SequenceNumber value, CORBA::ULong num_bits, const CORBA::Long bits[]) |
bool | to_bitmap (CORBA::Long bitmap[], CORBA::ULong length, CORBA::ULong &num_bits, bool invert=false) const |
OPENDDS_VECTOR (SequenceRange) missing_sequence_ranges() const | |
Returns missing ranges of SequenceNumbers (internal gaps in the sequence). | |
OPENDDS_VECTOR (SequenceRange) present_sequence_ranges() const | |
void | dump () const |
Static Public Member Functions | |
static bool | fill_bitmap_range (CORBA::ULong low, CORBA::ULong high, CORBA::Long bitmap[], CORBA::ULong length, CORBA::ULong &num_bits) |
Set the bits in range [low, high] in the bitmap, updating num_bits. | |
Private Types | |
typedef bool(*) | SRCompare (const SequenceRange &, const SequenceRange &) |
Private Member Functions | |
typedef | OPENDDS_SET_CMP (SequenceRange, SRCompare) RangeSet |
bool | insert_i (const SequenceRange &range, OPENDDS_VECTOR(SequenceRange)*gaps=0) |
bool | insert_bitmap_range (RangeSet::iterator &iter, const SequenceRange &sr) |
Static Private Member Functions | |
static void | validate (const SequenceRange &range) |
static bool | SequenceRange_LessThan (const SequenceRange &lhs, const SequenceRange &rhs) |
Private Attributes | |
RangeSet | sequences_ |
Definition at line 23 of file DisjointSequence.h.
typedef bool(*) OpenDDS::DCPS::DisjointSequence::SRCompare(const SequenceRange &, const SequenceRange &) [private] |
Definition at line 115 of file DisjointSequence.h.
ACE_INLINE OpenDDS::DCPS::DisjointSequence::DisjointSequence | ( | ) |
Definition at line 52 of file DisjointSequence.inl.
00053 : sequences_(SequenceRange_LessThan) 00054 { 00055 }
bool OpenDDS::DCPS::DisjointSequence::contains | ( | SequenceNumber | value | ) | const |
Definition at line 326 of file DisjointSequence.cpp.
00327 { 00328 RangeSet::const_iterator iter = 00329 sequences_.lower_bound(SequenceRange(0 /*ignored*/, value)); 00330 return iter != sequences_.end() && iter->first <= value; 00331 }
ACE_INLINE SequenceNumber OpenDDS::DCPS::DisjointSequence::cumulative_ack | ( | ) | const |
Gets the high end of the lowest contiguous range. Named after the use case of tracking received messages (which may be received out-of-order) and then determining the largest value that the receiver is allowed to acknowledge (under a cumulative-acking protocol). If empty(), returns SEQUENCENUMBER_UNKNOWN.
Definition at line 24 of file DisjointSequence.inl.
References OpenDDS::RTPS::SEQUENCENUMBER_UNKNOWN, and sequences_.
Referenced by OpenDDS::DCPS::WriterInfo::ack_sequence(), OpenDDS::DCPS::WriteDataContainer::data_delivered(), OpenDDS::DCPS::RtpsUdpDataLink::deliver_held_data(), OpenDDS::DCPS::ReliableSession::deliver_held_data(), OpenDDS::DCPS::RtpsUdpDataLink::generate_nack_frags(), OpenDDS::DCPS::RtpsUdpDataLink::marshal_gaps(), OpenDDS::DCPS::ReliableSession::ready_to_deliver(), OpenDDS::DCPS::ReliableSession::send_naks(), OpenDDS::DCPS::WriteDataContainer::sequence_acknowledged(), OpenDDS::DCPS::RtpsUdpDataLink::WriterInfo::should_nack(), and to_bitmap().
00025 { 00026 return sequences_.empty() 00027 ? SequenceNumber::SEQUENCENUMBER_UNKNOWN() 00028 : sequences_.begin()->second; 00029 }
ACE_INLINE bool OpenDDS::DCPS::DisjointSequence::disjoint | ( | ) | const |
Objects with the disjoint() property have an internal gap in the inserted SequenceNumbers.
Definition at line 46 of file DisjointSequence.inl.
References sequences_.
Referenced by OpenDDS::DCPS::RtpsUdpDataLink::marshal_gaps(), OpenDDS::DCPS::ReliableSession::ready_to_deliver(), OpenDDS::DCPS::ReliableSession::send_naks(), OpenDDS::DCPS::RtpsUdpDataLink::WriterInfo::should_nack(), and to_bitmap().
00047 { 00048 return sequences_.size() > 1; 00049 }
void OpenDDS::DCPS::DisjointSequence::dump | ( | ) | const |
Definition at line 343 of file DisjointSequence.cpp.
References sequences_.
Referenced by OpenDDS::DCPS::RtpsUdpDataLink::received(), OpenDDS::DCPS::RtpsUdpDataLink::send_nack_replies(), and OpenDDS::DCPS::ReliableSession::send_naks().
00344 { 00345 ACE_DEBUG((LM_DEBUG, "(%P|%t) DisjointSequence[%X]::dump Ranges of seen " 00346 "SequenceNumbers:\n", this)); 00347 for (RangeSet::const_iterator iter = sequences_.begin(); 00348 iter != sequences_.end(); ++iter) { 00349 ACE_DEBUG((LM_DEBUG, "(%P|%t) DisjointSequence[%X]::dump\t%q-%q\n", 00350 this, iter->first.getValue(), iter->second.getValue())); 00351 } 00352 }
ACE_INLINE bool OpenDDS::DCPS::DisjointSequence::empty | ( | ) | const |
Definition at line 40 of file DisjointSequence.inl.
References sequences_.
Referenced by OpenDDS::DCPS::RtpsUdpDataLink::deliver_held_data(), OpenDDS::DCPS::ReliableSession::deliver_held_data(), OpenDDS::DCPS::RtpsUdpDataLink::generate_nack_frags(), OpenDDS::DCPS::RtpsUdpDataLink::RtpsReader::nack_durable(), OpenDDS::DCPS::RtpsUdpDataLink::process_heartbeat_i(), OpenDDS::DCPS::ReliableSession::ready_to_deliver(), OpenDDS::DCPS::RtpsUdpDataLink::received(), OpenDDS::DCPS::SingleSendBuffer::resend_fragments_i(), OpenDDS::DCPS::RtpsUdpDataLink::send_nack_replies(), and OpenDDS::DCPS::RtpsUdpDataLink::WriterInfo::should_nack().
00041 { 00042 return sequences_.empty(); 00043 }
bool OpenDDS::DCPS::DisjointSequence::fill_bitmap_range | ( | CORBA::ULong | low, | |
CORBA::ULong | high, | |||
CORBA::Long | bitmap[], | |||
CORBA::ULong | length, | |||
CORBA::ULong & | num_bits | |||
) | [static] |
Set the bits in range [low, high] in the bitmap, updating num_bits.
Definition at line 232 of file DisjointSequence.cpp.
Referenced by OpenDDS::DCPS::RtpsUdpDataLink::extend_bitmap_range(), OpenDDS::DCPS::TransportReassembly::get_gaps(), OpenDDS::DCPS::RtpsUdpDataLink::send_ack_nacks(), and to_bitmap().
00235 { 00236 bool clamped = false; 00237 CORBA::ULong idx_low = low / 32, bit_low = low % 32, 00238 idx_high = high / 32, bit_high = high % 32; 00239 00240 if (idx_low >= length) { 00241 return false; 00242 } 00243 if (idx_high >= length) { 00244 // clamp to largest number we can represent 00245 high = length * 32 - 1; 00246 idx_high = length - 1; 00247 bit_high = high % 32; 00248 clamped = true; 00249 } 00250 00251 // clear any full Longs between the last bit we wrote and idx_low 00252 for (CORBA::ULong i = (num_bits + 31) / 32; i < idx_low; ++i) { 00253 bitmap[i] = 0; 00254 } 00255 00256 // write the Long at idx_low, preserving bits that may already be there 00257 CORBA::ULong x = bitmap[idx_low]; // use unsigned for bitwise operators 00258 // clear the bits in x in the range [bit_last, bit_low) 00259 if (num_bits > 0) { 00260 const size_t bit_last = ((num_bits - 1) / 32 == idx_low) 00261 ? ((num_bits - 1) % 32 + 1) : 0; 00262 for (size_t m = bit_last; m < bit_low; ++m) { 00263 x &= ~(1 << (31 - m)); 00264 } 00265 } else { 00266 x = 0; 00267 } 00268 // set the bits in x in the range [bit_low, limit) 00269 const size_t limit = (idx_high == idx_low) ? bit_high : 31; 00270 for (size_t b = bit_low; b <= limit; ++b) { 00271 x |= (1 << (31 - b)); 00272 } 00273 bitmap[idx_low] = x; 00274 00275 // any full Longs inside the current range are set to all 1's 00276 for (CORBA::ULong elt = idx_low + 1; elt < idx_high; ++elt) { 00277 bitmap[elt] = 0xFFFFFFFF; 00278 } 00279 00280 if (idx_high > idx_low) { 00281 // write the Long at idx_high, no need to preserve bits since this is 00282 // the first iteration that's writing it 00283 x = 0; 00284 for (size_t b = 0; b <= bit_high; ++b) { 00285 x |= (1 << (31 - b)); 00286 } 00287 bitmap[idx_high] = x; 00288 } 00289 00290 num_bits = high + 1; 00291 return !clamped; 00292 }
ACE_INLINE SequenceNumber OpenDDS::DCPS::DisjointSequence::high | ( | ) | const |
Highest SequenceNumber in the set. Precondition: !empty()
Definition at line 18 of file DisjointSequence.inl.
References sequences_.
Referenced by OpenDDS::DCPS::WriterInfo::coherent_change_received(), OpenDDS::DCPS::RtpsUdpDataLink::generate_nack_frags(), insert_bitmap_range(), OpenDDS::DCPS::RtpsUdpDataLink::marshal_gaps(), OpenDDS::DCPS::RtpsUdpDataLink::received(), OpenDDS::DCPS::RtpsUdpDataLink::WriterInfo::should_nack(), and to_bitmap().
00019 { 00020 return sequences_.rbegin()->second; 00021 }
bool OpenDDS::DCPS::DisjointSequence::insert | ( | SequenceNumber | value, | |
CORBA::ULong | num_bits, | |||
const CORBA::Long | bits[] | |||
) |
Insert using the RTPS compact representation of a set. The three parameters, taken together, describe a set with each 1 bit starting at the msb of bits[0] and extending through num_bits (which are located at the next least significant bits of bits[0] followed by the msb of bits[1], etc.) indicating presence of the number (value + bit_index) in the set. bit_index is 0-based. Precondition: the array 'bits' has at least ceil(num_bits / 32) entries.
Definition at line 87 of file DisjointSequence.cpp.
References OpenDDS::DCPS::SequenceNumber::getValue(), insert_bitmap_range(), and sequences_.
00089 { 00090 bool inserted = false; 00091 RangeSet::iterator iter = sequences_.end(); 00092 SequenceNumber::Value range_start = 0; 00093 const SequenceNumber::Value val = value.getValue(); 00094 00095 // See RTPS v2.1 section 9.4.2.6 SequenceNumberSet 00096 for (CORBA::ULong i = 0, x = 0, bit = 0; i < num_bits; ++i, ++bit) { 00097 00098 if (bit == 32) bit = 0; 00099 00100 if (bit == 0) { 00101 x = static_cast<CORBA::ULong>(bits[i / 32]); 00102 if (x == 0) { 00103 // skip an entire Long if it's all 0's (adds 32 due to ++i) 00104 i += 31; 00105 bit = 31; 00106 //FUTURE: this could be generalized with something like the x86 "bsr" 00107 // instruction using compiler intrinsics, VC++ _BitScanReverse() 00108 // and GCC __builtin_clz() 00109 continue; 00110 } 00111 } 00112 00113 if (x & (1 << (31 - bit))) { 00114 if (range_start == 0) { 00115 range_start = val + i; 00116 } 00117 00118 } else if (range_start != 0) { 00119 // this is a "0" bit and we've previously seen a "1": insert a range 00120 const SequenceNumber::Value to_insert = val + i - 1; 00121 if (insert_bitmap_range(iter, SequenceRange(range_start, to_insert))) { 00122 inserted = true; 00123 } 00124 range_start = 0; 00125 00126 if (iter != sequences_.end() && iter->second.getValue() != to_insert) { 00127 // skip ahead: next gap in sequence must be past iter->second 00128 CORBA::ULong next_i = CORBA::ULong(iter->second.getValue() - val); 00129 bit = next_i % 32; 00130 if (next_i / 32 != i / 32) { 00131 x = static_cast<CORBA::ULong>(bits[next_i / 32]); 00132 } 00133 i = next_i; 00134 } 00135 } 00136 } 00137 00138 if (range_start != 0) { 00139 // iteration finished before we saw a "0" (inside a range) 00140 SequenceNumber range_end = (value + num_bits).previous(); 00141 if (insert_bitmap_range(iter, SequenceRange(range_start, range_end))) { 00142 return true; 00143 } 00144 } 00145 return inserted; 00146 }
ACE_INLINE bool OpenDDS::DCPS::DisjointSequence::insert | ( | SequenceNumber | value | ) |
Shorthand for "insert(SequenceRange(value, value))".
Definition at line 64 of file DisjointSequence.inl.
References insert_i().
00065 { 00066 return insert_i(SequenceRange(value, value)); 00067 }
ACE_INLINE bool OpenDDS::DCPS::DisjointSequence::insert | ( | const SequenceRange & | range | ) |
Insert all numbers between range.first and range.second (both inclusive).
Definition at line 70 of file DisjointSequence.inl.
References insert_i().
00071 { 00072 return insert_i(range); 00073 }
ACE_INLINE bool OpenDDS::DCPS::DisjointSequence::insert | ( | const SequenceRange & | range, | |
OPENDDS_VECTOR(SequenceRange)& | added | |||
) |
All insert() methods return true upon modifying the set and false if the set already contained the SequenceNumber(s) that were to be inserted. This is the general form of insert() whereby the caller receives a list of sub-ranges of 'range' that were not already in the DisjointSequence. For example, given a DisjointSequence 'seq' containing (1, 2, 5, 9), calling seq.insert(SequenceRange(4, 12), v) returns true and yields v = [(4, 4), (6, 8), (10, 12)] and seq = (1, 2, 4, ..., 12).
Definition at line 76 of file DisjointSequence.inl.
References insert_i().
Referenced by OpenDDS::DCPS::WriterInfo::ack_sequence(), OpenDDS::DCPS::ReliableSession::check_header(), OpenDDS::DCPS::WriteDataContainer::data_delivered(), OpenDDS::DCPS::ReliableSession::nakack_received(), OpenDDS::DCPS::RtpsUdpDataLink::process_heartbeat_i(), OpenDDS::DCPS::RtpsUdpDataLink::received(), OpenDDS::DCPS::ReliableSession::record_header_received(), OpenDDS::DCPS::RtpsUdpDataLink::send_nack_replies(), OpenDDS::DCPS::RtpsUdpDataLink::send_nackfrag_replies(), OpenDDS::DCPS::ReliableSession::send_naks(), and OpenDDS::DCPS::ReliableSession::syn_hook().
00078 { 00079 return insert_i(range, &gaps); 00080 }
bool OpenDDS::DCPS::DisjointSequence::insert_bitmap_range | ( | RangeSet::iterator & | iter, | |
const SequenceRange & | sr | |||
) | [private] |
Definition at line 149 of file DisjointSequence.cpp.
References high(), low(), and sequences_.
Referenced by insert().
00151 { 00152 // This is similar to insert_i(), except it doesn't need an O(log(n)) search 00153 // of sequences_ every time to find the starting point, and it doesn't 00154 // compute the 'gaps'. 00155 00156 const SequenceNumber::Value previous = range.first.getValue() - 1, 00157 next = range.second.getValue() + 1; 00158 00159 if (!sequences_.empty()) { 00160 if (iter == sequences_.end()) { 00161 iter = sequences_.lower_bound(SequenceRange(1 /*ignored*/, previous)); 00162 } else { 00163 // start where we left off last time and get the lower_bound(previous) 00164 for (; iter != sequences_.end() && iter->second < previous; ++iter) ; 00165 } 00166 } 00167 00168 if (iter == sequences_.end() || iter->first > next) { 00169 // can't combine on either side, insert a new range 00170 iter = sequences_.insert(iter, range); 00171 return true; 00172 } 00173 00174 if (iter->first <= range.first && iter->second >= range.second) { 00175 // range is already covered by this DisjointSet 00176 return false; 00177 } 00178 00179 // find the right-most (highest) range we can use 00180 RangeSet::iterator right = iter; 00181 for (; right != sequences_.end() && right->second < next; ++right) ; 00182 00183 SequenceNumber high = range.second; 00184 if (right != sequences_.end() 00185 && right->first <= next && right->first > range.first) { 00186 high = right->second; 00187 ++right; 00188 } 00189 00190 const SequenceNumber low = std::min(iter->first, range.first); 00191 sequences_.erase(iter, right); 00192 00193 iter = sequences_.insert(SequenceRange(low, high)).first; 00194 return true; 00195 }
bool OpenDDS::DCPS::DisjointSequence::insert_i | ( | const SequenceRange & | range, | |
OPENDDS_VECTOR(SequenceRange)* | gaps = 0 | |||
) | [private] |
Definition at line 26 of file DisjointSequence.cpp.
References sequences_, validate(), and OpenDDS::DCPS::SequenceNumber::ZERO().
Referenced by insert().
00028 { 00029 validate(range); 00030 00031 RangeSet::iterator range_above = sequences_.lower_bound(range); 00032 if (range_above != sequences_.end() 00033 && range_above->first <= range.first) { 00034 return false; // already have this range, nothing to insert 00035 } 00036 00037 SequenceRange newRange = range; 00038 if (range_above != sequences_.end() 00039 && ++SequenceNumber(newRange.second) >= range_above->first) { 00040 // newRange overlaps range_above, replace range_above with modified newRange 00041 newRange.second = range_above->second; 00042 // move to just past this iterator for the erase 00043 ++range_above; 00044 } 00045 00046 const SequenceNumber::Value previous = range.first.getValue() - 1; 00047 // find the lower_bound for the SequenceNumber just before this range 00048 // to see if any ranges need to combine 00049 const RangeSet::iterator range_below = 00050 sequences_.lower_bound(SequenceRange(1 /*ignored*/, 00051 (previous > 0) ? previous 00052 : SequenceNumber::ZERO())); 00053 if (range_below != sequences_.end()) { 00054 // if low end falls inside of the range_below range 00055 // then combine 00056 if (newRange.first > range_below->first) { 00057 newRange.first = range_below->first; 00058 } 00059 00060 if (gaps) { 00061 RangeSet::iterator gap_iter = range_below; 00062 if (range.first < gap_iter->second) { 00063 gaps->push_back(SequenceRange(range.first, 00064 gap_iter->second.previous())); 00065 } 00066 SequenceNumber last_gap = gap_iter++->second; 00067 for (; gap_iter != range_above; ++gap_iter) { 00068 const SequenceNumber in_range = 00069 std::min(gap_iter->first.previous().getValue(), 00070 range.second.getValue()); 00071 gaps->push_back(SequenceRange(++last_gap, in_range)); 00072 last_gap = gap_iter->second; 00073 } 00074 if (last_gap < range.second) { 00075 gaps->push_back(SequenceRange(++last_gap, range.second)); 00076 } 00077 } 00078 00079 sequences_.erase(range_below, range_above); 00080 } 00081 00082 sequences_.insert(newRange); 00083 return true; 00084 }
ACE_INLINE SequenceNumber OpenDDS::DCPS::DisjointSequence::last_ack | ( | ) | const |
Gets the low end of the highest contiguous range, may be thought of as the inverse of cumulative_ack(). If empty(), returns SEQUENCENUMBER_UNKNOWN.
Definition at line 32 of file DisjointSequence.inl.
References OpenDDS::RTPS::SEQUENCENUMBER_UNKNOWN, and sequences_.
Referenced by OpenDDS::DCPS::RtpsUdpDataLink::generate_nack_frags().
00033 { 00034 return sequences_.empty() 00035 ? SequenceNumber::SEQUENCENUMBER_UNKNOWN() 00036 : sequences_.rbegin()->first; 00037 }
ACE_INLINE SequenceNumber OpenDDS::DCPS::DisjointSequence::low | ( | ) | const |
Lowest SequenceNumber in the set. Precondition: !empty()
Definition at line 12 of file DisjointSequence.inl.
References sequences_.
Referenced by OpenDDS::DCPS::RtpsUdpDataLink::deliver_held_data(), OpenDDS::DCPS::ReliableSession::deliver_held_data(), insert_bitmap_range(), OpenDDS::DCPS::RtpsUdpDataLink::marshal_gaps(), OpenDDS::DCPS::RtpsUdpDataLink::RtpsReader::nack_durable(), OpenDDS::DCPS::RtpsUdpDataLink::process_heartbeat_i(), OpenDDS::DCPS::ReliableSession::ready_to_deliver(), OpenDDS::DCPS::RtpsUdpDataLink::received(), OpenDDS::DCPS::ReliableSession::send_naks(), and to_bitmap().
00013 { 00014 return sequences_.begin()->first; 00015 }
typedef OpenDDS::DCPS::DisjointSequence::OPENDDS_SET_CMP | ( | SequenceRange | , | |
SRCompare | ||||
) | [private] |
OpenDDS::DCPS::DisjointSequence::OPENDDS_VECTOR | ( | SequenceRange | ) | const |
Returns a representation of the members of the sequence as a list of contiguous ranges (each Range is inclusive on both sides).
OpenDDS::DCPS::DisjointSequence::OPENDDS_VECTOR | ( | SequenceRange | ) | const |
Returns missing ranges of SequenceNumbers (internal gaps in the sequence).
ACE_INLINE void OpenDDS::DCPS::DisjointSequence::reset | ( | ) |
Definition at line 58 of file DisjointSequence.inl.
References sequences_.
Referenced by OpenDDS::DCPS::WriterInfo::reset_coherent_info(), and OpenDDS::DCPS::ReliableSession::syn_hook().
00059 { 00060 sequences_.clear(); 00061 }
static bool OpenDDS::DCPS::DisjointSequence::SequenceRange_LessThan | ( | const SequenceRange & | lhs, | |
const SequenceRange & | rhs | |||
) | [inline, static, private] |
bool OpenDDS::DCPS::DisjointSequence::to_bitmap | ( | CORBA::Long | bitmap[], | |
CORBA::ULong | length, | |||
CORBA::ULong & | num_bits, | |||
bool | invert = false | |||
) | const |
Inverse of insert(value, num_bits, bits). Populates array of bitmap[length] with the bitmap of ranges above the cumulative_ack() value. Sets the number of significant (used) bits in num_bits. The 'base' of the bitmap is one larger than cumulative_ack(). Returns true if the entire DisjointSequence was able to fit in bitmap[]. Returning false is not an error, it's just that the higher-valued ranges didn't fit. If invert is true, the 1's in the bitmap represent the missing_sequence_ranges() instead of the present_sequence_ranges(). Precondition: the array 'bits' has 'length' entries allocated.
Definition at line 198 of file DisjointSequence.cpp.
References cumulative_ack(), disjoint(), fill_bitmap_range(), OpenDDS::DCPS::SequenceNumber::getValue(), high(), low(), and sequences_.
Referenced by OpenDDS::DCPS::RtpsUdpDataLink::marshal_gaps().
00200 { 00201 // num_bits will be 1 more than the index of the last bit we wrote 00202 num_bits = 0; 00203 if (!disjoint()) { 00204 return true; 00205 } 00206 00207 const SequenceNumber base = ++SequenceNumber(cumulative_ack()); 00208 00209 for (RangeSet::const_iterator iter = sequences_.begin(), prev = iter++; 00210 iter != sequences_.end(); ++iter, ++prev) { 00211 00212 CORBA::ULong low = 0, high = 0; 00213 00214 if (invert) { 00215 low = CORBA::ULong(prev->second.getValue() + 1 - base.getValue()); 00216 high = CORBA::ULong(iter->first.getValue() - 1 - base.getValue()); 00217 00218 } else { 00219 low = CORBA::ULong(iter->first.getValue() - base.getValue()); 00220 high = CORBA::ULong(iter->second.getValue() - base.getValue()); 00221 } 00222 00223 if (!fill_bitmap_range(low, high, bitmap, length, num_bits)) { 00224 return false; 00225 } 00226 } 00227 00228 return true; 00229 }
void OpenDDS::DCPS::DisjointSequence::validate | ( | const SequenceRange & | range | ) | [static, private] |
Definition at line 334 of file DisjointSequence.cpp.
Referenced by insert_i().
00335 { 00336 if (range.first > range.second) { 00337 throw std::runtime_error("SequenceNumber range invalid, range must " 00338 "be ascending."); 00339 } 00340 }
RangeSet OpenDDS::DCPS::DisjointSequence::sequences_ [private] |
Definition at line 117 of file DisjointSequence.h.
Referenced by cumulative_ack(), disjoint(), dump(), empty(), high(), insert(), insert_bitmap_range(), insert_i(), last_ack(), low(), reset(), and to_bitmap().