[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