From: victor Date: Sun, 25 Oct 2009 08:26:26 +0000 (+0000) Subject: binheap X-Git-Url: http://p2p-next.cs.pub.ro/gitweb/?a=commitdiff_plain;h=6699c018a2d9b7cec6e566fc1ccad048d2a2bae6;p=swift-upb.git binheap git-svn-id: https://ttuki.vtt.fi/svn/p2p-next/TUD/p2tp/trunk@471 e16421f0-f15b-0410-abcd-98678b794739 --- diff --git a/bins.cpp b/bins.cpp index f546982..6686655 100644 --- a/bins.cpp +++ b/bins.cpp @@ -314,4 +314,61 @@ void bins::remove (bins& b) { } zis.sibling(); zat.sibling(); } -} \ No newline at end of file +} + + +binheap::binheap() { + size_ = 32; + heap_ = (bin64_t*) malloc(size_*sizeof(bin64_t)); + filled_ = 0; +} + +bool bincomp (const bin64_t& a, const bin64_t& b) { + register uint64_t ab = a.base_offset(), bb = b.base_offset(); + if (ab==bb) + return a.tail_bit() < b.tail_bit(); + else + return ab > bb; +} + +bool bincomp_rev (const bin64_t& a, const bin64_t& b) { + register uint64_t ab = a.base_offset(), bb = b.base_offset(); + if (ab==bb) + return a.tail_bit() > b.tail_bit(); + else + return ab < bb; +} + +bin64_t binheap::pop() { + if (!filled_) + return bin64_t::NONE; + bin64_t ret = heap_[0]; + std::pop_heap(heap_, heap_+filled_--,bincomp); + while (filled_ && heap_[0].within(ret)) + std::pop_heap(heap_, heap_+filled_--,bincomp); + return ret; +} + +void binheap::extend() { + std::sort(heap_,heap_+filled_,bincomp_rev); + int solid = 0; + for(int i=1; isize_) { + size_ <<= 1; + heap_ = (bin64_t*) realloc(heap_,size_*sizeof(bin64_t)); + } +} + +void binheap::push(bin64_t val) { + if (filled_==size_) + extend(); + heap_[filled_++] = val; + std::push_heap(heap_, heap_+filled_,bincomp); +} + +binheap::~binheap() { + free(heap_); +} diff --git a/bins.h b/bins.h index e1d9130..dba5b8c 100644 --- a/bins.h +++ b/bins.h @@ -128,4 +128,19 @@ public: uint16_t& operator* () { return host->halves[half]; } }; + +class binheap { + bin64_t *heap_; + uint32_t filled_; + uint32_t size_; +public: + binheap(); + bin64_t pop(); + void push(bin64_t); + bool empty() const { return !filled_; } + void extend(); + ~binheap(); +}; + + #endif diff --git a/tests/binstest2.cpp b/tests/binstest2.cpp index a3fadfb..e75b0cf 100755 --- a/tests/binstest2.cpp +++ b/tests/binstest2.cpp @@ -212,6 +212,28 @@ TEST(BinsTest,Remove) { } +TEST(BinheapTest,Eat) { + + binheap b; + b.push(bin64_t(0,1)); + b.push(bin64_t(0,3)); + b.push(bin64_t(2,0)); + b.push(bin64_t(2,4)); + + EXPECT_EQ(bin64_t(2,0),b.pop()); + EXPECT_EQ(bin64_t(2,4),b.pop()); + EXPECT_EQ(bin64_t::none(),b.pop()); + + for (int i=0; i<64; i++) { + b.push(bin64_t(0,i)); + } + b.push(bin64_t(5,0)); + EXPECT_EQ(bin64_t(5,0),b.pop()); + for (int i=32; i<64; i++) + EXPECT_EQ(bin64_t(0,i),b.pop()); + +} + /*TEST(BinsTest,AddSub) { bins b; b|=15;