241146← ↑修正パッチ →241148


2004.07.20 (火) 23:12:16 <u*j*2*6*> インデックス関数(GetCharIndex,Index_Ip,GetKeywordIndex?)のResultの計算方法や値の範囲を変更しました
2004.07.20 (火) 23:15:10 <u*j*2*6*> 2バイト文字のID・キーワードのインデックスがなるべく違う値になるようにして、ユーザーIDやキーワードの一致判定が効率がよくなるようにしました
2004.07.20 (火) 23:19:24 <u*j*2*6*> それから、USERS_NAME_ARRAYとUSERS_IP_ARRAYのサイズをだいたい4分の1にして、起動時のメモリ常駐を少し小さく&USERS_*_ARRAYの回数の繰り返し処理を速く脱出できるようにしました

shuusei241147:shuusei241147:ID・IP・キーワードのインデックス関数の仕様変更

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
 
 
 
 
 
 
-
!
 
 
 
 
 
 
-
!
 
 
-
|
|
!
 
-
!
 
-
|
!
 
 
 
 
 
 
 
-
|
|
!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
|
|
|
|
!
-
|
|
|
|
!
 
 
-
|
|
|
|
|
|
|
|
!
 
 
 
 
-
|
|
|
|
|
!
 
-
|
|
|
|
|
-
|
|
|
|
|
|
|
-
|
|
!
|
|
|
|
|
|
!
!
 
 
 
 
 
 
 
 
 
-
|
|
|
|
!
-
|
|
|
!
 
-
|
|
|
|
|
|
|
|
|
|
!
 
 
 
-
|
|
|
|
|
|
|
|
|
|
!
 
 
 
diff --dos -urN 241146/constants.pas 241147/constants.pas
--- 241146/constants.pas    Sun Jul 18 14:55:36 2004
+++ 241147/constants.pas    Tue Jul 20 22:09:44 2004
@@ -98,9 +98,10 @@
   DefaultCryptPass      = 'himitsu';
   Null_Ip               = '0';
   // Users list
-  USERS_INDEX_INC       = 47; // 46;
-  USERS_NAME_ARRAY      = 2209; // 2116;
-  USERS_IP_ARRAY        = 1024;
+  // USERS_INDEX_INC       = 47; // 46;
+  USERS_NAME_ARRAY      = 503; // 定員と同数〜その3倍ぐらいの素数
+    // 2209; // 2116; // = USERS_INDEX_INC ^ 2
+  USERS_IP_ARRAY        = 1 shl 8; // 1 shl 10 = 1024; 必ず2のn乗にすること。
   // Sharing
   MAX_FILE_KEYWORDS     = 12; // Max keywords per file
   KEYWORD_LEN_MAX       = 24; // Maximum length of keyword
@@ -110,11 +111,12 @@
     // Limit of items in one keyword. All items exceeding this limit
     // won't be skipped - This limit makes sence only if keyword was
     // selected as base keyword for search
-  KEYWORDS_FIRST        = '!&0123456789@Abcdefghijklmnopqrstuvwxyz';
+  // KEYWORDS_FIRST        = '!&0123456789@Abcdefghijklmnopqrstuvwxyz';
     // List of Characters that can be first item of keyword
-  KEYWORDS_FIRST_COUNT  = 40; // 39;
+  // KEYWORDS_FIRST_COUNT  = 40; // 39;
     // # of KEYWORDS_FIRST + 1(for 2byte char)
     // Number of items in KEYWORDS_FIRST list
+  KEYWORDS_HASH_MAX     = 40; // DB_Keywordsの2次元目の配列数になる
   KEYWORDS_SEPARATORS   = #$00#$01#$02#$03#$04#$05#$06#$07#$08#$09 +
     #$0A#$0B#$0C#$0D#$0E#$0F#$10#$11#$12#$13#$14#$15#$16#$17#$18#$19 +
     #$1A#$1B#$1C#$1D#$1E#$1F#$20'"'#39'()*+,-./:;<=>?[\]_`。「」、・';
diff --dos -urN 241146/keywords.pas 241147/keywords.pas
--- 241146/keywords.pas    Sun Jul 18 14:47:36 2004
+++ 241147/keywords.pas    Tue Jul 20 22:08:28 2004
@@ -42,7 +42,7 @@
   // 1 - Type of shared file: SHARED_XXX constants
   // 2 - First character of keyword
   // 3 - Length of keyword
