19
Jun 09

Delphi: Chained List

:: articles :: by Gilberto Saraiva

Folks,

Some times when we need to hold stripped informations, like socket or audio buffers, we need to create a chained list that control all the information sequentially and provide a navigation on the holded data only by stepping forward(next) or stepping back(prior).

A structure of a Chained List is divided on 2 main variables: Data and Next(or Prior, as needed), for every Item on the Chain you have the Data(Pointer, value or someting you have to hold) and a reference for the next or prior item on the list. Chained list don’t provide a direct access for items, so you can’t access a item without navigate on others. Chained Lists can be improved, but the main goal is provide a near infinite list that have the best performance of all others techniques.

As you know now, Chained lists don’t hold indexs for items (don’t have a direct access) and that avoid re-index procedures that consume a big time when you’ve a large list. When you need to remove a item in a Chained list that have a predecessor and a antecessor, you’ll have to make the first improvement on the chain structure to hold the Prior and the Next item for each Item you have, and thats provide you a confortable way to manipulate items without writing a lot of code and variables.

A basic structure of a Chained List on Delphi

 Delphi |  copy code |? 
01
uses ChainedListCtrl;
02
 
03
type
04
  TfrmMain = class(TForm)
05
    edtWord: TEdit;
06
    btnAdd: TButton;
07
    lblPhrase: TLabel;
08
    btnClean: TButton;
09
    procedure FormCreate(Sender: TObject);
10
    procedure FormDestroy(Sender: TObject);
11
    procedure btnAddClick(Sender: TObject);
12
    procedure btnCleanClick(Sender: TObject);
13
  private
14
    { Private declarations }
15
  public
16
    Phrase: TChainedList;
17
    procedure UpdateList;
18
  end;
19
 
20
var
21
  frmMain: TfrmMain;
22
 
23
implementation
24
 
25
{$R *.dfm}
26
 
27
{ Note: Create the Chain List Control Object
28
}
29
procedure TfrmMain.FormCreate(Sender: TObject);
30
begin
31
  Phrase := TChainedList.Create;
32
end;
33
 
34
{ Note: Destroy the Chain Object
35
}
36
procedure TfrmMain.FormDestroy(Sender: TObject);
37
begin
38
  Phrase.Free;
39
end;
40
 
41
{ Note: Update the Label to hold all the words
42
        included on the Chained list
43
}
44
procedure TfrmMain.UpdateList;
45
var
46
  sPhrase: string;
47
begin
48
  sPhrase := '';
49
  Phrase.First;
50
  while Phrase.Current <> nil do
51
  begin
52
    if sPhrase <> '' then
53
      sPhrase := sPhrase + ' ';
54
 
55
    sPhrase := sPhrase + PChar(Phrase.Current^);
56
    Phrase.Next;
57
  end;
58
  lblPhrase.Caption := sPhrase;
59
end;
60
 
61
{ Note: Add the text on the Chain
62
   p.s: StrNew create a copy of the string that will be managed
63
        out of the garbage collector(str refcount structure)
64
}
65
procedure TfrmMain.btnAddClick(Sender: TObject);
66
begin
67
  Phrase.Add.Current^ := StrNew(PChar(edtWord.Text));
68
  UpdateList;
69
end;
70
 
71
{ Note: Clean the Chain list
72
   p.s: StrDispose release the memory of the create string
73
        to avoid memory leaks
74
}
75
procedure TfrmMain.btnCleanClick(Sender: TObject);
76
begin
77
  Phrase.Last;
78
  while Phrase.Current <> nil do
79
    Phrase.Remove(@StrDispose);
80
  UpdateList;
81
end;

I wrote some comments on the code to refers the goals of each method, but some things have to be said:
1st. Many improviments can be done on a Chained List, but some times a improvement can be bad to the performance result so keep it on the mind when you change some thing.
2nd. Chained List as the name says, chained, so don’t try to put a index control on it because can be a big mistake.
3rd. Use it when you need a great performance, not when you only need to hold some common data. A Indexed List control will be better and easy to manipulate then a Chained List.

Feel free to use and ask some thing.

Hugs for all

Tags: , , ,


Leave a comment