hint_out_ to bins
authorvictor <victor@e16421f0-f15b-0410-abcd-98678b794739>
Wed, 28 Oct 2009 14:27:52 +0000 (14:27 +0000)
committervictor <victor@e16421f0-f15b-0410-abcd-98678b794739>
Wed, 28 Oct 2009 14:27:52 +0000 (14:27 +0000)
git-svn-id: https://ttuki.vtt.fi/svn/p2p-next/TUD/p2tp/trunk@488 e16421f0-f15b-0410-abcd-98678b794739

bins.cpp
bins.h
ext/seq_picker.cpp
p2tp.cpp
p2tp.h
sendrecv.cpp
tests/binstest2.cpp

index 3dac225..cf53054 100644 (file)
--- a/bins.cpp
+++ b/bins.cpp
@@ -250,6 +250,25 @@ uint16_t bins::get (bin64_t bin) {
 }
 
 
+void bins::clear () {
+    set(bin64_t(height,0),EMPTY);
+}
+
+
+uint64_t bins::mass () {
+    iterator i(this,bin64_t(0,0),false);
+    uint64_t ret = 0;
+    while (!i.solid())
+        i.left();
+    while (!i.end()) {
+        if (*i==bins::FILLED)
+            ret += i.pos.width();
+        i.next(true);
+    }
+    return ret;
+}
+
+
 void bins::set (bin64_t bin, fill_t val) {
     assert(val==FILLED || val==EMPTY);
     iterator i(this,bin,false);
diff --git a/bins.h b/bins.h
index 919f893..2f613cc 100644 (file)
--- a/bins.h
+++ b/bins.h
@@ -42,8 +42,12 @@ public:
     uint32_t    size() { return cells_allocated; }
     
     bin64_t     cover(bin64_t val);
+
+    uint64_t    mass ();
     
-    bool        empty () const { return !deep(0) && !halves[0]; }
+    bool        is_empty () const { return !deep(0) && !halves[0]; }
+
+    void        clear ();
     
     static bool is_mixed (uint16_t val) { return val!=EMPTY && val!=FILLED; }
     
index eae0525..cc8a782 100644 (file)
@@ -46,8 +46,8 @@ public:
         ack_hint_out_.set(b,bins::FILLED);
     }
     
-    virtual void    Expired (bin64_t b) {
-        ack_hint_out_.copy_range(file_->ack_out(),b);
+    virtual void    Expired (bins& b) {
+        ack_hint_out_.remove(b);
     }
     
-};
\ No newline at end of file
+};
index e2c59fe..fce9416 100644 (file)
--- a/p2tp.cpp
+++ b/p2tp.cpp
@@ -38,7 +38,7 @@ PeerSelector* Channel::peer_selector = new SimpleSelector();
 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)
+    own_id_mentioned_(false), next_send_time_(0), hint_out_rotate_(0)
 {
     if (peer_==Address())
         peer_ = tracker;
diff --git a/p2tp.h b/p2tp.h
index 7f3ac0f..2867c5c 100644 (file)
--- a/p2tp.h
+++ b/p2tp.h
@@ -228,7 +228,7 @@ namespace p2tp {
     class PiecePicker {
     public:
         virtual bin64_t Pick (bins& offered, uint8_t layer) = 0;
-        virtual void    Expired (bin64_t b) = 0;
+        virtual void    Expired (bins& b) = 0;
         virtual void    Received (bin64_t b) = 0;
     };
 
@@ -312,7 +312,9 @@ namespace p2tp {
                /**     Transmit schedule: in most cases filled with the peer's hints */
                binqueue    hint_in_;
                /** Hints sent (to detect and reschedule ignored hints). */
-               tbqueue         hint_out_;
+               bins            hint_out_;
+        bins        hint_out_old_;
+        tint        hint_out_rotate_;
                /** The congestion control strategy. */
                CongestionController    *cc_;
         /** Types of messages the peer accepts. */
index 571c20b..db52e50 100644 (file)
@@ -121,30 +121,15 @@ void      Channel::Send () {
 
 void   Channel::AddHint (Datagram& dgram) {
 
-    tint hint_timeout = Datagram::now - 2*TINT_SEC;
-    while (!hint_out_.empty() && hint_out_.front().time<hint_timeout) {
-        tintbin old_hint = hint_out_.front();
-        file().picker().Expired(old_hint.bin);
-        hint_out_.pop_front();
-    }
-    // FIXME  weird weird weird
-    uint16_t state;
-    while ( !hint_out_.empty() && (state=file().ack_out().get(hint_out_.front().bin)) != bins::EMPTY ) {
-        if (state==bins::FILLED) {
-            hint_out_.pop_front();
-        } else {
-            tintbin old_hint = hint_out_.front();
-            hint_out_.pop_front();
-            old_hint.bin = old_hint.bin.right();
-            hint_out_.push_front(old_hint);
-            old_hint.bin = old_hint.bin.sibling();
-            hint_out_.push_front(old_hint);
-        }
+    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();
     }
     
-    uint64_t hinted = 0;
-    for(tbqueue::iterator i=hint_out_.begin(); i!=hint_out_.end(); i++)
-        hinted+=i->bin.width();
+    uint64_t hinted = hint_out_.mass() + hint_out_old_.mass();
     
     //float peer_cwnd = cc_->PeerBPS() * cc_->RoundTripTime() / TINT_SEC;
     
@@ -154,7 +139,7 @@ void        Channel::AddHint (Datagram& dgram) {
         bin64_t hint = file().picker().Pick(ack_in_,layer);
         
         if (hint!=bin64_t::NONE) {
-            this->hint_out_.push_back(tintbin(hint));
+            hint_out_.set(hint);
             dgram.Push8(P2TP_HINT);
             dgram.Push32(hint);
             dprintf("%s #%i +hint (%i,%lli)\n",Datagram::TimeStr(),id,hint.layer(),hint.offset());
@@ -170,7 +155,7 @@ bin64_t             Channel::AddData (Datagram& dgram) {
        bin64_t tosend = DequeueHint();
     if (tosend==bin64_t::NONE) 
         return bin64_t::NONE;
-    if (ack_in_.empty() && file().size())
+    if (ack_in_.is_empty() && file().size())
         AddPeakHashes(dgram);
     AddUncleHashes(dgram,tosend);
     uint8_t buf[1024];
@@ -252,6 +237,8 @@ bin64_t Channel::OnData (Datagram& dgram) {
     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();
 }
 
@@ -464,4 +451,4 @@ void    Channel::Loop (tint howlong) {
  
  }
  
- */
\ No newline at end of file
+ */
index 225f985..9496e8b 100755 (executable)
@@ -271,6 +271,22 @@ TEST(BinsTest,CopyRange) {
     EXPECT_EQ(bins::FILLED,data.get(bin64_t(1,7)));
 }
 
+TEST(BinsTest, Mass) {
+    bins b;
+    b.set(bin64_t(6,0),bins::FILLED);
+    b.set(bin64_t(0,0),bins::EMPTY);
+    EXPECT_EQ(63,b.mass());
+    EXPECT_FALSE(b.is_empty());
+    b.clear();
+    EXPECT_TRUE(b.is_empty());
+    EXPECT_EQ(0,b.mass());
+
+    bins b50;
+    for(int i=0; i<50; i++)
+        b50.set(bin64_t(4,i*2));
+    EXPECT_EQ(50<<4,b50.mass());
+}
+
 TEST(BinheapTest,Eat) {
     
     binheap b;