Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

nci/suif/suif2b/extratypes/tree_bit_vector/tree_bit_vector.h

Go to the documentation of this file.
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

Generated at Mon Jul 31 13:41:52 2000 for NCI SUIF by doxygen 1.1.2 written by Dimitri van Heesch, © 1997-2000