bins::find_filtered, bins::set_range
authorvictor <victor@e16421f0-f15b-0410-abcd-98678b794739>
Sun, 25 Oct 2009 16:52:48 +0000 (16:52 +0000)
committervictor <victor@e16421f0-f15b-0410-abcd-98678b794739>
Sun, 25 Oct 2009 16:52:48 +0000 (16:52 +0000)
git-svn-id: https://ttuki.vtt.fi/svn/p2p-next/TUD/p2tp/trunk@473 e16421f0-f15b-0410-abcd-98678b794739

bins.cpp
bins.h
tests/binstest2.cpp

index 6686655..f5a32b6 100644 (file)
--- 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 (file)
--- 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
index e75b0cf..bbe7796 100755 (executable)
@@ -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;