00001 #ifndef __TREE_BIT_VECTOR__ 00002 #define __TREE_BIT_VECTOR__ 00003 //#include <values.h> 00004 #include <stdio.h> 00005 #include <stddef.h> 00006 #include "oosplay/oosplay.h" 00007 #include <assert.h> 00008 #include <gc_cpp.h> 00009 00010 //unsigned long n_changed_unions = 0; 00011 //unsigned long n_unchanged_unions = 0; 00012 00013 #define BITS_PER_LONG (sizeof(long) * 8) 00014 00015 class BitVectorMapFcn/*: public gc*/ { 00016 public: 00017 virtual void apply(unsigned i) = 0; 00018 }; 00019 00020 class CountingFcn: public BitVectorMapFcn { 00021 public: 00022 unsigned count; 00023 CountingFcn() { count = 0; } 00024 void apply(unsigned i) { ++count; } 00025 }; 00026 00027 class BitVectorChunk/*: public gc*/ { 00028 unsigned long _data; 00029 public: 00030 BitVectorChunk() { _data = 0; } 00031 int bitor_into(const BitVectorChunk &other) { 00032 unsigned long old_data = _data; 00033 _data |= other._data; 00034 return old_data != _data; 00035 } 00036 void set_bit(size_t which_bit, bool value) { 00037 assert(value); 00038 assert(which_bit < BITS_PER_LONG); 00039 _data |= (1 << which_bit); 00040 } 00041 int get_bit(size_t which_bit) { 00042 return _data & (1 << which_bit); 00043 } 00044 void print(FILE *f, int offset) { 00045 int i = 0; 00046 unsigned long d = _data; 00047 while (d != 0) { 00048 if (d & 1) { 00049 fprintf(f, "%d ", i + offset); 00050 } 00051 d >>= 1; 00052 ++i; 00053 } 00054 } 00055 void map(BitVectorMapFcn *clo, int offset) { 00056 int i = 0; 00057 unsigned long d = _data; 00058 while (d != 0) { 00059 if (d & 1) { 00060 clo->apply(i+offset); 00061 } 00062 d >>= 1; 00063 ++i; 00064 } 00065 } 00066 00067 virtual void print_stdout(int offset) { 00068 print(stdout, offset); 00069 fflush(stdout); 00070 } 00071 bool is_zero() { 00072 return _data == 0; 00073 } 00074 void set_to_zero() { 00075 _data = 0; 00076 } 00077 }; 00078 00079 typedef oosplay_node_elt<unsigned, BitVectorChunk> bit_vector_node; 00080 typedef oosplay_tree<unsigned, bit_vector_node> bit_vector_tree; 00081 00082 00083 class BitVector; 00084 00085 class OrOneNode: public IterClosure<bit_vector_node> { 00086 BitVector *_or_with; 00087 public: 00088 int changed; 00089 OrOneNode(BitVector *or_with) { _or_with = or_with; changed = 0; } 00090 virtual void apply(bit_vector_node *n); 00091 }; 00092 00093 00094 class MapOneNode: public IterClosure<bit_vector_node> { 00095 BitVectorMapFcn *_map_with; 00096 public: 00097 MapOneNode(BitVectorMapFcn *map_with) { 00098 _map_with = map_with; 00099 } 00100 void apply(bit_vector_node *n) { 00101 n->get_elt_addr()->map(_map_with, n->get_key1() * BITS_PER_LONG); 00102 } 00103 }; 00104 00105 class PrintOneNode: public IterClosure<bit_vector_node> { 00106 FILE *_f; 00107 public: 00108 PrintOneNode(FILE *f) { _f = f; } 00109 virtual void apply(bit_vector_node *n) { 00110 assert(!n->get_elt_addr()->is_zero()); 00111 n->get_elt_addr()->print(_f, n->get_key1() * BITS_PER_LONG); 00112 } 00113 }; 00114 00115 class BitVector/*: public gc*/ { 00116 friend class OrOneNode; 00117 bit_vector_tree _tree; 00118 public: 00119 BitVector() {} 00120 void operator|=(BitVector &other) { 00121 if (_tree.is_empty()) { 00122 _tree.copy(&other._tree); 00123 // n_changed_unions++; 00124 } 00125 else { 00126 OrOneNode OON(this); 00127 other._tree.iterate(&OON); 00128 // if (OON.changed) n_changed_unions++; else n_unchanged_unions++; 00129 } 00130 } 00131 void set_bit(size_t which_bit, bool value) { 00132 /* Compute index */ 00133 unsigned int index = which_bit / BITS_PER_LONG; 00134 unsigned int offset = which_bit % BITS_PER_LONG; 00135 /* Find appropriate node */ 00136 bit_vector_node *lookup; 00137 /* If node exits, then modify it else create new node */ 00138 if (_tree.lookup(index, &lookup)) { 00139 lookup->get_elt_addr()->set_bit(offset, 1); 00140 } 00141 else { 00142 bit_vector_node *n = new bit_vector_node(index, BitVectorChunk()); 00143 n->get_elt_addr()->set_bit(offset, 1); 00144 _tree.insert_node(n); 00145 } 00146 } 00147 bool get_bit(size_t which_bit) { 00148 /* Compute index */ 00149 unsigned int index = which_bit / BITS_PER_LONG; 00150 unsigned int offset = which_bit % BITS_PER_LONG; 00151 /* Find appropriate node */ 00152 bit_vector_node *lookup; 00153 /* If node exits, then modify it else create new node */ 00154 if (_tree.lookup(index, &lookup)) { 00155 return lookup->get_elt_addr()->get_bit(offset); 00156 } 00157 return 0; 00158 } 00159 void print(FILE *f) { 00160 PrintOneNode PON(f); 00161 _tree.iterate(&PON); 00162 } 00163 00164 void map(BitVectorMapFcn *clo) { 00165 MapOneNode handle_node(clo); 00166 _tree.iterate(&handle_node); 00167 } 00168 00169 void set_to_zero() { 00170 _tree.erase(); 00171 } 00172 void copy(BitVector *from) { 00173 _tree.copy(&from->_tree); 00174 } 00175 int count() { 00176 CountingFcn cfcn; 00177 map(&cfcn); 00178 return cfcn.count; 00179 } 00180 int is_empty() { 00181 return _tree.is_empty(); 00182 } 00183 virtual void print_stdout() { 00184 print(stdout); 00185 printf("size: %d\n", _tree.tree_size()); 00186 fflush(stdout); 00187 } 00188 }; 00189 00190 void OrOneNode::apply(bit_vector_node *n) { 00191 bit_vector_node *lookup; 00192 if (_or_with->_tree.lookup(n->get_key1(), &lookup)) { 00193 changed = lookup->get_elt_addr()->bitor_into(n->get_elt()) || changed; 00194 } 00195 else { 00196 _or_with->_tree.insert_node(new bit_vector_node(n->get_key1(), 00197 n->get_elt())); 00198 } 00199 } 00200 #endif