wzarray.cxx

来自「有限元学习研究用源代码(老外的),供科研人员参考」· CXX 代码 · 共 229 行

CXX
229
字号
#include "wzarray.hxx"
#include <stdlib.h>
//#include <iostream.h>

#define wzArrayTraceAllocation
#undef  wzArrayTraceAllocation

wzIndex wzArrayStaticInitializationManager::count;
wzIndex wzArrayStaticInitializationManager::AllocationCount;

class wzAllocationStrategy{
public:
        wzIndex	MinimalAdditionalSize;
        wzIndex	MinimalSize;
        wzFloat MinimalFactor;
        wzIndex Multiple;
        wzIndex suggested(wzIndex min, wzIndex old);
        wzAllocationStrategy(wzFloat f=0,wzIndex m=0,wzIndex a=0,wzIndex s=0)
:MinimalAdditionalSize(a),MinimalSize(s),MinimalFactor(f),Multiple(m){;}
        ~wzAllocationStrategy();
};
static wzAllocationStrategy DefaultStrategy(1.2,0x10,100,0xf);

wzArrayStaticInitializationManager::wzArrayStaticInitializationManager()
{if(count++ == 0){
	DefaultStrategy.MinimalFactor = 1.2;
	DefaultStrategy.MinimalAdditionalSize = 100;
	DefaultStrategy.MinimalSize = 0xf;
	DefaultStrategy.Multiple = 0x10;
}}
wzArrayStaticInitializationManager::~wzArrayStaticInitializationManager()
{if(--count == 0){
	if(AllocationCount!=0) wzMessage("unpaired allocation\n");
}}

wzArrayBody::wzArrayBody(wzMultipleArrayController& c, wzIndex s, wzIndex m)
:Base(0),Max(0),Shift(s),Index(0),From(0)
{reinitialize(c,s,m);}

void wzArrayBody::reinitialize(wzMultipleArrayController& c, wzIndex s, wzIndex m)
{reinitialize(); Shift=s; c.defineArray(this); if(m) c.Allocate(m);}


wzArrayBody::wzArrayBody(const wzMultipleArrayController& c,
			 wzIndex s, wzIndex m)
:Base(0),Max(0),Shift(s),Index(0),From(0)
{reinitialize(c,s,m);}

void wzArrayBody::reinitialize(const wzMultipleArrayController& c,
			 wzIndex s, wzIndex m)
{reinitialize(); Shift=s; Allocate(c.Max); if(m) Allocate(m);}

wzArrayBody::wzArrayBody(wzArrayBody& a, wzIndex off)
:Base(0),Max(0),Index(0),From(0)
{reinitialize(a,off);}

void wzArrayBody::reinitialize(wzArrayBody& a, wzIndex off)
{reinitialize();
 if(!a.From){
   throw wzFailure("components of separate arrays are not supported");
 }
 a.From->defineComponent(this,a.Index,off);
}

wzArrayBody::~wzArrayBody()
{reinitialize();}

void wzArrayBody::reinitialize()
{if(From) From->destroyArray(Index); else Allocate(0);}

wzBoolean wzArrayBody::require(wzIndex i)
{if(From) return From->Allocate(i+1);
 else     return allocate(Base,Max,i+1,Shift);
}

wzBoolean wzMemoryAllocation::allocate(wzByte*& base,
		wzIndex& num, wzIndex min, wzIndex fac)
{wzIndex max = DefaultStrategy.suggested(min,num);
 wzAddress adr=0;
 if(fac==0){num=max; return wzTrue;}
 if(base){
        if(min==0){
#ifdef wzArrayTraceAllocation
		cerr << " released\n";
#endif
                wzArrayStaticInitializationManager::AllocationCount--;
                free(base); base = 0; num = 0; return wzTrue;
        }
        adr = realloc(base,(max+1)*fac);
#ifdef wzArrayTraceAllocation
		cerr << " reallocated: "<< max*fac<< " bytes\n";
#endif
        if(adr) {base = (wzByte*)adr; num = max; return wzTrue;}
#ifdef wzArrayTraceAllocation
		cerr << "not successful, second attempt: "<< min*fac
		     << " bytes\n";
#endif
        adr = realloc(base,min*fac);
        if(adr) {base = (wzByte*)adr; num = min; return wzTrue;}
#ifdef wzArrayTraceAllocation
		cerr << " not reallocated\n";
#endif
        return wzFalse;
 }else{
        if(max==0) return wzTrue;
        wzArrayStaticInitializationManager::AllocationCount++;
	{int size = (max+1)*fac;
        adr = malloc(size);
	}
#ifdef wzArrayTraceAllocation
		cerr << " allocated: "<< max*fac<< " bytes\n";
#endif
        if(adr) {base = (wzByte*)adr; num = max; return wzTrue;}
        adr = malloc(min*fac);
#ifdef wzArrayTraceAllocation
		cerr << "not successful, second attempt: "<< min*fac
		     << " bytes\n";
#endif
        if(adr) {base = (wzByte*)adr; num = min; return wzTrue;}
#ifdef wzArrayTraceAllocation
		cerr << " not allocated\n";
#endif
        return wzFalse;
 }
}


