bins performance
authorvictor <victor@e16421f0-f15b-0410-abcd-98678b794739>
Tue, 10 Nov 2009 07:44:22 +0000 (07:44 +0000)
committervictor <victor@e16421f0-f15b-0410-abcd-98678b794739>
Tue, 10 Nov 2009 07:44:22 +0000 (07:44 +0000)
git-svn-id: https://ttuki.vtt.fi/svn/p2p-next/TUD/p2tp/trunk@520 e16421f0-f15b-0410-abcd-98678b794739

bins.cpp
bins.h
sendrecv.cpp
tests/binstest2.cpp

index ca3616f..6d0d380 100644 (file)
--- a/bins.cpp
+++ b/bins.cpp
@@ -170,6 +170,7 @@ iterator::iterator(bins* host_, bin64_t start, bool split) {
     for(int i=0; i<64; i++)
         history[i] = 1;
     pos = bin64_t(host->height,0);
+    layer_ = host->height;
     while (!start.within(pos))
         parent();
     while (pos!=start && (deep() || split))
@@ -189,9 +190,10 @@ iterator::~iterator () {
 void iterator::to (bool right) {
     if (!deep())
         host->split(half);
-    history[pos.layer()] = half; // FIXME
+    history[layer()] = half; // FIXME
     pos = pos.to(right);
-    if ( (host->twist_mask >> pos.layer()) & 1 )
+    layer_--;
+    if ( (host->twist_mask >> layer()) & 1 )
         right = !right; // twist it!
     half = (host->halves[half]<<1) + right;
 }
@@ -218,10 +220,11 @@ void bins::extend_range () {
 void iterator::parent () {
     if (!half) {
         host->extend_range();
-        history[pos.layer()+1] = 0;
+        history[layer()+1] = 0;
     }
     pos = pos.parent();
-    half = history[pos.layer()];
+    layer_++;
+    half = history[layer()];
     host->join(half);
     //host->dump("| ");
 }
@@ -231,9 +234,9 @@ bin64_t bins::find (const bin64_t range, const uint8_t layer, fill_t seek) {
     iterator i(this,range,true);
     fill_t stop = seek==EMPTY ? FILLED : EMPTY;
     while (true) {
-        while ( i.bin().layer()>layer && (i.deep() || *i!=stop) )
+        while ( i.layer()>layer && (i.deep() || *i!=stop) )
             i.left();
-        if (i.bin().layer()==layer && !i.deep() && *i==seek)
+        if (i.layer()==layer && !i.deep() && *i==seek)
             return i.bin();
         while (i.bin().is_right() && i.bin()!=range)
             i.parent();
@@ -348,8 +351,8 @@ bin64_t     bins::cover(bin64_t val) {
     iterator i(this,val,false);
     while (i.pos!=val && !i.solid())
         i.towards(val);
-    //if (!i.half && !halves[0])
-    //    return bin64_t::ALL;
+    if (!i.solid())
+        return bin64_t::NONE;
     return i.pos;
 }
 
@@ -359,19 +362,27 @@ bin64_t     bins::find_filtered
 {
     if (range==bin64_t::ALL)
         range = bin64_t ( height>filter.height ? height : filter.height, 0 );
-    iterator i(this,range,true), j(&filter,range,true);
+    iterator ti(this,range,true), fi(&filter,range,true);
     fill_t stop = seek==EMPTY ? FILLED : EMPTY;
     while (true) {
-        while ( i.bin().layer()>layer && (i.deep() || *i!=stop || j.deep() || *j!=FILLED) )
-            i.left(), j.left(); // TODO may optimize a lot here 
-        if (i.bin().layer()==layer && !i.deep() && *i==seek && *j==EMPTY)
-            return i.bin();
-        while (i.bin().is_right() && i.bin()!=range)
-            i.parent(), j.parent();
-        if (i.bin()==range)
+        while ( ti.layer()>layer ) {
+            bool go = fi.deep() ?
+                (ti.deep() || *ti!=stop)  :
+                (ti.deep() ? *fi!=FILLED : (*ti^stop)&~*fi );
+            if (go) {
+                ti.left(); fi.left();                
+            } else 
+                break;
+        }
+        //while ( i.bin().layer()>layer && (i.deep() || *i!=stop || j.deep() || *j!=FILLED) )
+        //    i.left(), j.left(); // TODO may optimize a lot here 
+        if (ti.layer()==layer && !ti.deep() && *ti==seek && *fi==EMPTY)
+            return ti.bin();
+        while (ti.bin().is_right() && ti.bin()!=range)
+            ti.parent(), fi.parent();
+        if (ti.bin()==range)
             break;
-        i.parent(), j.parent();
-        i.right(), j.right();
+        ti.sibling(), fi.sibling();
     }
     return bin64_t::NONE;    
 }
diff --git a/bins.h b/bins.h
index 6d6bd40..2e5fa0b 100644 (file)
--- a/bins.h
+++ b/bins.h
@@ -118,6 +118,7 @@ public: // rm this
     bins        *host;
     uint32_t    history[64];
     uint32_t    half;
+    uint8_t     layer_;
     bin64_t     pos;  // TODO: half[] layer bin
 public:
     iterator(bins* host, bin64_t start=0, bool split=false);
@@ -144,6 +145,7 @@ public:
     void parent() ;
     bool defined() { return !host->deep(half); }
     uint16_t& operator* () { return host->halves[half]; }
+    uint8_t layer() const { return layer_; }
 };
 
 
index cf7ec6f..7a8a5d4 100644 (file)
@@ -112,8 +112,10 @@ void       Channel::Send () {
     dgram.Push32(peer_channel_id_);
     bin64_t data = bin64_t::NONE;
     if ( is_established() ) {
+        // FIXME: seeder check
         AddAck(dgram);
-        AddHint(dgram);
+        if (!file().is_complete())
+            AddHint(dgram);
         AddPex(dgram);
         ClearStaleDataOut();
         if (cc_->MaySendData()) 
@@ -242,8 +244,7 @@ void        Channel::AddAck (Datagram& dgram) {
         // TODO bins::ANY_LAYER
         if (ack==bin64_t::NONE)
             break;
-        while (file().ack_out().get(ack.parent())==bins::FILLED)
-            ack = ack.parent();
+        ack = file().ack_out().cover(ack);
         ack_out_.set(ack);
         dgram.Push8(P2TP_ACK);
         dgram.Push32(ack);
index 99b7078..f50e1ee 100755 (executable)
@@ -234,6 +234,8 @@ TEST(BinsTest, Cover) {
     b.set(bin64_t(2,0));
     b.set(bin64_t(4,1));
     EXPECT_EQ(bin64_t(4,1),b.cover(bin64_t(0,30)));
+    EXPECT_EQ(bin64_t(2,0),b.cover(bin64_t(0,3)));
+    EXPECT_EQ(bin64_t(2,0),b.cover(bin64_t(2,0)));
     //bins c;
     //EXPECT_EQ(bin64_t::ALL,b.cover(bin64_t(0,30)));