.スタッククラスの実装(オリジナル)

7499 ワード

アナログスタックの実現、スレッドの安全、速度の速さ、オーバーヘッドの小さい//スタックの実現2012-11-04
unit sfStacks;



interface

{$DEFINE MULTI_THREAD_QUEUE} // 

{$IFDEF MULTI_THREAD_QUEUE}

uses

    Windows;

{$ENDIF}

type

  TsfStack=class

  private

    FStackSize:Integer;

    FBuff:Pointer;

  {$IFDEF MULTI_THREAD_QUEUE}

    FCS:TRTLCriticalSection;

  {$ENDIF}

    FPosition:Integer;

  protected

    procedure Lock();

    procedure UnLock();

  public

    constructor Create(StackSize:Integer=1024);

    destructor  Destroy();override;

    //\\

    function Push(AItem: Pointer): Integer;virtual;

    function Pop(): Pointer;virtual;

  public

    property Size:Integer read FStackSize;

    property Position:Integer read FPosition;

  end;



implementation

{ TsfQueue }

constructor TsfStack.Create(StackSize:Integer);

begin

  {$IFDEF MULTI_THREAD_QUEUE}

     InitializeCriticalSection(FCS);

  {$ENDIF}

  if StackSize < 1024 then StackSize := 1024;

  GetMem(FBuff,StackSize * 4);

  ZeroMemory(FBuff,StackSize * 4);

  FStackSize := StackSize;

  FPosition := 0;

end;

destructor TsfStack.Destroy;

begin

  FreeMem(FBuff);

  //\\

  {$IFDEF MULTI_THREAD_QUEUE}

     DeleteCriticalSection(FCS);

  {$ENDIF}

  inherited;

end;

procedure TsfStack.Lock;

begin

  {$IFDEF MULTI_THREAD_QUEUE}

     EnterCriticalSection(FCS);

  {$ENDIF}

end;

procedure TsfStack.UnLock;

begin

  {$IFDEF MULTI_THREAD_QUEUE}

      LeaveCriticalSection(FCS);

  {$ENDIF}

end;



function TsfStack.Pop: Pointer;

var

  P:PInteger;

begin

  Lock();

  try

    if Position > 0 then

    begin

      P := FBuff;

      Dec(FPosition);

      Inc(P,FPosition);

      Result := Pointer(P^);

    end

    else

      Result := nil;

  finally

    UnLock();

  end;

end;

function TsfStack.Push(AItem: Pointer): Integer;

var

  P:PInteger;

begin

  Lock();

  try

    if Position <= Size - 1 then

    begin

      P := FBuff;

      Inc(P,Position);

      P^ := Integer(AItem);

      Inc(FPosition);

      Result := Position;

    end

    else

      Result := -1;

  finally

    UnLock();

  end;

end;

end.