[MOAB-dev] r3390 - MOAB/trunk

kraftche at cae.wisc.edu kraftche at cae.wisc.edu
Mon Nov 30 17:07:51 CST 2009


Author: kraftche
Date: 2009-11-30 17:07:51 -0600 (Mon, 30 Nov 2009)
New Revision: 3390

Added:
   MOAB/trunk/BitTagServer.cpp
   MOAB/trunk/BitTagServer.hpp
Removed:
   MOAB/trunk/MBBits.cpp
   MOAB/trunk/MBBits.hpp
Modified:
   MOAB/trunk/Makefile.am
   MOAB/trunk/TagServer.cpp
   MOAB/trunk/TagServer.hpp
Log:
Re-write bit tag handling:
  o remove much indirection (reduce length of chain of pointers followed
     to access a tag value)
  o round requested number of bits per tag up to a power of two, so that
     tag values do not span byte boundaries
  o increase memory block size from 0.5kB to 4kB.

These changes reduce the type to skin a mesh by 5-10%.





Added: MOAB/trunk/BitTagServer.cpp
===================================================================
--- MOAB/trunk/BitTagServer.cpp	                        (rev 0)
+++ MOAB/trunk/BitTagServer.cpp	2009-11-30 23:07:51 UTC (rev 3390)
@@ -0,0 +1,404 @@
+#include "BitTagServer.hpp"
+#include "MBRange.hpp"
+#include "MBInternals.hpp"
+#include <stdlib.h>
+#include <string.h>
+
+void BitPage::search( unsigned char value, int offset, int count, 
+                      int per_ent, MBRange& results, MBEntityHandle start ) const
+{
+  const int end = offset + count;
+  MBRange::iterator hint = results.begin();
+  while (offset != end) {
+    if (get_bits( offset, per_ent ) == value)
+      hint = results.insert( hint, start );
+    ++offset;
+    ++start;
+  }
+}
+
+BitPage::BitPage( int per_ent, unsigned char init_val )
+{
+  unsigned char mask = (1<<per_ent)-1; // 2^per_ent - 1
+  init_val &= mask;
+  switch (per_ent) {
+    default: assert(false); abort(); break; // must be power of two
+      // Note: no breaks. fall through such that all bits in init_val are set
+    case 1: init_val |= (init_val << 1);
+    case 2: init_val |= (init_val << 2);
+    case 4: init_val |= (init_val << 4);
+    case 8: ;
+  }
+  memset( byteArray, init_val, BitTag::PageSize );
+}
+
+MBErrorCode BitTagServer::reserve_tag_id( int num_bits, MBTagId tag_id )
+{
+  if (tag_id > tagList.size())
+    tagList.resize( tag_id );
+  else if (tagList[tag_id-1].in_use())
+    return MB_ALREADY_ALLOCATED;
+  
+  return tagList[tag_id-1].reserve( num_bits );
+}
+
+MBErrorCode BitTagServer::release_tag_id( MBTagId tag_id )
+{
+  if (tag_id > tagList.size() && !tagList[tag_id-1].in_use())
+    return MB_TAG_NOT_FOUND;
+  
+  tagList[tag_id-1].release();
+  return MB_SUCCESS;
+}
+
+void BitTagServer::reset_data()
+{
+  for (std::vector<BitTag>::iterator i = tagList.begin(); i != tagList.end(); ++i) 
+    i->reset_data();
+}
+
+MBErrorCode BitTagServer::get_tags( MBEntityHandle entity,  
+                                    std::vector<MBTag> &tags ) const
+{
+  for (size_t i = 0; i < tagList.size(); ++i)
+    if (tagList[i].in_use())
+      tags.push_back( (MBTag)(i+1) );
+  return MB_SUCCESS;
+}
+
+MBErrorCode BitTag::reserve( unsigned bits )
+{
+  if (in_use() || bits > 8)
+    return MB_FAILURE;
+  
+  inUse = true;
+  requestedBitsPerEntity = bits;
+    // store smallest power of two greater than or 
+    // equal to the number of bits
+  storedBitsPerEntity = 1;
+  pageShift = Ln2PageSize+1;
+  while (storedBitsPerEntity < bits) {
+    storedBitsPerEntity *= 2;
+  }
+
+  return MB_SUCCESS;
+}
+
+void BitTag::reset_data()
+{
+  for (MBEntityType t = (MBEntityType)0; t != MBMAXTYPE; ++t) {
+    for (size_t i = 0; i < pageList[t].size(); ++i)
+      delete pageList[t][i];
+    pageList[t].clear();
+  }
+}
+
+void BitTag::release()
+{
+  reset_data();
+  inUse = false;
+}
+
+MBErrorCode BitTag::get_bits( const MBEntityHandle* handles, 
+                              int num_handles, 
+                              unsigned char* data,
+                              const unsigned char* default_value ) const
+{
+  MBEntityType type;
+  size_t page;
+  int offset;
+  unsigned char def = default_value ? *default_value : 0;
+  for (int i = 0; i < num_handles; ++i) {
+    unpack( handles[i], type, page, offset );
+    if (pageList[type].size() <= page || !pageList[type][page]) 
+      data[i] = def;
+    else
+      data[i] = pageList[type][page]->get_bits( offset, storedBitsPerEntity );
+  }
+  return MB_SUCCESS;
+}
+
+MBErrorCode BitTag::set_bits( const MBEntityHandle* handles, 
+                              int num_handles, 
+                              const unsigned char* data,
+                              const unsigned char* default_value )
+{
+  MBEntityType type;
+  size_t page;
+  int offset;
+  for (int i = 0; i < num_handles; ++i) {
+    unpack( handles[i], type, page, offset );
+    if (pageList[type].size() <= page)
+      pageList[type].resize(page+1, 0);
+    if (!pageList[type][page])
+      pageList[type][page] = new BitPage( storedBitsPerEntity, 
+                              default_value ? *default_value : 0 );
+    pageList[type][page]->set_bits( offset, storedBitsPerEntity, data[i] );
+  }
+  return MB_SUCCESS;
+}
+
+MBErrorCode BitTag::clear_bits( const MBEntityHandle* handles, 
+                                int num_handles, 
+                                const unsigned char* default_value )
+{
+  MBEntityType type;
+  size_t page;
+  int offset;
+  const unsigned char val = default_value ? *default_value : 0;
+  for (int i = 0; i < num_handles; ++i) {
+    unpack( handles[i], type, page, offset );
+    if (pageList[type].size() > page && pageList[type][page])
+      pageList[type][page]->set_bits( offset, storedBitsPerEntity, val );
+  }
+  return MB_SUCCESS;
+}
+
+MBErrorCode BitTag::get_bits( const MBRange& handles, 
+                              unsigned char* data,
+                              const unsigned char* default_value ) const
+{
+  MBEntityType type;
+  MBEntityID count;
+  size_t page;
+  int offset, per_page = ents_per_page();
+  unsigned char def = default_value ? *default_value : 0;
+  MBRange::const_pair_iterator i;
+  for (i = handles.const_pair_begin(); i != handles.const_pair_end(); ++i) {
+    unpack( i->first, type, page, offset );
+    assert(TYPE_FROM_HANDLE(i->second) == type); // should be true because id of zero is never used
+    count = i->second - i->first + 1;
+    if (page >= pageList[type].size()) {
+      memset( data, def, count );
+      data += count;
+      continue;
+    }
+    
+    while (count) {
+      size_t pcount = std::min( (MBEntityID)per_page, count );
+      if (pageList[type][page])
+        pageList[type][page]->get_bits( offset, pcount, storedBitsPerEntity, data );
+      else
+        memset( data, def, pcount );
+      data += pcount;
+      count -= pcount; 
+      offset = 0;
+      ++page;
+    }
+  }
+  return MB_SUCCESS;
+}
+
+MBErrorCode BitTag::set_bits( const MBRange& handles, 
+                              const unsigned char* data, 
+                              const unsigned char* default_value )
+{
+  MBEntityType type;
+  MBEntityID count;
+  size_t page;
+  int offset, per_page = ents_per_page();
+  unsigned char def = default_value ? *default_value : 0;
+  MBRange::const_pair_iterator i;
+  for (i = handles.const_pair_begin(); i != handles.const_pair_end(); ++i) {
+    unpack( i->first, type, page, offset );
+    assert(TYPE_FROM_HANDLE(i->second) == type); // should be true because id of zero is never used
+    count = i->second - i->first + 1;
+    
+    while (count) {
+      if (page >= pageList[type].size())
+        pageList[type].resize( page+1, 0 );
+      if (!pageList[type][page])
+        pageList[type][page] = new BitPage( storedBitsPerEntity, def );
+
+      size_t pcount = std::min( (MBEntityID)per_page, count );
+      pageList[type][page]->set_bits( offset, pcount, storedBitsPerEntity, data );
+      data += pcount;
+      count -= pcount; 
+      offset = 0;
+      ++page;
+    }
+  }
+  return MB_SUCCESS;
+}
+
+MBErrorCode BitTag::clear_bits( const MBRange& handles, 
+                                const unsigned char* default_value )
+{
+  MBEntityType type;
+  MBEntityID count;
+  size_t page;
+  int offset, per_page = ents_per_page();
+  unsigned char val = default_value ? *default_value : 0;
+  MBRange::const_pair_iterator i;
+  for (i = handles.const_pair_begin(); i != handles.const_pair_end(); ++i) {
+    unpack( i->first, type, page, offset );
+    assert(TYPE_FROM_HANDLE(i->second) == type); // should be true because id of zero is never used
+    count = i->second - i->first + 1;
+    
+    while (count) {
+      size_t pcount = std::min( (MBEntityID)per_page, count );
+      if (page < pageList[type].size() && pageList[type][page])
+        pageList[type][page]->set_bits( offset, pcount, storedBitsPerEntity, val );
+      count -= pcount; 
+      offset = 0;
+      ++page;
+    }
+  }
+  return MB_SUCCESS;
+}
+
+MBErrorCode BitTag::get_entities( MBRange& entities ) const
+{
+  MBErrorCode rval = MB_SUCCESS;
+  MBEntityType type = MBMAXTYPE;
+  while (type--) {
+    rval = get_entities( type, entities );
+    if (MB_SUCCESS != rval)
+      break;
+  }
+  return rval;
+}
+    
+
+MBErrorCode BitTag::get_entities( MBEntityType type, MBRange& entities ) const
+{
+  const int per_page = ents_per_page();
+  MBRange::iterator hint = entities.begin();
+  for (size_t i = 0; i < pageList[type].size(); ++i) {
+    if (pageList[type][i]) {
+      MBEntityID id = i * per_page;
+      MBEntityHandle h = CREATE_HANDLE( type, id );
+      MBEntityHandle last = h + per_page - 1;
+        // never zero ID
+      if (!id) ++h;
+      hint = entities.insert( h, last );
+    }
+  }
+  return MB_SUCCESS;
+}
+
+MBErrorCode BitTag::get_entities( const MBRange& range, 
+                                  MBEntityType in_type,
+                                  MBRange& entities ) const
+{
+  MBEntityType type;
+  MBEntityID count;
+  size_t page;
+  int offset, per_page = ents_per_page();
+  MBRange::const_iterator j, i = range.lower_bound( in_type );
+  MBEntityHandle h;
+  while (i != range.end()) {
+    h = *i;
+    unpack( h, type, page, offset );
+    if (type != in_type)
+      break;
+    
+    i = i.end_of_block();
+    count = *i - h + 1;
+    ++i;
+    while (count > 0) {
+      MBEntityID pcount = std::min( count, (MBEntityID)(per_page - offset) );
+      if (page < pageList[type].size() && pageList[type][page]) 
+        entities.insert( h, h+pcount-1 );
+    
+      count -= pcount;
+      h += pcount;
+      assert(TYPE_FROM_HANDLE(h) == type);
+      offset = 0;
+      ++page;
+    }
+  }
+  return MB_SUCCESS;
+}
+
+MBErrorCode BitTag::get_entities_with_bits( MBEntityType type, 
+                                            MBRange& entities,
+                                            unsigned char bits ) const
+{
+  const int per_page = ents_per_page();
+  for (size_t i = 0; i < pageList[type].size(); ++i) {
+    if (pageList[type][i]) {
+      MBEntityID id = i * per_page;
+      MBEntityHandle h = CREATE_HANDLE( type, id );
+      int off = !i; // never zero ID
+      pageList[type][i]->search( bits, off, per_page-off, storedBitsPerEntity, 
+                                 entities, h+off );
+    }
+  }
+  return MB_SUCCESS;
+}
+
+MBErrorCode BitTag::get_entities_with_bits( const MBRange &range,
+                                            MBEntityType in_type, 
+                                            MBRange& entities,
+                                            unsigned char bits ) const
+{
+  MBEntityType type;
+  MBEntityID count;
+  size_t page;
+  int offset, per_page = ents_per_page();
+  MBRange::const_iterator j, i = range.lower_bound( in_type );
+  MBEntityHandle h;
+  while (i != range.end()) {
+    h = *i;
+    unpack( h, type, page, offset );
+    if (type != in_type)
+      break;
+    
+    i = i.end_of_block();
+    count = *i - h + 1;
+    ++i;
+    while (count > 0) {
+      MBEntityID pcount = std::min( count, (MBEntityID)(per_page - offset) );
+      if (page < pageList[type].size() && pageList[type][page]) 
+        pageList[type][page]->search( bits, offset, pcount, 
+                                      storedBitsPerEntity,
+                                      entities, h );
+    
+      count -= pcount;
+      h += pcount;
+      assert(TYPE_FROM_HANDLE(h) == type);
+      offset = 0;
+      ++page;
+    }
+  }
+  return MB_SUCCESS;
+}
+
+MBErrorCode BitTag::get_number_entities( MBEntityType type,
+                                         int& num_entities ) const
+{
+  const int per_page = ents_per_page();
+  num_entities = 0;
+  if (pageList[type].empty())
+    return MB_SUCCESS;
+  if (pageList[type][0])
+    num_entities = per_page - 1; // never zero ID
+  for (size_t i = 1; i < pageList[type].size(); ++i) 
+    if (pageList[type][i])
+      num_entities += per_page;
+  return MB_SUCCESS;
+}
+
+MBErrorCode BitTag::get_number_entities( const MBRange &range,
+                                         MBEntityType type,
+                                         int& num_entities ) const
+{
+  MBRange tmp;
+  MBErrorCode result = get_entities( range, type, tmp );
+  num_entities = tmp.size();
+  return result;
+}
+
+MBErrorCode BitTag::get_memory_use( unsigned long& total,
+                                    unsigned long& per_entity ) const
+{
+  per_entity = (storedBitsPerEntity > 4); // cannot return fraction of bytes, so round
+  for (MBEntityType t = (MBEntityType)0; t < MBMAXTYPE; ++t) {
+    total += pageList[t].capacity() * sizeof(BitPage*);
+    for (size_t i = 0; i < pageList[t].size(); ++i)
+      if (pageList[t][i])
+        total += sizeof(BitPage);
+  }
+  return MB_SUCCESS;
+}