wzAllocationStrategy::~wzAllocationStrategy()
{;}

wzIndex wzAllocationStrategy::suggested(wzIndex min, wzIndex old)
{wzIndex i=min;
 if(i==0) return 0;
 if(old){
	if(i<old+MinimalAdditionalSize)   i=old+MinimalAdditionalSize;
        if(i<(wzIndex)(MinimalFactor*old))i=(wzIndex)(MinimalFactor*old);
 }else{
	if(i<MinimalSize)                 i=MinimalSize;
 }
 if(Multiple>1) i = ((i/Multiple) + 1) * Multiple - 1;
 return i;
}

// implementation of wzMultipleArrayController:

const wzIndex wzMultipleArrayController::TypeUndefined = 1;
const wzIndex wzMultipleArrayController::TypeSeparate  = 2;
const wzIndex wzMultipleArrayController::TypeComponent = 3;

wzMultipleArrayController::wzMultipleArrayController(wzIndex max)
:Offset(1,max),Field(1,max),Base(1,max),Type(1,max),Max(max),Last(0),Free(0)
{;}

wzMultipleArrayController::~wzMultipleArrayController()
{wzIndex k;
 for(k=1;k<=Last;k++){
        destroyArray(k);
 }
 Last=Free=0;
}

wzIndex wzMultipleArrayController::defineArray(wzArrayBody* a)
{wzIndex f;
 if(Free) {f=Free,Free=Base[Free];}
 else     {f=++Last;}
 Type (f)  = TypeSeparate;
 Field(f)  = a;
 Base(f)   = 0;
 Offset(f) = 0;
 a->From   = this;
 a->Index  = f;
 if(Max) a->Allocate(Max);
 return f;
}

wzIndex wzMultipleArrayController::defineComponent(wzArrayBody *a,
				wzIndex base, wzIndex off)
{wzIndex f;
 if(Free) {f=Free,Free=Base[Free];}
 else     {f=++Last;}
 Type (f)  = TypeComponent;
 Field(f)  = a;
 if(Type(base)==TypeSeparate){
	Base (f)  = base;
	Offset(f) = off;
 }else if (Type(base)==TypeComponent){
	Base(f)   = Base(base);
	Offset(f) = Offset(base) + off;
 }else {throw wzFailure("incorrect base array of a component");}
 a->Base   = Field[base]->Base + off; // sicher ist sicher
 a->Shift  = Field[base]->Shift;
 a->Max    = Field[base]->Max;
 a->From   = this;
 a->Index  = f;
 return f;
}

void wzMultipleArrayController::destroyArray(wzIndex f)
{
 if (Type(f)== TypeSeparate){
	for(wzIndex k=1;k<=Last;k++){
		if(Type[k]==TypeComponent && Base[k]==f) destroyArray(k);
	}
        Field[f]->Allocate(0);
 }else if (Type(f)== TypeComponent){  Field[f]->Base = 0;
 }else return;
 Field[f]->From  = 0;
 Field[f]->Index = 0;
 Field[f]->Max   = 0;
 Type[f] = TypeUndefined;
 Field[f] = 0;
 Base[f] = Free; Free = f;
}

wzBoolean wzMultipleArrayController::Allocate(wzIndex i)
{wzIndex k,m=0,m0;
 for(k=1;k<=Last;k++) if(Type[k]==TypeSeparate){
	Field[k]->Allocate(i);
	m0 = Field[k]->Max;
	if(m==0 || m>m0) m=m0;
 }
 for(k=1;k<=Last;k++) if(Type[k]==TypeComponent){
	Field[k]->Base   = Field[Base[k]]->Base + Offset[k];
	Field[k]->Max    = Field[Base[k]]->Max;
 }
 Max = m;
 if(m>=i) return wzTrue; else return wzFalse;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?