[Back to WIN-OS2 SWAG index] [Back to Main SWAG index] [Original]
{
From: perivar@ibg.uit.no (Per Ivar Steinsund)
I've made a unit (Huge) that uses the global-heap to allocate
memory for arrays. The size of the arrays are only limited by
hardware memory.
}
Unit Huge;
(***********************************************)
(* Unit for making dynamic arrays and matrix. *)
(* The elementsize has a limit of 64 kB, but *)
(* the total size of each array/matrix is only *)
(* limited by available memory. *)
(* *)
(* Per Ivar Steinsund (1994) *)
(* *)
(* Example of use: *)
(* *)
(* var J:longint; *)
(* Arr:PHugeRealArray; *)
(* *)
(* begin *)
(* Arr:=new(PHugeRealArray,Init(0,200000, *)
(* SizeOf(Real),true)); *)
(* if Arr^.Data<>nil then *)
(* for J:=0 to 200000 do Arr^.I(J)^:=J/5;*)
(* Arr^.Done; *)
(* end; *)
(* *)
(***********************************************)
interface
uses Objects,WinAPI,OMemory,WinTypes;
Const
SegSize=$FFFF;
Type
Adr=record
Off,Seg:Word;
end;
PHugeArray=^THugeArray;
THugeArray=Object(TObject)
Data:Pointer;
MinX,MaxX:LongInt;
ElementSize,ElementsPerSeg:LongInt;
constructor Init(Min,Max:LongInt; Size:Word; Message:boolean);
function ChangeSize(Min,Max:LongInt; Message:boolean):boolean;
function I(X:LongInt):Pointer;
destructor done; virtual;
procedure GrabMem(var NewData:Pointer; Range:LongInt;
Change,Message:boolean);
function GetPtr(Pos:LongInt):Pointer;
end;
PReal=^Real;
PHugeRealArray=^THugeRealArray;
THugeRealArray=Object(THugeArray)
function I(X:LongInt):PReal;
end;
PHugeMatrix=^THugeMatrix;
THugeMatrix=Object(THugeArray)
MinY,MaxY,RangeY:LongInt;
constructor Init(Min1,Max1,Min2,Max2:LongInt; Size:Word;
Message:boolean);
function ChangeSize(Min1,Max1,Min2,Max2:LongInt;
Message:boolean):boolean;
function I(X,Y:LongInt):Pointer;
end;
PHugeWordMatrix=^THugeWordMatrix;
THugeWordMatrix=Object(THugeMatrix)
function I(X,Y:LongInt):PWord;
end;
implementation
constructor THugeArray.Init(Min,Max:LongInt; Size:Word; Message:boolean);
begin
MinX:=Min;
MaxX:=Max;
ElementSize:=Size;
GrabMem(Data,MaxX-MinX+1,false,Message);
end;
destructor THugeArray.done;
begin
GlobalFreePtr(Data);
end;
function THugeArray.I(X:LongInt):Pointer;
begin
I:=GetPtr(X-MinX);
{$IFOPT R+}
if (X<MinX) or (X>MaxX) then
if id_No=MessageBox(0,'Error in huge array, continue?','Index out of range!',
mb_YesNo or mb_IconQuestion) then
begin
Done;
Halt;
end;
{$ENDIF}
end;
function THugeArray.ChangeSize(Min,Max:LongInt; Message:boolean):boolean;
var NewData:Pointer;
begin
MinX:=Min;
MaxX:=Max;
GrabMem(NewData,MaxX-MinX+1,true,Message);
if NewData<>nil then
begin
ChangeSize:=true;
Data:=NewData;
end
else ChangeSize:=false;
end;
procedure THugeArray.GrabMem(var NewData:Pointer; Range:LongInt;
Change,Message:boolean);
var MemSize:LongInt;
begin
MemSize:=Range*ElementSize;
if not Change then ElementsPerSeg:=SegSize div ElementSize;
if (MemSize>SegSize) and (SegSize mod ElementSize<>0) then
MemSize:=(Range div ElementsPerSeg)*SegSize+ElementSize*(Range mod
ElementsPerSeg);
if Change then NewData:=GlobalReAllocPtr(Data,MemSize,Gmem_Moveable or
Gmem_NoDiscard)
else NewData:=GlobalAllocPtr(Gmem_Moveable or
Gmem_NoDiscard,MemSize);
if (NewData=nil) and Message then
MessageBox(0,'It is not possible to allocate enough memory.',
'Error',mb_OK or mb_IconInformation);
end;
function THugeArray.GetPtr(Pos:LongInt):Pointer;
begin
GetPtr:=Ptr(Adr(Data).Seg+(Pos div ElementsPerSeg)*SelectorInc,
Adr(Data).Off+(Pos mod ElementsPerSeg)*ElementSize);
end;
function THugeRealArray.I(X:LongInt):PReal;
begin
I:=inherited I(X);
end;
constructor THugeMatrix.Init(Min1,Max1,Min2,Max2:LongInt; Size:Word;
Message:boolean);
begin
MinX:=Min1;
MaxX:=Max1;
MinY:=Min2;
MaxY:=Max2;
RangeY:=1+MaxY-MinY;
ElementSize:=Size;
GrabMem(Data,(MaxX-MinX+1)*(MaxY-MinY+1),false,Message);
end;
function THugeMatrix.ChangeSize(Min1,Max1,Min2,Max2:LongInt;
Message:boolean):boolean;
var NewData:Pointer;
begin
MinX:=Min1;
MaxX:=Max1;
MinY:=Min2;
MaxY:=Max2;
RangeY:=1+MaxY-MinY;
GrabMem(NewData,(MaxX-MinX+1)*(MaxY-MinY+1),true,Message);
if NewData<>nil then
begin
ChangeSize:=true;
Data:=NewData;
end
else ChangeSize:=false;
end;
function THugeMatrix.I(X,Y:LongInt):Pointer;
begin
I:=GetPtr(Y-MinY+RangeY*(X-MinX));
{$IFOPT R+}
if (X<MinX) or (X>MaxX) or (Y<MinY) or (Y>MaxY) then
if id_No=MessageBox(0,'Error in huge matrix, continue?','Index out of range!',
mb_YesNo or mb_IconQuestion) then
begin
Done;
Halt;
end;
{$ENDIF}
end;
function THugeWordMatrix.I(X,Y:LongInt):PWord;
begin
I:=inherited I(X,Y);
end;
end.
program TestHuge;
uses Huge,WinCrt;
const Max:LongInt=200000;
MaxMat:LongInt=2500;
var J:longint;
Arr:PHugeRealArray;
Mat:PHugeWordMatrix;
begin
Arr:=new(PHugeRealArray,Init(0,Max,
SizeOf(Real),true));
if Arr^.Data<>nil then
begin
RandSeed:=1;
for J:=0 to 50 do
Arr^.I(random(Max))^:=J;
RandSeed:=1;
for J:=0 to 50 do
writeln(Arr^.I(random(Max))^:5:1);
end;
Arr^.Done;
Mat:=new(PHugeWordMatrix,Init(0,MaxMat,0,MaxMat,
SizeOf(Word),true));
if Mat^.Data<>nil then
begin
RandSeed:=1;
for J:=0 to 50 do
Mat^.I(random(MaxMat),random(MaxMat))^:=J;
RandSeed:=1;
for J:=0 to 50 do
writeln(Mat^.I(random(MaxMat),random(MaxMat))^);
end;
Mat^.Done;
writeln('Done');
end.
[Back to WIN-OS2 SWAG index] [Back to Main SWAG index] [Original]