5 * Created by Victor Grishchenko on 4/1/09.
6 * Copyright 2009 Delft University of Technology. All rights reserved.
14 // make it work piece by piece
16 const uint8_t bins::SPLIT[16] =
17 {0, 3, 12, 15, 48, 51, 60, 63, 192, 195, 204, 207, 240, 243, 252, 255};
18 const uint8_t bins::JOIN[16] =
19 {0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15};
20 const int bins::NOJOIN = 0x10000;
23 void bins::extend () {
24 uint16_t nblocks = blocks_allocated ? (blocks_allocated<<1) : 1;
25 size_t had_bytes = blocks_allocated<<6;
26 size_t need_bytes = nblocks<<6;
27 cells = (uint32_t*) realloc(cells,need_bytes);
28 memset(((char*)cells)+had_bytes,0,need_bytes-had_bytes);
29 for(int b=blocks_allocated; b<nblocks; b++)
30 cells[(b<<4)|0xf] = 0x55555555; // cells are free
31 blocks_allocated = nblocks;
34 bins::bins() : height(4), blocks_allocated(0), cells(NULL),
35 ap(0), cells_allocated(0), twist_mask(0) {
37 assert(!alloc_cell());
40 void bins::twist (uint64_t mask) {
41 while ( (1<<height) <= mask )
46 bins::bins (const bins& b) : height(b.height), ap(b.ap),
47 blocks_allocated(b.blocks_allocated), cells_allocated(b.cells_allocated) {
48 size_t memsz = blocks_allocated*16*32;
49 cells = (uint32_t*) malloc(memsz);
50 memcpy(cells,b.cells,memsz);
53 void bins::dump (const char* note) {
55 for(int i=0; i<(blocks_allocated<<5); i++) {
57 printf("|%x ",halves[i]);
59 printf(">%i ",halves[i]);
61 printf("%x ",halves[i]);
68 uint32_t bins::split16to32(uint16_t halfval) {
70 for(int i=0; i<4; i++) {
72 nval |= (SPLIT[halfval&0xf])<<24;
79 int bins::join32to16(uint32_t cval) {
80 union { uint32_t i; uint8_t a[4]; } uvar;
81 uvar.i = cval & (cval>>1) & 0x55555555;
82 if ( (uvar.i|(uvar.i<<1)) != cval )
84 uvar.i = (uvar.i&0x05050505) | ((uvar.i&0x50505050U)>>3);
86 for(int i=3; i>=0; i--) {
88 res |= JOIN[uvar.a[i]];
94 void bins::split (uint32_t half) {
97 uint32_t cell = alloc_cell(), left=cell<<1, right=left+1;
98 mark(half); //cells[(half>>1)|0xf] |= 1<<(half&0x1f);
99 uint16_t halfval = halves[half];
100 uint32_t nval = split16to32(halfval);
101 halves[left] = nval&0xffff;
102 halves[right] = nval>>16;
107 bool bins::join (uint32_t half) {
108 uint32_t cellno = halves[half];
109 int left = cellno<<1, right=left+1;
110 if (deep(left) || deep(right))
112 int res = join32to16(cells[cellno]);
115 halves[half] = (uint16_t)res;
118 //cells[(half>>1)|0xf] &= ~(1<<(half&0x1f));
119 //(*childdeepcell) &= 0xffff>>1; // clean the full bit
123 void bins::free_cell (uint16_t cell) {
125 int left = cell<<1, right=left+1;
133 /** Get a free cell. */
134 uint16_t bins::alloc_cell () {
137 for(; ap<(blocks_allocated<<4); ap++) {
140 if (!cells[ap] && deep(ap<<1)) {
154 bin64_t iterator::next (bool need_solid) {
156 while (pos.is_right())
159 //if (need_solid ? !solid() : deep())
162 while (need_solid ? !solid() : deep())
168 iterator::iterator(bins* host_, bin64_t start, bool split) {
171 for(int i=0; i<64; i++)
173 pos = bin64_t(host->height,0);
174 layer_ = host->height;
175 while (!start.within(pos))
177 while (pos!=start && (deep() || split))
182 iterator::~iterator () {
183 while (half>1 && !deep())
185 // PROBLEM: may hang in the air if two iters
186 // exist simultaneously
187 // FIX: iterators are not exposed (protected)
191 void iterator::to (bool right) {
194 history[layer()] = half; // FIXME
197 if ( (host->twist_mask >> layer()) & 1 )
198 right = !right; // twist it!
199 half = (host->halves[half]<<1) + right;
203 void bins::extend_range () {
206 uint16_t newroot = alloc_cell();
207 int left = newroot<<1, right = left+1;
208 cells[newroot] = cells[0];
221 void iterator::parent () {
223 host->extend_range();
224 history[layer()+1] = 0;
228 half = history[layer()];
234 bin64_t bins::find (const bin64_t range, fill_t seek) {
235 iterator i(this,range,true);
236 fill_t stop = seek==EMPTY ? FILLED : EMPTY;
238 while ( i.deep() || (*i!=stop && *i!=seek) )
240 if (!i.deep() && *i==seek)
242 while (i.bin().is_right() && i.bin()!=range)
249 return bin64_t::NONE;
253 uint16_t bins::get (bin64_t bin) {
254 iterator i(this,bin,true);
255 //while ( i.pos!=bin &&
256 // (i.deep() || (*i!=BIN_FULL && *i!=BIN_EMPTY)) )
258 //printf("at %i ",i.half);
260 return *i; // deep cell is never 0xffff or 0x0000
264 void bins::clear () {
265 set(bin64_t(height,0),EMPTY);
269 uint64_t bins::mass () {
270 iterator i(this,bin64_t(0,0),false);
275 if (*i==bins::FILLED)
276 ret += i.pos.width();
283 void bins::set (bin64_t bin, fill_t val) {
284 assert(val==FILLED || val==EMPTY);
285 iterator i(this,bin,false);
286 while (i.bin()!=bin && (i.deep() || *i!=val))
288 if (!i.deep() && *i==val)
295 } while (i.bin().within(bin));
300 uint64_t* bins::get_stripes (int& count) {
302 uint64_t *stripes = (uint64_t*) malloc(32*8);
304 uint16_t cur = bins::EMPTY;
305 stripes[count++] = 0;
306 iterator i(this,0,false);
312 if (cur!=*i) { // new stripe
314 stripes[count++] = i.bin().base_offset();
317 stripes = (uint64_t*) realloc(stripes,size*8);
326 stripes[count++] = i.bin().base_offset();
332 void bins::remove (bins& b) {
333 uint8_t start_lr = b.height>height ? b.height : height;
334 bin64_t top(start_lr,0);
335 iterator zis(this,top), zat(&b,top);
337 while (zis.deep() || zat.deep()) {
338 zis.left(); zat.left();
343 while (zis.pos.is_right()) {
344 zis.parent(); zat.parent();
346 zis.sibling(); zat.sibling();
351 bin64_t bins::cover(bin64_t val) {
352 iterator i(this,val,false);
353 while (i.pos!=val && !i.solid())
356 return bin64_t::NONE;
361 bin64_t bins::find_filtered
362 (bins& filter, bin64_t range, fill_t seek)
364 if (range==bin64_t::ALL)
365 range = bin64_t ( height>filter.height ? height : filter.height, 0 );
366 iterator ti(this,range,true), fi(&filter,range,true);
367 fill_t stop = seek==EMPTY ? FILLED : EMPTY;
371 (ti.deep() || *ti!=stop) :
372 (ti.deep() ? *fi!=FILLED : ( ((*ti^stop)&~*fi) && (*ti!=seek || *fi!=EMPTY) ) )
375 ti.left(); fi.left();
377 if (!ti.deep() && *ti==seek && !fi.deep() && *fi==EMPTY)
379 while (ti.bin().is_right() && ti.bin()!=range)
380 ti.parent(), fi.parent();
383 ti.sibling(), fi.sibling();
385 return bin64_t::NONE;
388 // FIXME unite with remove(); do bitwise()
389 void bins::copy_range (bins& origin, bin64_t range) {
390 if (range==bin64_t::ALL)
391 range = bin64_t ( height>origin.height ? height : origin.height, 0 );
392 iterator zis(this,range,true), zat(&origin,range,true);
393 while (zis.pos.within(range)) {
394 while (zis.deep() || zat.deep()) {
395 zis.left(); zat.left();
400 while (zis.pos.is_right()) {
401 zis.parent(); zat.parent();
403 zis.sibling(); zat.sibling();
407 uint64_t bins::seq_length () {
409 if (!i.deep() && *i==FILLED)
410 return i.pos.width();
411 while (!i.pos.is_base()) {
412 if (i.deep() || *i!=FILLED)
417 return i.pos.base_offset() + (*i==FILLED ? 1 : 0);
422 heap_ = (bin64_t*) malloc(size_*sizeof(bin64_t));
426 bool bincomp (const bin64_t& a, const bin64_t& b) {
427 register uint64_t ab = a.base_offset(), bb = b.base_offset();
429 return a.tail_bit() < b.tail_bit();
434 bool bincomp_rev (const bin64_t& a, const bin64_t& b) {
435 register uint64_t ab = a.base_offset(), bb = b.base_offset();
437 return a.tail_bit() > b.tail_bit();
442 bin64_t binheap::pop() {
444 return bin64_t::NONE;
445 bin64_t ret = heap_[0];
446 std::pop_heap(heap_, heap_+filled_--,bincomp);
447 while (filled_ && heap_[0].within(ret))
448 std::pop_heap(heap_, heap_+filled_--,bincomp);
452 void binheap::extend() {
453 std::sort(heap_,heap_+filled_,bincomp_rev);
455 for(int i=1; i<filled_; i++)
456 if (!heap_[i].within(heap_[solid]))
457 heap_[++solid] = heap_[i];
459 if (2*filled_>size_) {
461 heap_ = (bin64_t*) realloc(heap_,size_*sizeof(bin64_t));
465 void binheap::push(bin64_t val) {
468 heap_[filled_++] = val;
469 std::push_heap(heap_, heap_+filled_,bincomp);
472 binheap::~binheap() {