-  DB_Keywords: array[0..SHARED_ARRAY - 1, 0..KEYWORDS_FIRST_COUNT - 1,
+  DB_Keywords: array[0..SHARED_ARRAY - 1, 0..KEYWORDS_HASH_MAX - 1,
     KEYWORD_LEN_MIN..KEYWORD_LEN_MAX] of PKeywordList;
 
 implementation
@@ -364,7 +364,29 @@
   Tmp_Pos := 1281;
 end;
 
+// 2バイト文字に対応したGetKeywordIndex
+// Returns index of keyword or -1 if keyword is invalid
+// ResultはDB_Keywordsの第二次元の配列の数(KEYWORDS_HASH_MAX)より少ないこと。
 function GetKeywordIndex(Keyword: string): Integer;
+  // IniFiles.pasのTStringHash.HashOfより
+  function HashOf(const Key: string): Cardinal;
+  var
+    I: Integer;
+  begin
+    Result := 0;
+    for I := 1 to Length(Key) do
+      Result := ((Result shl 2) or (Result shr (SizeOf(Result) * 8 - 2))) xor
+        Ord(Key[I]);
+  end;
+begin
+  if Length(Keyword) < 1 then
+    Result := KEYWORDS_NOINDEX
+  else
+    Result := HashOf(Keyword) mod KEYWORDS_HASH_MAX;
+end;
+
+// 1バイト文字のキーワードしか考えてない古いGetKeywordIndex
+{function GetKeywordIndexOld(Keyword: string): Integer;
 // Returns index of keyword or -1 if keyword is invalid
 begin
   if Length(Keyword) < 1 then
@@ -373,14 +395,14 @@
     Result := KEYWORDS_FIRST_COUNT - 1 // 2byte char
   else
     Result := Pos(Keyword[1], KEYWORDS_FIRST) - 1;
-end;
+end;}
 
 procedure InitKeywords;
 var
   I, J, K: Integer;
 begin
   for I := 0 to SHARED_ARRAY - 1 do
-    for J := 0 to KEYWORDS_FIRST_COUNT - 1 do
+    for J := 0 to KEYWORDS_HASH_MAX - 1 do
       for K := KEYWORD_LEN_MIN to KEYWORD_LEN_MAX do
         DB_Keywords[I, J, K] := KWList_CreateList;
 end;
@@ -392,7 +414,7 @@
 begin
   ATime := GetTickCount;
   for I := 0 to SHARED_ARRAY - 1 do
-    for J := 0 to KEYWORDS_FIRST_COUNT - 1 do
+    for J := 0 to KEYWORDS_HASH_MAX - 1 do
       for K := KEYWORD_LEN_MIN to KEYWORD_LEN_MAX do
       begin
         KWList_FreeList(DB_Keywords[I, J, K]);
diff --dos -urN 241146/stypes.pas 241147/stypes.pas
--- 241146/stypes.pas    Thu Jul 15 00:35:32 2004
+++ 241147/stypes.pas    Tue Jul 20 21:42:46 2004
@@ -1057,7 +1057,7 @@
 
 function Index_Ip(Ip: Cardinal): Integer;
 begin
-  Result := (Ip shr 12) and 1023;
+  Result := (Ip shr 12) and (USERS_IP_ARRAY - 1); // USERS_IP_ARRAY = 1 shl n
 end;
 
 function UnixTimeToDateTime(Time: Time_T): TDateTime;
diff --dos -urN 241146/users.pas 241147/users.pas
--- 241146/users.pas    Sun May 09 22:06:54 2004
+++ 241147/users.pas    Tue Jul 20 22:21:52 2004
@@ -120,8 +120,28 @@
   end;
 end;
 
-function GetCharIndex2(C: Char): Integer;
+// 2バイト対応のGetCharIndex
+// Returns array index for user names
+function GetCharIndex(Nick: string): Integer;
+  // IniFiles.TStringHash.HashOfより
+  function HashOf(const Key: string): Cardinal;
+  var
+    I: Integer;
+  begin
+    Result := 0;
+    for I := 1 to Length(Key) do
+      Result := ((Result shl 2) or (Result shr (SizeOf(Result) * 8 - 2))) xor
+        Ord(Key[I]);
+  end;
+begin
+  Result := -1;
+  if Length(Nick) < 2 then Exit;
+  Result := HashOf(Nick) mod USERS_NAME_ARRAY;
+end;
+
+(* function GetCharIndex2(C: Char): Integer;
 begin
+  // Result < USERS_INDEX_INC
   case C of
     'a'..'z': Result := Ord(C) - Ord('a'); // 0..25
     'A'..'Z': Result := Ord(C) - Ord('A'); // 0..25
@@ -139,9 +159,10 @@
   else
     Result := 46; // -1;
   end;
-end;
+end; *)
 
-function GetCharIndex(Nick: string): Integer;
+// Nickに単バイト文字しか考えてない古いGetCharIndex
+(* function GetCharIndex(Nick: string): Integer;
 var // Returns array index for user names
   I, J: Integer;
 begin
@@ -151,8 +172,8 @@
   if I = -1 then Exit;
   J := GetCharIndex2(Nick[2]);
   if J = -1 then Exit;
-  Result := USERS_INDEX_INC * I + J;
-end;
+  Result := USERS_INDEX_INC * I + J; // Result < USERS_INDEX_INC^2
+end; *)
 
 constructor TOnlineUsers.Create;
 var
241146← ↑修正パッチ →241148