Commit f3de6b96 authored by Kirill Terekhov's avatar Kirill Terekhov

Fixes

Cleaned bugs; added features.
parent 4792fc70
......@@ -45,7 +45,7 @@ add_library(inmost STATIC ${SOURCE} ${HEADER})
option(USE_MPI "Compile with MPI support" ON)
option(USE_MPI_P2P "Use MPI point to point functionality, may be faster with hardware support" ON)
option(USE_MPI_FILE "Use MPI extension to work with files, may save a lot of memory" ON)
option(USE_MPI2 "Use MPI-2 extensions, useful if your MPI library produces warnings to use new functions" ON)
option(USE_MPI2 "Use MPI-2 extensions, useful if your MPI library warns you to use new functions" ON)
option(USE_OMP "Compile with OpenMP support (experimental)" OFF)
option(USE_MESH "Compile mesh capabilities" ON)
......
......@@ -12,6 +12,7 @@
#include <cmath>
#include <assert.h>
#include <limits>
#include "inmost_common.h"
//#define OUT_OF_RANGE
......@@ -43,7 +44,9 @@ namespace INMOST
template<> struct make_unsigned<unsigned long long> {typedef unsigned long long type;};
#define USE_OPTIMIZED_ARRAY_ALLOCATION
#if defined(PACK_ARRAY)
#pragma pack(push,r1,4)
#endif
// notice: array class would not properly support classes that contain self-references
// like std::map
// notice: next class shell have to implement same algorithms as array
......@@ -129,8 +132,10 @@ namespace INMOST
typedef _reverse_iterator<element> reverse_iterator;
typedef _reverse_iterator<const element> const_reverse_iterator;
private:
element * m_arr;
size_type m_size;
//notice: push_back, pop_back, insert, erase are optimized for current growth_formula
__INLINE static size_type growth_formula(size_type future_size)
{
......@@ -503,7 +508,9 @@ namespace INMOST
}
template<class> friend class shell;
};
#if defined(PACK_ARRAY)
#pragma pack(pop,r1)
#endif
template<typename element>
class shell
{
......@@ -677,7 +684,7 @@ namespace INMOST
*m_arr = static_cast<element *>(realloc(*m_arr,sizeof(element)*(++(*m_size))));
else if( (((*m_size)+1) & ((*m_size)-1)) == 1 )
*m_arr = static_cast<element *>(realloc(*m_arr,sizeof(element)*((*m_size)++ << 1)));
else ++m_size;
else ++(*m_size);
#endif
assert((*m_arr) != NULL);
new ((*m_arr)+(*m_size)-1) element(e);
......
......@@ -797,7 +797,7 @@ namespace INMOST
ElementArray<Element> Element::BridgeAdjacencies(ElementType Bridge, ElementType Dest, MarkerType mask, bool invert)
ElementArray<Element> Element::BridgeAdjacencies(ElementType Bridge, ElementType Dest, MarkerType mask, bool invert) const
{
Mesh * m = GetMeshLink();
MarkerType mrk = m->CreateMarker();
......@@ -822,7 +822,7 @@ namespace INMOST
}
ElementArray<Node> Element::BridgeAdjacencies2Node(ElementType Bridge, MarkerType mask, bool invert)
ElementArray<Node> Element::BridgeAdjacencies2Node(ElementType Bridge, MarkerType mask, bool invert) const
{
Mesh * m = GetMeshLink();
MarkerType mrk = m->CreateMarker();
......@@ -846,7 +846,7 @@ namespace INMOST
return adjcells;
}
ElementArray<Edge> Element::BridgeAdjacencies2Edge(ElementType Bridge, MarkerType mask, bool invert)
ElementArray<Edge> Element::BridgeAdjacencies2Edge(ElementType Bridge, MarkerType mask, bool invert) const
{
Mesh * m = GetMeshLink();
MarkerType mrk = m->CreateMarker();
......@@ -870,7 +870,7 @@ namespace INMOST
return adjcells;
}
ElementArray<Face> Element::BridgeAdjacencies2Face(ElementType Bridge, MarkerType mask, bool invert)
ElementArray<Face> Element::BridgeAdjacencies2Face(ElementType Bridge, MarkerType mask, bool invert) const
{
Mesh * m = GetMeshLink();
MarkerType mrk = m->CreateMarker();
......@@ -894,7 +894,7 @@ namespace INMOST
return adjcells;
}
ElementArray<Cell> Element::BridgeAdjacencies2Cell(ElementType Bridge, MarkerType mask, bool invert)
ElementArray<Cell> Element::BridgeAdjacencies2Cell(ElementType Bridge, MarkerType mask, bool invert) const
{
Mesh * m = GetMeshLink();
MarkerType mrk = m->CreateMarker();
......
......@@ -1627,6 +1627,16 @@ namespace INMOST
Element::adj_type & hc = m->HighConn(GetHandle());
return (lc.size() - (hc.size() - high_conn_reserved));
}
void ElementSet::Clear() const
{
Mesh * m = GetMeshLink();
Element::adj_type & lc = m->LowConn(GetHandle());
Element::adj_type & hc = m->HighConn(GetHandle());
hc.resize(ElementSet::high_conn_reserved);
lc.clear();
BulkDF(m->SetComparatorTag()) = UNSORTED_COMPARATOR;
}
}
#endif
......@@ -505,7 +505,7 @@ namespace INMOST
case 0: *ret = 0; break;
case 1: //length of edge
{
ElementArray<Node> nodes = Element(this,e)->getNodes(NODE);
ElementArray<Node> nodes = Element(this,e)->getNodes();
Storage::real c[3];
vec_diff(nodes[0]->Coords().data(),nodes[1]->Coords().data(),c,mdim);
*ret = vec_len(c,mdim);
......@@ -514,7 +514,7 @@ namespace INMOST
}
case 2: //area of face
{
ElementArray<Node> nodes = Element(this,e)->getNodes(NODE);
ElementArray<Node> nodes = Element(this,e)->getNodes();
real x[3] = {0,0,0};
Storage::real_array x0 = nodes[0].Coords();
for(ElementArray<Node>::size_type i = 1; i < nodes.size()-1; i++)
......
......@@ -34,22 +34,36 @@
// when you release marker checks all the elements
// that no element is marked by released marker
//#define CHECKS_MARKERS
// use additional sets to store elements for parallel
// exchanges, otherwise it will recompute those elements
// which is quite expensive
#define USE_PARALLEL_STORAGE
// output xml files for debugging of parallel algorithms
// search for style.xsl within examples for comfortable
// view of generated xml files
#define USE_PARALLEL_WRITE_TIME
// this will revert Mesh::PrepareReceiveInner to always
// use MPI point to point functionality disregarding problem type
// read comments in Mesh::SetParallelStrategy for more info
// USE_MPI_P2P must be enabled for feature to work
//#define PREFFER_MPI_P2P
// this will write out shared set of elements that lay between processors in GMV format
//#define DEBUG_COMPUTE_SHARED_SKIN_SET
// this controls how sparse data will be allocated,
// when difinition is not commented memory will be always consumed
// by data structure needed to support sparse data,
// otherwise data structure will be allocated only when
// sparse data is presenet
//#define LAZY_SPARSE_ALLOCATION
// this will force array class to use 12 bytes instead of 16 bytes
#define PACK_ARRAY
#define __INLINE inline
#if defined(USE_OMP)
......
This diff is collapsed.
......@@ -73,7 +73,6 @@ namespace INMOST
memset(remember,0,sizeof(remember));
tag_coords = CreateTag("COORD",DATA_REAL, NODE,NONE,dim);
tag_topologyerror = CreateTag("TOPOLOGY_ERROR_TAG",DATA_INTEGER,CELL | FACE | EDGE,CELL | FACE | EDGE,1);
tag_high_conn = CreateTag("HIGH_CONN",DATA_REFERENCE,ESET|CELL|FACE|EDGE|NODE,NONE);
tag_low_conn = CreateTag("LOW_CONN",DATA_REFERENCE,ESET|CELL|FACE|EDGE|NODE,NONE);
tag_markers = CreateTag("MARKERS",DATA_BULK,CELL|FACE|EDGE|NODE|ESET|MESH,NONE,MarkerFields);
......@@ -154,7 +153,6 @@ namespace INMOST
//setup system tags shortcuts
dim = other.dim;
tag_coords = CreateTag("COORD",DATA_REAL, NODE,NONE,dim);
tag_topologyerror = CreateTag("TOPOLOGY_ERROR_TAG",DATA_INTEGER,CELL | FACE | EDGE,CELL | FACE | EDGE,1);
tag_high_conn = CreateTag("HIGH_CONN",DATA_REFERENCE,ESET|CELL|FACE|EDGE|NODE,NONE);
tag_low_conn = CreateTag("LOW_CONN",DATA_REFERENCE,ESET|CELL|FACE|EDGE|NODE,NONE);
tag_markers = CreateTag("MARKERS",DATA_BULK,CELL|FACE|EDGE|NODE|ESET|MESH,NONE,MarkerFields);
......@@ -262,7 +260,6 @@ namespace INMOST
//setup system tags shortcuts
dim = other.dim;
tag_coords = CreateTag("COORD",DATA_REAL, NODE,NONE,dim);
tag_topologyerror = CreateTag("TOPOLOGY_ERROR_TAG",DATA_INTEGER,CELL | FACE | EDGE,CELL | FACE | EDGE,1);
tag_high_conn = CreateTag("HIGH_CONN",DATA_REFERENCE,ESET|CELL|FACE|EDGE|NODE,NONE);
tag_low_conn = CreateTag("LOW_CONN",DATA_REFERENCE,ESET|CELL|FACE|EDGE|NODE,NONE);
tag_markers = CreateTag("MARKERS",DATA_BULK,CELL|FACE|EDGE|NODE|ESET|MESH,NONE,MarkerFields);
......@@ -1439,7 +1436,7 @@ namespace INMOST
}
else
{
ADDR = static_cast<integer>(links[etypenum].size() - empty_links[etypenum].size());
ADDR = static_cast<integer>(links[etypenum].size());
}
if( !empty_links[etypenum].empty() )
{
......@@ -1472,7 +1469,7 @@ namespace INMOST
back_links[etypenum][old_addr] = -1;
back_links[etypenum][new_addr] = ID;
links[etypenum][ID] = new_addr;
sparse_data[etypenum][new_addr].swap(sparse_data[etypenum][new_addr]);
sparse_data[etypenum][new_addr].swap(sparse_data[etypenum][old_addr]);
for(Mesh::iteratorTag t = BeginTag(); t != EndTag(); t++)
{
if( !t->isSparseNum(etypenum) )
......@@ -1498,24 +1495,25 @@ namespace INMOST
{
for(int etypenum = 0; etypenum < ElementNum(MESH); etypenum++) if( ElementTypeFromDim(etypenum) & etype )
{
int cend = static_cast<int>(back_links[etypenum].size())-1;
integer cend = static_cast<integer>(back_links[etypenum].size())-1;
//Very likely we have leading free space
while( cend >= 0 && back_links[etypenum][cend] == -1 )
cend--;
while( cend >= 0 && !empty_space[etypenum].empty() )
{
if( empty_space[etypenum].back() >= cend )
integer last = empty_space[etypenum].back();
if( last >= cend )
empty_space[etypenum].pop_back();
else if( back_links[etypenum][cend] != -1 )
{
MoveStorage(etypenum,cend,empty_space[etypenum].back());
MoveStorage(etypenum,cend,last);
empty_space[etypenum].pop_back();
}
else cend--;
}
while( cend >= 0 && back_links[etypenum][cend] == -1 )
cend--;
back_links[etypenum].resize(cend); //those should not be needed
//back_links[etypenum].resize(cend); //those should not be needed
empty_space[etypenum].clear();
ReallocateData(etypenum,GetArrayCapacity(etypenum));
}
......@@ -1786,7 +1784,7 @@ namespace INMOST
void Mesh::DelData(HandleType h,const Tag & tag)
{
assert( tag.GetMeshLink() == this );
if( tag.isSparse(GetElementType()) )
if( tag.isSparse(GetHandleElementType(h)) )
DelSparseData(h,tag);
else
DelDenseData(h,tag);
......@@ -1843,5 +1841,18 @@ namespace INMOST
}
return ret;
}
void Mesh::SetTopologyCheck (TopologyCheck mask)
{
checkset = checkset | mask;
if( mask & MARK_ON_ERROR )
tag_topologyerror = CreateTag("TOPOLOGY_ERROR_TAG",DATA_INTEGER,CELL | FACE | EDGE,CELL | FACE | EDGE,1);
}
void Mesh::RemTopologyCheck (TopologyCheck mask)
{
checkset = checkset & ~mask;
if( mask & MARK_ON_ERROR )
tag_topologyerror = DeleteTag(tag_topologyerror);
}
}
#endif
This diff is collapsed.
......@@ -31,26 +31,143 @@ static INMOST_DATA_BIG_ENUM_TYPE pmid = 0;
namespace INMOST
{
//////////////////////////////
/// REDUCTION FUNCTIONS ///
//////////////////////////////
void DefaultUnpack(const Tag & tag, const Element & element, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
{
if( size == 0 )
{
if( tag.isDefined(element->GetElementType()) )
{
if( tag.isSparse(element->GetElementType()) )
{
if( element->HaveData(tag) )
element->DelData(tag);
}
else if( tag.GetSize() == ENUMUNDEF )
element->SetDataSize(tag,size);
else
{
std::cerr << "received zero size for dense nonzero tag" << std::endl;
assert(false);
}
}
return;
}
if( !element->HaveData(tag) )
element->SetDataSize(tag,size);
else if( size != element->GetDataSize(tag) )
{
if( tag.GetSize() == ENUMUNDEF )
element->SetDataSize(tag,size);
else
{
assert(false);
}
}
element->SetData(tag,0,size,data);
}
void UnpackOnSkin(const Tag & tag, const Element & e, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
{
if( size )
{
const Storage::integer * recv = static_cast<const Storage::integer *>(static_cast<const void *>(data));
Storage::integer_array arr = e->IntegerArray(tag);
arr.push_back(recv[0]);
}
}
void UnpackSkin(const Tag & tag, const Element & e, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
{
if( size )
{
bool flag = true;
const Storage::integer * recv = static_cast<const Storage::integer *>(static_cast<const void *>(data));
Storage::integer_array arr = e->IntegerArray(tag);
for(Storage::integer_array::iterator it = arr.begin(); it != arr.end(); it++)
if( *it == recv[0] )
{
flag = false;
break;
}
if( flag )
{
arr.push_back(recv[0]);
arr.push_back(recv[1]);
}
}
}
void DeleteUnpack(const Tag & tag, const Element & e, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
{
if( size )
{
int old_size;
if( e->HaveData(tag) ) old_size = e->GetDataSize(tag);
else old_size = 0;
e->SetDataSize(tag,old_size+size);
e->SetData(tag,old_size,size,data);
}
}
void RedistUnpack(const Tag & tag,const Element & e, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
{
if( size )
{
Storage::integer_array p1 = e->IntegerArray(tag);
const Storage::integer * p2 = static_cast<const Storage::integer *>(static_cast<const void *>(data));
dynarray<Storage::integer,64> result(p1.size()+size);
dynarray<Storage::integer,64>::iterator end;
end = std::set_union(p1.begin(),p1.end(),p2,p2+size,result.begin());
result.resize(end-result.begin());
p1.clear();
p1.insert(p1.end(),result.begin(),result.end());
}
}
void UnpackLayersMarker(const Tag & tag, const Element & e, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
{
if( size )
{
int old_size;
if( e->HaveData(tag) ) old_size = e->GetDataSize(tag);
else old_size = 0;
e->SetDataSize(tag,old_size+size);
e->SetData(tag,old_size,size,data);
}
}
void UnpackSyncMarkerOR(const Tag & tag, const Storage & element, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
void UnpackSyncMarkerOR(const Tag & tag, const Element & element, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
{
(void) size;
element->Bulk(tag) |= *data;
}
void UnpackSyncMarkerXOR(const Tag & tag, const Storage & element, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
void UnpackSyncMarkerXOR(const Tag & tag, const Element & element, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
{
(void) size;
element->Bulk(tag) ^= *data;
}
void UnpackSyncMarkerAND(const Tag & tag, const Storage & element, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
void UnpackSyncMarkerAND(const Tag & tag, const Element & element, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
{
(void) size;
element->Bulk(tag) &= *data;
}
//////////////////////////////
/// REDUCTION FUNCTIONS END///
//////////////////////////////
void Mesh::SynchronizeMarker(MarkerType marker, ElementType mask, SyncBitOp op)
{
#if defined(USE_MPI)
......@@ -291,45 +408,6 @@ namespace INMOST
#endif //USE_MPI
return output;
}
void DefaultUnpack(const Tag & tag, const Storage & element, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
{
if( size == 0 )
{
if( tag.isDefined(element->GetElementType()) )
{
if( tag.isSparse(element->GetElementType()) )
{
if( element->HaveData(tag) )
element->DelData(tag);
}
else if( tag.GetSize() == ENUMUNDEF )
element->SetDataSize(tag,size);
else
{
std::cerr << "received zero size for dense nonzero tag" << std::endl;
throw Impossible;
}
}
return;
}
if( !element->HaveData(tag) )
element->SetDataSize(tag,size);
else if( size != element->GetDataSize(tag) )
{
if( tag.GetSize() == ENUMUNDEF )
element->SetDataSize(tag,size);
else
{
throw Impossible;
}
}
element->SetData(tag,0,size,data);
}
INMOST_MPI_Comm Mesh::GetCommunicator()
......@@ -1199,17 +1277,6 @@ namespace INMOST
EXIT_FUNC();
}
void DeleteUnpack(const Tag & tag, const Storage & e, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
{
if( size )
{
int old_size;
if( e->HaveData(tag) ) old_size = e->GetDataSize(tag);
else old_size = 0;
e->SetDataSize(tag,old_size+size);
e->SetData(tag,old_size,size,data);
}
}
void Mesh::RemoveGhost()
{
......@@ -1603,36 +1670,8 @@ namespace INMOST
EXIT_FUNC();
}
void UnpackSkin(const Tag & tag, const Storage & e, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
{
if( size )
{
bool flag = true;
const Storage::integer * recv = static_cast<const Storage::integer *>(static_cast<const void *>(data));
Storage::integer_array arr = e->IntegerArray(tag);
for(Storage::integer_array::iterator it = arr.begin(); it != arr.end(); it++)
if( *it == recv[0] )
{
flag = false;
break;
}
if( flag )
{
arr.push_back(recv[0]);
arr.push_back(recv[1]);
}
}
}
void UnpackOnSkin(const Tag & tag, const Storage & e, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
{
if( size )
{
const Storage::integer * recv = static_cast<const Storage::integer *>(static_cast<const void *>(data));
Storage::integer_array arr = e->IntegerArray(tag);
arr.push_back(recv[0]);
}
}
Mesh::proc_elements Mesh::ComputeSharedSkinSet(ElementType bridge_type)
{
......@@ -1911,7 +1950,7 @@ namespace INMOST
{
eit = elements[i].begin() + array_size_recv[k++];
assert( !select || GetMarker(*eit,select) ); //if fires then very likely that marker was not synchronized
op(tag,Storage(this,*eit),&array_data_recv[pos],array_size_recv[k]);
op(tag,Element(this,*eit),&array_data_recv[pos],array_size_recv[k]);
pos += array_size_recv[k]*tag.GetBytesSize();
k++;
}
......@@ -1922,7 +1961,7 @@ namespace INMOST
{
eit = elements[i].begin() + array_size_recv[k++];
assert( !select || GetMarker(*eit,select) ); //if fires then very likely that marker was not synchronized
op(tag,Storage(this,*eit),&array_data_recv[pos],size);
op(tag,Element(this,*eit),&array_data_recv[pos],size);
pos += size*tag.GetBytesSize();
}
}
......@@ -1933,7 +1972,7 @@ namespace INMOST
{
for(eit = elements[i].begin(); eit != elements[i].end(); eit++) if( !select || GetMarker(*eit,select) )
{
op(tag,Storage(this,*eit),&array_data_recv[pos],array_size_recv[k]);
op(tag,Element(this,*eit),&array_data_recv[pos],array_size_recv[k]);
pos += array_size_recv[k]*tag.GetBytesSize();
k++;
}
......@@ -1942,7 +1981,7 @@ namespace INMOST
{
for(eit = elements[i].begin(); eit != elements[i].end(); eit++) if( !select || GetMarker(*eit,select) )
{
op(tag,Storage(this,*eit),&array_data_recv[pos],size);
op(tag,Element(this,*eit),&array_data_recv[pos],size);
pos += size*tag.GetBytesSize();
}
}
......@@ -3505,17 +3544,6 @@ namespace INMOST
}
void UnpackLayersMarker(const Tag & tag, const Storage & e, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
{
if( size )
{
int old_size;
if( e->HaveData(tag) ) old_size = e->GetDataSize(tag);
else old_size = 0;
e->SetDataSize(tag,old_size+size);
e->SetData(tag,old_size,size,data);
}
}
void Mesh::ExchangeGhost(Storage::integer layers, ElementType bridge)
{
......@@ -3672,21 +3700,6 @@ namespace INMOST
}
void RedistUnpack(const Tag & tag,const Storage & e, const INMOST_DATA_BULK_TYPE * data, INMOST_DATA_ENUM_TYPE size)
{
if( size )
{
Storage::integer_array p1 = e->IntegerArray(tag);
const Storage::integer * p2 = static_cast<const Storage::integer *>(static_cast<const void *>(data));
dynarray<Storage::integer,64> result(p1.size()+size);
dynarray<Storage::integer,64>::iterator end;
end = std::set_union(p1.begin(),p1.end(),p2,p2+size,result.begin());
result.resize(end-result.begin());
p1.clear();
p1.insert(p1.end(),result.begin(),result.end());
}
}
void Mesh::Redistribute()
{
......
......@@ -2163,7 +2163,7 @@ public:
GetMeshLink()->RecomputeGeometricData(GetHandle());
}
void Element::Disconnect(HandleType * adjacent, INMOST_DATA_ENUM_TYPE num) const
void Element::Disconnect(const HandleType * adjacent, INMOST_DATA_ENUM_TYPE num) const
{
Mesh * m = GetMeshLink();
INMOST_DATA_ENUM_TYPE k = 0;
......@@ -2325,7 +2325,7 @@ public:
m->ReleaseMarker(mrk);
}
void Element::Connect(HandleType * adjacent, INMOST_DATA_ENUM_TYPE num) const
void Element::Connect(const HandleType * adjacent, INMOST_DATA_ENUM_TYPE num) const
{
assert( !(GetElementType() == EDGE && GetMeshLink()->LowConn(GetHandle()).size() > 2) ); // cannot add another node to edge
Mesh * m = GetMeshLink();
......
......@@ -5,6 +5,18 @@
namespace INMOST
{
Storage & Storage::operator =(Storage const & other)
{
handle = other.handle;
if( handle_link != NULL )
{
assert(m_link == other.m_link);
*handle_link = handle;
}
else handle_link = other.handle_link; //if other have remote link this will copy this link and current will also be remote
m_link = other.m_link;
return *this;
}
INMOST_DATA_ENUM_TYPE Storage::GetDataSize(const Tag & tag) const
{
......@@ -187,6 +199,11 @@ namespace INMOST
return handle != InvalidHandle() && GetMeshLink()->isValidElement(handle);
}
Element Storage::reference_array::operator [](size_type n)
{
return Element(m,&shell<HandleType>::operator[](n));
}
Element Storage::reference_array::operator [](size_type n) const
{
return Element(m,shell<HandleType>::operator[](n));
......@@ -194,23 +211,30 @@ namespace INMOST
Element Storage::reference_array::iterator::operator->()
{
return Element(m,shell<HandleType>::iterator::operator *());
return Element(m,&shell<HandleType>::iterator::operator *());
}
Element Storage::reference_array::const_iterator::operator->()
{
return Element(m,shell<HandleType>::const_iterator::operator *());
}
Element Storage::reference_array::reverse_iterator::operator->()
{
return Element(m,shell<HandleType>::reverse_iterator::operator *());
return Element(m,&shell<HandleType>::reverse_iterator::operator *());
}
Element Storage::reference_array::const_reverse_iterator::operator->()
{
return Element(m,shell<HandleType>::const_reverse_iterator::operator *());
}
void Storage::reference_array::push_back(const Storage & ref) {shell<reference>::push_back(ref->GetHandle());}
Storage::integer Storage::DataLocalID () const
{
return GetMeshLink()->DataLocalID(GetHandle());
}
}
#endif
......@@ -238,6 +238,9 @@ namespace INMOST
Tag TagManager::CreateTag(Mesh *m, std::string name, DataType dtype, ElementType etype,ElementType sparse, INMOST_DATA_ENUM_TYPE size)
{
Tag new_tag;
#if !defined(LAZY_SPARSE_ALLOCATION)
bool need_sparse[6] = {false,false,false,false,false,false};
#endif
for(tag_array_type::size_type i = 0; i < tags.size(); i++)
if( tags[i].GetTagName() == name )
{
......@@ -262,6 +265,9 @@ namespace INMOST
{
new_tag.SetPosition(ENUMUNDEF-1,mask);
new_tag.SetSparse(mask);
#if !defined(LAZY_SPARSE_ALLOCATION)
need_sparse[ElementNum(mask)] = true;
#endif
}
else
{
......@@ -276,13 +282,21 @@ namespace INMOST
new_tag.SetPosition(new_pos,mask);
INMOST_DATA_ENUM_TYPE new_size = dynamic_cast<Mesh *>(this)->GetArrayCapacity(ElementNum(mask));
if( new_size < 1024 && mask != MESH ) new_size = 1024;
if( new_size < 1 && mask == MESH ) new_size = 1;
if( new_size != 1 && mask == MESH ) new_size = 1;
ReallocateData(new_tag,ElementNum(mask),new_size);
}
}
}
#if !defined(LAZY_SPARSE_ALLOCATION)
for(int j = 0; j < 6; j++)
if( need_sparse[j] && sparse_data[j].empty() )
{
INMOST_DATA_ENUM_TYPE new_size = dynamic_cast<Mesh *>(this)->GetArrayCapacity(j);
if( new_size < 1024 && j != ElementNum(MESH) ) new_size = 1024;
if( new_size != 1 && j == ElementNum(MESH) ) new_size = 1;
sparse_data[j].resize(new_size);
}
#endif
return new_tag;
}
Tag TagManager::GetTag(std::string name) const
......@@ -303,6 +317,9 @@ namespace INMOST
Tag TagManager::DeleteTag(Tag tag, ElementType type_mask)
{
bool delete_entirely = true;
#if !defined(LAZY_SPARSE_ALLOCATION)
bool was_sparse[6] =