質問

I'm implementing a local cache to speed up DNS lookups (IP->hostname). The cache is loaded from a CSV file("1.1.1.1host.example.com") into a TStringList with two fields:

TStringList[0] := IPAddress;
TStringList[1] := HostName;

Since I will be querying TStringList via the IP, I obliously want the first field to be sorted:

TStringList.sorted := True;

Will that take care of it so that I can find faster with

IPResolved:=TStringList[TStringList.IndexOf('1.1.1.1'),1];

?

Thanks!

役に立ちましたか?

解決

Disclaimer:

This won't answer you how to sort a string list or how to load your data into a string list. It will offer you to use a hash table, which is more efficient than using a string list for your purpose (40k name, value pairs with the search by name).

Alternative:

Since you have Delphi XE2, you can use generics TDictionary class. It will contain IP address as the key and host name as the value. In the following code is shown, how to fill a dictionary and how to search for the value (host name) by a given key (IP address):

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Generics.Collections;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    IPList: TDictionary<string, string>;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  // create the TDictionary instance
  IPList := TDictionary<string, string>.Create;
  // here you will read your CSV file and add the items in a loop
  // I've used here some of the major IP addresses for Sweden
  IPList.Add('77.244.224.0', 'Insat Net AB');
  IPList.Add('79.138.128.0', 'Hi3G Access AB');
  IPList.Add('62.181.192.0', 'DGC Access AB');
  IPList.Add('81.216.128.0', 'TDC Swerige AB');
  IPList.Add('80.252.176.0', 'Phonera Networks AB');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  // release a dictionary instance
  IPList.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  HostName: string;
begin
  // and how to search by the IP address and get the host name if found
  if IPList.TryGetValue('81.216.128.0', HostName) then
    ShowMessage(HostName)
  else
    ShowMessage('IP address not found!');
end;

end.

Extension:

The above solution you can then simply extend to use a structure to store more than only a host name, e.g. also a host location:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Generics.Collections;

type
  TIPData = record
    HostName: string;
    HostLocation: string;
  end;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    IPList: TDictionary<string, TIPData>;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  IPData: TIPData;
begin
  IPList := TDictionary<string, TIPData>.Create;

  IPData.HostName := 'Broadnet Europe France';
  IPData.HostLocation := 'France';
  IPList.Add('78.155.128.0', IPData);

  IPData.HostName := 'DNA Palvelut Oy';
  IPData.HostLocation := 'Finland';
  IPList.Add('62.113.160.0', IPData);

  IPData.HostName := 'CD-Telematika a.s.';
  IPData.HostLocation := 'Czech republic';
  IPList.Add('89.203.128.0', IPData);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  IPList.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  IPData: TIPData;
begin
  if IPList.TryGetValue('89.203.128.0', IPData) then
    ShowMessage('Provider ' + IPData.HostName + ' from ' + IPData.HostLocation)
  else
    ShowMessage('IP address not found!');
end;

end.
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top