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 namespace OpenDDS {
00023 namespace DCPS {
00024
00025 bool
00026 DisjointSequence::insert_i(const SequenceRange& range,
00027 OPENDDS_VECTOR(SequenceRange)* gaps )
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;
00035 }
00036
00037 SequenceRange newRange = range;
00038 if (range_above != sequences_.end()
00039 && ++SequenceNumber(newRange.second) >= range_above->first) {
00040
00041 newRange.second = range_above->second;
00042
00043 ++range_above;
00044 }
00045
00046 const SequenceNumber::Value previous = range.first.getValue() - 1;
00047
00048
00049 const RangeSet::iterator range_below =
00050 sequences_.lower_bound(SequenceRange(1 ,
00051 (previous > 0) ? previous
00052 : SequenceNumber::ZERO()));
00053 if (range_below != sequences_.end()) {
00054
00055
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 }
00085
00086 bool
00087 DisjointSequence::insert(SequenceNumber value, CORBA::ULong num_bits,
00088 const CORBA::Long bits[])
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
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
00104 i += 31;
00105 bit = 31;
00106
00107
00108
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
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
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
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 }
00147
00148 bool
00149 DisjointSequence::insert_bitmap_range(RangeSet::iterator& iter,
00150 const SequenceRange& range)
00151 {
00152
00153
00154
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 , previous));
00162 } else {
00163
00164 for (; iter != sequences_.end() && iter->second < previous; ++iter) ;
00165 }
00166 }
00167
00168 if (iter == sequences_.end() || iter->first > next) {
00169
00170 iter = sequences_.insert(iter, range);
00171 return true;
00172 }
00173
00174 if (iter->first <= range.first && iter->second >= range.second) {
00175
00176 return false;
00177 }
00178
00179
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 }
00196
00197 bool
00198 DisjointSequence::to_bitmap(CORBA::Long bitmap[], CORBA::ULong length,
00199 CORBA::ULong& num_bits, bool invert) const
00200 {
00201
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 }
00230
00231 bool
00232 DisjointSequence::fill_bitmap_range(CORBA::ULong low, CORBA::ULong high,
00233 CORBA::Long bitmap[], CORBA::ULong length,
00234 CORBA::ULong& num_bits)
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
00245 high = length * 32 - 1;
00246 idx_high = length - 1;
00247 bit_high = high % 32;
00248 clamped = true;
00249 }
00250
00251
00252 for (CORBA::ULong i = (num_bits + 31) / 32; i < idx_low; ++i) {
00253 bitmap[i] = 0;
00254 }
00255
00256
00257 CORBA::ULong x = bitmap[idx_low];
00258
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
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
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
00282
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 }
00293
00294 OPENDDS_VECTOR(SequenceRange)
00295 DisjointSequence::missing_sequence_ranges() const
00296 {
00297 OPENDDS_VECTOR(SequenceRange) missing;
00298 if (!disjoint()) {
00299 return missing;
00300 }
00301
00302 RangeSet::const_iterator secondIter = sequences_.begin();
00303 for (RangeSet::const_iterator firstIter = secondIter++;
00304 secondIter != sequences_.end(); ++firstIter, ++secondIter) {
00305
00306 const SequenceNumber missingLow = ++SequenceNumber(firstIter->second),
00307 missingHigh = secondIter->first.previous();
00308
00309 if (missingLow <= missingHigh) {
00310 missing.push_back(SequenceRange(missingLow, missingHigh));
00311 }
00312 }
00313
00314 return missing;
00315 }
00316
00317 OPENDDS_VECTOR(SequenceRange)
00318 DisjointSequence::present_sequence_ranges() const
00319 {
00320 OPENDDS_VECTOR(SequenceRange) present;
00321 std::copy(sequences_.begin(), sequences_.end(), std::back_inserter(present));
00322 return present;
00323 }
00324
00325 bool
00326 DisjointSequence::contains(SequenceNumber value) const
00327 {
00328 RangeSet::const_iterator iter =
00329 sequences_.lower_bound(SequenceRange(0 , value));
00330 return iter != sequences_.end() && iter->first <= value;
00331 }
00332
00333 void
00334 DisjointSequence::validate(const SequenceRange& range)
00335 {
00336 if (range.first > range.second) {
00337 throw std::runtime_error("SequenceNumber range invalid, range must "
00338 "be ascending.");
00339 }
00340 }
00341
00342 void
00343 DisjointSequence::dump() const
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 }
00353
00354 }
00355 }