-
Notifications
You must be signed in to change notification settings - Fork 51
/
Copy pathuFastList.pas
134 lines (120 loc) · 3.56 KB
/
uFastList.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
unit uFastList;
interface
uses
Classes, Sysutils;
type
TListSorted = class(TList)
private
//FValues: TList;
// Allow duplicate objects in the
// list of objects based on
// compare(item1,item2) = 0
// Default to dupIgnore (dupes ok)
Duplicates : TDuplicates;
public
procedure AfterConstruction; override;
destructor Destroy; override;
constructor Create;
// an abstract compare function
// this should be overridden by an inheriting class
// it should return -1 if item1 < item2
// 0 if item1 = item2
// 1 if item1 > item2
function Compare(Item1, Item2: Pointer; const aFindMode: LongBool): Integer; virtual; abstract;
//function AddKeyValue(Key, Value: Pointer): Integer;
function Add(Item: Pointer): Integer;
// returns the index of Item using the compare method to find
// the object
// note: if more than one object matches using the compare method,
// this does not look for the same memory address by
// matching the pointers, it looks for the same value
// ie compare method returns 0
// then any one of those matching could be returned
// The index returned, ranges from 0 to Count-1
// A value of -1 indicates that no Item was found
function FindObject(Item : Pointer) : Integer;
end;
implementation
procedure TListSorted.AfterConstruction;
begin
inherited;
//FValues := TList.Create;
end;
constructor TListSorted.Create;
begin
Duplicates := dupIgnore;
inherited Create;
end;
destructor TListSorted.Destroy;
begin
//FValues.Free;
inherited;
end;
//function TListSorted.AddKeyValue(Key, Value: Pointer): Integer;
function TListSorted.Add(Item: Pointer): Integer;
var
nCount : Integer;
bFound : LongBool;
nResult : Integer;
begin
nCount := 0;
bFound := False;
// search the list of objects until we find the
// correct position for the new object we are adding
while (not bFound) and (nCount < Count) do
begin
if (Compare(Items[nCount], Item, False) >= 0) then
bFound := True
else
inc(nCount);
end;
if (bFound) then
begin
if (Duplicates = dupIgnore) or (Compare(Items[nCount], Item, False) <> 0) then
begin
Insert(nCount,Item);
nResult := nCount;
end
else
nResult := -1;
end
else
nResult := inherited Add(Item);
Add := nResult;
end;
function TListSorted.FindObject(Item : Pointer) : Integer;
// Find the object using the compare method and
// a binary chop search
var
nResult : Integer;
nLow : Integer;
nHigh : Integer;
nCompare : Integer;
nCheckPos : Integer;
begin
nLow := 0;
nHigh := Count-1;
nResult := -1;
Result := -1;
// keep searching until found or
// no more items to search
while (nResult = -1) and (nLow <= nHigh) do
begin
nCheckPos := (nLow + nHigh) div 2;
nCompare := Compare(Item, Items[nCheckPos], True);
if (nCompare <= -1) then // less than
nHigh := nCheckPos - 1
else if (nCompare >= 1) then // greater than
begin
FindObject := nCheckPos; //best c.q. last c.q. lowest result
nLow := nCheckPos + 1
end
else // equal to
begin
nResult := nCheckPos;
Exit;
end;
end;
//FindObject := nCheckPos; //nResult; best c.q. last result
end;
end.