Added: MOAB/trunk/BitTagServer.hpp
===================================================================
--- MOAB/trunk/BitTagServer.hpp	                        (rev 0)
+++ MOAB/trunk/BitTagServer.hpp	2009-11-30 23:07:51 UTC (rev 3390)
@@ -0,0 +1,613 @@
+#ifndef BIT_TAG_SERVER_HPP
+#define BIT_TAG_SERVER_HPP
+
+#include "MBTypes.h"
+#include "MBInternals.hpp"
+#include <algorithm>
+#include <vector>
+#include <assert.h>
+
+class MBRange;
+class BitTag;
+class BitPage;
+
+/**\brief Manage all bit tag data 
+ *
+ * This class manages data for all bit tags.
+ */
+class BitTagServer
+{
+public:
+
+  /**\brief Clear all tag data
+   *
+   * Clear all tag values, but keep the actual tags 
+   */
+  void reset_data();
+
+    /** Allocate space for a tag with the specified ID.
+     * Returns MB_TAG_NOT_FOUND if ID is already in use.
+     *\param num_bits Number of bits in each per-entity tag value
+     */
+  MBErrorCode reserve_tag_id( int num_bits, MBTagId tag_id );
+
+    /**\brief Deallocate tag
+     *
+     * Mask specified tag id as unused and release any memory
+     * associated with the tag.
+     */
+  MBErrorCode release_tag_id( MBTagId tag_id );
+
+    /**\brief Get tag values for an array of entity handles */
+  MBErrorCode get_bits( MBTagId tag_id, 
+                        const MBEntityHandle* handles, 
+                        int num_handles, 
+                        unsigned char* data,
+                        const unsigned char* default_value ) const;
+    /**\brief Get tag values for a range of entity handles */
+  MBErrorCode get_bits( MBTagId tag_id, 
+                        const MBRange& handles, 
+                        unsigned char* data,
+                        const unsigned char* default_value ) const;
+
+    /**\brief Set tag values for an array of entity handles */
+  MBErrorCode set_bits( MBTagId tag_id, 
+                        const MBEntityHandle* handles, 
+                        int num_handles,
+                        const unsigned char* data, 
+                        const unsigned char* default_value );
+    /**\brief Set tag values for a range of entity handles */
+  MBErrorCode set_bits( MBTagId tag_id, 
+                        const MBRange& handles, 
+                        const unsigned char* data, 
+                        const unsigned char* default_value );
+
+    /**\brief Clear tag values for an array of entity handles */
+  MBErrorCode clear_bits( MBTagId tag_id, 
+                          const MBEntityHandle* handles, 
+                          int num_handles,
+                          const unsigned char* default_value );
+    /**\brief Clear tag values for a range of entity handles */
+  MBErrorCode clear_bits( MBTagId tag_id, 
+                          const MBRange& handles, 
+                          const unsigned char* default_value );
+    
+    /**\brief Get entities for which an explicit tag value is stored */
+  MBErrorCode get_entities( MBTagId tag_id, 
+                            MBRange& entities ) const;
+
+    /**\brief Get entities for which an explicit tag value is stored */
+  MBErrorCode get_entities( MBTagId tag_id, 
+                            MBEntityType type, 
+                            MBRange& entities ) const;
+
+    /**\brief Get entities for which an explicit tag of the specified value is stored */
+  MBErrorCode get_entities_with_tag_value( MBTagId tag_id, 
+                                           MBEntityType type, 
+                                           MBRange& entities,
+                                           unsigned char bits ) const;
+
+    /**\brief Get entities for which an explicit tag value is stored */
+  MBErrorCode get_entities( const MBRange &range,
+                            MBTagId tag_id, 
+                            MBEntityType type, 
+                            MBRange& entities ) const;
+
+    /**\brief Get entities for which an explicit tag of the specified value is stored */
+  MBErrorCode get_entities_with_tag_value( const MBRange &range,
+                                           MBTagId tag_id, 
+                                           MBEntityType type, 
+                                           MBRange& entities,
+                                           unsigned char bits ) const;
+
+    //! get all tags defined on an entity
+  MBErrorCode get_tags( MBEntityHandle entity,
+                        std::vector<MBTag> &tags ) const;
+
+    /**\brief Get number of entities for which an explicit tag value is stored */
+  MBErrorCode get_number_entities( MBTagId tag_id, 
+                                   MBEntityType type,
+                                   int& num_entities ) const;
+  
+    /**\brief Get number of entities for which an explicit tag value is stored */
+  MBErrorCode get_number_entities( const MBRange &range,
+                                   MBTagId tag_id, 
+                                   MBEntityType type,
+                                   int& num_entities ) const;
+  
+  MBErrorCode get_memory_use( MBTagId tag,
+                              unsigned long& total,
+                              unsigned long& per_entity ) const;
+
+private:
+  
+    /**\brief Get BitTag instance for specified tag ID, or NULL if none */
+  inline BitTag* get_tag( MBTagId id );
+  
+    /**\brief Get BitTag instance for specified tag ID, or NULL if none */
+  inline const BitTag* get_tag( MBTagId id ) const;
+  
+    /**\brief Array of BitTag instances, indexed by (tag id - 1) */
+  std::vector<BitTag> tagList;
+  
+};
+
+/**\brief All data for a single bit tag */
+class BitTag 
+{
+  public:
+  
+  BitTag() : inUse(false) {}
+  ~BitTag() { release(); }
+  
+    // Do destructive copying (assiging moves data from
+    // source to destination, such that source is invalid)
+    // so that resizing the vector doesn't copy data
+  BitTag( const BitTag& other ) 
+    { const_cast<BitTag&>(other).swap(*this); }
+  BitTag& operator=( const BitTag& other ) 
+    { const_cast<BitTag&>(other).swap(*this); return *this; }
+    
+    /**\brief Get tag values for an array of entity handles */
+  MBErrorCode get_bits( const MBEntityHandle* handles, 
+                        int num_handles, 
+                        unsigned char* data,
+                        const unsigned char* default_value ) const;
+    /**\brief Get tag values for a range of entity handles */
+  MBErrorCode get_bits( const MBRange& handles, 
+                        unsigned char* data,
+                        const unsigned char* default_value ) const;
+
+    /**\brief Set tag values for an array of entity handles */
+  MBErrorCode set_bits( const MBEntityHandle* handles, 
+                        int num_handles,
+                        const unsigned char* data, 
+                        const unsigned char* default_value );
+    /**\brief Set tag values for a range of entity handles */
+  MBErrorCode set_bits( const MBRange& handles, 
+                        const unsigned char* data, 
+                        const unsigned char* default_value );
+
+    /**\brief Clear tag values for an array of entity handles */
+  MBErrorCode clear_bits( const MBEntityHandle* handles, 
+                          int num_handles,
+                          const unsigned char* default_value );
+    /**\brief Clear tag values for a range of entity handles */
+  MBErrorCode clear_bits( const MBRange& handles, 
+                          const unsigned char* default_value );
+    
+
+    /**\brief Get entities for which an explicit tag value is stored */
+  MBErrorCode get_entities( MBRange& entities ) const;
+
+    /**\brief Get entities for which an explicit tag value is stored */
+  MBErrorCode get_entities( MBEntityType type, 
+                            MBRange& entities ) const;
+
+    /**\brief Get entities for which an explicit tag value is stored */
+  MBErrorCode get_entities( const MBRange &range,
+                            MBEntityType type, 
+                            MBRange& entities ) const;
+
+    /**\brief Get entities for which an explicit tag of the specified value is stored */
+  MBErrorCode get_entities_with_bits( MBEntityType type, 
+                                      MBRange& entities,
+                                      unsigned char bits ) const;
+
+    /**\brief Get entities for which an explicit tag of the specified value is stored */
+  MBErrorCode get_entities_with_bits( const MBRange &range,
+                                      MBEntityType type, 
+                                      MBRange& entities,
+                                      unsigned char bits ) const;
+
+    /**\brief Get number of entities for which an explicit tag value is stored */
+  MBErrorCode get_number_entities( MBEntityType type,
+                                   int& num_entities ) const;
+  
+    /**\brief Get number of entities for which an explicit tag value is stored */
+  MBErrorCode get_number_entities( const MBRange &range,
+                                   MBEntityType type,
+                                   int& num_entities ) const;
+  
+  MBErrorCode get_memory_use( unsigned long& total,
+                              unsigned long& per_entity ) const;
+                              
+  enum { Ln2PageSize = 12,              //!< Constant: log2(PageSize)
+         PageSize = (1u << Ln2PageSize) //!< Constant: Bytes per BitPage (power of 2)
+      };
+  
+    /**\return false if instance is not in use, true otherwise */
+  bool in_use() const { return inUse; }
+  
+    /**\brief Release all stored tag data
+     *
+     * Releases all tag data such that tag is still defined, but stores
+     * no value for any entity.
+     */
+  void reset_data();
+  
+    /**\brief Delete tag.
+     *
+     * Releases all tag data such that tag is no longer defined.  
+     * Equivalent to reset_data() and setting inUse to false.
+     */
+  void release();
+  
+    /**\brief Mark this instance is in use.
+     *
+     * Initialize this BitTag instance such that inUse 
+     * returns true.
+     *\param bits_per_entity Desired bits per entity.  Note:
+     *         implementation is free to allocate more than the
+     *         requested number of bits for each entity
+     */
+  MBErrorCode reserve( unsigned int bits_per_entity );
+  
+    /**\brief Helper function for destructive assignment */
+  void swap( BitTag& other ) {
+    std::swap( inUse, other.inUse );
+    std::swap( storedBitsPerEntity, other.storedBitsPerEntity );
+    std::swap( requestedBitsPerEntity, other.requestedBitsPerEntity );
+    for (MBEntityType t = (MBEntityType)0; t != MBMAXTYPE; ++t)
+      pageList[t].swap( other.pageList[t] );
+  }
+
+  private:
+  
+  bool inUse; //!< This instance is in use (represents data for some tag)
+  std::vector<BitPage*> pageList[MBMAXTYPE]; //!< Array of BitPage instances storing actual data.
+  unsigned int requestedBitsPerEntity; //!< user-requested bits per entity
+  unsigned int storedBitsPerEntity;    //!< allocated bits per entity (power of 2)
+  unsigned int pageShift;              //!< Ln2PageSize + log2(storedBitsPerEntity)
+  
+  /**\brief Get indices from handle 
+   *
+   *\param type   Output: entity type
+   *\param page   Output: index into pageList[type]
+   *\param offset Output: index into pageList[type][page]
+   */
+  void unpack( MBEntityHandle h, MBEntityType& type, size_t& page, int& offset ) const
+    { 
+      type = TYPE_FROM_HANDLE(h);
+      h = ID_FROM_HANDLE(h);
+      page = ((size_t)h) >> pageShift;   // h / (offset*storedBitsPerEntity)
+      offset = h & ((1u<<pageShift)-1u); // h % (offset*storedBitsPerEntity)
+    }
+    
+  /**\brief Get the number of tag values that are stored in each BitPage */
+  int ents_per_page() const { return 8*PageSize/storedBitsPerEntity; }
+};
+
+/**\brief bit tag data
+ *
+ * This class represents a fixed-size block of memory in which bit tag
+ * values are stored.  
+ */
+class BitPage
+{
+public:
+  /**\brief Initialize memory
+   *
+   *\param bits_per_ent  Number of bits in each tag value.
+   *                     MUST BE A POWER OF TWO.
+   *\param init_val      The lower bits_per_ent bits of this byte are
+   *                     used to initialize each tag value.
+   */
+  BitPage( int bits_per_ent, unsigned char init_val );
+  
+  /**\brief Get tag values
+   *
+   * Get 'count' tag values, beginning with the one at 'offset'.
+   *\param offset Offset into list of values, where a value of zero indicates
+   *              the first tag value, a value of one indicates the second
+   *              tag value, etc.  NOTE:  This is the value offset, not the
+   *              bit offset.
+   *\param count  Number of consecutive tag values to get.
+   *\param bits_per_ent  Number of bits composing each tag value.  
+   *                     NOTE: Must be a power of two.
+   *\param data   Memory into which to copy tag values.  Each value is copied
+   *              into a separate byte, such that the lower bits of the bit
+   *              contain the tag value and any unused higher bits are zero.
+   */
+  void get_bits( int offset, int count, int bits_per_ent, unsigned char* data ) const;
+  
+  /**\brief Set tag values
+   *
+   * Set 'count' tag values, beginning with the one at 'offset'.
+   *\param offset Offset into list of values, where a value of zero indicates
+   *              the first tag value, a value of one indicates the second
+   *              tag value, etc.  NOTE:  This is the value offset, not the
+   *              bit offset.
+   *\param count  Number of consecutive tag values to set.
+   *\param bits_per_ent  Number of bits composing each tag value.  
+   *                     NOTE: Must be a power of two.
+   *\param data   Memory from which to copy tag values.  Each value is copied
+   *              from a separate byte.  The lower 'bits_per_ent' of each
+   *              byte are used as the tag value.  Any additional higher bits
+   *              are ignored.
+   */
+  void set_bits( int offset, int count, int bits_per_ent, const unsigned char* data );
+  
+  /**\brief Set several tag values to the same value.
+   *
+   * Set 'count' tag values to specified value.
+   *\param offset Offset into list of values, where a value of zero indicates
+   *              the first tag value, a value of one indicates the second
+   *              tag value, etc.  NOTE:  This is the value offset, not the
+   *              bit offset.
+   *\param count  Number of consecutive tag values to set.
+   *\param bits_per_ent  Number of bits composing each tag value.  
+   *                     NOTE: Must be a power of two.
+   *\param value  The lower 'bits_per_ent' of this
+   *              byte are used as the tag value.  Any additional higher bits
+   *              are ignored.
+   */
+  void set_bits( int offset, int count, int bits_per_ent, unsigned char value );
+
+  /**\brief Get tag value
+   *
+   * Get one tag value.
+   *\param offset Offset into list of values, where a value of zero indicates
+   *              the first tag value, a value of one indicates the second
+   *              tag value, etc.  NOTE:  This is the value offset, not the
+   *              bit offset.
+   *\param bits_per_ent  Number of bits composing each tag value.  
+   *                     NOTE: Must be a power of two.
+   *\return       A byte containing the tag value in the lower bits with
+   *              any unused higher bits zeroed.
+   */
+  unsigned char get_bits( int offset, int bits_per_ent ) const;
+  
+  /**\brief Set tag value
+   *
+   * Set tag value.
+   *\param offset Offset into list of values, where a value of zero indicates
+   *              the first tag value, a value of one indicates the second
+   *              tag value, etc.  NOTE:  This is the value offset, not the
+   *              bit offset.
+   *\param bits_per_ent  Number of bits composing each tag value.  
+   *                     NOTE: Must be a power of two.
+   *\param value  The lower 'bits_per_ent' of this
+   *              byte are used as the tag value.  Any additional higher bits
+   *              are ignored.
+   */
+  void set_bits( int offset, int bits_per_ent, unsigned char data );
+  
+  /**\brief Search stored values for specified value.
+   *
+   * Find the offsets n in the data at which the specified value occurs,
+   * and for each one insert 'start + n' into the passed MBRange.
+   *\param value   The value to look for
+   *\param offset  The offset at which to begin searching
+   *\param count   The number of values to search
+   *\param bits_per_ent Number of bits composing each tag value.
+   *\param results Result list.
+   *\param start   The handle of the entity corresponding to the 
+   *               tag value stored at 'offset'
+   */
+  void search( unsigned char value, int offset, int count, 
+               int bits_per_ent, MBRange& results, MBEntityHandle start ) const;
+
+private:
+
+  /**\brief The actual array of bytes */
+  char byteArray[BitTag::PageSize];
+};
+
+inline unsigned char BitPage::get_bits( int offset, int per_ent ) const
+{
+    // Assume per_ent is a power of two, which should be guaranteed
+    // by higher-level code.
+  unsigned char mask = (1<<per_ent)-1; // 2^per_ent - 1
+  int byte = (offset * per_ent) >> 3; // shifting 3 is dividing by eight
+  int bit =  (offset * per_ent) & 7;  // masking with 7 is modulo eight
+  assert(byte < BitTag::PageSize);
+  return (byteArray[byte] >> bit) & mask;
+} 
+
+inline void BitPage::set_bits( int offset, int per_ent, unsigned char bits )
+{
+  int byte = (offset * per_ent) >> 3; // shifting 3 is dividing by eight
+  int bit =  (offset * per_ent) & 7;  // masking with 7 is modulo eight
+  assert(byte < BitTag::PageSize);
+    // Assume per_ent is a power of two, which should be guaranteed
+    // by higher-level code.
+  unsigned char mask = ((1<<per_ent)-1) << bit;
+  byteArray[byte] = (byteArray[byte] & ~mask) | ((bits << bit) & mask);
+} 
+
+inline void BitPage::get_bits( int offset, int count, int per_ent, unsigned char* data ) const
+{
+  unsigned char* end = data+count;
+  while (data != end)
+    *(data++) = get_bits( offset++, per_ent );
+}
+
+inline void BitPage::set_bits( int offset, int count, int per_ent, const unsigned char* data )
+{
+  const unsigned char* end = data+count;
+  while (data != end)
+    set_bits( offset++, per_ent, *(data++) );
+}
+
+inline void BitPage::set_bits( int offset, int count, int per_ent, unsigned char value )
+{
+  int end = offset + count;
+  while (offset < end)
+    set_bits( offset++, per_ent, value );
+}
+
+  
+inline BitTag* BitTagServer::get_tag( MBTagId id )
+  { return id-1 >= tagList.size() || !tagList[id-1].in_use() ? 0 : &tagList[id-1]; }
+  
+inline const BitTag* BitTagServer::get_tag( MBTagId id ) const
+  { return id-1 >= tagList.size() || !tagList[id-1].in_use() ? 0 : &tagList[id-1]; }
+
+inline MBErrorCode 
+BitTagServer::get_bits( MBTagId tag_id, 
+                        const MBEntityHandle* handles, 
+                        int num_handles, 
+                        unsigned char* data,
+                        const unsigned char* default_value ) const
+{
+  if (const BitTag* ptr = get_tag(tag_id))
+    return ptr->get_bits( handles, num_handles, data, default_value );
+  else
+    return MB_TAG_NOT_FOUND;
+}
+
+inline MBErrorCode 
+BitTagServer::get_bits( MBTagId tag_id, 
+                        const MBRange& handles, 
+                        unsigned char* data,
+                        const unsigned char* default_value ) const
+{
+  if (const BitTag* ptr = get_tag(tag_id))
+    return ptr->get_bits( handles, data, default_value );
+  else
+    return MB_TAG_NOT_FOUND;
+}
+
+inline MBErrorCode 
+BitTagServer::set_bits( MBTagId tag_id, 
+                        const MBEntityHandle* handles, 
+                        int num_handles,
+                        const unsigned char* data, 
+                        const unsigned char* default_value )
+{
+  if (BitTag* ptr = get_tag(tag_id))
+    return ptr->set_bits( handles, num_handles, data, default_value );
+  else
+    return MB_TAG_NOT_FOUND;
+}
+inline MBErrorCode 
+BitTagServer::set_bits( MBTagId tag_id, 
+                        const MBRange& handles, 
+                        const unsigned char* data, 
+                        const unsigned char* default_value )
+{
+  if (BitTag* ptr = get_tag(tag_id))
+    return ptr->set_bits( handles, data, default_value );
+  else
+    return MB_TAG_NOT_FOUND;
+}
+
+inline MBErrorCode 
+BitTagServer::clear_bits( MBTagId tag_id, 
+                          const MBEntityHandle* handles, 
+                          int num_handles,
+                          const unsigned char* default_value )
+{
+  if (BitTag* ptr = get_tag(tag_id))
+    return ptr->clear_bits( handles, num_handles, default_value );
+  else
+    return MB_TAG_NOT_FOUND;
+}
+inline MBErrorCode 
+BitTagServer::clear_bits( MBTagId tag_id, 
+                          const MBRange& handles, 
+                          const unsigned char* default_value )
+{
+  if (BitTag* ptr = get_tag(tag_id))
+    return ptr->clear_bits( handles, default_value );
+  else
+    return MB_TAG_NOT_FOUND;
+}
+    
+
+inline MBErrorCode 
+BitTagServer::get_entities( MBTagId tag_id, MBRange& entities ) const
+{
+  if (const BitTag* ptr = get_tag(tag_id))
+    return ptr->get_entities( entities );
+  else
+    return MB_TAG_NOT_FOUND;
+}
+
+inline MBErrorCode 
+BitTagServer::get_entities( MBTagId tag_id, 
+                            MBEntityType type, 
+                            MBRange& entities ) const
+{
+  if (const BitTag* ptr = get_tag(tag_id))
+    return ptr->get_entities( type, entities );
+  else
+    return MB_TAG_NOT_FOUND;
+}
+
+inline MBErrorCode 
+BitTagServer::get_entities_with_tag_value( MBTagId tag_id, 
+                                           MBEntityType type, 
+                                           MBRange& entities,
+                                           unsigned char bits ) const
+{
+  if (const BitTag* ptr = get_tag(tag_id))
+    return ptr->get_entities_with_bits( type, entities, bits );
+  else
+    return MB_TAG_NOT_FOUND;
+}
+
+inline MBErrorCode 
+BitTagServer::get_entities( const MBRange &range,
+                            MBTagId tag_id, 
+                            MBEntityType type, 
+                            MBRange& entities ) const
+{
+  if (const BitTag* ptr = get_tag(tag_id))
+    return ptr->get_entities( range, type, entities );
+  else
+    return MB_TAG_NOT_FOUND;
+}
+
+inline MBErrorCode 
+BitTagServer::get_entities_with_tag_value( const MBRange &range,
+                                           MBTagId tag_id, 
+                                           MBEntityType type, 
+                                           MBRange& entities,
+                                           unsigned char bits ) const
+{
+  if (const BitTag* ptr = get_tag(tag_id))
+    return ptr->get_entities_with_bits( range, type, entities, bits );
+  else
+    return MB_TAG_NOT_FOUND;
+}
+
+inline MBErrorCode 
+BitTagServer::get_number_entities( const MBTagId tag_id, 
+                                   const MBEntityType type,
+                                   int& num_entities ) const
+{
+  if (const BitTag* ptr = get_tag(tag_id))
+    return ptr->get_number_entities( type, num_entities );
+  else
+    return MB_TAG_NOT_FOUND;
+}
+  
+inline MBErrorCode 
+BitTagServer::get_number_entities( const MBRange &range,
+                                   const MBTagId tag_id, 
+                                   const MBEntityType type,
+                                   int& num_entities ) const
+{
+  if (const BitTag* ptr = get_tag(tag_id))
+    return ptr->get_number_entities( range, type, num_entities );
+  else
+    return MB_TAG_NOT_FOUND;
+}
+  
+inline MBErrorCode 
+BitTagServer::get_memory_use( MBTagId tag,
+                              unsigned long& total,
+                              unsigned long& per_entity ) const
+{
+  if (const BitTag* ptr = get_tag(tag)) {
+    MBErrorCode result = ptr->get_memory_use( total, per_entity );
+    total += sizeof(*this);
+    return result;
+  }
+  else
+    return MB_TAG_NOT_FOUND;
+}
+
+#endif

