|
@@ -159,6 +159,7 @@ type
|
|
NextIndex : Integer;
|
|
NextIndex : Integer;
|
|
Data : Pointer;
|
|
Data : Pointer;
|
|
end;
|
|
end;
|
|
|
|
+ PHashItem=^THashItem;
|
|
|
|
|
|
const
|
|
const
|
|
MaxHashListSize = Maxint div 16;
|
|
MaxHashListSize = Maxint div 16;
|
|
@@ -195,6 +196,7 @@ type
|
|
procedure StrExpand(MinIncSize:Integer);
|
|
procedure StrExpand(MinIncSize:Integer);
|
|
procedure SetStrCapacity(NewCapacity: Integer);
|
|
procedure SetStrCapacity(NewCapacity: Integer);
|
|
procedure SetHashCapacity(NewCapacity: Integer);
|
|
procedure SetHashCapacity(NewCapacity: Integer);
|
|
|
|
+ procedure ReHash;
|
|
public
|
|
public
|
|
constructor Create;
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
destructor Destroy; override;
|
|
@@ -216,6 +218,7 @@ type
|
|
property Count: Integer read FCount write SetCount;
|
|
property Count: Integer read FCount write SetCount;
|
|
property Items[Index: Integer]: Pointer read Get; default;
|
|
property Items[Index: Integer]: Pointer read Get; default;
|
|
property List: PHashItemList read FHashList;
|
|
property List: PHashItemList read FHashList;
|
|
|
|
+ property Strs: PChar read FStrs;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -228,7 +231,7 @@ type
|
|
TFPHashObject = class
|
|
TFPHashObject = class
|
|
private
|
|
private
|
|
FOwner : TFPHashObjectList;
|
|
FOwner : TFPHashObjectList;
|
|
- FIndex : Integer;
|
|
|
|
|
|
+ FStrIndex : Integer;
|
|
protected
|
|
protected
|
|
function GetName:string;
|
|
function GetName:string;
|
|
public
|
|
public
|
|
@@ -765,47 +768,26 @@ begin
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TFPList.Pack;
|
|
procedure TFPList.Pack;
|
|
-Var
|
|
|
|
- {Last,I,J,}
|
|
|
|
- Runner : Longint;
|
|
|
|
-begin
|
|
|
|
- // Not the fastest; but surely correct
|
|
|
|
- for Runner := Fcount - 1 downto 0 do
|
|
|
|
- if Items[Runner] = Nil then
|
|
|
|
- Self.Delete(Runner);
|
|
|
|
-{ The following may be faster in case of large and defragmented lists
|
|
|
|
- If count=0 then exit;
|
|
|
|
- Runner:=0;I:=0;
|
|
|
|
- TheLast:=Count;
|
|
|
|
- while runner<count do
|
|
|
|
|
|
+var
|
|
|
|
+ NewCount,
|
|
|
|
+ i : integer;
|
|
|
|
+ pdest,
|
|
|
|
+ psrc : PPointer;
|
|
|
|
+begin
|
|
|
|
+ NewCount:=0;
|
|
|
|
+ psrc:=@FList[0];
|
|
|
|
+ pdest:=psrc;
|
|
|
|
+ For I:=0 To FCount-1 Do
|
|
begin
|
|
begin
|
|
- // Find first Nil
|
|
|
|
- While (FList^[Runner]<>Nil) and (Runner<Count) do Runner:=Runner+1;
|
|
|
|
- if Runner<Count do
|
|
|
|
- begin
|
|
|
|
- // Start searching for non-nil from last known nil+1
|
|
|
|
- if i<Runner then I:=Runner+1;
|
|
|
|
- While (Flist[I]^=Nil) and (I<Count) do I:=I+1;
|
|
|
|
- // Start looking for last non-nil of block.
|
|
|
|
- J:=I+1;
|
|
|
|
- While (Flist^[J]<>Nil) and (J<Count) do J:=J+1;
|
|
|
|
- // Move block and zero out
|
|
|
|
- Move (Flist^[I],Flist^[Runner],J*SizeOf(Pointer));
|
|
|
|
- FillWord (Flist^[I],(J-I)*WordRatio,0);
|
|
|
|
- // Update Runner and Last to point behind last block
|
|
|
|
- TheLast:=Runner+(J-I);
|
|
|
|
- If J=Count then
|
|
|
|
- begin
|
|
|
|
- // Shortcut, when J=Count we checked all pointers
|
|
|
|
- Runner:=Count
|
|
|
|
- else
|
|
|
|
- begin
|
|
|
|
- Runner:=TheLast;
|
|
|
|
- I:=j;
|
|
|
|
- end;
|
|
|
|
|
|
+ if assigned(psrc^) then
|
|
|
|
+ begin
|
|
|
|
+ pdest^:=psrc^;
|
|
|
|
+ inc(pdest);
|
|
|
|
+ inc(NewCount);
|
|
|
|
+ end;
|
|
|
|
+ inc(psrc);
|
|
end;
|
|
end;
|
|
- Count:=TheLast;
|
|
|
|
-}
|
|
|
|
|
|
+ FCount:=NewCount;
|
|
end;
|
|
end;
|
|
|
|
|
|
// Needed by Sort method.
|
|
// Needed by Sort method.
|
|
@@ -1189,8 +1171,6 @@ end;
|
|
|
|
|
|
|
|
|
|
procedure TFPHashList.SetHashCapacity(NewCapacity: Integer);
|
|
procedure TFPHashList.SetHashCapacity(NewCapacity: Integer);
|
|
-var
|
|
|
|
- i : Integer;
|
|
|
|
begin
|
|
begin
|
|
If (NewCapacity < 1) then
|
|
If (NewCapacity < 1) then
|
|
Error (SListCapacityError, NewCapacity);
|
|
Error (SListCapacityError, NewCapacity);
|
|
@@ -1198,7 +1178,14 @@ begin
|
|
exit;
|
|
exit;
|
|
FHashCapacity:=NewCapacity;
|
|
FHashCapacity:=NewCapacity;
|
|
ReallocMem(FHashTable, FHashCapacity*sizeof(Integer));
|
|
ReallocMem(FHashTable, FHashCapacity*sizeof(Integer));
|
|
- { Rehash }
|
|
|
|
|
|
+ ReHash;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+procedure TFPHashList.ReHash;
|
|
|
|
+var
|
|
|
|
+ i : Integer;
|
|
|
|
+begin
|
|
FillDword(FHashTable^,FHashCapacity,LongWord(-1));
|
|
FillDword(FHashTable^,FHashCapacity,LongWord(-1));
|
|
For i:=0 To FCount-1 Do
|
|
For i:=0 To FCount-1 Do
|
|
AddToHashTable(i);
|
|
AddToHashTable(i);
|
|
@@ -1371,7 +1358,29 @@ begin
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TFPHashList.Pack;
|
|
procedure TFPHashList.Pack;
|
|
|
|
+var
|
|
|
|
+ NewCount,
|
|
|
|
+ i : integer;
|
|
|
|
+ pdest,
|
|
|
|
+ psrc : PHashItem;
|
|
begin
|
|
begin
|
|
|
|
+ NewCount:=0;
|
|
|
|
+ psrc:=@FHashList[0];
|
|
|
|
+ pdest:=psrc;
|
|
|
|
+ For I:=0 To FCount-1 Do
|
|
|
|
+ begin
|
|
|
|
+ if assigned(psrc^.Data) then
|
|
|
|
+ begin
|
|
|
|
+ pdest^:=psrc^;
|
|
|
|
+ inc(pdest);
|
|
|
|
+ inc(NewCount);
|
|
|
|
+ end;
|
|
|
|
+ inc(psrc);
|
|
|
|
+ end;
|
|
|
|
+ FCount:=NewCount;
|
|
|
|
+ { We need to ReHash to update the IndexNext }
|
|
|
|
+ ReHash;
|
|
|
|
+ { Release over-capacity }
|
|
SetCapacity(FCount);
|
|
SetCapacity(FCount);
|
|
SetStrCapacity(FStrCount);
|
|
SetStrCapacity(FStrCount);
|
|
end;
|
|
end;
|
|
@@ -1447,15 +1456,18 @@ end;
|
|
*****************************************************************************}
|
|
*****************************************************************************}
|
|
|
|
|
|
constructor TFPHashObject.Create(HashObjectList:TFPHashObjectList;const s:string);
|
|
constructor TFPHashObject.Create(HashObjectList:TFPHashObjectList;const s:string);
|
|
|
|
+var
|
|
|
|
+ Index : Integer;
|
|
begin
|
|
begin
|
|
FOwner:=HashObjectList;
|
|
FOwner:=HashObjectList;
|
|
- FIndex:=HashObjectList.Add(s,Self);
|
|
|
|
|
|
+ Index:=HashObjectList.Add(s,Self);
|
|
|
|
+ FStrIndex:=HashObjectList.List.List^[Index].StrIndex;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
function TFPHashObject.GetName:string;
|
|
function TFPHashObject.GetName:string;
|
|
begin
|
|
begin
|
|
- Result:=FOwner.NameOfIndex(FIndex);
|
|
|
|
|
|
+ Result:=PShortString(@FOwner.List.Strs[FStrIndex])^;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|