Channel::Channel (FileTransfer* file, int socket, Address peer_addr) :
file_(file), peer_(peer_addr), peer_channel_id_(0), pex_out_(0),
socket_(socket==-1?sockets[0]:socket), // FIXME
- own_id_mentioned_(false), next_send_time_(0), hint_out_rotate_(0)
+ own_id_mentioned_(false), next_send_time_(0)
{
if (peer_==Address())
peer_ = tracker;
int Channel::DecodeID(int scrambled) {
- return scrambled;
+ return scrambled ^ (int)Datagram::epoch;
}
int Channel::EncodeID(int unscrambled) {
- return unscrambled;
+ return unscrambled ^ (int)Datagram::epoch;
}
uint64_t complete () const { return complete_; }
uint64_t complete_kilo () const { return completek_; }
uint64_t seq_complete () const { return seq_complete_; }
+ bool is_complete () const
+ { return seq_complete_==size_; }
bins& ack_out () { return ack_out_; }
int file_descriptor () const { return fd_; }
PiecePicker& picker () { return *picker_; }
class PiecePicker {
public:
virtual bin64_t Pick (bins& offered, uint8_t layer) = 0;
- virtual void Expired (bins& b) = 0;
+ virtual void Expired (bin64_t b) = 0;
virtual void Received (bin64_t b) = 0;
};
/** Transmit schedule: in most cases filled with the peer's hints */
binqueue hint_in_;
/** Hints sent (to detect and reschedule ignored hints). */
- bins hint_out_;
- bins hint_out_old_;
- tint hint_out_rotate_;
+ tbqueue hint_out_;
/** The congestion control strategy. */
CongestionController *cc_;
/** Types of messages the peer accepts. */
void Channel::AddHint (Datagram& dgram) {
- if (hint_out_rotate_<Datagram::now-TINT_SEC) {
- hint_out_rotate_ = Datagram::now;
- if ( ! hint_out_old_.is_empty() )
- file().picker().Expired(hint_out_old_);
- swap(hint_out_,hint_out_old_);
- hint_out_.clear();
+ while (!hint_out_.empty() &&
+ hint_out_.front().time<Datagram::now-TINT_SEC) {
+ file().picker().Expired(hint_out_.front().bin);
+ hint_out_.pop_front();
}
-
- uint64_t hinted = hint_out_.mass();// + hint_out_old_.mass();
+ uint64_t hinted = 0;
+ for(tbqueue::iterator i=hint_out_.begin(); i!=hint_out_.end(); i++)
+ hinted += i->bin.width();
int bps = cc_->PeerBPS();
dprintf("%s #%i hinted %lli peer_bps %i\n",Datagram::TimeStr(),id,hinted,bps);
//float peer_cwnd = cc_->PeerBPS() * cc_->RoundTripTime() / TINT_SEC;
hint = file().picker().Pick(ack_in_,0);
if (hint!=bin64_t::NONE) {
- hint_out_.set(hint);
+ hint_out_.push_back(hint);
dgram.Push8(P2TP_HINT);
dgram.Push32(hint);
dprintf("%s #%i +hint (%i,%lli)\n",Datagram::TimeStr(),id,hint.layer(),hint.offset());
int length = dgram.Pull(&data,1024);
bool ok = file().OfferData(pos, data, length) ;
dprintf("%s #%i %cdata (%lli)\n",Datagram::TimeStr(),id,ok?'-':'!',pos.offset());
- data_in_ = tintbin(Datagram::now,pos);
- hint_out_.set(pos,bins::EMPTY);
- hint_out_old_.set(pos,bins::EMPTY);
- return ok ? pos : bin64_t::none();
+ if (ok) {
+ data_in_ = tintbin(Datagram::now,pos);
+ return pos;
+ } else
+ return bin64_t::NONE;
}