{$ifdef debug} type TLenStat = array[1..BucketSize] of integer;procedure Stat(ht: THashTable; var MaxLevel, PeakCnt, FillCnt, EmptyCnt: integer; var LenStat: TLenStat); {$endif}implementation{$ifdef debug} procedure Stat(ht: THashTable; var MaxLevel, PeakCnt, FillCnt, EmptyCnt: integer; var LenStat: TLenStat); procedure TreeStat(ht: TTreeItem); var j,i: integer; LinkedItem: TLinkedItem; begin Inc(PeakCnt); if ht.Level+1 > MaxLevel then MaxLevel:=ht.Level+1; for j:=0 to LeafSize-1 do if ht.Items[j] <> nil then begin Inc(FillCnt); if ht.Items[j] is TTreeItem then begin TreeStat(TTreeItem(ht.Items[j])); end else begin i:=0; LinkedItem:=TLinkedItem(ht.Items[j]); while LinkedItem <> nil do begin Inc(i); LinkedItem:=LinkedItem.Next; end; LenStat[i]:=LenStat[i]+1; end; end else Inc(EmptyCnt); end; begin if ht.Root <> nil then TreeStat(ht.Root); end; {$endif}{ TTreeItem }procedure TTreeItem.AddDown(Value, Data, Hash: DWORD); var i,j: integer; TreeItem: TTreeItem; LinkedItem: TLinkedItem; begin i:=Hash and $FF; if Items[i] = nil then begin Items[i]:=TLinkedItem.Create(Value,Data,nil); Inc(Filled); end else if Items[i] is TTreeItem then begin TTreeItem(Items[i]).AddDown(Value,Data,ROR(Hash)); end else begin j:=0; LinkedItem:=TLinkedItem(Items[i]); while LinkedItem <> nil do begin if Owner.CompareValue(LinkedItem.Value,Value) then begin // found LinkedItem.Data:=Data; Exit; end; LinkedItem:=LinkedItem.Next; Inc(j) end; if j >= BucketSize then begin // full TreeItem:=TTreeItem.Create(Owner); TreeItem.Level:=Level+1; LinkedItem:=TLinkedItem(Items[i]); while LinkedItem <> nil do begin TreeItem.AddDown(LinkedItem.Value, LinkedItem.Data, RORN(Owner.HashValue(LinkedItem.Value), Level+1)); LinkedItem:=LinkedItem.Next; end; TreeItem.AddDown(Value,Data,ROR(Hash)); TLinkedItem(Items[i]).Free; Items[i]:=TreeItem; end else Items[i]:=TLinkedItem.Create(Value,Data,TLinkedItem(Items[i])); end; end;constructor TTreeItem.Create(AOwner: THashTable); var j: integer; begin Owner:=AOwner; Level:=0; Filled:=0; for j:=0 to LeafSize-1 do Items[j]:=nil; end;procedure TTreeItem.Delete(Value, Hash: DWORD); var i: integer; TreeItem: TTreeItem; PrevLinkedItem,LinkedItem: TLinkedItem; begin i:=Hash and $FF; if Items[i] = nil then begin Exit; end else if Items[i] is TTreeItem then begin TTreeItem(Items[i]).Delete(Value,ROR(Hash)); if TTreeItem(Items[i]).Filled = 0 then begin TTreeItem(Items[i]).Free; Items[i]:=nil; end; end else begin PrevLinkedItem:=nil; LinkedItem:=TLinkedItem(Items[i]); while LinkedItem <> nil do begin if Owner.CompareValue(LinkedItem.Value,Value) then begin // found if PrevLinkedItem = nil then begin Items[i]:=LinkedItem.Next; if Items[i] = nil then Dec(Filled); end else PrevLinkedItem.Next:=LinkedItem.Next; LinkedItem.Next:=nil; Owner.DestroyItem(LinkedItem.Value,LinkedItem.Data); LinkedItem.Free; Exit; end; PrevLinkedItem:=LinkedItem; LinkedItem:=LinkedItem.Next; end; end; end;destructor TTreeItem.Destroy; var j: integer; LinkedItem: TLinkedItem; begin for j:=0 to LeafSize-1 do if Items[j] <> nil then if Items[j] is TTreeItem then TTreeItem(Items[j]).Free else begin LinkedItem:=TLinkedItem(Items[j]); while LinkedItem <> nil do begin Owner.DestroyItem(LinkedItem.Value,LinkedItem.Data); LinkedItem:=LinkedItem.Next; end; TLinkedItem(Items[j]).Free; end; inherited; end;function TTreeItem.Find(Value, Hash: DWORD; var Data: DWORD): Boolean; var i: integer; TreeItem: TTreeItem; LinkedItem: TLinkedItem; begin Result:=False; i:=Hash and $FF; if Items[i] = nil then begin Exit; end else if Items[i] is TTreeItem then begin Result:=TTreeItem(Items[i]).Find(Value,ROR(Hash),Data); end else begin LinkedItem:=TLinkedItem(Items[i]); while LinkedItem <> nil do begin if Owner.CompareValue(LinkedItem.Value,Value) then begin // found Data:=LinkedItem.Data; Result:=True; Exit; end; LinkedItem:=LinkedItem.Next; end; end; end;function TTreeItem.ROR(Value: DWORD): DWORD; begin Result:=((Value and $FF) shl 24) or ((Value shr 8) and $FFFFFF); end;function TTreeItem.RORN(Value: DWORD; Level: integer): DWORD; begin Result:=Value; while Level > 0 do begin Result:=ROR(Result); Dec(Level); end; end;function TTreeItem.Traverse(UserData,UserProc: Pointer; TraverseProc: TTraverseProc): Boolean; var j: integer; LinkedItem: TLinkedItem; begin Result:=False; for j:=0 to LeafSize-1 do if Items[j] <> nil then begin if Items[j] is TTreeItem then begin Result:=TTreeItem(Items[j]).Traverse(UserData,UserProc,TraverseProc); end else begin LinkedItem:=TLinkedItem(Items[j]); while LinkedItem <> nil do begin TraverseProc(UserData,UserProc,LinkedItem.Value,LinkedItem.Data,Result); LinkedItem:=LinkedItem.Next; end; end; if Result then Exit; end; end;{ TLinkedItem }constructor TLinkedItem.Create(FValue,FData: DWORD; FNext: TLinkedItem); begin Value:=FValue; Data:=FData; Next:=FNext; end;destructor TLinkedItem.Destroy; begin if Next <> nil then Next.Free; end;{ THashTable }procedure THashTable.AddDown(Value,Data,Hash: DWORD); begin if Root = nil then Root:=TTreeItem.Create(Self); Root.AddDown(Value,Data,Hash); end;procedure THashTable.Delete(Value,Hash: DWORD); begin if Root <> nil then Root.Delete(Value,Hash); end;function THashTable.Find(Value,Hash: DWORD; var Data: DWORD): Boolean; begin if Root <> nil then Result:=Root.Find(Value,Hash,Data) else Result:=False; end;constructor THashTable.Create; begin inherited; Root:=nil; end;destructor THashTable.Destroy; begin if Root <> nil then Root.Free; inherited; end;procedure THashTable.Traverse(UserData, UserProc: Pointer; TraverseProc: TTraverseProc); begin if Root <> nil then Root.Traverse(UserData, UserProc, TraverseProc); end;{ TStringHashTable }procedure TStringHashTable.Add(const S: string; Data: TObject); begin AddDown(DWORD(NewStr(S)),DWORD(Data),HashStr(S)); end;function TStringHashTable.CompareValue(Value1, Value2: DWORD): Boolean; begin if FCaseSensitive then Result:=PString(Value1)^ = PString(Value2)^ else Result:=ANSICompareText(PString(Value1)^,PString(Value2)^) = 0; end;constructor TStringHashTable.Create; begin inherited; FCaseSensitive:=False; FAutoFreeObjects:=False; end;procedure TStringHashTable.Delete(const S: string); begin inherited Delete(DWORD(@S),HashStr(S)); end;procedure TStringHashTable.DestroyItem(var Value,Data: DWORD); begin DisposeStr(PString(Value)); if FAutoFreeObjects then TObject(Data).Free; Value:=0; Data:=0; end;function TStringHashTable.Find(const S: string; var Data: TObject): Boolean; begin Result:=inherited Find(DWORD(@S),HashStr(S),DWORD(Data)); end;function TStringHashTable.HashStr(const S: string): DWORD; {var i: integer;} begin if CaseSensitive then Result:=CalcStrCRC32(S) else Result:=CalcStrCRC32(ANSIUpperCase(S));{ another hash fucn with good performance see code at the end of this unit if CaseSensitive then Result:=HashP2Str(S) else Result:=HashP2Str(ANSIUpperCase(S)); }{ simple hash-func. don't use it !!! result:=Length(S); for i:=1 to Length(S) do if CaseSensitive then Result:= ((Result shl 5) xor (Result shr 27)) xor Ord(S[i]) else Result:= ((Result shl 5) xor (Result shr 27)) xor Ord(ANSIUpperCase(S)[i]); } end;function TStringHashTable.HashValue(Value: DWORD): DWORD; begin Result:=HashStr(PString(Value)^); end;procedure TStringHashTable.Traverse(UserData: Pointer; UserProc: TStrHashTraverseProc); begin inherited Traverse(UserData,@UserProc,TraverseProc); end;procedure TStringHashTable.TraverseProc(UserData, UserProc: Pointer; Value, Data: DWORD; var Done: Boolean); begin TStrHashTraverseProc(UserProc)(UserData,PString(Value)^,TObject(Data),Done); end;procedure TStringHashTable.Traverse(UserData: Pointer; UserProc: TStrHashTraverseMeth); begin inherited Traverse(UserData,@TMethod(UserProc),TraverseMeth); end;procedure TStringHashTable.TraverseMeth(UserData, UserProc: Pointer; Value, Data: DWORD; var Done: Boolean); type PTStrHashTraverseMeth = ^TStrHashTraverseMeth; begin PTStrHashTraverseMeth(UserProc)^(UserData,PString(Value)^,TObject(Data),Done); end;{ dynamic crc32 table }const CRC32_POLYNOMIAL = $EDB88320; var Ccitt32Table: array[0..255] of DWORD;function CalcStrCRC32(const S: string): DWORD; var j: integer; begin Result:=$FFFFFFFF; for j:=1 to Length(S) do Result:= (((Result shr 8) and $00FFFFFF) xor (Ccitt32Table[(Result xor byte(S[j])) and $FF])); end;procedure BuildCRCTable; var i, j: longint; value: DWORD; begin for i := 0 to 255 do begin value := i; for j := 8 downto 1 do if ((value and 1) <> 0) then value := (value shr 1) xor CRC32_POLYNOMIAL else value := value shr 1; Ccitt32Table[i] := value; end end;initialization BuildCRCTable; end.
这么多啊!
试这个看看行不行?
$cha="select * from table where(name=$name)and(email=$email);
无论怎么优化,查询时还是要遍历每一条记录的。就看你算法怎么优化了。
按照你的思路,字段email中的值应该是唯一的,所以查询要首先用email去判断。
把那些过滤后的结果直接根据一个数据库里的字段提取呗
比如用户名啊,ip啊什么的显示这条记录你所想要的字段的数据呗 ”
能具体说一下吗?
我个人认为好一点的算法是哈西算法,就是写一个哈西算法的脚本去读那个索引表把你想要的那些记录读出来
关于哈西算法的实现,我只有delphi的不过原理是一样的你可以看看:(php好久没用了*^*)
{$define debug}
unit HashTable;interfaceuses Windows, SysUtils;const
LeafSize = 256;
BucketSize = 8;type
TLinkedItem = class
private
Value: DWORD;
Data: DWORD;
Next: TLinkedItem;
constructor Create(FValue,FData: DWORD; FNext: TLinkedItem);
destructor Destroy; override;
end; THashTable = class; // forward
TTraverseProc = procedure (UserData,UserProc: Pointer;
Value,Data: DWORD; var Done: Boolean) of object; TTreeItem = class
private
Owner: THashTable;
Level: integer;
Filled: integer;
Items: array[0..LeafSize-1] of TObject;
constructor Create(AOwner: THashTable);
destructor Destroy; override;
function ROR(Value: DWORD): DWORD;
function RORN(Value: DWORD; Level: integer): DWORD;
procedure AddDown(Value,Data,Hash: DWORD);
procedure Delete(Value,Hash: DWORD);
function Find(Value,Hash: DWORD; var Data: DWORD): Boolean;
function Traverse(UserData,UserProc: Pointer; TraverseProc: TTraverseProc): Boolean;
end; THashTable = class
private
Root: TTreeItem;
protected
function HashValue(Value: DWORD): DWORD; virtual; abstract;
procedure DestroyItem(var Value,Data: DWORD); virtual; abstract;
function CompareValue(Value1,Value2: DWORD): Boolean; virtual; abstract;
procedure AddDown(Value,Data,Hash: DWORD);
procedure Delete(Value,Hash: DWORD);
function Find(Value,Hash: DWORD; var Data: DWORD): Boolean;
procedure Traverse(UserData,UserProc: Pointer; TraverseProc: TTraverseProc);
public
constructor Create; virtual;
destructor Destroy; override;
end; TStrHashTraverseProc = procedure (UserData: Pointer; const Value: string;
Data: TObject; var Done: Boolean);
TStrHashTraverseMeth = procedure (UserData: Pointer; const Value: string;
Data: TObject; var Done: Boolean) of object; TStringHashTable = class(THashTable)
private
FCaseSensitive: Boolean;
FAutoFreeObjects: Boolean;
protected
function HashValue(Value: DWORD): DWORD; override;
procedure DestroyItem(var Value,Data: DWORD); override;
function CompareValue(Value1,Value2: DWORD): Boolean; override;
function HashStr(const S: string): DWORD;
procedure TraverseProc(UserData,UserProc: Pointer;
Value,Data: DWORD; var Done: Boolean);
procedure TraverseMeth(UserData,UserProc: Pointer;
Value,Data: DWORD; var Done: Boolean);
public
constructor Create; override;
procedure Add(const S: string; Data: TObject);
procedure Delete(const S: string);
function Find(const S: string; var Data: TObject): Boolean;
procedure Traverse(UserData: Pointer; UserProc: TStrHashTraverseProc); overload;
procedure Traverse(UserData: Pointer; UserProc: TStrHashTraverseMeth); overload;
property CaseSensitive: Boolean read FCaseSensitive write FCaseSensitive default False;
property AutoFreeObjects: Boolean read FAutoFreeObjects write FAutoFreeObjects default False;
end;function CalcStrCRC32(const S: string): DWORD;
{$ifdef debug}
type
TLenStat = array[1..BucketSize] of integer;procedure Stat(ht: THashTable; var MaxLevel, PeakCnt, FillCnt, EmptyCnt: integer;
var LenStat: TLenStat);
{$endif}implementation{$ifdef debug}
procedure Stat(ht: THashTable; var MaxLevel, PeakCnt, FillCnt, EmptyCnt: integer;
var LenStat: TLenStat); procedure TreeStat(ht: TTreeItem);
var j,i: integer;
LinkedItem: TLinkedItem;
begin
Inc(PeakCnt);
if ht.Level+1 > MaxLevel then
MaxLevel:=ht.Level+1;
for j:=0 to LeafSize-1 do
if ht.Items[j] <> nil then begin
Inc(FillCnt);
if ht.Items[j] is TTreeItem then begin
TreeStat(TTreeItem(ht.Items[j]));
end else begin
i:=0;
LinkedItem:=TLinkedItem(ht.Items[j]);
while LinkedItem <> nil do begin
Inc(i);
LinkedItem:=LinkedItem.Next;
end;
LenStat[i]:=LenStat[i]+1;
end;
end else
Inc(EmptyCnt);
end;
begin
if ht.Root <> nil then
TreeStat(ht.Root);
end;
{$endif}{ TTreeItem }procedure TTreeItem.AddDown(Value, Data, Hash: DWORD);
var i,j: integer;
TreeItem: TTreeItem;
LinkedItem: TLinkedItem;
begin
i:=Hash and $FF;
if Items[i] = nil then begin
Items[i]:=TLinkedItem.Create(Value,Data,nil);
Inc(Filled);
end else if Items[i] is TTreeItem then begin
TTreeItem(Items[i]).AddDown(Value,Data,ROR(Hash));
end else begin
j:=0;
LinkedItem:=TLinkedItem(Items[i]);
while LinkedItem <> nil do begin
if Owner.CompareValue(LinkedItem.Value,Value) then begin
// found
LinkedItem.Data:=Data;
Exit;
end;
LinkedItem:=LinkedItem.Next;
Inc(j)
end;
if j >= BucketSize then begin
// full
TreeItem:=TTreeItem.Create(Owner);
TreeItem.Level:=Level+1;
LinkedItem:=TLinkedItem(Items[i]);
while LinkedItem <> nil do begin
TreeItem.AddDown(LinkedItem.Value, LinkedItem.Data,
RORN(Owner.HashValue(LinkedItem.Value), Level+1));
LinkedItem:=LinkedItem.Next;
end;
TreeItem.AddDown(Value,Data,ROR(Hash));
TLinkedItem(Items[i]).Free;
Items[i]:=TreeItem;
end else
Items[i]:=TLinkedItem.Create(Value,Data,TLinkedItem(Items[i]));
end;
end;constructor TTreeItem.Create(AOwner: THashTable);
var j: integer;
begin
Owner:=AOwner;
Level:=0;
Filled:=0;
for j:=0 to LeafSize-1 do Items[j]:=nil;
end;procedure TTreeItem.Delete(Value, Hash: DWORD);
var i: integer;
TreeItem: TTreeItem;
PrevLinkedItem,LinkedItem: TLinkedItem;
begin
i:=Hash and $FF;
if Items[i] = nil then begin
Exit;
end else if Items[i] is TTreeItem then begin
TTreeItem(Items[i]).Delete(Value,ROR(Hash));
if TTreeItem(Items[i]).Filled = 0 then begin
TTreeItem(Items[i]).Free;
Items[i]:=nil;
end;
end else begin
PrevLinkedItem:=nil;
LinkedItem:=TLinkedItem(Items[i]);
while LinkedItem <> nil do begin
if Owner.CompareValue(LinkedItem.Value,Value) then begin
// found
if PrevLinkedItem = nil then begin
Items[i]:=LinkedItem.Next;
if Items[i] = nil then
Dec(Filled);
end else
PrevLinkedItem.Next:=LinkedItem.Next;
LinkedItem.Next:=nil;
Owner.DestroyItem(LinkedItem.Value,LinkedItem.Data);
LinkedItem.Free;
Exit;
end;
PrevLinkedItem:=LinkedItem;
LinkedItem:=LinkedItem.Next;
end;
end;
end;destructor TTreeItem.Destroy;
var j: integer;
LinkedItem: TLinkedItem;
begin
for j:=0 to LeafSize-1 do
if Items[j] <> nil then
if Items[j] is TTreeItem then
TTreeItem(Items[j]).Free
else begin
LinkedItem:=TLinkedItem(Items[j]);
while LinkedItem <> nil do begin
Owner.DestroyItem(LinkedItem.Value,LinkedItem.Data);
LinkedItem:=LinkedItem.Next;
end;
TLinkedItem(Items[j]).Free;
end;
inherited;
end;function TTreeItem.Find(Value, Hash: DWORD; var Data: DWORD): Boolean;
var i: integer;
TreeItem: TTreeItem;
LinkedItem: TLinkedItem;
begin
Result:=False;
i:=Hash and $FF;
if Items[i] = nil then begin
Exit;
end else if Items[i] is TTreeItem then begin
Result:=TTreeItem(Items[i]).Find(Value,ROR(Hash),Data);
end else begin
LinkedItem:=TLinkedItem(Items[i]);
while LinkedItem <> nil do begin
if Owner.CompareValue(LinkedItem.Value,Value) then begin
// found
Data:=LinkedItem.Data;
Result:=True;
Exit;
end;
LinkedItem:=LinkedItem.Next;
end;
end;
end;function TTreeItem.ROR(Value: DWORD): DWORD;
begin
Result:=((Value and $FF) shl 24) or ((Value shr 8) and $FFFFFF);
end;function TTreeItem.RORN(Value: DWORD; Level: integer): DWORD;
begin
Result:=Value;
while Level > 0 do begin
Result:=ROR(Result);
Dec(Level);
end;
end;function TTreeItem.Traverse(UserData,UserProc: Pointer;
TraverseProc: TTraverseProc): Boolean;
var j: integer;
LinkedItem: TLinkedItem;
begin
Result:=False;
for j:=0 to LeafSize-1 do
if Items[j] <> nil then begin
if Items[j] is TTreeItem then begin
Result:=TTreeItem(Items[j]).Traverse(UserData,UserProc,TraverseProc);
end else begin
LinkedItem:=TLinkedItem(Items[j]);
while LinkedItem <> nil do begin
TraverseProc(UserData,UserProc,LinkedItem.Value,LinkedItem.Data,Result);
LinkedItem:=LinkedItem.Next;
end;
end;
if Result then Exit;
end;
end;{ TLinkedItem }constructor TLinkedItem.Create(FValue,FData: DWORD; FNext: TLinkedItem);
begin
Value:=FValue;
Data:=FData;
Next:=FNext;
end;destructor TLinkedItem.Destroy;
begin
if Next <> nil then
Next.Free;
end;{ THashTable }procedure THashTable.AddDown(Value,Data,Hash: DWORD);
begin
if Root = nil then
Root:=TTreeItem.Create(Self);
Root.AddDown(Value,Data,Hash);
end;procedure THashTable.Delete(Value,Hash: DWORD);
begin
if Root <> nil then
Root.Delete(Value,Hash);
end;function THashTable.Find(Value,Hash: DWORD; var Data: DWORD): Boolean;
begin
if Root <> nil then
Result:=Root.Find(Value,Hash,Data)
else
Result:=False;
end;constructor THashTable.Create;
begin
inherited;
Root:=nil;
end;destructor THashTable.Destroy;
begin
if Root <> nil then Root.Free;
inherited;
end;procedure THashTable.Traverse(UserData, UserProc: Pointer;
TraverseProc: TTraverseProc);
begin
if Root <> nil then
Root.Traverse(UserData, UserProc, TraverseProc);
end;{ TStringHashTable }procedure TStringHashTable.Add(const S: string; Data: TObject);
begin
AddDown(DWORD(NewStr(S)),DWORD(Data),HashStr(S));
end;function TStringHashTable.CompareValue(Value1, Value2: DWORD): Boolean;
begin
if FCaseSensitive then
Result:=PString(Value1)^ = PString(Value2)^
else
Result:=ANSICompareText(PString(Value1)^,PString(Value2)^) = 0;
end;constructor TStringHashTable.Create;
begin
inherited;
FCaseSensitive:=False;
FAutoFreeObjects:=False;
end;procedure TStringHashTable.Delete(const S: string);
begin
inherited Delete(DWORD(@S),HashStr(S));
end;procedure TStringHashTable.DestroyItem(var Value,Data: DWORD);
begin
DisposeStr(PString(Value));
if FAutoFreeObjects then
TObject(Data).Free;
Value:=0;
Data:=0;
end;function TStringHashTable.Find(const S: string; var Data: TObject): Boolean;
begin
Result:=inherited Find(DWORD(@S),HashStr(S),DWORD(Data));
end;function TStringHashTable.HashStr(const S: string): DWORD;
{var i: integer;}
begin
if CaseSensitive then
Result:=CalcStrCRC32(S)
else
Result:=CalcStrCRC32(ANSIUpperCase(S));{ another hash fucn with good performance
see code at the end of this unit
if CaseSensitive then
Result:=HashP2Str(S)
else
Result:=HashP2Str(ANSIUpperCase(S));
}{ simple hash-func. don't use it !!!
result:=Length(S);
for i:=1 to Length(S) do
if CaseSensitive then
Result:= ((Result shl 5) xor (Result shr 27)) xor Ord(S[i])
else
Result:= ((Result shl 5) xor (Result shr 27)) xor Ord(ANSIUpperCase(S)[i]);
}
end;function TStringHashTable.HashValue(Value: DWORD): DWORD;
begin
Result:=HashStr(PString(Value)^);
end;procedure TStringHashTable.Traverse(UserData: Pointer;
UserProc: TStrHashTraverseProc);
begin
inherited Traverse(UserData,@UserProc,TraverseProc);
end;procedure TStringHashTable.TraverseProc(UserData, UserProc: Pointer; Value,
Data: DWORD; var Done: Boolean);
begin
TStrHashTraverseProc(UserProc)(UserData,PString(Value)^,TObject(Data),Done);
end;procedure TStringHashTable.Traverse(UserData: Pointer; UserProc: TStrHashTraverseMeth);
begin
inherited Traverse(UserData,@TMethod(UserProc),TraverseMeth);
end;procedure TStringHashTable.TraverseMeth(UserData, UserProc: Pointer; Value,
Data: DWORD; var Done: Boolean);
type
PTStrHashTraverseMeth = ^TStrHashTraverseMeth;
begin
PTStrHashTraverseMeth(UserProc)^(UserData,PString(Value)^,TObject(Data),Done);
end;{ dynamic crc32 table }const
CRC32_POLYNOMIAL = $EDB88320;
var
Ccitt32Table: array[0..255] of DWORD;function CalcStrCRC32(const S: string): DWORD;
var j: integer;
begin
Result:=$FFFFFFFF;
for j:=1 to Length(S) do
Result:= (((Result shr 8) and $00FFFFFF) xor (Ccitt32Table[(Result xor byte(S[j])) and $FF]));
end;procedure BuildCRCTable;
var i, j: longint;
value: DWORD;
begin
for i := 0 to 255 do begin
value := i;
for j := 8 downto 1 do
if ((value and 1) <> 0) then
value := (value shr 1) xor CRC32_POLYNOMIAL
else
value := value shr 1;
Ccitt32Table[i] := value;
end
end;initialization
BuildCRCTable;
end.