Deleted: MOAB/trunk/MBBits.cpp
===================================================================
--- MOAB/trunk/MBBits.cpp	2009-11-30 23:06:35 UTC (rev 3389)
+++ MOAB/trunk/MBBits.cpp	2009-11-30 23:07:51 UTC (rev 3390)
@@ -1,552 +0,0 @@
-/**
- * MOAB, a Mesh-Oriented datABase, is a software component for creating,
- * storing and accessing finite element mesh data.
- * 
- * Copyright 2004 Sandia Corporation.  Under the terms of Contract
- * DE-AC04-94AL85000 with Sandia Coroporation, the U.S. Government
- * retains certain rights in this software.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * 
- */
-
-
-
-
-/*  Bit tools for MB
- *
- *  File   :      MBBits.hpp
- *  Creator:      Clinton Stimpson
- *  Date   :      10-10-2002
- */
-
-#include "MBBits.hpp"
-#include "MBRange.hpp"
-#include <algorithm>
-
-
-/*! bit masks for how many bits to mask */
-const unsigned int MBBitManipulator::masks[9] = 
-{
-  0x0,
-  0x01,
-  0x03,
-  0x07,
-  0x0F,
-  0x1F,
-  0x3F,
-  0x7F,
-  0xFF
-};
-
-/*! page size of 512 bytes for storing bits */
-const int MBBitPage::mPageSize = 512;
-
-/*! returns an available tag id to use when getting and setting bits */
-MBErrorCode MBBitServer::reserve_tag_id(int num_bits, MBTagId tag_id)
-{
-  for(int i=0; i<(int)MBMAXTYPE; i++)
-    if (tag_id >= mBitPageGroups[i].size())
-      mBitPageGroups[i].resize( tag_id + 1, 0 );
-  
-  for(int i=0; i<(int)MBMAXTYPE; i++)
-    if (mBitPageGroups[i][tag_id-1])
-      return MB_FAILURE;
-
-  for(int i=0; i<(int)MBMAXTYPE; i++)
-    mBitPageGroups[i][tag_id-1] = new MBBitPageGroup(num_bits);
-
-  mBitPageGroupsSize = (*mBitPageGroups).size();
-
-  return MB_SUCCESS;
-}
-
-  
-MBErrorCode MBBitPage::get_entities_with_value( unsigned char value, 
-                                                int offset, 
-                                                int count, 
-                                                int num_bits_per_flag,
-                                                MBEntityHandle first,
-                                                MBRange& results ) const
-{
-  if (mBitArray) {
-    MBRange::iterator hint = results.begin();
-    for (int i = 0; i < count; ++i) 
-      if (value == MBBitManipulator::get_bits( (offset+i)*num_bits_per_flag, 
-                                               num_bits_per_flag, mBitArray))
-        hint = results.insert( hint, first + i );
-  }
-  return MB_SUCCESS;
-}
-
-void MBBitPage::alloc_array( int num_bits_per_flag, 
-                             const unsigned char* default_value )
-{
-  assert(!mBitArray);
-  
-  mBitArray = new unsigned char[mPageSize];
-    // Modifed by J.Kraftcheck : 31 Jan, 2008:
-    //  Need to initialize to default value to ensure that we return
-    //  the default value for unset entities.  
-
-    // Zero memory if no default value.  Also, if default value is
-    // zero, we can zero all the memory w/out worring about the
-    // number of bits per entity.
-  if (!default_value || !*default_value)
-    memset(mBitArray, 0, mPageSize);
-    // Otherwise initialize memory using default value
-  else {
-      // Mask unused bits of default value so that we can set
-      // individual bits using bitwise-OR w/out having to worry
-      // about masking unwanted stuff.
-    unsigned char defval = (*default_value) & ((1u << num_bits_per_flag) - 1);
-
-    switch (num_bits_per_flag) {
-      // If number of bits is a power of two (a byte contains a whole
-      // number of tag bit values) then use memset to initialize the memory.
-      // Note fall-through for switch cases:  for 1-bit tags we first
-      // copy the lsb into the adjacent bit, then fall through to 2-bit
-      // case, copying last two bits into next two, and so on.
-      case 1: defval |= (defval << 1);
-      case 2: defval |= (defval << 2);
-      case 4: defval |= (defval << 4);
-      case 8: memset( mBitArray, defval, mPageSize );
-        break;
-      // If num_bits_per_flag is not a power of two, then values do
-      // not align with byte boundaries.  Need to initialize values
-      // individually.
-      default:
-        memset(mBitArray, 0, mPageSize);
-        // Subtract 1 from mPageSize because last byte is unused, allowing
-        // questionable MBBitManipulator code to read/write 1 past end 
-        // of array.
-        for (int i = 0; i < 8 * (mPageSize-1); i += num_bits_per_flag)
-          MBBitManipulator::set_bits( i, num_bits_per_flag, defval, mBitArray );
-    }
-  }
-}
-
-
-MBErrorCode MBBitPageGroup::get_bits( MBEntityHandle start, 
-                                      MBEntityID count,
-                                      unsigned char* bits,
-                                      const unsigned char* def_val)
-{
-  MBErrorCode result = MB_SUCCESS, tmp_result;
-  
-  
-  MBEntityID id = ID_FROM_HANDLE(start);
-  MBEntityHandle page = id/mOffsetFactor;
-  MBEntityID offset = id%mOffsetFactor;
-  MBEntityID pcount = mOffsetFactor - offset;
-  while (count) {
-    if (pcount > count)
-      pcount = count;
-    
-    if (page >= mBitPagesSize) {
-      memset( bits, def_val ? *def_val : 0, count );
-      break;
-    }
-    
-    tmp_result = mBitPages[page]->get_bits( offset, pcount, mBitsPerFlag, bits, def_val);
-    if (MB_SUCCESS != tmp_result) {
-      memset( bits, 0, pcount );
-      result = tmp_result;
-    }
-    
-    count -= pcount;
-    bits += pcount;
-    ++page;
-    offset = 0;
-    pcount = mOffsetFactor;
-  }
-  
-  return result;
-}
-
-MBErrorCode MBBitPageGroup::set_bits( MBEntityHandle start, 
-                                      MBEntityID count,
-                                      const unsigned char* bits,
-                                      const unsigned char* def_val)
-{
-  MBErrorCode result = MB_SUCCESS, tmp_result;
-  MBEntityID id = ID_FROM_HANDLE(start);
-  MBEntityHandle page = id/mOffsetFactor;
-  MBEntityID offset = id%mOffsetFactor;
-  MBEntityID pcount = mOffsetFactor - offset;
-  while (count) {
-    if (pcount > count)
-      pcount = count;
-    
-    if (page >= mBitPagesSize) {
-      for(int j = page - mBitPagesSize +1; j--;)
-        mBitPages.push_back(new MBBitPage());
-      mBitPagesSize = mBitPages.size();
-    }
-
-    tmp_result = mBitPages[page]->set_bits( offset, pcount, mBitsPerFlag, bits, def_val);
-    if (MB_SUCCESS != tmp_result) {
-      result = tmp_result;
-    }
-    
-    count -= pcount;
-    bits += pcount;
-    ++page;
-    offset = 0;
-    pcount = mOffsetFactor;
-  }
-  
-  return result;
-}
-
-  
-MBErrorCode MBBitPageGroup::get_entities_with_value( unsigned char value,
-                                                     MBEntityHandle first,
-                                                     MBEntityHandle last,
-                                                     MBRange& results )
-{
-  MBErrorCode rval;
-  assert(last >= first);
-  MBEntityID count = last - first + 1;
-  
-  MBEntityID id = ID_FROM_HANDLE(first);
-  MBEntityHandle page = id/mOffsetFactor;
-  MBEntityID offset = id%mOffsetFactor;
-  MBEntityID pcount = mOffsetFactor - offset;
-  while (count && page < mBitPagesSize) {
-    if (pcount > count)
-      pcount = count;
-    
-    rval = mBitPages[page]->get_entities_with_value( value, offset, pcount, mBitsPerFlag, first, results );
-    if (MB_SUCCESS != rval)
-      return rval;
-    
-    first += pcount;
-    count -= pcount;
-    ++page;
-    offset = 0;
-    pcount = mOffsetFactor;
-  }
-  
-  return MB_SUCCESS;
-}
-
-MBErrorCode MBBitServer::set_bits( MBTagId tag_id, 
-                                   const MBRange& handles,
-                                   const unsigned char* data,
-                                   const unsigned char* default_val)
-{
-  --tag_id; // First ID is 1.
-  if(tag_id >= mBitPageGroups[0].size() || mBitPageGroups[0][tag_id] == NULL)
-    return MB_TAG_NOT_FOUND;
-
-  MBErrorCode rval;
-  MBRange::const_pair_iterator i;
-  for (i = handles.const_pair_begin(); i != handles.const_pair_end(); ++i) {
-    MBEntityType type = TYPE_FROM_HANDLE(i->first);
-    assert(TYPE_FROM_HANDLE(i->second) == type); // should be true because id of zero is never used
-    MBEntityID count = i->second - i->first + 1;
-    rval = mBitPageGroups[type][tag_id]->set_bits(i->first, count, data, default_val);
-    if (MB_SUCCESS != rval)
-      return rval;
-    data += count;
-  }
-  return MB_SUCCESS;
-}
-
-MBErrorCode MBBitServer::get_bits( MBTagId tag_id, 
-                                   const MBRange& handles,
-                                   unsigned char* data,
-                                   const unsigned char* default_val)
-{
-  --tag_id; // First ID is 1.
-  if(tag_id >= mBitPageGroups[0].size() || mBitPageGroups[0][tag_id] == NULL)
-    return MB_TAG_NOT_FOUND;
-
-  MBErrorCode rval;
-  MBRange::const_pair_iterator i;
-  for (i = handles.const_pair_begin(); i != handles.const_pair_end(); ++i) {
-    MBEntityType type = TYPE_FROM_HANDLE(i->first);
-    assert(TYPE_FROM_HANDLE(i->second) == type); // should be true because id of zero is never used
-    MBEntityID count = i->second - i->first + 1;
-    rval = mBitPageGroups[type][tag_id]->get_bits(i->first, count, data, default_val);
-    if (MB_SUCCESS != rval)
-      return rval;
-    data += count;
-  }
-  return MB_SUCCESS;
-}
-
-/*! give back a tag id that was used to set and get bits */
-MBErrorCode MBBitServer::release_tag_id(MBTagId tag_id)
-{
-  // tag ids begin with 1
-  --tag_id;
-  
-  // make sure tag_id is good
-  if(tag_id >= (*mBitPageGroups).size())
-    return MB_TAG_NOT_FOUND;
-
-  // mark it unused
-  for(int i=0; i<(int)MBMAXTYPE; i++)
-  {
-    delete mBitPageGroups[i][tag_id];
-    mBitPageGroups[i][tag_id] = NULL;
-  }
-
-  // clean up a bit if this is the last one
-  if((tag_id+1) == (unsigned short)(*mBitPageGroups).size())
-  {
-    for(int i=0; i<(int)MBMAXTYPE; i++)
-    {
-      mBitPageGroups[i].resize(mBitPageGroups[i].size()-1);
-    }
-  }
-  
-  mBitPageGroupsSize = (*mBitPageGroups).size();
-  
-  return MB_SUCCESS;
-}
-
-
-void MBBitServer::reset_data()
-{
-  for(int i = 0; i<(int)MBMAXTYPE; i++)
-  {
-    for (std::vector<MBBitPageGroup*>::iterator iter = mBitPageGroups[i].begin();
-        iter != mBitPageGroups[i].end();
-        ++iter)
-    {
-      if(*iter == NULL)
-        continue;
-      int tag_size = (*iter)->tag_size();
-      delete *iter;
-      *iter = new MBBitPageGroup(tag_size);
-    }
-  }
-}
-
-MBErrorCode MBBitServer::get_memory_use( MBTagId tag_id,
-                                         unsigned long& total,
-                                         unsigned long& per_entity ) const
-{
-  per_entity = 1; // cannot return fraction of bytes
-  
-  unsigned max_num_tags = 0;
-  for (unsigned i = 0; i < MBMAXTYPE; ++i) {
-    if (mBitPageGroups[i].size() > max_num_tags)
-      max_num_tags = mBitPageGroups[i].size();
-
-    if (tag_id >= mBitPageGroups[i].size())
-      continue;
-      
-    total += mBitPageGroups[i][tag_id]->get_memory_use();
-    total += sizeof(MBBitPageGroup*) * mBitPageGroups[i].capacity() / mBitPageGroups[i].size();
-  }
-  total += sizeof( std::vector<MBBitPageGroup*> );
-  total += sizeof(*this) / max_num_tags;
-
-  return MB_SUCCESS;
-}
-
-unsigned long MBBitPageGroup::get_memory_use() const
-{
-  unsigned long result = sizeof(*this);
-  result += sizeof(MBBitPage*) * mBitPages.capacity();
-  for (unsigned long i = 0; i < mBitPages.size(); ++i)
-    if (mBitPages[i] && mBitPages[i]->has_data())
-      result += MBBitPage::mPageSize;
-  return result;
-}
-
-//! get the entities
-MBErrorCode MBBitPageGroup::get_entities(MBEntityType type, MBRange& entities)
-{
-  std::vector<MBBitPage*>::iterator iter;
-  int dum =0;
-  MBEntityHandle handle = CREATE_HANDLE(type, MB_START_ID, dum);
-  bool first_time = true;
-  for(iter = mBitPages.begin(); iter < mBitPages.end(); ++iter)
-  {
-    if(*iter)
-    {
-      if((*iter)->has_data())
-      {
-        entities.insert(handle, handle + mOffsetFactor);
-      }        
-    }
-    if(first_time)
-    {
-      first_time = false;
-      handle = handle + mOffsetFactor - MB_START_ID;
-    }
-    else
-      handle += mOffsetFactor;
-  }
-  return MB_SUCCESS;
-}
-
-MBErrorCode MBBitServer::get_entities(const MBRange &range, MBTagId tag_id, MBEntityType type, 
-                                        MBRange& entities)
-{
-  --tag_id;
-  if(tag_id >= mBitPageGroupsSize || (*mBitPageGroups)[tag_id] == NULL)
-    return MB_FAILURE;
-
-  MBRange dum_range;
-  MBErrorCode result = mBitPageGroups[type][tag_id]->get_entities(type, dum_range);
-  if (MB_FAILURE == result) return result;
-
-  std::set_intersection(dum_range.begin(), dum_range.end(),
-                        range.begin(), range.end(),
-                        mb_range_inserter(entities));
-  
-  return result;
-}
-
-MBErrorCode MBBitServer::get_entities_with_tag_value( MBTagId tag_id, 
-                                                      MBEntityType type,
-                                                      MBRange& entities, 
-                                                      const unsigned char bits)
-{
-  --tag_id; // First ID is 1.
-  if(tag_id >= mBitPageGroups[type].size() || mBitPageGroups[type][tag_id] == NULL)
-    return MB_TAG_NOT_FOUND;
-
-  return mBitPageGroups[type][tag_id]->
-    get_entities_with_value( bits, FIRST_HANDLE(type), LAST_HANDLE(type), entities );
-}
-
-MBErrorCode MBBitServer::get_entities_with_tag_value( const MBRange &range,
-                                                      MBTagId tag_id, 
-                                                      MBEntityType type, 
-                                                      MBRange& entities,
-                                                      const unsigned char bits)
-{
-  --tag_id; // First ID is 1.
-  if(tag_id >= mBitPageGroups[0].size() || mBitPageGroups[0][tag_id] == NULL)
-    return MB_TAG_NOT_FOUND;
-
-  MBErrorCode rval;
-  MBRange::const_pair_iterator i;
-  for (i = range.const_pair_begin(); i != range.const_pair_end(); ++i) {
-    MBEntityType this_type = TYPE_FROM_HANDLE(i->first);
-    assert(TYPE_FROM_HANDLE(i->second) == this_type); // should be true because id of zero is never used
-    if (type < this_type)
-      continue;
-    if (type > this_type)
-      break;
-      
-    rval = mBitPageGroups[type][tag_id]->
-      get_entities_with_value( bits, i->first, i->second, entities );
-    if (MB_SUCCESS != rval)
-      return rval;
-  }
-  return MB_SUCCESS;
-}
-
-MBErrorCode MBBitServer::get_number_entities( const MBTagId tag_id,
-                                              const MBEntityType type,
-                                              int& num_entities) 
-{
-  MBRange dum_range;
-  MBErrorCode result = get_entities(tag_id, type, dum_range);
-  num_entities = dum_range.size();
-  return result;
-}
-
-  
-MBErrorCode MBBitServer::get_number_entities( const MBRange &range,
-                                                const MBTagId tag_id, 
-                                                const MBEntityType type,
-                                                int& num_entities)
-{
-  MBRange dum_range;
-  MBErrorCode result = get_entities(range, tag_id, type, dum_range);
-  num_entities = dum_range.size();
-  return result;
-}
-
-#ifdef BIT_MANIP_TEST
-
-int main()
-{
-
-  unsigned char arr[10] = { 0 };
-
-  unsigned char bits=0;
-
-  MBBitManipulator::set_bits(7, 2, 0x3, arr);
-
-  bits = MBBitManipulator::get_bits(6, 3, arr);
-  
-
-  return 0;
-}
-
-
-#endif
-
-
-// unit test
-#ifdef TEST
-
-#include <stdio.h>
-#include <assert.h>
-
-int main()
-{
-
-  MBBitServer bit_server;
-  MBTagId tag_id;
-  bit_server.reserve_tag_id(5, tag_id);
-  unsigned char bits;
-  bit_server.get_bits(tag_id, 400, bits);
-  assert(bits == 0x0);
-
-  bit_server.set_bits(tag_id, 600, 0x9);
-  bit_server.get_bits(tag_id, 600, bits);
-  assert(bits == 0x9);
-
-  //bit_server.release_tag_id(tag_id);
-    
-  srand(0xb);
-
-  for(int i=100; i--; )
-  {
-    int num_bits = rand() % 9;
-    if(bit_server.reserve_tag_id(num_bits, tag_id) == MB_SUCCESS)
-    {
-      for(int j=1000; j--;)
-      {
-        unsigned short handle = rand();
-        unsigned char some_bits = rand();
-        some_bits <<= 8-num_bits;
-        some_bits >>= 8-num_bits;
-        bit_server.set_bits(tag_id, handle, some_bits);
-        unsigned char some_bits_again = rand();
-        bit_server.get_bits(tag_id, handle, some_bits_again);
-        if(some_bits_again != some_bits)
-        {
-          bit_server.get_bits(tag_id, handle, some_bits_again);
-          printf("ERROR\n  num bits = %i\n", num_bits);
-          printf( "   tag id    %i\n", tag_id);
-          printf( "   handle    %u\n", handle);
-          printf( "   set value %i\n", (int)some_bits);
-          printf( "   get value %i\n", (int)some_bits_again);
-          assert(some_bits_again == some_bits);
-        }
-      }
-      
-      bit_server.release_tag_id(tag_id);
-    }
-  }
-  return 0;
-}
-
-#endif
-
-

