5 * Created by Victor Grishchenko on 3/28/09.
6 * Copyright 2009 Delft University of Technology. All rights reserved.
12 #include <gtest/gtest.h>
14 /** A binmap covering 2^64 range. Complexity limit: 100+200LoC */
18 typedef enum { FILLED=0xffff, EMPTY=0x0000 } fill_t;
19 static const int NOJOIN;
25 uint16_t get (bin64_t bin);
27 void set (bin64_t bin, fill_t val=FILLED);
29 bin64_t find (const bin64_t range, const uint8_t layer, fill_t seek=EMPTY) ;
31 void remove (bins& b);
33 void dump(const char* note);
35 uint64_t* get_stripes (int& count);
37 uint32_t size() { return cells_allocated; }
39 bool empty () const { return !deep(0) && !halves[0]; }
43 /** Every 16th uint32 is a flag field denoting whether
44 previous 30 halves (in 15 cells) are deep or not.
45 The last bit is used as a fill-flag.
46 Free cells have a value of 0; neither deep nor flat
47 cell could have a value of 0 except for the root
48 cell in case the binmap is all-0. */
53 uint32_t blocks_allocated;
54 uint32_t cells_allocated;
60 static const uint8_t SPLIT[16];
61 static const uint8_t JOIN[16];
63 bool deep(uint32_t half) const {
64 return cells[(half>>1)|0xf] & (1<<(half&0x1f));
66 void mark(uint32_t half) {
67 cells[(half>>1)|0xf] |= (1<<(half&0x1f));
69 void unmark(uint32_t half) {
70 cells[(half>>1)|0xf] &= ~(1<<(half&0x1f));
75 uint16_t alloc_cell ();
76 void free_cell (uint16_t cell);
78 /** Join the cell this half is pointing to
79 (in other words, flatten the half). */
80 bool join(uint32_t half) ;
82 /** Make the half deep. */
83 void split(uint32_t half) ;
85 static uint32_t split16to32(uint16_t half);
86 static int join32to16(uint32_t cell);
88 friend class iterator;
89 FRIEND_TEST(BinsTest,Routines);
93 /** Iterates over bins; for deep halves, bin==half.
94 For flat halves, bin is a range of bits in a half.
95 Iterator may split cells if needed.
96 Value is either undefined (deep cell, mixed cell)
101 uint32_t history[64];
103 bin64_t pos; // TODO: half[] layer bin
105 iterator(bins* host, bin64_t start=0, bool split=false);
107 bool deep () { return host->deep(half); }
109 return !deep() && (host->halves[half]==bins::FILLED ||
110 host->halves[half]==bins::EMPTY);
112 void sibling () { half^=1; pos=pos.sibling(); }
113 bool end () { return half==1; }
114 void to (bool right);
116 void right() {to(1);}
117 /** Move to the next defined (non-deep, flat) cell.
118 If solid==true, move to a solid (0xffff/0x0) cell. */
119 bin64_t next (bool solid=false);
120 bin64_t bin() { return pos; }
121 void towards(bin64_t bin) {
122 bin64_t next = pos.towards(bin);
123 assert(next!=bin64_t::NONE);
127 bool defined() { return !host->deep(half); }
128 uint16_t& operator* () { return host->halves[half]; }
140 bool empty() const { return !filled_; }