66interface
77
88uses
9- Classes, SysUtils, Math, syncobjs;
10-
11- type
12- TWSManager = class ;
9+ { $IFDEF MSWINDOWS} Windows, { $ENDIF} Classes, SysUtils, Math, syncobjs;
1310
1411const
1512 HashBuckets = 1 shl 17 ;
1613
14+ type
15+ TWSManager = class ;
16+
1717type
1818 TData = record
19- FMin: Single ;
20- FMax: Single ;
21- FTot: Single ;
19+ FMin: Int64 ;
20+ FMax: Int64 ;
21+ FTot: Int64 ;
2222 FCnt: Integer;
2323 FHash: QWord;
2424 end ;
@@ -73,7 +73,7 @@ TWSThread = class(TWSThreadBase)
7373 FWSList: TWSList;
7474 procedure UpdateMainHashList ;
7575 procedure ProcessBytes (ABytes: TBytes);
76- procedure AddToHashList (AStation: TBytes; ATemp: Single ; AHash: QWord);
76+ procedure AddToHashList (AStation: TBytes; ATemp: Int64 ; AHash: QWord);
7777 procedure UpdateThreadList (AUpdateType: TUpdateType);
7878 protected
7979 procedure Execute ; override;
@@ -93,21 +93,19 @@ TWSThreadsWatcher = class(TWSThreadBase)
9393
9494 TWSManager = class
9595 private
96+ FDone: Boolean;
9697 FSrcFile: String;
9798 FThreadCnt: Integer;
9899 FTerminated: Boolean;
99100 FThreadList: TLockList;
100101 FWSListALL: TWSList;
101102 FWSThreadsWatcher: TWSThreadsWatcher;
102- FOnStart: TNotifyEvent;
103- FOnFinish: TNotifyEvent;
104103 public
105104 constructor Create(ASrcFile: String; AThreadCnt: Integer);
106105 destructor Destroy; override;
107106 public
108107 property WSThreadsWatcher: TWSThreadsWatcher read FWSThreadsWatcher;
109- property OnStart: TNotifyEvent read FOnStart write FOnStart;
110- property OnFinish: TNotifyEvent read FOnFinish write FOnFinish;
108+ property Done: Boolean read FDone;
111109 end ;
112110
113111implementation
@@ -294,7 +292,7 @@ procedure TWSThread.ProcessBytes(ABytes: TBytes);
294292 PDel: Int64;
295293 Len: Int64;
296294 Station: TBytes;
297- Temp: Single ;
295+ Temp: Int64 ;
298296 DoHash: Boolean;
299297 DoTemp: Boolean;
300298 IsNeg: Boolean;
@@ -303,7 +301,7 @@ procedure TWSThread.ProcessBytes(ABytes: TBytes);
303301 PCur := -1 ;
304302 PBeg := 0 ;
305303 PDel := 0 ;
306- Temp := 0 ;
304+ Temp := 1000 ;
307305 Station := nil ;
308306 DoHash := True;
309307 DoTemp := False;
@@ -313,25 +311,25 @@ procedure TWSThread.ProcessBytes(ABytes: TBytes);
313311 Inc(PCur);
314312 if DoTemp then
315313 begin
316- IsNeg := False;
317- if ABytes[PCur] = 45 then
318- begin
319- Inc(PCur);
320- IsNeg := True;
321- end ;
322- Temp := Ord(ABytes[PCur]) - Ord(' 0' );
323- Inc(PCur);
324- if ABytes[PCur] <> 46 then
325- begin
326- Temp := Temp*10 + (Ord(ABytes[PCur]) - Ord(' 0' ));
327- Inc(PCur)
328- end ;
329- Inc(PCur);
330- Temp := Temp + ( Ord(ABytes[PCur]) - Ord(' 0' ))/ 10 ;
331- if IsNeg then
332- Temp := -Temp;
333- Inc(PCur);
334- DoTemp := False;
314+ IsNeg := False;
315+ if ABytes[PCur] = 45 then
316+ begin
317+ Inc(PCur);
318+ IsNeg := True;
319+ end ;
320+ Temp := Ord(ABytes[PCur]) - Ord(' 0' );
321+ Inc(PCur);
322+ if ABytes[PCur] <> 46 then
323+ begin
324+ Temp := Temp*10 + (Ord(ABytes[PCur]) - Ord(' 0' ));
325+ Inc(PCur)
326+ end ;
327+ Inc(PCur);
328+ Temp := Temp* 10 + Ord(ABytes[PCur]) - Ord(' 0' );
329+ if IsNeg then
330+ Temp := -Temp;
331+ Inc(PCur);
332+ DoTemp := False;
335333 end ;
336334 if ABytes[PCur] = 59 then
337335 begin
@@ -349,10 +347,12 @@ procedure TWSThread.ProcessBytes(ABytes: TBytes);
349347 begin
350348 SetLength(Station, PDel - PBeg);
351349 Move(ABytes[PBeg], Station[0 ], PDel - PBeg);
352- AddToHashList(Station, Temp, Hash);
350+ if (Station <> nil ) and (Temp < 1000 ) then
351+ AddToHashList(Station, Temp, Hash);
353352 Hash := 14695981039346656037 ;
354353 DoHash := True;
355- Temp := 0 ;
354+ Station := nil ;
355+ Temp := 1000 ;
356356 DoTemp := False;
357357 PBeg := PCur + 1 ;
358358 end ;
@@ -369,6 +369,7 @@ procedure TWSThread.Execute;
369369begin
370370 UpdateThreadList(utAdd);
371371 try
372+ FStarted := True;
372373 FMS.Write(FBytes[0 ], Length(FBytes));
373374 FMS.Position := 0 ;
374375 FBytes := nil ;
@@ -399,7 +400,7 @@ procedure TWSThread.Execute;
399400 end ;
400401end ;
401402
402- procedure TWSThread.AddToHashList (AStation: TBytes; ATemp: Single ; AHash: QWord);
403+ procedure TWSThread.AddToHashList (AStation: TBytes; ATemp: Int64 ; AHash: QWord);
403404var
404405 Index: Integer;
405406begin
@@ -408,20 +409,20 @@ procedure TWSThread.AddToHashList(AStation: TBytes; ATemp: Single; AHash: QWord)
408409 begin
409410 if FWSList[Index].FStation = nil then
410411 begin
411- SetLength(FWSList[Index].FStation, Length(Astation ));
412- Move(Astation [0 ], FWSList[Index].FStation[0 ], Length(Astation ));
413- FWSList[Index].FData.FMin := Atemp ;
414- FWSList[Index].FData.FMax := Atemp ;
415- FWSList[Index].FData.FTot := Atemp ;
412+ SetLength(FWSList[Index].FStation, Length(AStation ));
413+ Move(AStation [0 ], FWSList[Index].FStation[0 ], Length(AStation ));
414+ FWSList[Index].FData.FMin := ATemp ;
415+ FWSList[Index].FData.FMax := ATemp ;
416+ FWSList[Index].FData.FTot := ATemp ;
416417 FWSList[Index].FData.FCnt := 1 ;
417418 FWSList[Index].FData.FHash := AHash;
418419 Break;
419420 end ;
420- if CompareMem(@FWSList[Index].FStation[0 ], @Astation [0 ], Length(Astation )) then
421+ if CompareMem(@FWSList[Index].FStation[0 ], @AStation [0 ], Length(AStation )) then
421422 begin
422- FWSList[Index].FData.FMin := min(FWSList[Index].FData.FMin, Atemp );
423- FWSList[Index].FData.FMax := max(FWSList[Index].FData.FMax, Atemp );
424- FWSList[Index].FData.FTot := FWSList[Index].FData.FTot + Atemp ;
423+ FWSList[Index].FData.FMin := min(FWSList[Index].FData.FMin, ATemp );
424+ FWSList[Index].FData.FMax := max(FWSList[Index].FData.FMax, ATemp );
425+ FWSList[Index].FData.FTot := FWSList[Index].FData.FTot + ATemp ;
425426 Inc(FWSList[Index].FData.FCnt);
426427 Break;
427428 end ;
@@ -498,8 +499,10 @@ procedure TWSThreadsWatcher.CreateFinalList;
498499 WS: TWS;
499500 Str: String;
500501 Name : RawByteString;
501- Mean: Single;
502+ Min, Max: Double;
503+ Mean: Double;
502504 SL: TStringList;
505+ // MS: TMemoryStream;
503506begin
504507 SL := TStringList.Create;
505508 try
@@ -513,9 +516,10 @@ procedure TWSThreadsWatcher.CreateFinalList;
513516 Continue;
514517 SetString(Name , Pointer(@WS.FStation[0 ]), Length(WS.FStation));
515518 SetCodePage(Name , CP_UTF8, True);
516- WS.FData.FTot := Round(WS.FData.FTot*10 )/10 ;
517- Mean := WS.FData.FTot/WS.FData.FCnt;
518- Str := Name + ' =' + FormatFloat(' 0.0' , WS.FData.FMin) + ' /' + FormatFloat(' 0.0' , Mean) + ' /' + FormatFloat(' 0.0' , WS.FData.FMax) + ' ,' ;
519+ Min := WS.FData.FMin/10 ;
520+ Max := WS.FData.FMax/10 ;
521+ Mean := WS.FData.FTot/WS.FData.FCnt/10 ;
522+ Str := Name + ' =' + FormatFloat(' 0.0' , Min) + ' /' + FormatFloat(' 0.0' , Mean) + ' /' + FormatFloat(' 0.0' , Max) + ' ,' ;
519523 SL.Add(Str);
520524 end ;
521525 SL.EndUpdate;
@@ -528,7 +532,26 @@ procedure TWSThreadsWatcher.CreateFinalList;
528532 Delete(Str, Length(Str), 1 );
529533 Str := ' {' + Str + ' }' ;
530534 Str := StringReplace(Str, sLineBreak, ' ' , [rfReplaceAll]);
535+ // write to console
536+ { $IFDEF MSWINDOWS}
537+ SetConsoleOutputCP(CP_UTF8);
538+ SetTextCodePage(Output, CP_UTF8);
539+ SetString(Name , Pointer(@Str[1 ]), Length(Str));
540+ SetCodePage(Name , CP_UTF8, False);
541+ Writeln(Name );
542+ { $ELSE}
531543 Writeln(Str);
544+ { $ENDIF}
545+
546+ // save to file
547+ { MS := TMemoryStream.Create;
548+ try
549+ MS.Write(Pointer(Str)^, Length(Str) div SizeOf(Char));
550+ MS.Position := 0;
551+ MS.SaveToFile('summary.txt');
552+ finally
553+ MS.Free
554+ end;}
532555end ;
533556
534557procedure TWSThreadsWatcher.Execute ;
@@ -543,8 +566,6 @@ procedure TWSThreadsWatcher.Execute;
543566 WSThread: TWSThread;
544567begin
545568 FStarted := True;
546- if (not Terminated) and (FWSManager.FOnStart <> nil ) then
547- FWSManager.FOnStart(Self);
548569 FS := TFileStream.Create(FWSManager.FSrcFile, fmOpenRead or fmShareDenyNone);
549570 try
550571 Size := Round(FS.Size/(FWSManager.FThreadCnt + 1 ));
@@ -569,6 +590,8 @@ procedure TWSThreadsWatcher.Execute;
569590 AddLineBreak(Bytes);
570591 WSThread := TWSThread.Create(Bytes, FWSManager);
571592 WSThread.Start;
593+ while not WSThread.FStarted do
594+ Wait(10 );
572595 end ;
573596 until (ReadCnt = 0 );
574597 finally
@@ -577,20 +600,20 @@ procedure TWSThreadsWatcher.Execute;
577600 ThreadCnt := -1 ;
578601 repeat
579602 ThreadCnt := GetThreadCnt;
580- Wait (100 );
603+ Sleep (100 );
581604 until ThreadCnt = 0 ;
582605 if (not Terminated) then
583606 CreateFinalList;
584- if (not Terminated) and (FWSManager.FOnFinish <> nil ) then
585- FWSManager.FOnFinish(Self);
607+ FWSManager.FDone := True;
586608end ;
587609
588610{ TWSManager }
589- constructor TWSManager.Create(ASrcFile:String; AThreadCnt: Integer);
611+ constructor TWSManager.Create(ASrcFile: String; AThreadCnt: Integer);
590612var
591613 I: Integer;
592614begin
593615 FSrcFile := ASrcFile;
616+ FDone := False;
594617 FThreadCnt := AThreadCnt;
595618 FTerminated := False;
596619 for I := Low(FWSListAll) to High(FWSListAll) do
0 commit comments