Deleted: MOAB/trunk/MBBits.hpp
===================================================================
--- MOAB/trunk/MBBits.hpp	2009-11-30 23:06:35 UTC (rev 3389)
+++ MOAB/trunk/MBBits.hpp	2009-11-30 23:07:51 UTC (rev 3390)
@@ -1,710 +0,0 @@
-/**
- * MOAB, a Mesh-Oriented datABase, is a software component for creating,
- * storing and accessing finite element mesh data.
- * 
- * Copyright 2004 Sandia Corporation.  Under the terms of Contract
- * DE-AC04-94AL85000 with Sandia Coroporation, the U.S. Government
- * retains certain rights in this software.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * 
- */
-
-
-/*  Bit tools for MB
- *
- *  File   :      MBBits.hpp
- *  Creator:      Clinton Stimpson
- *  Date   :      10-10-2002
- */
-
-#ifndef MB_BITS_HPP
-#define MB_BITS_HPP
-
-#ifndef IS_BUILDING_MB
-#error "MBBits.hpp isn't supposed to be included into an application"
-#endif
-
-#include "MBForward.hpp"
-#include "MBInternals.hpp"
-
-#include <assert.h>
-#include <string.h>
-
-//! bit manipulator class
-class MBBitManipulator
-{
-public:
-
-  //! set bits from value into bit array given an offset and bits per offset
-  static MBErrorCode set_bits(int bit_offset, int num_bits, 
-                       unsigned char value, unsigned char* bit_array );
-
-  //! gets bits from bit_array given an offset and bits per offset
-  static unsigned char get_bits(int bit_offset, int num_bits, 
-                      unsigned char* bit_array );
-
-  // bit_array example
-  //
-  //                 010101010101001100100111010010101010010111001010
-  // char            \1 byte/\1 byte/\1 byte/\1 byte/\1 byte/\1 byte/
-  // 3 bits per flag \1/\2/\3/\4/\5/\6/\7/\8/\9/\./\./\./\./\./\./
-  //
-  // lets offset 5 and get those bits
-  // int x = get_bits( 5, 3, char_array )
-  // bits returned are  001
-  //
-  // Assumptions made by this class:
-  //   num_bits is 8 or less, if it is greater, there is no guarantee 
-  //   you'll get what you want.
-
-private:
-
-  //! quick mod 8 operation for finding out how far some bits
-  //! are from a byte boundary
-  static int mod_8(int val)
-  {
-    return val & 0x7;
-  }  
-
-  // stores the masks indexed by how many bits to mask
-  static const unsigned int masks[9];
-};
-
-/*! set the bits in an array
-    takes bit_offset which is the ith bit in the array
-    takes num_bits which is number of bits from the ith bit to set
-    takes value which is the value to set
-    takes_byte array which is the array of bits
-*/
-inline MBErrorCode MBBitManipulator::set_bits(
-    int bit_offset,
-    int num_bits,
-    unsigned char value,
-    unsigned char* byte_array 
-    )
-{
-
-  // check the value to make sure it is good
-  if((value | masks[num_bits]) != masks[num_bits])
-    return MB_FAILURE;
-
-  // offset our pointer to where we want it
-  byte_array += bit_offset/8;
-
-  // copy data from two bytes into our unsigned short
-  unsigned short int old_data = *(byte_array +1) << 8;
-  old_data += *byte_array;
-
-  // shift the value so it is lined up with word boundary of bit array
-  unsigned short int aligned_value = value << mod_8(bit_offset);
-
-  // shift the mask where we need it
-  unsigned short int aligned_mask = masks[num_bits] << mod_8(bit_offset);
-
-  // AND aligned_ask and byte_bound to preserve bits that are on
-  unsigned short int x = (~aligned_mask) & old_data;
-
-  // OR to set value
-  old_data = x | aligned_value;
-
-  // set the data
-  *byte_array = (old_data & 0xFF); 
-  *(byte_array + 1) = (old_data >> 8);
-
-  return MB_SUCCESS;
-}
-
-/*! get the bits in an array
-    takes bit_offset which is the ith bit in the array
-    takes num_bits which is number of bits from the ith bit to get
-    takes_byte array which is the array of bits
-    return the bits
-*/
-inline unsigned char MBBitManipulator::get_bits(
-    int bit_offset,
-    int num_bits,
-    unsigned char* byte_array
-    )
-{
-  // offset our pointer to where we want it
-  byte_array += bit_offset/8;
-  
-  // copy data from two bytes into our unsigned short
-  unsigned short int data = *(byte_array +1) << 8;
-  data += *byte_array;
-
-  // shift data where we need it
-  unsigned int aligned_data = data >> mod_8(bit_offset);
-
-  // AND caputures value of the flag
-  return aligned_data & masks[num_bits];
-}
-
-
-//! bit page class
-/*! This class stores a page of memory for storing bits
-*/
-class MBBitPage
-{
-
-public:
-
-  //! the page size
-  static const int mPageSize;
-  
-  // page sizes are 512 bytes   
-  //   for 1 bit per entity, that is 4096 bit flags
-  //   for 2 bits per entity, that is 2048 bit flags
-  //   for 3 bits per entity, that is 1365.333 bit flags
-  //   for 4 bits per entity, that is 1024 bit flags
-  //   for 5 bits per entity, that is 819.2 bit flags
-  //   for 6 bits per entity, that is 682.666 bit flags
-  //   for 7 bits per entity, that is 585.142857
-  //   for 8 bits per entity, that is 512 bit flags
-  //
-  //   for some, we'll have left over bits on the end.
-
-  // default constructor
-  MBBitPage() : mBitArray(NULL) {}
-  
-  // default destructor
-  ~MBBitPage()
-  {  
-    if(mBitArray)
-      delete [] mBitArray;
-  }
-  
-  //! get the bits from a bit page
-  MBErrorCode get_bits(int offset, int num_bits_per_flag, unsigned char& bits,
-                       const unsigned char* default_value);
-  
-  //! set the bits in a bit page
-  MBErrorCode set_bits(int offset, int num_bits_per_flag, unsigned char bits, 
-                       const unsigned char* default_value);
-  
-  //! get the bits from a bit page
-  MBErrorCode get_bits(int offset, int count, int num_bits_per_flag, 
-                       unsigned char* bits,
-                       const unsigned char* default_value);
-  
-  //! set the bits in a bit page
-  MBErrorCode set_bits(int offset, int count, int num_bits_per_flag, 
-                       const unsigned char* bits, 
-                       const unsigned char* default_value);
-  
-  MBErrorCode get_entities_with_value( unsigned char value, 
-                                       int offset, 
-                                       int count, 
-                                       int num_bits_per_flag,
-                                       MBEntityHandle first,
-                                       MBRange& results ) const;
-  
-  //! set the bits in a bit page only if space has been allocated
-  MBErrorCode weak_set_bits(int offset, int num_bits_per_flag, unsigned char bits);
-
-  bool has_data() const { return mBitArray != NULL; }
-
-private:
-  //! bit array  uses lazy allocation
-  unsigned char* mBitArray;
-
-  void alloc_array( int num_bits_per_flag, const unsigned char* default_value );
-  
-  //! don't allow copying of these bit pages
-  MBBitPage(const MBBitPage&) 
-    : mBitArray(NULL) 
-  { 
-    // not even by self
-    assert(0);
-  }
-  
-  //! don't allow copying of these bit pages
-  MBBitPage& operator=(const MBBitPage&) 
-  { 
-    // not even by self
-    assert(0);
-    return *this;
-  }
-  
-};
-
-/*! get the bits from a bit page
-    takes bit offset into the page
-    takes how many bits to get
-    return bits
-*/
-inline MBErrorCode MBBitPage::get_bits(int offset, int num_bits_per_flag,
-                                       unsigned char& bits,
-                                       const unsigned char* def_val)
-{
-  // because the default bits are 0x0, 
-  // we'll return that if no memory has been allocated
-  if(!mBitArray)
-  {
-    bits = def_val ? *def_val : 0;
-    return MB_SUCCESS;
-  }
-
-  // get bits using bit manipulator
-  bits = MBBitManipulator::get_bits(
-      offset*num_bits_per_flag, num_bits_per_flag, mBitArray);
-
-  return MB_SUCCESS;
-}
-inline MBErrorCode MBBitPage::get_bits(int offset, int count,
-                                       int num_bits_per_flag,
-                                       unsigned char* bits,
-                                       const unsigned char* def_val)
-{
-  // because the default bits are 0x0, 
-  // we'll return that if no memory has been allocated
-  if(!mBitArray)
-  {
-    memset( bits, def_val ? *def_val : 0, count );
-    return MB_SUCCESS;
-  }
-
-  // get bits using bit manipulator
-  for (int i = 0; i < count; ++i)
-    bits[i] = MBBitManipulator::get_bits(
-      (offset+i)*num_bits_per_flag, num_bits_per_flag, mBitArray);
-
-  return MB_SUCCESS;
-}
-
-
-/*! set the bits in a bit page
-    takes bit offset into the page
-    takes how many bits to set
-    takes the bits to set
-*/
-inline MBErrorCode MBBitPage::set_bits( int offset, 
-                                        int num_bits_per_flag, 
-                                        unsigned char bits,
-                                        const unsigned char* default_value)
-{
-  // if memory hasn't been allocated, allocate it and zero the memory
-  if(!mBitArray)
-    alloc_array( num_bits_per_flag, default_value );
-
-  // set the bits using bit manipulator
-  return MBBitManipulator::set_bits(
-      offset*num_bits_per_flag, num_bits_per_flag, bits, mBitArray);
-}
-inline MBErrorCode MBBitPage::set_bits( int offset, int count,
-                                        int num_bits_per_flag, 
-                                        const unsigned char* bits,
-                                        const unsigned char* default_value)
-{
-  // if memory hasn't been allocated, allocate it and zero the memory
-  if(!mBitArray)
-    alloc_array( num_bits_per_flag, default_value );
-
-  // set the bits using bit manipulator
-  for (int i = 0; i < count; ++i) 
-    MBBitManipulator::set_bits( (offset+i)*num_bits_per_flag,
-                                num_bits_per_flag,
-                                bits[i], mBitArray );
-  return MB_SUCCESS;
-}
-
-
-/*! weak set bits only sets bits if memory has been allocated
-    takes bit offset
-    takes number of bits to set
-    takes the bits to set
-*/
-inline MBErrorCode MBBitPage::weak_set_bits(int offset, 
-    int num_bits_per_flag, unsigned char bits)
-{
-  return mBitArray ? MBBitManipulator::set_bits(
-      offset*num_bits_per_flag, num_bits_per_flag, bits, mBitArray) : MB_SUCCESS;
-}
-
-//! class which is a collection of bit pages
-class MBBitPageGroup
-{
-public:
-  // default constructor
-  MBBitPageGroup(int bits_per_flag)
-    : mBitsPerFlag(bits_per_flag)
-  {
-    //compute the offset factor based on the number of bits for each entity
-    //this offset will most likely leave some unused bits at the end of a page
-    mOffsetFactor = compute_offset_factor(bits_per_flag);
-    mBitPagesSize = 0;
-  }
-
-  // default destructor
-  ~MBBitPageGroup() 
-  { 
-    // delete each bit page
-    for (std::vector<MBBitPage*>::iterator iter = mBitPages.begin(); iter != mBitPages.end(); ++iter)
-      delete *iter;
-
-    // clean out the vector of pointers
-    mBitPages.clear(); 
-  }
-
-  //! get bits from bit pages
-  MBErrorCode get_bits(MBEntityHandle handle, unsigned char& bits,
-                       const unsigned char* default_value);
-
-  //! set bits in bit pages
-  MBErrorCode set_bits(MBEntityHandle handle, unsigned char bits, 
-                       const unsigned char* default_value);
-
-  //! get bits from bit pages
-  MBErrorCode get_bits(MBEntityHandle start, MBEntityID count,
-                       unsigned char* data,
-                       const unsigned char* default_value);
-
-  //! set bits in bit pages
-  MBErrorCode set_bits(MBEntityHandle start, MBEntityID count,
-                       const unsigned char* data, 
-                       const unsigned char* default_value);
-
-  //! set bits in bit pages only if the bit page allocated memory
-  MBErrorCode weak_set_bits(MBEntityHandle handle, unsigned char bits);
-
-  MBErrorCode get_entities(MBEntityType type, MBRange& entities);
-  
-  MBErrorCode get_entities_with_value( unsigned char value,
-                                       MBEntityHandle first,
-                                       MBEntityHandle last,
-                                       MBRange& results );
-
-  //! if this page group contains this entity, return true, otherwise false
-  bool contains(const MBEntityHandle handle) const;
-
-  int tag_size() const { return mBitsPerFlag; }
-  
-  unsigned long get_memory_use( ) const;
-
-private:
-
-  // compute offset factor to use when computing which page to index into
-  int compute_offset_factor(int num_bits)
-  {
-    // subtract one from page size to prevent reading past
-    // the page one byte (BitManipulator does this).
-    // this results in one byte at the end of the page
-    // that isn't used, but that's no big deal.
-    return (MBBitPage::mPageSize - 1) * 8 / num_bits;
-  }
-  
-  //!  number of bits for each entity  
-  unsigned short mBitsPerFlag;
-  
-  //! offset factor used when computing which page to jump to
-  unsigned short mOffsetFactor;
-
-  unsigned int  mBitPagesSize;
-
-  //! vector of bit pages
-  std::vector<MBBitPage*> mBitPages;
-  
-  //! don't allow copy of this class
-  MBBitPageGroup& operator=(const MBBitPageGroup&)
-  {
-    assert(0);
-    return *this;
-  }
-
-  //! don't allow copy of this class
-  MBBitPageGroup(const MBBitPageGroup&)
-  {
-    assert(0);
-  }
-
-};
-
-/*! get the bits from bit pages
-    takes entity handle
-    return the bits
-*/
-inline MBErrorCode MBBitPageGroup::get_bits(MBEntityHandle handle, 
-                                            unsigned char& bits,
-                                            const unsigned char* def_val)
-{
-  // strip off the entity type
-  handle = ID_FROM_HANDLE(handle);
-  // figure out which page to jump to
-  unsigned int which_page = handle / mOffsetFactor;
-  
-  // if the page isn't there, just return 0x0
-  if(which_page >= mBitPagesSize) {
-    bits = def_val ? *def_val : 0;
-    return MB_SUCCESS;
-  }
-
-  // return bits from bit page
-  return mBitPages[which_page]->get_bits( (handle - ( which_page * mOffsetFactor )), 
-                                          mBitsPerFlag, bits, def_val);
-}
-
-/*! set the bits in bit pages
-    takes entity handle
-    takes the bits to set
-*/
-inline MBErrorCode MBBitPageGroup::set_bits( MBEntityHandle handle, 
-                                             unsigned char bits,
-                                             const unsigned char* default_value )
-{
-  // strip off the entity type
-  handle = ID_FROM_HANDLE(handle);
-  // figure out which page to jump to
-  unsigned int which_page = handle / mOffsetFactor;
-
-  // if the page doesn't exist, make one
-  if(which_page >= mBitPagesSize)
-  {
-    for(int j= which_page - mBitPagesSize +1; j--;)
-      mBitPages.push_back(new MBBitPage());
-    mBitPagesSize = mBitPages.size();
-  }
-
-  // return set of bits in page
-  return mBitPages[which_page]->
-    set_bits( (handle - ( which_page * mOffsetFactor )), 
-              mBitsPerFlag, bits, default_value );
-}
-
-
-/*! set the bits in bit pages
-    if the page didn't allocate memory yet, the bits aren't set
-    takes entity handle
-    takes the bits to set
-*/
-inline MBErrorCode MBBitPageGroup::weak_set_bits(MBEntityHandle handle, unsigned char bits)
-{
-  // strip off entity type
-  handle = ID_FROM_HANDLE(handle);
-  // find out which page to jump to
-  unsigned int which_page = handle / mOffsetFactor;
-  
-  // if the page doesn't exist, return
-  if(which_page >= mBitPagesSize)
-    return MB_SUCCESS;
- 
-  // try to set bits 
-  return mBitPages[which_page]->weak_set_bits( (handle - ( which_page * mOffsetFactor )), mBitsPerFlag, bits);
-}
-
-inline bool MBBitPageGroup::contains(const MBEntityHandle handle) const
-{
-  // strip off the entity type
-  unsigned int entity_id = ID_FROM_HANDLE(handle);
-  // figure out which page to jump to
-  unsigned int which_page = entity_id / mOffsetFactor;
-  
-  // if the page isn't there, just return 0x0
-  return (which_page >= mBitPagesSize ? false : true);
-}
-
-//! MBBitServer class provides constant time 
-//! lookup for bit flags tagged on entities
-class MBBitServer
-{
-public:
-  //! default constructor
-  MBBitServer()
-  {
-    mBitPageGroupsSize = 0;
-  }
-  //! default destructor
-  ~MBBitServer()
-  {
-    // clean things out
-    for(int i = 0; i<(int)MBMAXTYPE; i++)
-    {
-      for (std::vector<MBBitPageGroup*>::iterator iter = mBitPageGroups[i].begin();
-          iter != mBitPageGroups[i].end();
-          ++iter)
-      {
-        if(*iter == NULL)
-          continue;
-        delete *iter;
-      }
-
-      mBitPageGroups[i].clear();
-    }
-  }
-
-  void reset_data();
-
-  //! allocate data for tag with specified ID
-  MBErrorCode reserve_tag_id(int num_bits, MBTagId tag_id);
-  //! release a tag id for reuse
-  MBErrorCode release_tag_id(MBTagId tag_id);
-
-  //! get the bits associated with entity handles
-  MBErrorCode get_bits(MBTagId tag_id, 
-                       const MBEntityHandle* handles, 
-                       int num_handles, 
-                       unsigned char* data,
-                       const unsigned char* default_value);
-  MBErrorCode get_bits(MBTagId tag_id, 
-                       const MBRange& handles, 
-                       unsigned char* data,
-                       const unsigned char* default_value);
-  //! set the bits associated with an entity handle
-  MBErrorCode set_bits(MBTagId tag_id, 
-                       const MBEntityHandle* handles, 
-                       int num_handles,
-                       const unsigned char* data, 
-                       const unsigned char* default_value);
-  MBErrorCode set_bits(MBTagId tag_id, 
-                       const MBRange& handles, 
-                       const unsigned char* data, 
-                       const unsigned char* default_value);
-  //! set the bits associated with an entity handle, only if memory has been allocated
-  MBErrorCode weak_set_bits(MBTagId tag_id, MBEntityHandle handle, unsigned char bits);
-
-  //! clear bits
-  MBErrorCode clear_bits( MBTagId tag_id, MBEntityHandle handle, const unsigned char* defval )
-    { return weak_set_bits( tag_id, handle, defval ? *defval : '\0' ); }
-
-  MBErrorCode get_entities(MBTagId tag_id, MBRange& entities);
-
-  MBErrorCode get_entities(MBTagId tag_id, MBEntityType type, MBRange& entities);
-
-  MBErrorCode get_entities_with_tag_value(MBTagId tag_id, 
-                                           MBEntityType type, 
-                                           MBRange& entities,
-                                           const unsigned char bits);
-
-  MBErrorCode get_entities(const MBRange &range,
-                            MBTagId tag_id, 
-                            MBEntityType type, 
-                            MBRange& entities);
-
-  MBErrorCode get_entities_with_tag_value(const MBRange &range,
-                                           MBTagId tag_id, MBEntityType type, 
-                                           MBRange& entities,
-                                           const unsigned char bits);
-
-    //! get all tags defined on an entity
-  MBErrorCode get_tags(const MBEntityHandle entity,
-                        std::vector<MBTag> &tags);
-
-  MBErrorCode get_number_entities(const MBTagId tag_id, 
-                                   const MBEntityType type,
-                                   int& num_entities);
-  
-  MBErrorCode get_number_entities( const MBRange &range,
-                                    const MBTagId tag_id, 
-                                    const MBEntityType type,
-                                    int& num_entities);
-  
-  MBErrorCode get_memory_use( MBTagId tag,
-                              unsigned long& total,
-                              unsigned long& per_entity ) const;
-private:
-  //! bit pages are indexed by tag id and entity type
-  std::vector< MBBitPageGroup* > mBitPageGroups[MBMAXTYPE];
-  unsigned long mBitPageGroupsSize;
-
-};
-
-/*! get some bits based on a tag id and handle */
-inline 
-MBErrorCode MBBitServer::get_bits( MBTagId tag_id, 
-                                   const MBEntityHandle* handles, 
-                                   int num_handles,
-                                   unsigned char* data,
-                                   const unsigned char* default_val)
-{
-  --tag_id; // First ID is 1.
-  if(tag_id >= mBitPageGroups[0].size() || mBitPageGroups[0][tag_id] == NULL)
-    return MB_TAG_NOT_FOUND;
-
-  MBErrorCode rval;
-  for (int i = 0; i < num_handles; ++i) {
-    rval = mBitPageGroups[TYPE_FROM_HANDLE(handles[i])][tag_id]
-      ->get_bits(handles[i], data[i], default_val);
-    if (MB_SUCCESS != rval)
-      return rval;
-  }
-  return MB_SUCCESS;
-}
-
-inline 
-MBErrorCode MBBitServer::set_bits( MBTagId tag_id, 
-                                   const MBEntityHandle* handles, 
-                                   int num_handles,
-                                   const unsigned char* data,
-                                   const unsigned char* default_val)
-{
-  --tag_id; // First ID is 1.
-  if(tag_id >= mBitPageGroups[0].size() || mBitPageGroups[0][tag_id] == NULL)
-    return MB_TAG_NOT_FOUND;
-
-  MBErrorCode rval;
-  for (int i = 0; i < num_handles; ++i) {
-    rval = mBitPageGroups[TYPE_FROM_HANDLE(handles[i])][tag_id]
-      ->set_bits(handles[i], data[i], default_val);
-    if (MB_SUCCESS != rval)
-      return rval;
-  }
-  return MB_SUCCESS;
-}
-
-/*! set some bits based on a tag id and handle only if memory has been allocated*/
-inline MBErrorCode MBBitServer::weak_set_bits(MBTagId tag_id, 
-    MBEntityHandle handle, unsigned char bits)
-{
-  --tag_id; // First ID is 1.
-  if(tag_id >= mBitPageGroupsSize || (*mBitPageGroups)[tag_id] == NULL)
-    return MB_SUCCESS;
-
-  return mBitPageGroups[TYPE_FROM_HANDLE(handle)][tag_id]->weak_set_bits(handle, bits);
-}
-
-inline MBErrorCode MBBitServer::get_entities(MBTagId tag_id, MBRange& entities)
-{
-  --tag_id; // First ID is 1.
-  MBErrorCode result = MB_SUCCESS;
-  if(tag_id >= mBitPageGroupsSize || (*mBitPageGroups)[tag_id] == NULL)
-    result = MB_FAILURE;
-  else {
-    for (MBEntityType type = MBVERTEX; type != MBMAXTYPE; type++) {
-      MBErrorCode tmp_result = mBitPageGroups[type][tag_id]->get_entities(type, entities);
-      if (MB_SUCCESS != tmp_result) result = tmp_result;
-    }
-  }
-  
-  return result;
-}
-
-inline MBErrorCode MBBitServer::get_entities(MBTagId tag_id, MBEntityType type, MBRange& entities)
-{
-  --tag_id; // First ID is 1.
-  if(tag_id >= mBitPageGroupsSize || (*mBitPageGroups)[tag_id] == NULL)
-    return MB_FAILURE;
-
-  return mBitPageGroups[type][tag_id]->get_entities(type, entities);
-}
-
-    //! get all tags defined on an entity
-inline MBErrorCode MBBitServer::get_tags(const MBEntityHandle entity,
-                                           std::vector<MBTag> &tags) 
-{
-    // get the tags defined for this type
-  MBEntityType this_type = TYPE_FROM_HANDLE(entity);
-
-  for (long i = 0; i < (long) mBitPageGroups[this_type].size(); i++) {
-    if (mBitPageGroups[this_type][i] != NULL &&
-        mBitPageGroups[this_type][i]->contains(entity))
-      tags.push_back(TAG_HANDLE_FROM_ID(i+1, MB_TAG_BIT));
-  }
-  return MB_SUCCESS;
-}
-
-#endif
-
-

