I'm just working on the FIFO queue (the simple one, just what's pushed first, pops at first) with the variable data size but I'm not sure with the way I'm designing it. The data types I will store there will be known in advance and let's say will be the same for each instance of this class. I was thinking about using TList where the records with the following definition will be stored (@David - it's for D2007, so I have no Generics.Collections available :)
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;
with the implementation like this (I'm pretending here that everything works fine, so no exception handling is used)
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;
My question is:
Is this the efficient way how to make FIFO queue (for data types like strings, streams, records) with size from several bytes to about 1MB (in case of stream) ?
Thanks a lot
ListItem := AllocMem(SizeOf(TListItem));
I would useNew(Listitem);
mutch "cleaner" IMO... – ColocynthNew(Listitem);
about the data types, I forgot to mention that I will know, what data type comes in and what comes out. I will have several queues and each of them will handle only one data type. Anyway it might be saved to the TListItem. – ScampiDispose()
to free the mem allocated withNew
. – ColocynthDispose
, I'm just editing the question right now. About 3rd party libraries I don't think it's necessary for this kind of stuff. Now I finally pass the stream to this queue, surely you have toSetSize
of the stream before you pass it to thePush
, so I will create also some data size getter. – Scampi