[MOAB-dev] r1266 - MOAB/trunk
kraftche at mcs.anl.gov
kraftche at mcs.anl.gov
Fri Aug 31 11:38:22 CDT 2007
Author: kraftche
Date: 2007-08-31 11:38:22 -0500 (Fri, 31 Aug 2007)
New Revision: 1266
Modified:
MOAB/trunk/DenseTagCollections.cpp
MOAB/trunk/DenseTagCollections.hpp
MOAB/trunk/MBBits.cpp
MOAB/trunk/MBBits.hpp
MOAB/trunk/SparseTagCollections.cpp
MOAB/trunk/SparseTagCollections.hpp
MOAB/trunk/TagServer.cpp
MOAB/trunk/TagServer.hpp
Log:
o make TagServer::mTagTable a 2D array indexed by tag type and tag id
(was a std::map from tag handle to TagInfo)
o make TagServer responsible for allocating tag ids, rather than the
individual tag storage implementations (dense, sparse, bit)
Modified: MOAB/trunk/DenseTagCollections.cpp
===================================================================
--- MOAB/trunk/DenseTagCollections.cpp 2007-08-30 14:50:36 UTC (rev 1265)
+++ MOAB/trunk/DenseTagCollections.cpp 2007-08-31 16:38:22 UTC (rev 1266)
@@ -36,25 +36,23 @@
const int DensePage::mPageSize = 1024;
/*! returns an available tag id to use when getting and setting data */
-MBErrorCode DenseTagSuperCollection::reserve_tag_id(int num_bytes, const void* default_data, MBTagId& tag_id)
+MBErrorCode DenseTagSuperCollection::reserve_tag_id(int num_bytes, const void* default_data, MBTagId tag_id)
{
// make sure we get a good number of bytes
if(num_bytes <= 0 )
- {
- tag_id = 0;
return MB_FAILURE;
- }
- for (tag_id = 0; tag_id < mDensePageGroups.size(); ++tag_id)
- if (!mDensePageGroups[tag_id])
- break;
+ // make sure we have storage for tag id
+ if (mDensePageGroups.size() <= tag_id)
+ mDensePageGroups.resize( tag_id+1, 0 );
- if (tag_id == mDensePageGroups.size())
- mDensePageGroups.push_back( new DensePageGroup( num_bytes, default_data ) );
- else
- mDensePageGroups[tag_id] = new DensePageGroup( num_bytes, default_data ) ;
+ // make sure tag_id isn't already in use
+ if (mDensePageGroups[tag_id])
+ return MB_FAILURE;
+
+ // allocate tag data
+ mDensePageGroups[tag_id] = new DensePageGroup( num_bytes, default_data ) ;
- // can we really fail?
return MB_SUCCESS;
}
Modified: MOAB/trunk/DenseTagCollections.hpp
===================================================================
--- MOAB/trunk/DenseTagCollections.hpp 2007-08-30 14:50:36 UTC (rev 1265)
+++ MOAB/trunk/DenseTagCollections.hpp 2007-08-31 16:38:22 UTC (rev 1266)
@@ -362,8 +362,8 @@
void reset_data();
- //! return an available tag id for use
- MBErrorCode reserve_tag_id(int data_size, const void* default_data, MBTagId& tag_id);
+ //! allocate new tag id
+ MBErrorCode reserve_tag_id(int data_size, const void* default_data, MBTagId tag_id);
//! release a tag id for reuse
MBErrorCode release_tag_id(MBTagId tag_id);
//! get the tag size
Modified: MOAB/trunk/MBBits.cpp
===================================================================
--- MOAB/trunk/MBBits.cpp 2007-08-30 14:50:36 UTC (rev 1265)
+++ MOAB/trunk/MBBits.cpp 2007-08-31 16:38:22 UTC (rev 1266)
@@ -45,41 +45,22 @@
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)
+MBErrorCode MBBitServer::reserve_tag_id(int num_bits, MBTagId tag_id)
{
- tag_id = 0;
+ 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;
- // make sure we get a good number of bits
- if(num_bits <= 0 || num_bits >8)
- return MB_FAILURE;
-
- // see if we have any bit page groups that aren't being used
- for(std::vector<MBBitPageGroup*>::iterator iter = (*mBitPageGroups).begin();
- iter != (*mBitPageGroups).end(); ++iter)
- {
- if(*iter == NULL)
- {
- tag_id = iter - (*mBitPageGroups).begin() + 1;
- break;
- }
- }
-
- // if they are all being used, make space for a new one
- if(!tag_id)
- {
- for(int i=0; i<(int)MBMAXTYPE; i++)
- mBitPageGroups[i].push_back( NULL );
- tag_id = (*mBitPageGroups).size();
- }
-
for(int i=0; i<(int)MBMAXTYPE; i++)
mBitPageGroups[i][tag_id-1] = new MBBitPageGroup(num_bits);
mBitPageGroupsSize = (*mBitPageGroups).size();
- // can we really fail?
return MB_SUCCESS;
-
}
Modified: MOAB/trunk/MBBits.hpp
===================================================================
--- MOAB/trunk/MBBits.hpp 2007-08-30 14:50:36 UTC (rev 1265)
+++ MOAB/trunk/MBBits.hpp 2007-08-31 16:38:22 UTC (rev 1266)
@@ -453,8 +453,8 @@
void reset_data();
- //! return an available tag id for use
- MBErrorCode reserve_tag_id(int num_bits, MBTagId& tag_id);
+ //! 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);
Modified: MOAB/trunk/SparseTagCollections.cpp
===================================================================
--- MOAB/trunk/SparseTagCollections.cpp 2007-08-30 14:50:36 UTC (rev 1265)
+++ MOAB/trunk/SparseTagCollections.cpp 2007-08-31 16:38:22 UTC (rev 1266)
@@ -60,20 +60,17 @@
}
-MBErrorCode SparseTagSuperCollection::reserve_tag_id(int data_size, MBTagId& tag_id)
+MBErrorCode SparseTagSuperCollection::reserve_tag_id(int data_size, MBTagId tag_id)
{
if(data_size<=0)
return MB_FAILURE;
- // start at 1
- tag_id = 1;
-
- while (tag_id < mDataTags.size() && mDataTags[tag_id])
- ++tag_id;
-
if (tag_id >= mDataTags.size())
mDataTags.resize( tag_id+1, 0 );
+ if (mDataTags[tag_id])
+ return MB_FAILURE;
+
mDataTags[tag_id] = new SparseTagCollection(data_size);
return MB_SUCCESS;
}
Modified: MOAB/trunk/SparseTagCollections.hpp
===================================================================
--- MOAB/trunk/SparseTagCollections.hpp 2007-08-30 14:50:36 UTC (rev 1265)
+++ MOAB/trunk/SparseTagCollections.hpp 2007-08-31 16:38:22 UTC (rev 1266)
@@ -137,8 +137,8 @@
void reset_data();
- //! reserves an MBTagId for use
- MBErrorCode reserve_tag_id(int data_size, MBTagId& tag_id);
+ //! allocate new tag id
+ MBErrorCode reserve_tag_id(int data_size, MBTagId tag_id);
//! releases an MBTagId
MBErrorCode release_tag_id(MBTagId tag_id);
Modified: MOAB/trunk/TagServer.cpp
===================================================================
--- MOAB/trunk/TagServer.cpp 2007-08-30 14:50:36 UTC (rev 1265)
+++ MOAB/trunk/TagServer.cpp 2007-08-31 16:38:22 UTC (rev 1266)
@@ -58,19 +58,24 @@
return sizes[t];
}
+
+void TagInfo::invalidate()
+{
+ mTagName.clear();
+ isValid = false;
+ delete [] mDefaultValue;
+ mDefaultValue = 0;
+ delete [] mMeshValue;
+ mMeshValue = 0;
+}
+
+
/*
TagServer functions ----------------------------------
*/
TagServer::TagServer()
{
- // we need these tag properties to be in order.
- // if this order is changed, then change reset_data() as well
- assert(MB_TAG_BIT < MB_TAG_SPARSE);
- assert(MB_TAG_SPARSE < MB_TAG_DENSE );
- assert(MB_TAG_DENSE < MB_TAG_MESH );
- assert(MB_TAG_MESH < MB_TAG_LAST );
-
mSparseData = new SparseTagSuperCollection;
mDenseData = new DenseTagSuperCollection;
mBitServer = new MBBitServer;
@@ -78,12 +83,9 @@
TagServer::~TagServer()
{
- if(mSparseData)
- delete mSparseData;
- if(mDenseData)
- delete mDenseData;
- if(mBitServer)
- delete mBitServer;
+ delete mSparseData;
+ delete mDenseData;
+ delete mBitServer;
}
@@ -104,96 +106,90 @@
MBTag &tag_handle,
const void *default_value)
{
+ // Check if name is already in use
+ // if so, pass back the existing tag handle.
+ // NOTE: If name is NULL or empty (tag is unnamed),
+ // get_handle will return zero, so no explicit
+ // check is required here.
+ tag_handle = get_handle( tag_name );
+ if (tag_handle)
+ return MB_ALREADY_ALLOCATED;
- if(NULL != tag_name && strcmp(tag_name, "") != 0)
- {
- // verify that the name doesn't already exist for this entity type
- for(std::map<MBTag, TagInfo>::iterator tag_iterator = mTagTable.begin();
- tag_iterator != mTagTable.end();
- ++tag_iterator)
- {
- // if the type and name matches, another tag, return a "null" handle
- if(strcmp(tag_name, tag_iterator->second.get_name().c_str()) == 0)
- {
- tag_handle = tag_iterator->first;
- return MB_ALREADY_ALLOCATED;
- }
- }
- }
-
- MBErrorCode result = MB_FAILURE;;
- MBTagId id;
-
// Input size must be a multiple of the size of the data type.
int typesize = TagInfo::size_from_data_type( data_type );
if (data_size % typesize)
return MB_FAILURE;
-
- switch(storage) {
+
+ // data type must be BIT of tag storage type is BIT
+ if (storage == MB_TAG_BIT && data_type != MB_TYPE_BIT)
+ return MB_FAILURE;
+
+ // find an unused tag id
+ std::vector<TagInfo>& list = mTagTable[storage];
+ std::vector<TagInfo>::iterator i;
+ for (i = list.begin(); i != list.end(); ++i)
+ if (!i->is_valid())
+ break;
+
+ // add TagInfo entry for new tag
+ if (i == list.end())
+ i = list.insert( i, TagInfo( tag_name, data_size, data_type, default_value ) );
+ else
+ *i = TagInfo( tag_name, data_size, data_type, default_value );
+
+
+ MBTagId tag_id = i - list.begin() + 1;
+ tag_handle = TAG_HANDLE_FROM_ID( tag_id, storage );
+
+ MBErrorCode result = MB_FAILURE;
+ switch (storage) {
case MB_TAG_BIT:
- if (data_type != MB_TYPE_BIT)
- return MB_FAILURE;
- result = mBitServer->reserve_tag_id(data_size, id);
+ result = mBitServer->reserve_tag_id( data_size, tag_id );
break;
case MB_TAG_SPARSE:
- result = mSparseData->reserve_tag_id(data_size, id);
+ result = mSparseData->reserve_tag_id(data_size, tag_id);
break;
case MB_TAG_DENSE:
- result = mDenseData->reserve_tag_id(data_size, default_value, id);
+ result = mDenseData->reserve_tag_id(data_size, default_value, tag_id);
break;
case MB_TAG_MESH:
- result = reserve_mesh_tag_id( id );
+ result = MB_SUCCESS;
break;
}
- if(result != MB_SUCCESS)
- return result;
-
- tag_handle = TAG_HANDLE_FROM_ID( id, storage );
-
- // we have a valid id, lets register it
- if(tag_handle > 0)
- {
- TagInfo tag_info(tag_name, data_size, data_type, default_value);
- mTagTable.insert( std::pair<MBTag, TagInfo>( tag_handle, tag_info ) );
- }
-
- return MB_SUCCESS;
+ if (MB_SUCCESS != result)
+ i->invalidate();
+ return result;
}
MBErrorCode TagServer::remove_tag(const MBTag tag_handle)
{
-
- const std::map<MBTag, TagInfo>::iterator iterator = mTagTable.find(tag_handle);
-
- if(iterator == mTagTable.end())
+ const MBTagId tag_id = ID_FROM_TAG_HANDLE( tag_handle );
+ const MBTagType tag_type = PROP_FROM_TAG_HANDLE( tag_handle );
+ const unsigned tag_idx = tag_id - 1;
+ if (tag_idx >= mTagTable[tag_type].size() ||
+ !mTagTable[tag_type][tag_idx].is_valid())
return MB_TAG_NOT_FOUND;
-
- MBErrorCode status = MB_FAILURE;
- MBTagId id = ID_FROM_TAG_HANDLE(tag_handle);
- switch (PROP_FROM_TAG_HANDLE(tag_handle)) {
+ MBErrorCode status = MB_FAILURE;
+ switch (tag_type) {
case MB_TAG_BIT:
- status = mBitServer->release_tag_id(id);
+ status = mBitServer->release_tag_id(tag_id);
break;
case MB_TAG_SPARSE:
- status = mSparseData->release_tag_id(id);
+ status = mSparseData->release_tag_id(tag_id);
break;
case MB_TAG_DENSE:
- status = mDenseData->release_tag_id(id);
+ status = mDenseData->release_tag_id(tag_id);
break;
case MB_TAG_MESH:
status = MB_SUCCESS;
break;
}
-
- if (MB_SUCCESS == status) {
- mTagTable.erase(iterator);
- }
+ mTagTable[tag_type][tag_idx].invalidate();
return status;
-
}
@@ -201,36 +197,22 @@
//! this is used to clean out stale data that might be referenced again
MBErrorCode TagServer::reset_data(MBEntityHandle entity_handle)
{
- // note: this algorithm assumes that tag properties are
- // BITS < SPARSE < DENSE < STATIC.
- // if that is not the case anymore, then rearrange this algorithm
+ std::vector<TagInfo>::iterator i;
- if(TYPE_FROM_HANDLE(entity_handle) >= MBMAXTYPE)
- return MB_TYPE_OUT_OF_RANGE;
+ MBTagId tag_id;
- std::map<MBTag, TagInfo>::iterator iter;
+ 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 );
- // go through and clean out the bits
- MBTag max_tag = TAG_HANDLE_FROM_ID(0,MB_TAG_SPARSE);
- for(iter = mTagTable.begin(); iter != mTagTable.end() && iter->first < max_tag; ++iter)
- {
- // default data for bits is zero
- mBitServer->weak_set_bits(ID_FROM_TAG_HANDLE(iter->first), entity_handle, 0);
- }
+ for (tag_id = 1; tag_id <= mTagTable[MB_TAG_SPARSE].size(); ++tag_id)
+ if (mTagTable[MB_TAG_SPARSE][tag_id-1].is_valid())
+ mSparseData->remove_data( tag_id, entity_handle );
- // now clean out the sparse data
- max_tag = TAG_HANDLE_FROM_ID(0,MB_TAG_DENSE);
- for( ; iter != mTagTable.end() && iter->first < max_tag; ++iter)
- {
- mSparseData->remove_data(ID_FROM_TAG_HANDLE(iter->first), entity_handle);
- }
-
- // now clean out the dense data
- max_tag = TAG_HANDLE_FROM_ID(0,MB_TAG_MESH);
- for( ; iter != mTagTable.end() && iter->first < max_tag; ++iter)
- {
- mDenseData->remove_data(ID_FROM_TAG_HANDLE(iter->first), entity_handle);
- }
+ for (tag_id = 1; tag_id <= mTagTable[MB_TAG_DENSE].size(); ++tag_id)
+ if (mTagTable[MB_TAG_DENSE][tag_id-1].is_valid())
+ mDenseData->remove_data( tag_id, entity_handle );
return MB_SUCCESS;
}
@@ -588,30 +570,23 @@
return MB_SUCCESS;
}
-MBTag TagServer::get_handle(const char *tag_name)
+MBTag TagServer::get_handle(const char *tag_name) const
{
-
- // perhaps speed this up since tag handles are sorted by tag properties
- // then sorted by entity type
- std::map<MBTag, TagInfo>::iterator iterator;
- for(iterator = mTagTable.begin(); iterator != mTagTable.end(); ++iterator)
- {
- if (strcmp(tag_name, iterator->second.get_name().c_str()) == 0)
- {
- return iterator->first;
- }
- }
-
+ if (tag_name && *tag_name)
+ for (int i = 0; i < MB_TAG_LAST; ++i)
+ for (MBTagId j = 0; j < mTagTable[i].size(); ++j)
+ if (mTagTable[i][j].is_valid() && mTagTable[i][j].get_name() == tag_name)
+ return TAG_HANDLE_FROM_ID( j + 1, (MBTagType)i );
+
return 0;
}
MBErrorCode TagServer::get_tags(std::vector<MBTag> &all_tags)
{
- std::map<MBTag, TagInfo>::iterator iterator;
- for(iterator = mTagTable.begin(); iterator != mTagTable.end(); ++iterator)
- {
- all_tags.push_back(iterator->first);
- }
+ for (int i = 0; i < MB_TAG_LAST; ++i)
+ for (MBTagId j = 0; j < mTagTable[i].size(); ++j)
+ if (mTagTable[i][j].is_valid())
+ all_tags.push_back( TAG_HANDLE_FROM_ID( j + 1, (MBTagType)i ) );
return MB_SUCCESS;
}
@@ -634,10 +609,11 @@
MBErrorCode TagServer::get_mesh_tags( std::vector<MBTag>& all_tags ) const
{
- std::map<MBTag,TagInfo>::const_iterator i;
- for (i = mTagTable.begin(); i != mTagTable.end(); ++i)
- if (i->second.get_mesh_value())
- all_tags.push_back( i->first );
+ for (int i = 0; i < MB_TAG_LAST; ++i)
+ for (MBTagId j = 0; j < mTagTable[i].size(); ++j)
+ if (mTagTable[i][j].is_valid() && mTagTable[i][j].get_mesh_value())
+ all_tags.push_back( TAG_HANDLE_FROM_ID( j + 1, (MBTagType)i ) );
+
return MB_SUCCESS;
}
@@ -1014,7 +990,7 @@
unsigned long TagServer::get_memory_use( MBTag tag_handle ) const
{
- if (mTagTable.find(tag_handle) == mTagTable.end())
+ if (!get_tag_info(tag_handle))
return 0;
unsigned long result = 0, tmp;
@@ -1070,23 +1046,6 @@
return MB_SUCCESS;
}
-
-MBErrorCode TagServer::reserve_mesh_tag_id( MBTagId& id_out ) const
-{
- MBTag tag = TAG_HANDLE_FROM_ID( 1, MB_TAG_MESH );
- std::map<MBTag,TagInfo>::const_iterator i = mTagTable.lower_bound( tag );
- if (i == mTagTable.end() || i->first > tag) {
- id_out = 1;
- return MB_SUCCESS;
- }
-
- tag = i->first + 1;
- for (++i; i != mTagTable.end() && tag == i->first; ++i)
- tag = i->first + 1;
-
- id_out = ID_FROM_TAG_HANDLE( tag );
- return MB_SUCCESS;
-}
Modified: MOAB/trunk/TagServer.hpp
===================================================================
--- MOAB/trunk/TagServer.hpp 2007-08-30 14:50:36 UTC (rev 1265)
+++ MOAB/trunk/TagServer.hpp 2007-08-31 16:38:22 UTC (rev 1266)
@@ -37,7 +37,6 @@
#include <string>
#include <vector>
-#include <map>
#include "MBTypes.h"
#include "MBInternals.hpp"
@@ -55,6 +54,7 @@
//! constructor
TagInfo() : mTagName(""),
mDataSize(0),
+ isValid(false),
mDefaultValue(NULL),
mMeshValue(NULL),
dataType(MB_TYPE_OPAQUE)
@@ -101,6 +101,9 @@
inline void set_data_type( MBDataType t ) { dataType = t; }
static int size_from_data_type( MBDataType t );
+
+ bool is_valid() const { return isValid; }
+ void invalidate();
private:
@@ -111,6 +114,9 @@
//! stores the size of the data for this tag
unsigned short mDataSize;
+
+ //! flag to mark unused entries
+ bool isValid;
//! stores the default data, if any
unsigned char *mDefaultValue;
@@ -245,7 +251,7 @@
MBEntityHandle find_entity( const MBTag tag_handle, const void* data );
//! gets a tag handle by name and entity handle
- MBTag get_handle(const char *tag_name);
+ MBTag get_handle(const char *tag_name) const;
//! get all the tags which have been defined for this entity
MBErrorCode get_tags(const MBEntityHandle entity, std::vector<MBTag> &all_tags);
@@ -275,14 +281,11 @@
private:
- MBErrorCode reserve_mesh_tag_id( MBTagId& id_out ) const;
+ //! Table of tag ids and tag information
+ //! Primary (array) index is tag type.
+ //! Secondary (std::vector) index is tag id less one (tag ids begin with 1).
+ std::vector<TagInfo> mTagTable[MB_TAG_LAST];
- //! table of tag ids and tag information
- //! do we really need to do it this way?
- //! we at least need a table between names and tag ids
- //! and we need information between tag ids and tag usage
- std::map< MBTag, TagInfo > mTagTable;
-
//! container for storing the sparse data and tag ids
SparseTagSuperCollection* mSparseData;
@@ -303,6 +306,7 @@
inline TagInfo::TagInfo(const TagInfo& copy)
: mTagName( copy.mTagName ),
mDataSize( copy.mDataSize ),
+ isValid( copy.isValid ),
mDefaultValue( 0 ),
mMeshValue( 0 ),
dataType( copy.dataType )
@@ -324,6 +328,7 @@
const void* default_value)
: mTagName( name ),
mDataSize( size ),
+ isValid( true ),
mDefaultValue( 0 ),
mMeshValue( 0 ),
dataType( type )
@@ -338,6 +343,7 @@
{
mTagName = rhs.mTagName;
mDataSize = rhs.mDataSize;
+ isValid = rhs.isValid;
delete [] mDefaultValue;
delete [] mMeshValue;
@@ -380,38 +386,28 @@
inline const TagInfo* TagServer::get_tag_info( const char *tag_name ) const
{
- if(NULL == tag_name || strcmp(tag_name, "") == 0)
- return NULL;
-
- std::map<MBTag, TagInfo>::const_iterator iterator;
- const std::string temp_name = tag_name;
- for(iterator = mTagTable.begin(); iterator != mTagTable.end(); ++iterator)
- {
- if ( temp_name.size() == iterator->second.get_name().size() &&
- std::equal(temp_name.begin(), temp_name.end(), iterator->second.get_name().begin() ) )
- {
- return &(iterator->second);
- }
- }
- return NULL;
+ const MBTag handle = get_handle( tag_name );
+ return handle ? get_tag_info( handle ) : 0;
}
inline const TagInfo* TagServer::get_tag_info( MBTag tag_handle ) const
{
- std::map<MBTag, TagInfo>::const_iterator iterator = mTagTable.find(tag_handle);
-
- if ( iterator != mTagTable.end() )
- {
- return &(iterator->second);
- }
-
- return NULL;
+ const MBTagId id = ID_FROM_TAG_HANDLE( tag_handle );
+ const MBTagType type = PROP_FROM_TAG_HANDLE( tag_handle );
+ if (id <= mTagTable[type].size() && mTagTable[type][id-1].is_valid())
+ return &mTagTable[type][id-1];
+ else
+ return NULL;
}
inline TagInfo* TagServer::get_tag_info( MBTag tag_handle )
{
- std::map<MBTag, TagInfo>::iterator i = mTagTable.find(tag_handle);
- return (i == mTagTable.end()) ? (TagInfo*)0 : &(i->second);
+ const MBTagId id = ID_FROM_TAG_HANDLE( tag_handle );
+ const MBTagType type = PROP_FROM_TAG_HANDLE( tag_handle );
+ if (id <= mTagTable[type].size() && mTagTable[type][id-1].is_valid())
+ return &mTagTable[type][id-1];
+ else
+ return NULL;
}
#endif //TAG_SERVER_HPP
More information about the moab-dev
mailing list