Modified: MOAB/trunk/Makefile.am
===================================================================
--- MOAB/trunk/Makefile.am	2009-11-30 23:06:35 UTC (rev 3389)
+++ MOAB/trunk/Makefile.am	2009-11-30 23:07:51 UTC (rev 3390)
@@ -112,6 +112,8 @@
 libMOAB_la_SOURCES = \
   AEntityFactory.cpp \
   AEntityFactory.hpp \
+  BitTagServer.cpp \
+  BitTagServer.hpp \
   DualTool.cpp \
   ElementSequence.hpp \
   EntitySequence.cpp \
@@ -135,8 +137,6 @@
   MBAlloc.hpp \
   MBAxisBox.cpp \
   MBAxisBox.hpp \
-  MBBits.cpp \
-  MBBits.hpp \
   MBBSPTree.cpp \
   MBCN.cpp \
   MBCNArrays.hpp \

Modified: MOAB/trunk/TagServer.cpp
===================================================================
--- MOAB/trunk/TagServer.cpp	2009-11-30 23:06:35 UTC (rev 3389)
+++ MOAB/trunk/TagServer.cpp	2009-11-30 23:07:51 UTC (rev 3390)
@@ -41,7 +41,7 @@
 #include "TagServer.hpp"
 #include "MBRange.hpp"
 #include "SparseTagSuperCollection.hpp"
