bit_vector.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. #include "bit_vector.h"
  2. /* ================================================================ */
  3. /* Bit vector class method definitions */
  4. /* ================================================================ */
  5. void BitVector::reset()
  6. {
  7. for (UInt32 i = 0; i < VECTOR_SIZE; i++)
  8. m_words[i] = 0;
  9. m_size = 0;
  10. m_last_pos = -1;
  11. }
  12. /*
  13. * reset "find". a subsequent call to find()
  14. * will return the first set bit.
  15. */
  16. bool BitVector::resetFind()
  17. {
  18. m_last_pos = -1;
  19. return true; //maybe do something with this?
  20. }
  21. /*
  22. * find() will find the next set bit.
  23. * the BitVector class remembers the last found set bit,
  24. * so that subsequent calls to find() will start off from
  25. * the last found set bit (i.e, just keep calling find()
  26. * to iterate through the set bits in BitVector.
  27. * Call "resetFind()" to start from the beginning again.
  28. * However, if you get to the end of the BitVector and
  29. * keep calling find(), it will wrap around and start over!
  30. * (b/c if you find no more set bits last_pos is set to -1)
  31. */
  32. SInt32 BitVector::find()
  33. {
  34. int windex = (m_last_pos == -1) ? 0 : m_last_pos >> 6; //divide by 64
  35. int word_count = (m_capacity + 64 -1) >> 6;
  36. //walk through bitVector one word at a time
  37. //return when we find a set bit (whose pos is > last_pos)
  38. while (windex < word_count)
  39. {
  40. UInt64 word64 = m_words[windex];
  41. if (word64 != 0)
  42. {
  43. UInt32 words32[2];
  44. words32[1] = (word64 >> 32) ;
  45. words32[0] = word64 & 0xFFFFFFFF;
  46. for (int i = 0; i < 2; i++)
  47. {
  48. if (words32[i] != 0)
  49. {
  50. UInt16 words16[2];
  51. words16[1] = (words32[i] >> 16);
  52. words16[0] = words32[i] & 0xFFFF;
  53. for (int j = 0; j < 2; j++)
  54. {
  55. if (words16[j] != 0)
  56. {
  57. UInt8 words8[2];
  58. words8[1] = (words16[j] >> 8);
  59. words8[0] = words16[j] & 0xFF;
  60. for (int k = 0; k < 2; k++)
  61. {
  62. if (words8[k] != 0)
  63. {
  64. for (int l = 0; l < 8; l++)
  65. {
  66. //loop through byte and look for set bit
  67. if (bTestBit(words8[k], l))
  68. {
  69. int return_pos = 64*windex + 32*i + 16*j + 8*k + l;
  70. if (return_pos > m_last_pos)
  71. {
  72. m_last_pos = return_pos;
  73. return return_pos;
  74. }
  75. }
  76. }
  77. }
  78. }
  79. }
  80. }
  81. }
  82. }
  83. }
  84. ++windex;
  85. }
  86. //if we get here, there is no set bit in bitVector (after the last_pos that is)
  87. m_last_pos = -1;
  88. return -1;
  89. }
  90. //helper function to "find", accepts a byte
  91. //and a bit location and returns true if bit is set
  92. bool BitVector::bTestBit(UInt8 byte_word, UInt32 bit)
  93. {
  94. assert(bit < 8);
  95. // UInt8 shift = bit & 0xF; i don't think this is necessary b/c of assert
  96. UInt8 one = 1;
  97. UInt8 mask = one << bit;
  98. return (byte_word & mask) ? true : false;
  99. }
  100. bool BitVector::at(UInt32 bit)
  101. {
  102. assert(bit < m_capacity);
  103. UInt32 index = bit >> 6;
  104. UInt64 shift = bit & 63;
  105. UInt64 one = 1;
  106. UInt64 mask = one << shift;
  107. return (m_words[index] & mask) ? true : false;
  108. }
  109. void BitVector::set(UInt32 bit)
  110. {
  111. assert(bit < m_capacity);
  112. UInt32 index = bit >> 6;
  113. UInt64 shift = bit & 63;
  114. UInt64 one = 1;
  115. UInt64 mask = one << shift;
  116. if (! at(bit))
  117. {
  118. m_words[index] |= mask;
  119. m_size ++;
  120. }
  121. }
  122. void BitVector::clear(UInt32 bit)
  123. {
  124. assert(bit < m_capacity);
  125. UInt32 index = bit >> 6;
  126. UInt64 shift = bit & 63;
  127. UInt64 one = 1;
  128. UInt64 mask = ~(one << shift);
  129. if (at(bit))
  130. {
  131. m_words[index] &= mask;
  132. m_size --;
  133. }
  134. }
  135. #if BITVECT_DEBUG
  136. void BitVector::set(const BitVector& vec2)
  137. {
  138. assert(m_capacity == vec2.m_capacity);
  139. for (UInt32 i = 0; i < VECTOR_SIZE; i++)
  140. words[i] |= vec2.m_words[i];
  141. }
  142. void BitVector::clear(const BitVector& vec2)
  143. {
  144. assert(m_capacity == vec2.m_capacity);
  145. for (UInt32 i = 0; i < VECTOR_SIZE; i++)
  146. words[i] &= ~vec2.m_words[i];
  147. }
  148. bool BitVector::test(const BitVector& vec2)
  149. {
  150. assert(vec2.m_capacity == m_capacity);
  151. for (UInt32 i = 0; i < VECTOR_SIZE; i++)
  152. {
  153. if (vec2.m_words[i] & m_words[i])
  154. return true;
  155. }
  156. return false;
  157. }
  158. void BitVector::debug()
  159. {
  160. assert(m_capacity > 68);
  161. set(66);
  162. cout << "set(66) -> " << at(66) << endl;
  163. clear(66);
  164. cout << "clear(66) -> " << at(66) << endl;
  165. set(66);
  166. set(68);
  167. BitVector vec2(m_capacity);
  168. vec2.set(44);
  169. cout << "test( (1<<66 | 1<<68), (1<<44) ) -> " << test(vec2) << endl;
  170. vec2.set(66);
  171. cout << "test( (1<<66 | 1<<68), (1<<66) | (1<<44) ) -> "
  172. << test(vec2) << endl;
  173. clear(vec2);
  174. cout << "test( (1<<68), (1<<66) | (1<<44) ) -> " << test(vec2)
  175. << endl;
  176. cout << "at(66) = " << at(66) << "; at(68) = " << at(68) << endl;
  177. cout << endl;
  178. //reset();
  179. }
  180. #endif