00001
00002
00003
00004
00005
00006
00007
00008 #include "DCPS/DdsDcps_pch.h"
00009
00010 #include "DisjointSequence.h"
00011
00012 #include "ace/Log_Msg.h"
00013
00014 #include <stdexcept>
00015 #include <algorithm>
00016 #include <iterator>
00017
00018 #ifndef __ACE_INLINE__
00019 # include "DisjointSequence.inl"
00020 #endif
00021
00022 OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
00023
00024 namespace OpenDDS {
00025 namespace DCPS {
00026
00027 bool
00028 DisjointSequence::insert_i(const SequenceRange& range,
00029 OPENDDS_VECTOR(SequenceRange)* gaps )
00030 {
00031 validate(range);
00032
00033 RangeSet::iterator range_above = sequences_.lower_bound(range);
00034 if (range_above != sequences_.end()
00035 && range_above->first <= range.first) {
00036 return false;
00037 }
00038
00039 SequenceRange newRange = range;
00040 if (range_above != sequences_.end()
00041 && ++SequenceNumber(newRange.second) >= range_above->first) {
00042
00043 newRange.second = range_above->second;
00044
00045 ++range_above;
00046 }
00047
00048 const SequenceNumber::Value previous = range.first.getValue() - 1;
00049
00050
00051 const RangeSet::iterator range_below =
00052 sequences_.lower_bound(SequenceRange(1 ,
00053 (previous > 0) ? previous
00054 : SequenceNumber::ZERO()));
00055 if (range_below != sequences_.end()) {
00056
00057
00058 if (newRange.first > range_below->first) {
00059 newRange.first = range_below->first;
00060 }
00061
00062 if (gaps) {
00063 RangeSet::iterator gap_iter = range_below;
00064 if (range.first < gap_iter->second) {
00065 gaps->push_back(SequenceRange(range.first,
00066 gap_iter->second.previous()));
00067 }
00068 SequenceNumber last_gap = gap_iter++->second;
00069 for (; gap_iter != range_above; ++gap_iter) {
00070 const SequenceNumber in_range =
00071 std::min(gap_iter->first.previous().getValue(),
00072 range.second.getValue());
00073 gaps->push_back(SequenceRange(++last_gap, in_range));
00074 last_gap = gap_iter->second;
00075 }
00076 if (last_gap < range.second) {
00077 gaps->push_back(SequenceRange(++last_gap, range.second));
00078 }
00079 }
00080
00081 sequences_.erase(range_below, range_above);
00082 }
00083
00084 sequences_.insert(newRange);
00085 return true;
00086 }
00087
00088 bool
00089 DisjointSequence::insert(SequenceNumber value, CORBA::ULong num_bits,
00090 const CORBA::Long bits[])
00091 {
00092 bool inserted = false;
00093 RangeSet::iterator iter = sequences_.end();
00094 SequenceNumber::Value range_start = 0;
00095 const SequenceNumber::Value val = value.getValue();
00096
00097
00098 for (CORBA::ULong i = 0, x = 0, bit = 0; i < num_bits; ++i, ++bit) {
00099
00100 if (bit == 32) bit = 0;
00101
00102 if (bit == 0) {
00103 x = static_cast<CORBA::ULong>(bits[i / 32]);
00104 if (x == 0) {
00105
00106 i += 31;
00107 bit = 31;
00108
00109
00110
00111 continue;
00112 }
00113 }
00114
00115 if (x & (1 << (31 - bit))) {
00116 if (range_start == 0) {
00117 range_start = val + i;
00118 }
00119
00120 } else if (range_start != 0) {
00121
00122 const SequenceNumber::Value to_insert = val + i - 1;
00123 if (insert_bitmap_range(iter, SequenceRange(range_start, to_insert))) {
00124 inserted = true;
00125 }
00126 range_start = 0;
00127
00128 if (iter != sequences_.end() && iter->second.getValue() != to_insert) {
00129
00130 CORBA::ULong next_i = CORBA::ULong(iter->second.getValue() - val);
00131 bit = next_i % 32;
00132 if (next_i / 32 != i / 32) {
00133 x = static_cast<CORBA::ULong>(bits[next_i / 32]);
00134 }
00135 i = next_i;
00136 }
00137 }
00138 }
00139
00140 if (range_start != 0) {
00141
00142 SequenceNumber range_end = (value + num_bits).previous();
00143 if (insert_bitmap_range(iter, SequenceRange(range_start, range_end))) {
00144 return true;
00145 }
00146 }
00147 return inserted;
00148 }
00149
00150 bool
00151 DisjointSequence::insert_bitmap_range(RangeSet::iterator& iter,
00152 const SequenceRange& range)
00153 {
00154
00155
00156
00157
00158 const SequenceNumber::Value previous = range.first.getValue() - 1,
00159 next = range.second.getValue() + 1;
00160
00161 if (!sequences_.empty()) {
00162 if (iter == sequences_.end()) {
00163 iter = sequences_.lower_bound(SequenceRange(1 , previous));
00164 } else {
00165
00166 for (; iter != sequences_.end() && iter->second < previous; ++iter) ;
00167 }
00168 }
00169
00170 if (iter == sequences_.end() || iter->first > next) {
00171
00172 iter = sequences_.insert(iter, range);
00173 return true;
00174 }
00175
00176 if (iter->first <= range.first && iter->second >= range.second) {
00177
00178 return false;
00179 }
00180
00181
00182 RangeSet::iterator right = iter;
00183 for (; right != sequences_.end() && right->second < next; ++right) ;
00184
00185 SequenceNumber high = range.second;
00186 if (right != sequences_.end()
00187 && right->first <= next && right->first > range.first) {
00188 high = right->second;
00189 ++right;
00190 }
00191
00192 const SequenceNumber low = std::min(iter->first, range.first);
00193 sequences_.erase(iter, right);
00194
00195 iter = sequences_.insert(SequenceRange(low, high)).first;
00196 return true;
00197 }
00198
00199 bool
00200 DisjointSequence::to_bitmap(CORBA::Long bitmap[], CORBA::ULong length,
00201 CORBA::ULong& num_bits, bool invert) const
00202 {
00203
00204 num_bits = 0;
00205 if (!disjoint()) {
00206 return true;
00207 }
00208
00209 const SequenceNumber base = ++SequenceNumber(cumulative_ack());
00210
00211 for (RangeSet::const_iterator iter = sequences_.begin(), prev = iter++;
00212 iter != sequences_.end(); ++iter, ++prev) {
00213
00214 CORBA::ULong low = 0, high = 0;
00215
00216 if (invert) {
00217 low = CORBA::ULong(prev->second.getValue() + 1 - base.getValue());
00218 high = CORBA::ULong(iter->first.getValue() - 1 - base.getValue());
00219
00220 } else {
00221 low = CORBA::ULong(iter->first.getValue() - base.getValue());
00222 high = CORBA::ULong(iter->second.getValue() - base.getValue());
00223 }
00224
00225 if (!fill_bitmap_range(low, high, bitmap, length, num_bits)) {
00226 return false;
00227 }
00228 }
00229
00230 return true;
00231 }
00232
00233 bool
00234 DisjointSequence::fill_bitmap_range(CORBA::ULong low, CORBA::ULong high,
00235 CORBA::Long bitmap[], CORBA::ULong length,
00236 CORBA::ULong& num_bits)
00237 {
00238 bool clamped = false;
00239 CORBA::ULong idx_low = low / 32, bit_low = low % 32,
00240 idx_high = high / 32, bit_high = high % 32;
00241
00242 if (idx_low >= length) {
00243 return false;
00244 }
00245 if (idx_high >= length) {
00246
00247 high = length * 32 - 1;
00248 idx_high = length - 1;
00249 bit_high = high % 32;
00250 clamped = true;
00251 }
00252
00253
00254 for (CORBA::ULong i = (num_bits + 31) / 32; i < idx_low; ++i) {
00255 bitmap[i] = 0;
00256 }
00257
00258
00259 CORBA::ULong x = bitmap[idx_low];
00260
00261 if (num_bits > 0) {
00262 const size_t bit_last = ((num_bits - 1) / 32 == idx_low)
00263 ? ((num_bits - 1) % 32 + 1) : 0;
00264 for (size_t m = bit_last; m < bit_low; ++m) {
00265 x &= ~(1 << (31 - m));
00266 }
00267 } else {
00268 x = 0;
00269 }
00270
00271 const size_t limit = (idx_high == idx_low) ? bit_high : 31;
00272 for (size_t b = bit_low; b <= limit; ++b) {
00273 x |= (1 << (31 - b));
00274 }
00275 bitmap[idx_low] = x;
00276
00277
00278 for (CORBA::ULong elt = idx_low + 1; elt < idx_high; ++elt) {
00279 bitmap[elt] = 0xFFFFFFFF;
00280 }
00281
00282 if (idx_high > idx_low) {
00283
00284
00285 x = 0;
00286 for (size_t b = 0; b <= bit_high; ++b) {
00287 x |= (1 << (31 - b));
00288 }
00289 bitmap[idx_high] = x;
00290 }
00291
00292 num_bits = high + 1;
00293 return !clamped;
00294 }
00295
00296 OPENDDS_VECTOR(SequenceRange)
00297 DisjointSequence::missing_sequence_ranges() const
00298 {
00299 OPENDDS_VECTOR(SequenceRange) missing;
00300 if (!disjoint()) {
00301 return missing;
00302 }
00303
00304 RangeSet::const_iterator secondIter = sequences_.begin();
00305 for (RangeSet::const_iterator firstIter = secondIter++;
00306 secondIter != sequences_.end(); ++firstIter, ++secondIter) {
00307
00308 const SequenceNumber missingLow = ++SequenceNumber(firstIter->second),
00309 missingHigh = secondIter->first.previous();
00310
00311 if (missingLow <= missingHigh) {
00312 missing.push_back(SequenceRange(missingLow, missingHigh));
00313 }
00314 }
00315
00316 return missing;
00317 }
00318
00319 OPENDDS_VECTOR(SequenceRange)
00320 DisjointSequence::present_sequence_ranges() const
00321 {
00322 OPENDDS_VECTOR(SequenceRange) present;
00323 std::copy(sequences_.begin(), sequences_.end(), std::back_inserter(present));
00324 return present;
00325 }
00326
00327 bool
00328 DisjointSequence::contains(SequenceNumber value) const
00329 {
00330 RangeSet::const_iterator iter =
00331 sequences_.lower_bound(SequenceRange(0 , value));
00332 return iter != sequences_.end() && iter->first <= value;
00333 }
00334
00335 void
00336 DisjointSequence::validate(const SequenceRange& range)
00337 {
00338 if (range.first > range.second) {
00339 throw std::runtime_error("SequenceNumber range invalid, range must "
00340 "be ascending.");
00341 }
00342 }
00343
00344 void
00345 DisjointSequence::dump() const
00346 {
00347 ACE_DEBUG((LM_DEBUG, "(%P|%t) DisjointSequence[%X]::dump included ranges of "
00348 "SequenceNumbers:\n", this));
00349 for (RangeSet::const_iterator iter = sequences_.begin();
00350 iter != sequences_.end(); ++iter) {
00351 ACE_DEBUG((LM_DEBUG, "(%P|%t) DisjointSequence[%X]::dump\t%q-%q\n",
00352 this, iter->first.getValue(), iter->second.getValue()));
00353 }
00354 }
00355
00356 }
00357 }
00358
00359 OPENDDS_END_VERSIONED_NAMESPACE_DECL