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

我正在研究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(如果是流)?

非常感谢

解决方法

为什么不使用:
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
    Next: PListItem; // pointer to the next data entry,or nil for the last one.
  end;

你还需要一个var Root:PListItem = nil;并使用New()和Dispose()分配/释放项目.您可能想要添加一个var LastItem:PListItem = nil;其中包含列表中的最后一项,因此每次要添加项目时都不必遍历整个列表.虽然与现代“基于对象的解决方案”相比仍然是原始的,但单个链表对于FIFO解决方案仍然非常有效.不太优雅,但嘿,它运作良好.如果你想要更优雅,可以围绕这一切建立一个班级!

相关文章

ffmpeg 是一套强大的开源的多媒体库 一般都是用 c/c++ 调用, 抽空研究了一下该库的最新版 ,把...
32位CPU所含有的寄存器有:4个数据寄存器(EAX、EBX、ECX和EDX)2个变址和指针寄存器(ESI和EDI) 2个指针寄...
1 mov dst, src dst是目的操作数,src是源操作数,指令实现的功能是:将源操作数送到目的操作数中,即:...
有三个API函数可以运行可执行文件WinExec、ShellExecute和CreateProcess。 1.CreateProcess因为使用复杂...
API原型: Declare Function MoveFileEx& Lib "kernel32" Alias "MoveFileExA" (By...