Example #1
0
void SequenceSet::decode(Buffer& buffer)
{
    clear();
    uint16_t size = buffer.getShort();
    uint16_t count = size / RANGE_SIZE;//number of ranges
    if (size % RANGE_SIZE)
        throw IllegalArgumentException(QPID_MSG("Invalid size for sequence set: " << size)); 

    for (uint16_t i = 0; i < count; i++) {
        add(SequenceNumber(buffer.getLong()), SequenceNumber(buffer.getLong()));
    }
}
bool
SingleSendBuffer::resend_i(const SequenceRange& range, DisjointSequence* gaps)
{
  //Special case, nak to make sure it has all history
  const SequenceNumber lowForAllResent = range.first == SequenceNumber() ? low() : range.first;

  for (SequenceNumber sequence(range.first);
       sequence <= range.second; ++sequence) {
    // Re-send requested sample if still buffered; missing samples
    // will be scored against the given DisjointSequence:
    BufferMap::iterator it(this->buffers_.find(sequence));
    if (it == this->buffers_.end()) {
      if (gaps) {
        gaps->insert(sequence);
      }
    } else {
      if (Transport_debug_level > 5) {
        ACE_DEBUG((LM_DEBUG,
                   ACE_TEXT("(%P|%t) SingleSendBuffer::resend() - ")
                   ACE_TEXT("resending PDU: %q, (0x%@,0x%@)\n"),
                   sequence.getValue(),
                   it->second.first,
                   it->second.second));
      }
      if (it->second.first && it->second.second) {
        resend_one(it->second);
      } else {
        const FragmentMap::iterator fm_it = fragments_.find(it->first);
        if (fm_it != fragments_.end()) {
          for (BufferMap::iterator bm_it = fm_it->second.begin();
                bm_it != fm_it->second.end(); ++bm_it) {
            resend_one(bm_it->second);
          }
        }
      }
    }
  }
  // Have we resent all requested data?
  return lowForAllResent >= low() && range.second <= high();
}
Example #3
0
void
ReliableSession::send_synack()
{
  // Send nakack before sending synack to
  // reduce naks from remote.
  TransportSendBuffer* send_buffer = this->link_->send_buffer();
  if (!send_buffer->empty() && send_buffer->low() > ++SequenceNumber()) {
    send_nakack(send_buffer->low());
  }

  size_t len = sizeof(this->remote_peer_);

  ACE_Message_Block* data;
  ACE_NEW(data, ACE_Message_Block(len));

  Serializer serializer(
    data, this->link_->transport()->swap_bytes());

  serializer << this->remote_peer_;

  // Send control sample to remote peer:
  send_control(MULTICAST_SYNACK, data);
}
Example #4
0
void
ReliableSession::send_naks()
{
  // Could get data samples before syn control message.
  // No use nak'ing until syn control message is received and session is acked.
  if (!this->acked()) return;

  if (DCPS_debug_level > 5) {
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) ReliableSession::send_naks local %d ")
                         ACE_TEXT("remote %d nak request size %d \n"),
      this->link_->local_peer(), this->remote_peer_, this->nak_requests_.size()));
  }

  if (!this->nak_sequence_.disjoint()) return;  // nothing to send

  ACE_Time_Value now(ACE_OS::gettimeofday());

  // Record high-water mark for this interval; this value will
  // be used to reset the low-water mark in the event the remote
  // peer becomes unresponsive:
  this->nak_requests_[now] = this->nak_sequence_.high();

  typedef std::vector<SequenceRange> RangeVector;
  RangeVector ignored;

  /// The range first - second will be skiped (no naks sent for it).
  SequenceNumber first;
  SequenceNumber second;

  NakRequestMap::reverse_iterator itr(this->nak_requests_.rbegin());

  if (this->nak_requests_.size() > 1) {
    // The sequences between rbegin - 1 and rbegin will not be ignored for naking.
    ++itr;

    size_t nak_delay_intervals = this->link()->config()->nak_delay_intervals_;
    size_t nak_max = this->link()->config()->nak_max_;
    size_t sz = this->nak_requests_.size();

    // Image i is the index of element in nak_requests_ in reverse order.
    // index 0 sequence is most recent high water mark.
    // e.g index , 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
    //  0 (rbegin) is always skipped because missing sample between 1 and 0 interval
    //  should always be naked.,
    //  if nak_delay_intervals=4, nak_max=3, any sequence between 5 - 1, 10 - 6, 15 - 11
    //  are skipped for naking due to nak_delay_intervals and 20 - 16 are skipped for
    //  naking due to nak_max.
    for (size_t i = 1; i < sz; ++i) {
      if ((i * 1.0) / (nak_delay_intervals + 1) > nak_max) {
        if (first != SequenceNumber()) {
          first = this->nak_requests_.begin()->second;
        }
        else {
          ignored.push_back(std::make_pair(this->nak_requests_.begin()->second, itr->second));
        }
        break;
      }

      if (i % (nak_delay_intervals + 1) == 1) {
        second = itr->second;
      }
      if (second != SequenceNumber()) {
        first = itr->second;
      }

      if (i % (nak_delay_intervals + 1) == 0) {
        first = itr->second;

        if (first != SequenceNumber() && second != SequenceNumber()) {
          ignored.push_back(std::make_pair(first, second));
          first = SequenceNumber();
          second = SequenceNumber();
        }
      }

      ++itr;
    }

    if (first != SequenceNumber() && second != SequenceNumber() && first != second) {
      ignored.push_back(std::make_pair(first, second));
    }
  }

  // Take a copy to facilitate temporary suppression:
  DisjointSequence received(this->nak_sequence_);
  if (DCPS_debug_level > 0) {
    received.dump();
  }

  size_t sz = ignored.size();
  for (size_t i = 0; i < sz; ++i) {

    if (ignored[i].second > received.cumulative_ack()) {
      SequenceNumber high = ignored[i].second;
      SequenceNumber low = ignored[i].first;
      if (low < received.cumulative_ack()) {
        low = received.cumulative_ack();
      }

      if (DCPS_debug_level > 0) {
        ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%P|%t) ReliableSession::send_naks local %d ")
          ACE_TEXT("remote %d ignore missing [%q - %q]\n"),
          this->link_->local_peer(), this->remote_peer_, low.getValue(), high.getValue()));
      }

      // Make contiguous between ignored sequences.
      received.insert(SequenceRange(low, high));
    }
  }

  for (NakPeerSet::iterator it(this->nak_peers_.begin());
       it != this->nak_peers_.end(); ++it) {
    // Update sequence to temporarily suppress repair requests for
    // ranges already requested by other peers for this interval:
    received.insert(*it);
  }

  if (received.disjoint()) {
    send_naks(received);
  }

  // Clear peer repair requests:
  this->nak_peers_.clear();
}
Example #5
0
SequenceNumber WriteBatchInternal::Sequence(const WriteBatch* b) {
  return SequenceNumber(DecodeFixed64(b->rep_.data()));
}
Example #6
0
void deserialize(SequenceNumber& sn, InputArchive& ar)
{
    SequenceNumber::value_type tmp = 0;
    deserialize(tmp, ar);
    sn = SequenceNumber(ntoh(tmp));
}