怎么维护这3000万个状态?
现在有一个项目,需要用一个服务器保存3000万个电话号码的忙或空闲的状态,另外一台服务器监控这3000万个电话号码的状态,并且把状态更新及时发送到第一个服务器。假设服务器内存足够大,程序用delphi开发,用什么样的数据结构,能比较快的在这3000万个数据结构中查找到特定的一个电话号码,并且改变这个电话号码的状态,这个速度至少要达到1000次/秒。
我的初步想法是建立300-3000个hash表,每个表存放10万-1万个电话号码,这样的查找速度还算可以,但是达不到1000/秒。
各位XDJM,有没有什么高见?
[解决办法]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
FBits: TBits;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
FBits := TBits.Create;
FBits.Size := 99999999; // 8位号码 千万级 类填充索引
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeAndNil(FBits);
end;
procedure TForm1.Button1Click(Sender: TObject);
const
testCount = 1000000; //百万个测试
var
numberList: array of integer;
numberFlagList: array of boolean;
i: integer;
bt: DWORD;
begin
Randomize;
setlength(numberList, testCount);
setlength(numberFlagList, testCount);
for i := 0 to testCount - 1 do
begin
numberList[i] := Random(99999999);
// 造百万个测试 的号码
end;
bt := GetTickCount;
for i := 0 to testCount - 1 do
numberFlagList[i] := FBits.Bits[numberList[i]] ;
ShowMessage(IntToStr(GetTickCount-bt));
// 百万个测试不会 超过 1秒的
end;
end.
[解决办法]
30,000,000=30M
需要内存30/8=3.75M
所以,创建一个100倍大小的存储区也就是375M内存。
假如电话号码8位,那么最大电话号码数量是100M,需要内存只有12.5M,那么直接将电话号码对应的整数作为hash值即可。
Buf:=AllocMem(12500000);
hash := StrToInt(PhoneNum);
AByte := Buf[hash shr 3];
AStatus := (AByte and (1 shl (hash and 7))) <> 0;//取状态,AStatus:boolean;
设定状态
AByte:= AByte and not (1 shl (hash and 7));
AByte:= (AByte or (AStatus shl (hash and 7)))//AStatus:byte,两种状态:0,1
上述做法是基于byte的。其实如果是基于dword,效率会更快。
[解决办法]
TmyRec = record
quhao: string;//区号
list: TBits;
end;
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
myRecList: array of TmyRec;
public
{ Public declarations }
end;