-#include "MBBits.hpp"
+#include "BitTagServer.hpp"
 #include "MBInterface.hpp"
 #include "SequenceManager.hpp"
 #include "TagCompare.hpp"
@@ -65,7 +65,7 @@
   : sequenceManager(seqman)
 {
   mSparseData = new SparseTagSuperCollection;
-  mBitServer = new MBBitServer;
+  mBitServer = new BitTagServer;
 }
 
 TagServer::~TagServer()
@@ -207,8 +207,9 @@
 
   for (tag_id = 1; tag_id <= mTagTable[MB_TAG_BIT].size(); ++tag_id) 
     if (mTagTable[MB_TAG_BIT][tag_id-1].is_valid())
-        // default data for bits is zero
-      mBitServer->weak_set_bits( tag_id, entity_handle, 0 );
+      mBitServer->clear_bits( tag_id, &entity_handle, 1,
+                              reinterpret_cast<const unsigned char*>
+                              (mTagTable[MB_TAG_DENSE][tag_id-1].default_value()) );
 
   for (tag_id = 1; tag_id <= mTagTable[MB_TAG_SPARSE].size(); ++tag_id) 
     if (mTagTable[MB_TAG_SPARSE][tag_id-1].is_valid())
@@ -677,7 +678,7 @@
     case MB_TAG_SPARSE:
       return mSparseData->remove_data(tag_id, entity_handle);
     case MB_TAG_BIT:
-      return mBitServer->clear_bits( tag_id, entity_handle, 
+      return mBitServer->clear_bits( tag_id, &entity_handle, 1,
                                 static_cast<const unsigned char*>(defval) );
     case MB_TAG_MESH:
       return MB_FAILURE;

Modified: MOAB/trunk/TagServer.hpp
===================================================================
--- MOAB/trunk/TagServer.hpp	2009-11-30 23:06:35 UTC (rev 3389)
+++ MOAB/trunk/TagServer.hpp	2009-11-30 23:07:51 UTC (rev 3390)
@@ -45,7 +45,7 @@
 class MBRange;
 class SparseTagSuperCollection;
 class SequenceManager;
-class MBBitServer;
+class BitTagServer;
 
 //! SparseTagServer class which associates tag data with entities
 class TagServer
@@ -327,7 +327,7 @@
   SequenceManager* sequenceManager;
 
   //! manager for the bit data
-  MBBitServer* mBitServer;
+  BitTagServer* mBitServer;
 
 };
 



More information about the moab-dev mailing list