From: victor Date: Sun, 25 Oct 2009 16:52:48 +0000 (+0000) Subject: bins::find_filtered, bins::set_range X-Git-Url: http://p2p-next.cs.pub.ro/gitweb/?a=commitdiff_plain;h=6eeeb425ae152cfe62aeb0eb9204d08f091e94f1;p=swift-upb.git bins::find_filtered, bins::set_range git-svn-id: https://ttuki.vtt.fi/svn/p2p-next/TUD/p2tp/trunk@473 e16421f0-f15b-0410-abcd-98678b794739 --- diff --git a/bins.cpp b/bins.cpp index 6686655..f5a32b6 100644 --- a/bins.cpp +++ b/bins.cpp @@ -317,6 +317,42 @@ void bins::remove (bins& b) { } +bin64_t bins::find_filtered + (bins& filter, const bin64_t range, const uint8_t layer, fill_t seek) +{ + iterator i(this,range,true), j(&filter,range,true); + fill_t stop = seek==EMPTY ? FILLED : EMPTY; + while (true) { + while ( i.bin().layer()>layer && (i.deep() || *i!=stop || j.deep() || *j!=EMPTY) ) + 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) + break; + i.parent(), j.parent(); + i.right(), j.right(); + } + return bin64_t::NONE; +} + +void bins::set_range (bins& origin, bin64_t range) { // FIXME unite with remove(); do bitwise() + iterator zis(this,range,true), zat(&origin,range,true); + while (zis.pos.within(range)) { + while (zis.deep() || zat.deep()) { + zis.left(); zat.left(); + } + + *zis = *zat; + + while (zis.pos.is_right()) { + zis.parent(); zat.parent(); + } + zis.sibling(); zat.sibling(); + } +} + binheap::binheap() { size_ = 32; heap_ = (bin64_t*) malloc(size_*sizeof(bin64_t)); diff --git a/bins.h b/bins.h index dba5b8c..86b5d04 100644 --- a/bins.h +++ b/bins.h @@ -26,8 +26,13 @@ public: void set (bin64_t bin, fill_t val=FILLED); + void set_range (bins& origin, bin64_t range); + bin64_t find (const bin64_t range, const uint8_t layer, fill_t seek=EMPTY) ; + bin64_t find_filtered + (bins& filter, const bin64_t range, const uint8_t layer, fill_t seek=EMPTY) ; + void remove (bins& b); void dump(const char* note); @@ -38,6 +43,8 @@ public: bool empty () const { return !deep(0) && !halves[0]; } + static bool is_mixed (uint16_t val) { return val!=EMPTY && val!=FILLED; } + private: /** Every 16th uint32 is a flag field denoting whether diff --git a/tests/binstest2.cpp b/tests/binstest2.cpp index e75b0cf..bbe7796 100755 --- a/tests/binstest2.cpp +++ b/tests/binstest2.cpp @@ -212,6 +212,38 @@ TEST(BinsTest,Remove) { } +TEST(BinsTest,FindFiltered) { + + bins data, filter; + data.set(bin64_t(2,0)); + data.set(bin64_t(2,2)); + data.set(bin64_t(1,7)); + filter.set(bin64_t(2,1)); + filter.set(bin64_t(1,4)); + filter.set(bin64_t(0,13)); + + bin64_t x = data.find_filtered(filter,bin64_t(4,0),0); + EXPECT_EQ(bin64_t(0,12),x); + +} + +TEST(BinsTest,SetRange) { + bins data, add; + data.set(bin64_t(2,0)); + data.set(bin64_t(2,2)); + data.set(bin64_t(1,7)); + add.set(bin64_t(2,1)); + add.set(bin64_t(1,4)); + add.set(bin64_t(0,13)); + add.set(bin64_t(5,118)); + data.set_range(add, bin64_t(3,0)); + EXPECT_TRUE(bins::is_mixed(data.get(bin64_t(3,0)))); + EXPECT_EQ(bins::EMPTY,data.get(bin64_t(2,0))); + EXPECT_EQ(bins::FILLED,data.get(bin64_t(2,1))); + EXPECT_EQ(bins::EMPTY,data.get(bin64_t(1,6))); + EXPECT_EQ(bins::FILLED,data.get(bin64_t(1,7))); +} + TEST(BinheapTest,Eat) { binheap b;