1 {
2 Copyright (C) Alexey Torgashin, uvviewsoft.com
3 License: MPL 2.0 or LGPL
4 }
5 unit ATSynEdit_LinkCache;
6
7 {$mode objfpc}{$H+}
8 {$ModeSwitch advancedrecords}
9
10 interface
11
12 uses
13 SysUtils,
14 ATSynEdit_fgl;
15
16 const
17 cMaxLinksPerLine = 15;
18
19 type
20 TATLinkPair = record
21 NFrom, NLen: integer;
22 end;
23
24 PATLinkArray = ^TATLinkArray;
25 TATLinkArray = array[0..cMaxLinksPerLine-1] of TATLinkPair;
26
27 type
28 { TATLinkCacheItem }
29
30 PATLinkCacheItem = ^TATLinkCacheItem;
31 TATLinkCacheItem = record
32 LineIndex: integer;
33 Data: TATLinkArray;
34 class operator =(const a, b: TATLinkCacheItem): boolean;
35 end;
36
37 TATLinkCache = class(specialize TFPGList<TATLinkCacheItem>)
38 private
39 FMaxCount: integer;
40 procedure SetMaxCount(AValue: integer);
41 public
42 property MaxCount: integer read FMaxCount write SetMaxCount;
43 constructor Create;
FindDatanull44 function FindData(ALineIndex: integer): PATLinkArray;
45 procedure AddData(ALineIndex: integer; const AData: TATLinkArray);
46 procedure DeleteData(ALineIndex: integer);
47 procedure DeleteDataOutOfRange(ALine1, ALine2: integer);
DebugTextnull48 function DebugText: string;
49 end;
50
51 implementation
52
CompareItemsnull53 function CompareItems(const a, b: TATLinkCacheItem): integer;
54 begin
55 Result:= a.LineIndex - b.LineIndex;
56 end;
57
58 { TATLinkCacheItem }
59
60 class operator TATLinkCacheItem.=(const a, b: TATLinkCacheItem): boolean;
61 begin
62 Result:= false;
63 end;
64
65 { TATLinkCache }
66
67 procedure TATLinkCache.SetMaxCount(AValue: integer);
68 begin
69 if FMaxCount=AValue then Exit;
70 FMaxCount:= AValue;
71 if FMaxCount<2 then
72 FMaxCount:= 2;
73
74 while Count>FMaxCount do
75 Delete(0);
76 end;
77
78 constructor TATLinkCache.Create;
79 begin
80 inherited Create;
81 MaxCount:= 80;
82 end;
83
FindDatanull84 function TATLinkCache.FindData(ALineIndex: integer): PATLinkArray;
85 var
86 Ptr: PATLinkCacheItem;
87 a, b, m: integer;
88 dif: integer;
89 begin
90 a:= 0;
91 b:= Count-1;
92 while a<=b do
93 begin
94 m:= (a+b+1) div 2;
95 Ptr:= PATLinkCacheItem(InternalGet(m));
96 dif:= Ptr^.LineIndex-ALineIndex;
97 if dif=0 then
98 exit(@Ptr^.Data);
99 if dif<0 then
100 a:= m+1
101 else
102 b:= m-1;
103 end;
104 Result:= nil;
105 end;
106
107 procedure TATLinkCache.AddData(ALineIndex: integer; const AData: TATLinkArray);
108 var
109 Item: TATLinkCacheItem;
110 begin
111 Item.LineIndex:= ALineIndex;
112 Item.Data:= AData;
113 Add(Item);
114 Sort(@CompareItems);
115 end;
116
117 procedure TATLinkCache.DeleteData(ALineIndex: integer);
118 var
119 Ptr: PATLinkCacheItem;
120 i: integer;
121 begin
122 for i:= 0 to Count-1 do
123 begin
124 Ptr:= InternalGet(i);
125 if Ptr^.LineIndex=ALineIndex then
126 begin
127 Delete(i);
128 exit;
129 end;
130 end;
131 end;
132
133 procedure TATLinkCache.DeleteDataOutOfRange(ALine1, ALine2: integer);
134 var
135 Ptr: PATLinkCacheItem;
136 i: integer;
137 begin
138 for i:= Count-1 downto 0 do
139 begin
140 Ptr:= InternalGet(i);
141 if (Ptr^.LineIndex<ALine1) or (Ptr^.LineIndex>ALine2) then
142 Delete(i);
143 end;
144 end;
145
DebugTextnull146 function TATLinkCache.DebugText: string;
147 var
148 Ptr: PATLinkCacheItem;
149 iCache, iPair: integer;
150 begin
151 Result:= '';
152 for iCache:= 0 to Count-1 do
153 begin
154 Ptr:= InternalGet(iCache);
155 Result+= '['+IntToStr(Ptr^.LineIndex)+'] ';
156 for iPair:= 0 to High(TATLinkArray) do
157 with Ptr^.Data[iPair] do
158 begin
159 if NLen=0 then Break;
160 Result+= IntToStr(NFrom)+','+IntToStr(NLen)+' ';
161 end;
162 end;
163 end;
164
165 end.
166
167