• Main Page
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

chomp/struct/bitsets.h

Go to the documentation of this file.
00001 /// @addtogroup struct
00002 /// @{
00003 
00004 /////////////////////////////////////////////////////////////////////////////
00005 ///
00006 /// @file bitsets.h
00007 ///
00008 /// This file defines a class that uses bit representation of a set
00009 /// to store many small sets.
00010 ///
00011 /// @author Pawel Pilarczyk
00012 ///
00013 /////////////////////////////////////////////////////////////////////////////
00014 
00015 // Copyright (C) 1997-2013 by Pawel Pilarczyk.
00016 //
00017 // This file is part of the Homology Library.  This library is free software;
00018 // you can redistribute it and/or modify it under the terms of the GNU
00019 // General Public License as published by the Free Software Foundation;
00020 // either version 2 of the License, or (at your option) any later version.
00021 //
00022 // This library is distributed in the hope that it will be useful,
00023 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00024 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00025 // GNU General Public License for more details.
00026 //
00027 // You should have received a copy of the GNU General Public License along
00028 // with this software; see the file "license.txt".  If not, write to the
00029 // Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00030 // MA 02111-1307, USA.
00031 
00032 // Started on February 22, 2007. Last revision: March 29, 2011.
00033 
00034 
00035 #ifndef _CHOMP_STRUCT_BITSETS_H_
00036 #define _CHOMP_STRUCT_BITSETS_H_
00037 
00038 #include "chomp/system/config.h"
00039 
00040 #include <iostream>
00041 #include <cstdlib>
00042 
00043 namespace chomp {
00044 namespace homology {
00045 
00046 
00047 // --------------------------------------------------
00048 // ------------------- BitSets ---------------------
00049 // --------------------------------------------------
00050 
00051 /// This class uses bit representation to store many small sets.
00052 /// Each of the sets can contain integer numbers from 0 to the limit
00053 /// specified in the constructor. The number of sets must also be given
00054 /// in the constructor. A contiguous chunk of memory is used to store
00055 /// the bits that represent the sets.
00056 /// This class is not fool-proof, so use it carefully.
00057 /// Minimal interface, sorry.
00058 class BitSets
00059 {
00060         static const int_t longBits = sizeof (long) * 8;
00061         static const int_t longBitMask = longBits - 1;
00062         static const int_t longBitShift = (sizeof (long) == 8) ? 6 : 5;
00063 
00064 public:
00065         /// Constructor of a family of empty sets.
00066         /// The number of the sets and the maximal number of elements
00067         /// in each set must be provided at initialization.
00068         /// Both numbers must be positive.
00069         BitSets (int_t _nsets, int_t _nelem);
00070 
00071         /// Copy constructor.
00072         BitSets (const BitSets &s);
00073 
00074         /// Assignment operator.
00075         BitSets &operator = (const BitSets &s);
00076 
00077         /// Destructor.
00078         ~BitSets ();
00079 
00080         /// Adds an element to the given set.
00081         void add (int_t n, int_t e);
00082 
00083         /// Removes an element from the given set.
00084         void remove (int_t n, int_t e);
00085 
00086         /// Checks if an element belongs to the given set.
00087         bool check (int_t n, int_t e) const;
00088 
00089         /// Adds the entire set 'm' to the set 'n'.
00090         void addset (int_t n, int_t m);
00091 
00092         /// Retrieves an element >= 'start' in the given set.
00093         /// Returns -1 if none.
00094         int_t get (int_t n, int_t start = 0) const;
00095 
00096 private:
00097         /// The number of sets.
00098         int_t nsets;
00099         
00100         /// The maximal number of elements in each set.
00101         int_t nelem;
00102 
00103         /// The number of array entries used for each set.
00104         int_t nunits;
00105 
00106         /// The memory buffer for storing the bits.
00107         unsigned long *bits;
00108 
00109         /// Computes the size of the memory array for storing the bits.
00110         int_t arraySize ();
00111 
00112 }; /* BitSets */
00113 
00114 // --------------------------------------------------
00115 
00116 inline int_t BitSets::arraySize ()
00117 {
00118         long size = static_cast<long> (nsets) * static_cast<long> (nunits);
00119         if (static_cast<long> (static_cast<int_t> (size)) != size)
00120                 throw "Too large BitSets requested.";
00121         return static_cast<int_t> (size);
00122 } /* BitSets::arraySize */
00123 
00124 inline BitSets::BitSets (int_t _nsets, int_t _nelem):
00125         nsets (_nsets), nelem (_nelem),
00126         nunits ((_nelem + (sizeof (unsigned long) << 3) - 1) /
00127         (sizeof (unsigned long) << 3)), bits (0)
00128 {
00129         int_t size = arraySize ();
00130         bits = new unsigned long [size];
00131         for (int_t i = 0; i < size; ++ i)
00132                 bits [i] = 0;
00133         return;
00134 } /* BitSets::BitSets */
00135 
00136 inline BitSets::BitSets (const BitSets &s):
00137         nsets (s. nsets), nelem (s. nelem), nunits (s. nunits), bits (0)
00138 {
00139         int_t size = arraySize ();
00140         bits = new unsigned long [size];
00141         for (int_t i = 0; i < size; ++ i)
00142                 bits [i] = s. bits [i];
00143         return;
00144 } /* BitSets::BitSets */
00145 
00146 inline BitSets &BitSets::operator = (const BitSets &s)
00147 {
00148         if (this == &s)
00149                 return *this;
00150         delete [] bits;
00151         nsets = s. nsets;
00152         nelem = s. nelem;
00153         nunits = s. nunits;
00154         int_t size = arraySize ();
00155         bits = new unsigned long [size];
00156         for (int_t i = 0; i < size; ++ i)
00157                 bits [i] = s. bits [i];
00158         return *this;
00159 } /* BitSets::operator = */
00160 
00161 inline BitSets::~BitSets ()
00162 {
00163         delete [] bits;
00164         return;
00165 } /* BitSets::~BitSets */
00166 
00167 inline void BitSets::add (int_t n, int_t e)
00168 {
00169 //      sbug << "Add " << e << " to " << n << ".\n";
00170         unsigned long *buf = bits + n * nunits;
00171         buf [e >> longBitShift] |= (1ul << (e & longBitMask));
00172         return;
00173 } /* BitSets::add */
00174 
00175 inline void BitSets::remove (int_t n, int_t e)
00176 {
00177         unsigned long *buf = bits + n * nunits;
00178         buf [e >> longBitShift] &= ~(1ul << (e & longBitMask));
00179         return;
00180 } /* BitSets::remove */
00181 
00182 inline bool BitSets::check (int_t n, int_t e) const
00183 {
00184         unsigned long *buf = bits + n * nunits;
00185         return !!(buf [e >> longBitShift] & (1ul << (e & longBitMask)));
00186 } /* BitSets::check */
00187 
00188 inline void BitSets::addset (int_t n, int_t m)
00189 {
00190         unsigned long *nbuf = bits + n * nunits;
00191         unsigned long *mbuf = bits + m * nunits;
00192         for (int_t i = 0; i < nunits; ++ i)
00193                 *(nbuf ++) |= *(mbuf ++);
00194         return;
00195 } /* BitSets::addset */
00196 
00197 inline int_t BitSets::get (int_t n, int_t start) const
00198 {
00199         if (start >= nelem)
00200                 return -1;
00201         unsigned long *buf = bits + n * nunits;
00202         int_t offset = start >> longBitShift;
00203         int bit = start & longBitMask;
00204         if (buf [offset] & (~0ul << bit))
00205         {
00206                 for (; bit < longBits; ++ bit)
00207                 {
00208                         if (buf [offset] & (1ul << bit))
00209                                 return (offset << longBitShift) + bit;
00210                 }
00211                 throw "Wrong bit number in BitSets.";
00212         }
00213         for (++ offset; offset < nunits; ++ offset)
00214         {
00215                 if (!buf [offset])
00216                         continue;
00217                 for (int bit = 0; bit < longBits; ++ bit)
00218                 {
00219                         if (buf [offset] & (1ul << bit))
00220                                 return (offset << longBitShift) + bit;
00221                 }
00222                 throw "False bit in BitSets.";
00223         }
00224         return -1;
00225 } /* BitSets::get */
00226 
00227 
00228 } // namespace homology
00229 } // namespace chomp
00230 
00231 #endif // _CHOMP_STRUCT_BITSETS_H_
00232 
00233 /// @}
00234 

Generated on Sun Feb 3 2013 12:40:30 for The Uniform Expansion Software by  doxygen 1.7.2