Статьи Королевства Дельфи


Диспетчер кучи для объектов одного размера - часть 3


type psnFixSzMemMgr = class private FLastCommit, {указатель на последний выделенный массив, в начале которого - указатель на предпоследний...} FEmptyBlock : Pointer; {указатель на последний пустой блок из списка, в начале которого - указатель на предпоследний...} FBlockSize, FCommitSize, FFillCycles: Integer; public constructor Create( const BlockSize: Integer; {Размер выделяемых блоков памяти. Реально округляется в большую сторону до величины, кратной 4.} const CommitBlocks: Integer = 127 {Количество блоков в выделяемых массивах. Должно быть больше 1 (иначе зачем огород городить?), а для скорости желательно не меньше 31. Реально увеличивается до ближайшего сверху нечётного значения (алгоритм требует это для высокой скорости).} ); function FixNew: Pointer; {Выделяет блок памяти размера BlockSize и возвращает ссылку на эту память. Выполнено в виде функции во избежание обязательного преобразования типов параметра, передаваемого по ссылке.} procedure FixDsp(const Ptr: Pointer); {Освобождает блок памяти, выделенный ранее в данном экземпляре класса, указуемый параметром Ptr.} destructor Destroy; override; end; implementation constructor psnFixSzMemMgr.Create(const BlockSize, CommitBlocks: Integer); begin FBlockSize:= (BlockSize + 3) and $7FFFFFFC; FCommitSize:= (CommitBlocks and $7FFFFFFE + 1) * FBlockSize + 4; FFillCycles:= CommitBlocks shr 1 - 1; {заполняем в один присест два блока, и цикл оформим от нуля: for I:= 0 to FFillCycles, быстрее будет} end; function psnFixSzMemMgr.FixNew: Pointer; var P, P2: Pointer; I, DBlockSize: Integer; begin if not Assigned (FEmptyBlock) then begin {выделим массив} GetMem(P, FCommitSize); Pointer(P^):= FLastCommit; FLastCommit:= P; Inc(PChar(P), 4); Pointer(P^):= Nil; P2:= Pointer(Integer(P) + FBlockSize); DBlockSize:= FBlockSize shl 1; for I:= 0 to FFillCycles do begin {надо сделать список пустых блоков} Pointer(P2^):= P; Inc(PChar(P), DBlockSize); Pointer(P^):= P2; Inc(PChar(P2), DBlockSize); end; FEmptyBlock:= P; end; Result:= FEmptyBlock; FEmptyBlock:= Pointer(Result^); end; procedure psnFixSzMemMgr.FixDsp(const Ptr: Pointer); begin Pointer(Ptr^):= FEmptyBlock; FEmptyBlock:= Ptr; end; destructor psnFixSzMemMgr.Destroy; var P: Pointer; begin while Assigned(FLastCommit) do begin P:= FLastCommit; FLastCommit:= Pointer(P^); FreeMem(P, FCommitSize); end; inherited; end;






Начало  Назад  Вперед



Книжный магазин