From: victor Date: Fri, 20 Nov 2009 14:14:53 +0000 (+0000) Subject: clean data_out_ X-Git-Url: http://p2p-next.cs.pub.ro/gitweb/?a=commitdiff_plain;h=d165c1aa12b33f92d39e2a56238d077405e3830b;p=swift-upb.git clean data_out_ git-svn-id: https://ttuki.vtt.fi/svn/p2p-next/TUD/p2tp/trunk@609 e16421f0-f15b-0410-abcd-98678b794739 --- diff --git a/bins.cpp b/bins.cpp index cfca3a2..3641138 100644 --- a/bins.cpp +++ b/bins.cpp @@ -259,7 +259,7 @@ uint16_t bins::get (bin64_t bin) { // i.towards(bin); //printf("at %i ",i.half); //dump("get made"); - return *i; // deep cell is never 0xffff or 0x0000 + return *i; // deep cell is never 0xffff or 0x0000; FIXME: API caveat } @@ -422,13 +422,13 @@ uint64_t bins::seq_length () { } -bool bins::is_empty (bin64_t range) { +bool bins::is_solid (bin64_t range, fill_t val) { if (range==bin64_t::ALL) - return !deep(0) && !halves[0]; + return !deep(0) && (is_mixed(val) || halves[0]==val); iterator i(this,range,false); while ( i.pos!=range && (i.deep() || !i.solid()) ) i.towards(range); - return !i.deep() && *i==EMPTY; + return i.solid() && (is_mixed(val) || *i==val); } diff --git a/bins.h b/bins.h index 8275c73..5a8debd 100644 --- a/bins.h +++ b/bins.h @@ -14,7 +14,7 @@ class bins { public: - typedef enum { FILLED=0xffff, EMPTY=0x0000 } fill_t; + typedef enum { FILLED=0xffff, EMPTY=0x0000, MIXED=0x5555 } fill_t; static const int NOJOIN; bins(); @@ -46,11 +46,14 @@ public: uint64_t mass (); - bool is_empty (bin64_t range=bin64_t::ALL) ; + bool is_solid (bin64_t range=bin64_t::ALL, fill_t val=MIXED) ; + bool is_empty (bin64_t range=bin64_t::ALL) { return is_solid(range,EMPTY); } + bool is_filled (bin64_t range=bin64_t::ALL) { return is_solid(range,FILLED); } void clear (); static bool is_mixed (uint16_t val) { return val!=EMPTY && val!=FILLED; } + static bool is_solid (uint16_t val) { return val==EMPTY || val==FILLED; } void twist (uint64_t mask); @@ -126,8 +129,7 @@ public: ~iterator(); bool deep () { return host->deep(half); } bool solid () { - return !deep() && (host->halves[half]==bins::FILLED || - host->halves[half]==bins::EMPTY); + return !deep() && bins::is_solid(host->halves[half]); } void sibling () { half^=1; pos=pos.sibling(); } bool end () { return half==1; } diff --git a/do_tests.sh b/do_tests.sh index d87ec38..f02a6cc 100755 --- a/do_tests.sh +++ b/do_tests.sh @@ -1,6 +1,6 @@ #!/bin/bash -for tst in `ls tests/*test`; do +for tst in `ls tests/*test | grep -v ledbat`; do if echo $tst; $tst > $tst.log; then echo $tst OK else diff --git a/exec/bingrep.cpp b/exec/bingrep.cpp new file mode 100644 index 0000000..7ed2c1c --- /dev/null +++ b/exec/bingrep.cpp @@ -0,0 +1,20 @@ +#include +#include +#include "bin64.h" + +int main (int argn, char** args) { + int lr; + unsigned long long of; + sscanf(args[1],"%i,%lli",&lr,&of); + bin64_t target(lr,of); + char line[1024]; + while (gets(line)) { + char* br = strchr(line,'('); + if (br && 2==sscanf(br,"(%i,%lli)",&lr,&of)) { + bin64_t found(lr,of); + if ( found.within(target) || target.within(found)) + printf("%s\n",line); + } + } + return 0; +} diff --git a/p2tp.h b/p2tp.h index ebef7bc..ce5d029 100644 --- a/p2tp.h +++ b/p2tp.h @@ -306,10 +306,9 @@ namespace p2tp { } /** Get a request for one packet from the queue of peer's requests. */ bin64_t DequeueHint(); - void ClearStaleDataOut (); + void CleanDataOut (bin64_t acks_pos=bin64_t::NONE); void CleanStaleHintOut(); void CleanHintOut(bin64_t pos); - void CleanFulfilledDataOut(bin64_t pos); void Schedule(tint send_time); static PeerSelector* peer_selector; diff --git a/sendrecv.cpp b/sendrecv.cpp index da3fe14..bb62d37 100644 --- a/sendrecv.cpp +++ b/sendrecv.cpp @@ -87,23 +87,6 @@ void Channel::AddHandshake (Datagram& dgram) { } -void Channel::ClearStaleDataOut() { - int oldsize = data_out_.size(); - tint timeout = NOW - max( rtt_avg_-dev_avg_*4, 500*TINT_MSEC ); - while ( data_out_.size() && data_out_.front().time < timeout && - ack_in_.get(data_out_.front().bin)==bins::EMPTY ) { - dprintf("%s #%i Tdata %s\n",tintstr(),id,data_out_.front().bin.str()); - data_out_.pop_front(); - } - if (data_out_.size()!=oldsize) { - cc_->OnAckRcvd(bin64_t::NONE); - data_out_cap_ = bin64_t::ALL; - } - while (data_out_.size() && (data_out_.front()==tintbin() || ack_in_.get(data_out_.front().bin)==bins::FILLED)) - data_out_.pop_front(); -} - - void Channel::Send () { Datagram dgram(socket_,peer()); dgram.Push32(peer_channel_id_); @@ -114,7 +97,7 @@ void Channel::Send () { if (!file().is_complete()) AddHint(dgram); AddPex(dgram); - ClearStaleDataOut(); + CleanDataOut(); data = AddData(dgram); } else { AddHandshake(dgram); @@ -329,20 +312,54 @@ bin64_t Channel::OnData (Datagram& dgram) { } -void Channel::CleanFulfilledDataOut (bin64_t ackd_pos) { - for (int i=0; i<8 && i> 3; - dev_avg_ = ( dev_avg_*3 + abs(rtt-rtt_avg_) ) >> 2; - dprintf("%s #%i rtt %lli dev %lli\n", - tintstr(),id,rtt_avg_,dev_avg_); - cc_->OnAckRcvd(data_out_[i].bin); - data_out_[i]=tintbin(); +void Channel::CleanDataOut (bin64_t ackd_pos) { + + int max_ack_off = 0; + + if (ackd_pos!=bin64_t::NONE) { + for (int i=0; i<8 && i> 3; + dev_avg_ = ( dev_avg_*3 + abs(rtt-rtt_avg_) ) >> 2; + dprintf("%s #%i rtt %lli dev %lli\n",tintstr(),id,rtt_avg_,dev_avg_); + bin64_t pos = data_out_[i].bin; + cc_->OnAckRcvd(pos); + data_out_[i]=tintbin(); + max_ack_off = i; + if (ackd_pos==pos) + break; + } + } + while (!data_out_.empty() && data_out_.front().bin==bin64_t::NONE) { + data_out_.pop_front(); + max_ack_off--; + } + static const int MAX_REORDERING = 2; // the triple-ACK principle + if (max_ack_off>MAX_REORDERING) { + while (max_ack_off && ack_in_.is_filled(data_out_.front().bin)) { + data_out_.pop_front(); + max_ack_off--; + } + while (max_ack_off>MAX_REORDERING) { + cc_->OnAckRcvd(bin64_t::NONE); + data_out_.pop_front(); + max_ack_off--; + data_out_cap_ = bin64_t::ALL; + dprintf("%s #%i Rdata %s\n",tintstr(),id,data_out_.front().bin.str()); + } + } + } + tint timeout = NOW - rtt_avg_ - 4*std::max(dev_avg_,TINT_MSEC*50); + while (!data_out_.empty() && data_out_.front().timeOnAckRcvd(bin64_t::NONE); + data_out_cap_ = bin64_t::ALL; + dprintf("%s #%i Tdata %s\n",tintstr(),id,data_out_.front().bin.str()); } - while ( data_out_.size() && ( data_out_.front()==tintbin() || - ack_in_.get(data_out_.front().bin)==bins::FILLED ) ) data_out_.pop_front(); + } + } @@ -354,7 +371,7 @@ void Channel::OnAck (Datagram& dgram) { } dprintf("%s #%i -ack %s\n",tintstr(),id,ackd_pos.str()); ack_in_.set(ackd_pos); - CleanFulfilledDataOut(ackd_pos); + CleanDataOut(ackd_pos); } diff --git a/tests/binstest2.cpp b/tests/binstest2.cpp index 36149da..7d5d2c4 100755 --- a/tests/binstest2.cpp +++ b/tests/binstest2.cpp @@ -316,6 +316,39 @@ TEST(BinsTest,SeqLength) { EXPECT_EQ(11,b.seq_length()); } +TEST(BinsTest,EmptyFilled) { + // 1112 3312 2111 .... + bins b; + + EXPECT_TRUE(b.is_empty(bin64_t::ALL)); + + b.set(bin64_t(1,0)); + b.set(bin64_t(0,2)); + b.set(bin64_t(0,6)); + b.set(bin64_t(1,5)); + b.set(bin64_t(0,9)); + + EXPECT_FALSE(b.is_empty(bin64_t::ALL)); + + EXPECT_TRUE(b.is_empty(bin64_t(2,3))); + EXPECT_FALSE(b.is_filled(bin64_t(2,3))); + EXPECT_TRUE(b.is_solid(bin64_t(2,3),bins::MIXED)); + EXPECT_TRUE(b.is_filled(bin64_t(1,0))); + EXPECT_TRUE(b.is_filled(bin64_t(1,5))); + EXPECT_FALSE(b.is_filled(bin64_t(1,3))); + + b.set(bin64_t(0,3)); + b.set(bin64_t(0,7)); + b.set(bin64_t(0,8)); + + EXPECT_TRUE(b.is_filled(bin64_t(2,0))); + EXPECT_TRUE(b.is_filled(bin64_t(2,2))); + EXPECT_FALSE(b.is_filled(bin64_t(2,1))); + + b.set(bin64_t(1,2)); + EXPECT_TRUE(b.is_filled(bin64_t(2,1))); +} + TEST(BinheapTest,Eat) { binheap b;