From: victor Date: Tue, 10 Nov 2009 07:44:22 +0000 (+0000) Subject: bins performance X-Git-Url: http://p2p-next.cs.pub.ro/gitweb/?a=commitdiff_plain;h=a4a554a469ce8d916f2489a8402ef2295223bb3c;p=swift-upb.git bins performance git-svn-id: https://ttuki.vtt.fi/svn/p2p-next/TUD/p2tp/trunk@520 e16421f0-f15b-0410-abcd-98678b794739 --- diff --git a/bins.cpp b/bins.cpp index ca3616f..6d0d380 100644 --- 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 --- 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_; } }; diff --git a/sendrecv.cpp b/sendrecv.cpp index cf7ec6f..7a8a5d4 100644 --- a/sendrecv.cpp +++ b/sendrecv.cpp @@ -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); diff --git a/tests/binstest2.cpp b/tests/binstest2.cpp index 99b7078..f50e1ee 100755 --- a/tests/binstest2.cpp +++ b/tests/binstest2.cpp @@ -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)));