我正在研究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解决方案仍然非常有效.不太优雅,但嘿,它运作良好.如果你想要更优雅,可以围绕这一切建立一个班级!