#include <algorithm>
#include <cstdio>
#include <cstring>
+#include <cstdlib>
#include <limits>
#include <numeric>
#include <utility>
-#include "binmap.h"
+#include "bins.h"
#undef max
assert( free_top == 1 );
}
+binmap_t::~binmap_t () {
+ if (cells)
+ free(cells);
+}
+
void binmap_t::twist (uint64_t mask) {
while ( (1<<height) <= mask )
extend_range();
}
-bin64_t iterator::next (bool need_solid) {
- assert(!deep());
+bin64_t iterator::next (bool stop_undeep, bool stop_solid, uint8_t stop_layer) {
while (pos.is_right())
parent();
- //parent();
- //if (need_solid ? !solid() : deep())
- // right();
sibling();
- while (need_solid ? !solid() : deep())
+ while ( (!stop_undeep || deep()) &&
+ (!stop_solid || (deep() || !solid()) ) &&
+ (layer()>stop_layer) )
left();
return pos;
}
while (!i.end()) {
if (*i==binmap_t::FILLED)
ret += i.pos.width();
- i.next(true);
+ i.next_solid();
}
return ret;
}
}
}
- i.next(true);
+ i.next_solid();
}
while (
fi.deep() ?
(ti.deep() || *ti!=stop) :
- (ti.deep() ? *fi!=FILLED : ( ((*ti^stop)&~*fi) && (*ti!=seek || *fi!=EMPTY) ) )
+ (ti.deep() ? *fi!=FILLED :
+ ( ((*ti^stop)&~*fi) && (*ti!=seek || *fi!=EMPTY) ) )
)
{
ti.left(); fi.left();
return bin64_t::NONE;
}
-// FIXME unite with remove(); do bitwise()
-void binmap_t::copy_range (binmap_t& origin, bin64_t range) {
+void binmap_t::range_op (binmap_t& mask, bin64_t range, bin_op_t op) {
if (range==bin64_t::ALL)
- range = bin64_t ( height>origin.height ? height : origin.height, 0 );
- iterator zis(this,range,true), zat(&origin,range,true);
+ range = bin64_t ( height>mask.height ? height : mask.height, 0 );
+ iterator zis(this,range,true), zat(&mask,range,true);
while (zis.pos.within(range)) {
while (zis.deep() || zat.deep()) {
zis.left(); zat.left();
}
-
- *zis = *zat;
+
+ switch (op) {
+ case REMOVE_OP:
+ *zis &= ~*zat;
+ break;
+ case AND_OP:
+ *zis &= *zat;
+ break;
+ case COPY_OP:
+ *zis = *zat;
+ break;
+ case OR_OP:
+ *zis |= *zat;
+ }
while (zis.pos.is_right()) {
zis.parent(); zat.parent();
}
uint64_t binmap_t::seq_length () {
- iterator i(this);
+ iterator i(this,bin64_t(height,0));
if (!i.deep() && *i==FILLED)
return i.pos.width();
while (!i.pos.is_base()) {
}
+void binmap_t::map16 (uint16_t* target, bin64_t range) {
+ iterator lead(this,range,true);
+ if (!lead.deep()) {
+ *target = *lead;
+ return;
+ }
+ lead.left();
+ lead.left();
+ lead.left();
+ lead.left();
+ uint16_t shift = 1;
+ for(int i=0; i<16; i++) {
+ if (!lead.deep() && *lead==FILLED)
+ *target |= shift;
+ shift<<=1;
+ lead.next(false,false,range.layer()-4);
+ }
+}
+
+
+void binmap_t::to_coarse_bitmap (uint16_t* bits, bin64_t range, uint8_t height) {
+ //assert(range.layer()-height>=4);
+ int height16 = range.layer()-height-4;
+ int wordwidth = height16 > 0 ? (1 << height16) : 1;
+ int offset = height16 > 0 ? (range.offset() << height16) :
+ (range.offset() >> -height16);
+ for(int i=0; i<wordwidth; i++)
+ map16(bits+i,bin64_t(height+4,offset+i));
+}
+
+
binheap::binheap() {
size_ = 32;
heap_ = (bin64_t*) malloc(size_*sizeof(bin64_t));
binheap::~binheap() {
free(heap_);
}
+