Skip to content

Commit 038b7bb

Browse files
committed
replaced enumerator classes with records
1 parent c7ee903 commit 038b7bb

File tree

7 files changed

+811
-694
lines changed

7 files changed

+811
-694
lines changed

Source/Base/Collections/Spring.Collections.Base.pas

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -506,13 +506,19 @@ TInnerCollection<T> = class sealed(TEnumerableBase<T>,
506506
private type
507507
{$REGION 'Nested Types'}
508508
PT = ^T;
509-
TEnumerator = class(THashTableEnumerator, IEnumerator<T>)
510-
private
509+
PEnumerator = ^TEnumerator;
510+
TEnumerator = record
511+
Vtable: Pointer;
512+
RefCount: Integer;
513+
TypeInfo: PTypeInfo;
514+
Parent: TRefCountedObject;
515+
fSource: TInnerCollection<T>;
516+
fIndex: Integer;
517+
fVersion: Integer;
511518
fCurrent: T;
512519
function GetCurrent: T;
513-
public
514-
procedure BeforeDestruction; override;
515520
function MoveNext: Boolean;
521+
class var Enumerator_Vtable: TEnumeratorVtable;
516522
end;
517523
{$ENDREGION}
518524
private
@@ -791,7 +797,8 @@ function TEnumeratorBlock._Release: Integer;
791797
Result := AtomicDecrement(RefCount);
792798
if Result = 0 then
793799
begin
794-
Parent._Release;
800+
if Assigned(Parent) then
801+
Parent._Release;
795802
FinalizeRecord(@Self, TypeInfo);
796803
FreeMem(@Self);
797804
end;
@@ -2166,15 +2173,15 @@ function TInnerCollection<T>.GetElementType: PTypeInfo;
21662173
end;
21672174

21682175
function TInnerCollection<T>.GetEnumerator: IEnumerator<T>;
2169-
var
2170-
enumerator: TEnumerator;
21712176
begin
21722177
_AddRef;
2173-
enumerator := TEnumerator.Create;
2174-
enumerator.fSource := Self;
2175-
enumerator.fHashTable := fHashTable;
2176-
enumerator.fVersion := enumerator.fHashTable.Version;
2177-
Result := enumerator;
2178+
with PEnumerator(TEnumeratorBlock.Create(@Result, @TEnumerator.Enumerator_Vtable,
2179+
TypeInfo(TEnumerator), @TEnumerator.GetCurrent, @TEnumerator.MoveNext))^ do
2180+
begin
2181+
Parent := Self.fSource;
2182+
fSource := Self;
2183+
fVersion := Self.fHashTable.Version;
2184+
end;
21782185
end;
21792186

21802187
function TInnerCollection<T>.GetIsEmpty: Boolean;
@@ -2234,24 +2241,38 @@ function TInnerCollection<T>._Release: Integer;
22342241

22352242
{$REGION 'TInnerCollection<T>.TEnumerator'}
22362243

2237-
procedure TInnerCollection<T>.TEnumerator.BeforeDestruction;
2238-
begin
2239-
TInnerCollection<T>(fSource)._Release;
2240-
end;
2241-
22422244
function TInnerCollection<T>.TEnumerator.GetCurrent: T;
22432245
begin
22442246
Result := fCurrent;
22452247
end;
22462248

22472249
function TInnerCollection<T>.TEnumerator.MoveNext: Boolean;
2250+
var
2251+
hashTable: PHashTable;
2252+
item: PByte;
2253+
offset: Integer;
22482254
begin
2249-
if inherited MoveNext then
2255+
offset := fSource.fOffset;
2256+
hashTable := fSource.fHashTable;
2257+
if fVersion = hashTable.Version then
22502258
begin
2251-
fCurrent := PT(fItem + TInnerCollection<T>(fSource).fOffset)^;
2252-
Exit(True);
2253-
end;
2254-
Result := False;
2259+
repeat
2260+
if fIndex >= hashTable.ItemCount then
2261+
Break;
2262+
2263+
item := @hashTable.Items[fIndex * hashTable.ItemSize];
2264+
Inc(fIndex);
2265+
if PInteger(item)^ >= 0 then
2266+
begin
2267+
fCurrent := PT(item + offset)^;
2268+
Exit(True);
2269+
end;
2270+
until False;
2271+
fCurrent := Default(T);
2272+
Result := False;
2273+
end
2274+
else
2275+
Result := RaiseHelper.EnumFailedVersion;
22552276
end;
22562277

22572278
{$ENDREGION}

0 commit comments

Comments
 (0)