惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Engineering at Meta
Engineering at Meta
雷峰网
雷峰网
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
B
Blog
Y
Y Combinator Blog
WordPress大学
WordPress大学
Microsoft Azure Blog
Microsoft Azure Blog
小众软件
小众软件
G
Google Developers Blog
云风的 BLOG
云风的 BLOG
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
博客园 - 叶小钗
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
量子位
The Cloudflare Blog
T
The Blog of Author Tim Ferriss
博客园_首页
B
Blog RSS Feed
Hugging Face - Blog
Hugging Face - Blog
IT之家
IT之家
阮一峰的网络日志
阮一峰的网络日志
L
LangChain Blog
宝玉的分享
宝玉的分享

博客园 - shappy

5.12默哀 台风 - shappy - 博客园 童谣 回家 Web Control中填写JavaScript报告"缺少对象"错误问题解决 Midas如何在服务器端自动产生流水号 Clientdataset关于record change by another user错误的总结 游凤凰 设定MSAgent的说话(Balloon)停留时间 获取Agent角色的动作列表 MSAgent简介 摘录 DelphiX简介 摘录 DelphiX的刷新 TList源码分析 摘录 几种文字编码的介绍 获取/打开/关闭输入法 汉字编码标准与识别 摘录 Tclientdataset实现反向排序 关于Tclientdataset的bug
队列类
shappy · 2007-05-11 · via 博客园 - shappy

以前项目需要做的一个队列类,可能很多人习惯了用Tlist,看过Tlist代码的人知道,其实Tlist有两点不好,一个是每次需要扩展内存都是成倍扩展(2倍还是4倍),如果需要的对象很大,十万百万级别就不太适用了。另一个是对于先进先出的情况下每次出列都要整体移动一次内存,在队列数量庞大时比较耗系统开销。

{*******************************************************************************
  Project:    Project1
  Module:     uSeq.pas
  Designer:   Shappy
  Date:       2006-7-7 14:50:27
  Remark:
}

unit uSeq;
interface
uses classes, SysUtils, Windows;

type
  TSeque=class
  private
    FSeq:PPointerList;
    FHead,FTail:integer;
    FCount,FCapicity:integer;
    FCriticalSection:TRTLCriticalSection;
  protected
    procedure Enter;
    procedure Leave;
  public
    property Count:Integer read FCount;
    property Capicity:integer read FCapicity;
    constructor Create(iCapicity:Integer);
    destructor Destroy;
    function Push(item:Pointer):Boolean;
    function Pop:Pointer;
    function printBuf:string;
  end;

implementation

{ TSeque }

constructor TSeque.Create(iCapicity: Integer);
begin
  if iCapicity<=0 then iCapicity:=100;
  FCapicity:=iCapicity;
  GetMem(FSeq,FCapicity*SizeOf(Pointer));
  FHead:=0;
  FTail:=0;
  FCount:=0;
  InitializeCriticalSection(FCriticalSection);
end;

destructor TSeque.Destroy;
begin
  FreeMem(FSeq,FCapicity*SizeOf(Pointer));
  DeleteCriticalSection(FCriticalSection);
end;

procedure TSeque.Enter;
begin
  EnterCriticalSection(FCriticalSection);
end;

procedure TSeque.Leave;
begin
  LeaveCriticalSection(FCriticalSection);
end;

function TSeque.Pop: Pointer;
begin
  if (FHead=FTail) and (FCount=0) then
    result:=nil
  else begin
    enter;
    result:=FSeq^[Fhead];
    Inc(FHead);
    Dec(FCount);
    Leave;
  end;
end;

function TSeque.printBuf: string;
var
  i:integer;
begin
  result:='';
  for i:=FHead to FTail-1 do
    result:=result+inttostr(i)+' '+inttohex(Integer(FSeq^[i]),4)+#13#10;
end;

function TSeque.Push(item: Pointer): Boolean;
begin
  result:=false;
  if (FHead=FTail) and (FCount>0) or (item=nil) then
    exit  //full
  else
//    try
      enter;
      FSeq^[FTail]:=item;
      Inc(FTail);
      Inc(FCount);
//    finally
      leave;
//    end;
  result:=true;
end;

end.