3 * bin numbers (binaty tree enumeration/navigation)
5 * Created by Victor Grishchenko on ??/09/09 in Karlovy Vary
6 * Copyright 2009 Delft University of Technology. All rights reserved.
13 #include "compat/stdint.h"
19 /** Numbering for (aligned) logarithmical bins.
20 Each number stands for an interval
21 [o*2^l,(o+1)*2^l), where l is the layer and o
23 Bin numbers in the tail111 encoding: meaningless
24 bits in the tail are set to 0111...11, while the
25 head denotes the offset. Thus, 1101 is the bin
26 at layer 1, offset 3 (i.e. fourth).
27 Obviously, bins form a binary tree. All navigation
28 is made in terms of binary trees: left, right,
33 static const uint64_t NONE;
34 static const uint64_t ALL;
35 static const uint32_t NONE32;
36 static const uint32_t ALL32;
38 bin64_t() : v(NONE) {}
39 bin64_t(const bin64_t&b) : v(b.v) {}
40 bin64_t(const uint32_t val) ;
41 bin64_t(const uint64_t val) : v(val) {}
42 bin64_t(uint8_t layer, uint64_t offset) :
43 v( (offset<<(layer+1)) | ((1ULL<<layer)-1) ) {}
44 operator uint64_t () const { return v; }
45 uint32_t to32() const ;
46 bool operator == (bin64_t& b) const { return v==b.v; }
48 static bin64_t none () { return NONE; }
49 static bin64_t all () { return ALL; }
51 uint64_t tail_bits () const {
55 uint64_t tail_bit () const {
56 return (tail_bits()+1)>>1;
59 /** Get the sibling interval in the binary tree. */
60 bin64_t sibling () const {
61 // if (v==ALL) return NONE;
62 return bin64_t(v^(tail_bit()<<1));
67 uint64_t tail = ((v^(v+1))+1)>>1;
68 if (tail>0xffffffffULL) {
72 // courtesy of Sean Eron Anderson
73 // http://graphics.stanford.edu/~seander/bithacks.html
74 static const int DeBRUIJN[32] = {
75 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
76 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
78 r += DeBRUIJN[((uint32_t)(tail*0x077CB531U))>>27];
82 /** Get the bin's offset in base units, i.e. 4 for (1,2). */
83 uint64_t base_offset () const {
84 return (v&~(tail_bits()))>>1;
87 /** Get the bin's offset at its own layer, e.g. 2 for (1,2). */
88 uint64_t offset () const {
89 return v >> (layer()+1);
92 /** Get a child bin; either right(true) or left(false). */
93 bin64_t to (bool right) const {
96 uint64_t tb = ((tail_bits() >> 1) + 1) >> 1;
98 return bin64_t(v + tb);
99 return bin64_t(v ^ tb);
102 /** Get the left child bin. */
103 bin64_t left () const {
107 /** Get the right child bin. */
108 bin64_t right () const {
112 /** Check whether this bin is within the specified bin. */
113 bool within (bin64_t maybe_asc) {
114 if (maybe_asc==bin64_t::NONE)
116 uint64_t short_tail = maybe_asc.tail_bits();
117 if (tail_bits()>short_tail)
119 return (v&~short_tail) == (maybe_asc.v&~short_tail) ;
122 /** Left or right, depending whether the destination is. */
123 bin64_t towards (bin64_t dest) const {
124 if (!dest.within(*this))
126 if (dest.within(left()))
132 /** Twist/untwist a bin number according to the mask. */
133 bin64_t twisted (uint64_t mask) const {
134 return bin64_t( v ^ ((mask<<1)&~tail_bits()) );
137 /** Get the paretn bin. */
138 bin64_t parent () const {
139 uint64_t tbs = tail_bits(), ntbs = (tbs+1)|tbs;
140 return bin64_t( (v&~ntbs) | tbs );
143 /** Check whether this bin is the left sibling. */
144 bool is_left () const {
145 uint64_t tb = tail_bit();
149 /** Check whether this bin is the right sibling. */
150 bool is_right() const { return !is_left(); }
152 /** Get the leftmost basic bin within this bin. */
153 bin64_t left_foot () const {
156 return bin64_t(0,base_offset());
159 /** Whether layer is 0. */
160 bool is_base () const {
164 /** Depth-first in-order binary tree traversal. */
165 bin64_t next_dfsio (uint8_t floor);
167 /** Return the number of basic bins within this bin. */
168 bin64_t width () const {
169 return (tail_bits()+1)>>1;
172 /** Get the standard-form null-terminated string
173 representation of this bin, e.g. "(2,1)".
174 The string is statically allocated, must
175 not be reused or released. */
176 const char* str () const;
178 /** The array must have 64 cells, as it is the max
179 number of peaks possible +1 (and there are no reason
180 to assume there will be less in any given case. */
181 static int peaks (uint64_t length, bin64_t* peaks) ;
192 0 10 100 110 1000 1010 1100 1110
199 once we have peak hashes, this struture is more natural than bin-v1