delphi - 如何设计可变数据大小的 FIFO 队列?

标签 delphi queue delphi-2007 fifo memory-efficient

我正在研究具有可变数据大小的 FIFO 队列(简单的队列,即先推送的内容,然后首先弹出的内容),但我不确定我的设计方式。我将在那里存储的数据类型将提前已知,并且可以说对于此类的每个实例都是相同的。我正在考虑使用 TList,其中将存储具有以下定义的记录(@David - 它适用于 D2007,所以我没有 Generics.Collections 可用:)

type
  PListItem = ^TListItem;
  TListItem = record
    Size: Integer; // size of the data pointed by the following member
    Data: Pointer; // pointer to the target data reserved in memory
  end;

像这样的实现(我在这里假装一切正常,所以没有使用异常处理)

type
  TListQueue = class
private
  FList: TList;
public
  constructor Create;
  destructor Destroy; override;
  procedure Clear;
  procedure Push(const Value; const Size: Integer);
  procedure Pop(var Value; var Size: Integer);
end;

constructor TListQueue.Create;
begin
  inherited;
  FList := TList.Create;
end;

destructor TListQueue.Destroy;
begin
  Clear;
  FList.Free;
  inherited;
end;

procedure TListQueue.Push(const Value; const Size: Integer);
var ListItem: PListItem;
begin
  New(ListItem);
  ListItem.Size := Size;
  ListItem.Data := AllocMem(Size);
  Move(Value, ListItem.Data^, Size);
  FList.Add(ListItem);
end;

procedure TListQueue.Pop(var Value; var Size: Integer);
var ListItem: PListItem;
begin
  if FList.Count > 0 then
  begin
    ListItem := FList.Items[0];
    Size := ListItem^.Size;
    Move(ListItem.Data^, Value, ListItem.Size);
    FreeMem(ListItem.Data, ListItem.Size);
    Dispose(ListItem);
    FList.Delete(0);
  end;
end;

procedure TListQueue.Clear;
var I: Integer;
    ListItem: PListItem;
begin
  for I := 0 to FList.Count - 1 do
  begin
    ListItem := FList.Items[I];
    FreeMem(ListItem.Data, ListItem.Size);
    Dispose(ListItem);
  end;
  FList.Clear;
end;

我的问题是:

这是如何使 FIFO 队列(对于字符串、流、记录等数据类型)的大小从几个字节到大约 1MB(如果是流)的有效方法吗?

非常感谢

最佳答案

我建议使用位于 Contnrs.pas 中的内置 TQueue 和/或 TObjectQueue。由于缺乏泛型,我们可以为所使用的每种数据类型派生一个特殊的 TQueue。这将为您的程序的其余部分提供类型安全性,而所有与转换和指针相关的内容都捆绑在队列类中。

关于delphi - 如何设计可变数据大小的 FIFO 队列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6896666/

相关文章:

windows - 如何在 Delphi XE5 上安装 Cindy Component?

delphi - 用DELPHI获取网页内容

php - laravel队列系统适合大项目吗?

delphi - 如何判断一个单元是否已经编译成Delphi程序?

当我尝试在“搜索”菜单下使用 "Find References"时,Delphi 2007 IDE 崩溃

Delphi Aes解密函数

delphi - 在Delphi中将拉伸(stretch)图像添加到ImageList

laravel - 如何在 Laravel 8 中获取作业批处理列表

c - 无法在 fscanf() 循环中正确推送到队列

delphi - D2007 中的指针算术如何使其工作?