458 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			458 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
 | ||
| #include "..\..\tigris.hxx"
 | ||
| #include <stdlib.h>
 | ||
| 
 | ||
| DWORD groups[12] = { 0xa1,0xa2,0x0,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac };
 | ||
| DWORD Iter = 1000;
 | ||
| BOOL Verbose = FALSE;
 | ||
| DWORD nThreads = 1;
 | ||
| HANDLE hTerminate;
 | ||
| LONG activeThreads;
 | ||
| 
 | ||
| LPCSTR target = "<438b49$ja6@hecate.umd.edu>";
 | ||
| DWORD targetnum = 0;
 | ||
| 
 | ||
| #define NUM_ENTRIES     100000
 | ||
| #define MAX_MSG_ID      128
 | ||
| #define NUM_LOCKS       32
 | ||
| 
 | ||
| enum filetype {
 | ||
|         artmap,
 | ||
|         histmap
 | ||
|         };
 | ||
| 
 | ||
| PCHAR filelist[] = {
 | ||
|                 "c:\\afile",
 | ||
|                 "c:\\hfile"
 | ||
|                 };
 | ||
| 
 | ||
| typedef struct _entry {
 | ||
| 
 | ||
|     CHAR MsgId[MAX_MSG_ID];
 | ||
|     BOOL Inserted;
 | ||
| } ENTRY2, *PENTRY2;
 | ||
| 
 | ||
| CRITICAL_SECTION Locks[NUM_LOCKS];
 | ||
| 
 | ||
| ENTRY2 table[NUM_ENTRIES];
 | ||
| CMsgArtMap *AMap;
 | ||
| CHistory *HMap;
 | ||
| CNntpHash *Map;
 | ||
| 
 | ||
| enum filetype hashtype=artmap;
 | ||
| CHAR srcmsgid[MAX_PATH];
 | ||
| 
 | ||
| BOOL
 | ||
| setuplookup()
 | ||
| {
 | ||
| 
 | ||
|     DWORD entries = 0;
 | ||
|     HANDLE hFile;
 | ||
|     CHAR msgId[512];
 | ||
|     DWORD len;
 | ||
|     HANDLE hMap;
 | ||
|     PCHAR buffer;
 | ||
|     PCHAR p;
 | ||
| 
 | ||
|     printf("Creating table...\n");
 | ||
|     hFile = CreateFile(
 | ||
|                     srcmsgid,
 | ||
|                     GENERIC_READ,
 | ||
|                     0,
 | ||
|                     NULL,
 | ||
|                     OPEN_EXISTING,
 | ||
|                     FILE_FLAG_SEQUENTIAL_SCAN,
 | ||
|                     NULL
 | ||
|                     );
 | ||
| 
 | ||
|     if ( hFile == INVALID_HANDLE_VALUE ) {
 | ||
|         printf("createfile error %d\n",GetLastError());
 | ||
|         return(FALSE);
 | ||
|     }
 | ||
| 
 | ||
|     //
 | ||
|     // Map it
 | ||
|     //
 | ||
| 
 | ||
|     hMap = CreateFileMapping(
 | ||
|                         hFile,
 | ||
|                         NULL,
 | ||
|                         PAGE_READONLY,
 | ||
|                         0,
 | ||
|                         0,
 | ||
|                         NULL
 | ||
|                         );
 | ||
| 
 | ||
|     if ( hMap == NULL ) {
 | ||
|         printf("mapping error %d\n",GetLastError());
 | ||
|         return FALSE;
 | ||
|     }
 | ||
| 
 | ||
|     CloseHandle(hFile);
 | ||
| 
 | ||
|     //
 | ||
|     // create a view
 | ||
|     //
 | ||
| 
 | ||
|     buffer = (PCHAR)MapViewOfFile(
 | ||
|                         hMap,
 | ||
|                         FILE_MAP_READ,
 | ||
|                         0,
 | ||
|                         0,
 | ||
|                         0
 | ||
|                         );
 | ||
| 
 | ||
|     if ( buffer == NULL ) {
 | ||
|         printf("view error %d\n",GetLastError());
 | ||
|         return FALSE;
 | ||
|     }
 | ||
| 
 | ||
|     p=buffer;
 | ||
| 
 | ||
|     for (entries=0; entries < NUM_ENTRIES;) {
 | ||
| 
 | ||
|         len = 0;
 | ||
| 
 | ||
|         //
 | ||
|         // Get head
 | ||
|         //
 | ||
| 
 | ||
|         while ( *p != '<' ) p++;
 | ||
| 
 | ||
|         do {
 | ||
|             msgId[len++] = *p;
 | ||
|         } while ( *p++ != '>' );
 | ||
| 
 | ||
|         msgId[len] = '\0';
 | ||
| 
 | ||
|         if (len >= MAX_MSG_ID ) {
 | ||
|             continue;
 | ||
|         }
 | ||
| 
 | ||
|         CopyMemory(table[entries].MsgId,msgId,len+1);
 | ||
|         if ( strcmp(msgId,target) == 0 ) {
 | ||
|             printf("found %s at %d\n",target,entries);
 | ||
|             targetnum = entries;
 | ||
|         }
 | ||
|         table[entries].Inserted = FALSE;
 | ||
|         if ( Verbose) {
 | ||
|             printf("msg id %s\n",table[entries].MsgId);
 | ||
|         }
 | ||
|         entries++;
 | ||
|     }
 | ||
| 
 | ||
|     for ( DWORD i=0; i<NUM_LOCKS; i++) {
 | ||
|         InitializeCriticalSection(&Locks[i]);
 | ||
|     }
 | ||
| 
 | ||
|     UnmapViewOfFile( buffer );
 | ||
|     CloseHandle(hMap);
 | ||
|     return(TRUE);
 | ||
| }
 | ||
| 
 | ||
| DWORD
 | ||
| WINAPI
 | ||
| ChaCha(
 | ||
|     PVOID Context
 | ||
|     )
 | ||
| {
 | ||
|     DWORD val;
 | ||
|     DWORD i;
 | ||
|     DWORD myNum = (DWORD)Context;
 | ||
|     DWORD nDels = 0;
 | ||
|     DWORD nAdds = 0;
 | ||
|     DWORD lockNum;
 | ||
|     FILETIME beginTime;
 | ||
| 
 | ||
|     USHORT  HeaderOffsetJunk = 0 ;
 | ||
|     USHORT  HeaderLengthJunk = 0  ;
 | ||
| 
 | ||
|     printf("Thread %d: Doing %d iterations\n",myNum,Iter);
 | ||
|     GetSystemTimeAsFileTime( &beginTime );
 | ||
| 
 | ||
|     for (i=0; i<Iter; i++) {
 | ||
| 
 | ||
|         BOOL fok;
 | ||
|         val = rand( ) % NUM_ENTRIES;
 | ||
|         lockNum = val % NUM_LOCKS;
 | ||
|         EnterCriticalSection(&Locks[lockNum]);
 | ||
| 
 | ||
|         if ( table[val].Inserted ) {
 | ||
| 
 | ||
|             if ( val == targetnum ) {
 | ||
|                 printf("verifying inserted %d: %s \n",val,table[val].MsgId);
 | ||
|             }
 | ||
| 
 | ||
|             if (!Map->SearchMapEntry(table[val].MsgId)) {
 | ||
|                 printf("!!! cannot find inserted entry %s error %d\n",
 | ||
|                             table[val].MsgId,GetLastError());
 | ||
|                 goto cont;
 | ||
|             }
 | ||
| 
 | ||
|             if ( hashtype == artmap ) {
 | ||
|                 fok = AMap->InsertMapEntry(
 | ||
|                             table[val].MsgId,
 | ||
|                             HeaderOffsetJunk,
 | ||
|                             HeaderLengthJunk,
 | ||
|                             i,
 | ||
|                             val
 | ||
|                             );
 | ||
| 
 | ||
|             } else {
 | ||
| 
 | ||
|                 fok = HMap->InsertMapEntry(
 | ||
|                                 table[val].MsgId,
 | ||
|                                 &beginTime
 | ||
|                                 );
 | ||
|             }
 | ||
| 
 | ||
|             if (fok) {
 | ||
|                 nAdds++;
 | ||
|                 printf("Huh!!! inserted already inserted entry %s\n",
 | ||
|                             table[val].MsgId);
 | ||
|                 goto cont;
 | ||
|             }
 | ||
| 
 | ||
|             if ( (i % 2) == 0 ) {
 | ||
| 
 | ||
|                 if ( val == targetnum ) {
 | ||
|                     printf("deleting %d: %s \n",val,table[val].MsgId);
 | ||
|                 }
 | ||
|                 if (!Map->DeleteMapEntry(
 | ||
|                                 table[val].MsgId
 | ||
|                                 )) {
 | ||
| 
 | ||
|                     printf("cannot delete entry %s\n",table[val].MsgId);
 | ||
|                     goto cont;
 | ||
|                 } else {
 | ||
|                     if (Map->SearchMapEntry(table[val].MsgId)) {
 | ||
|                         DebugBreak() ;
 | ||
|                         printf(" found deleted entry %s error %d\n",
 | ||
|                                     table[val].MsgId,GetLastError());
 | ||
| 
 | ||
|                         
 | ||
|                     } else if( GetLastError() != ERROR_FILE_NOT_FOUND ) {
 | ||
|                         DebugBreak() ;
 | ||
|                     } 
 | ||
| 
 | ||
|                     table[val].Inserted = FALSE;
 | ||
|                     nDels++;
 | ||
|                     if ( Verbose) {
 | ||
|                         printf("deleted %s\n",table[val].MsgId);
 | ||
|                     }
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|         } else {
 | ||
| 
 | ||
|             if ( hashtype == artmap ) {
 | ||
|                 fok = AMap->InsertMapEntry(
 | ||
|                             table[val].MsgId,
 | ||
|                             HeaderOffsetJunk,
 | ||
|                             HeaderLengthJunk,
 | ||
|                             i,
 | ||
|                             val
 | ||
|                             );
 | ||
| 
 | ||
|             } else {
 | ||
| 
 | ||
|                 fok = HMap->InsertMapEntry(
 | ||
|                                 table[val].MsgId,
 | ||
|                                 &beginTime
 | ||
|                                 );
 | ||
|             }
 | ||
|             DWORD   dw = GetLastError() ;
 | ||
| 
 | ||
|             if ( fok ) {
 | ||
|                 table[val].Inserted = TRUE;
 | ||
|                 nAdds++;
 | ||
|                 if ( val == targetnum ) {
 | ||
|                     printf("inserted %d: %s \n",val,table[val].MsgId);
 | ||
|                 }
 | ||
|                 if ( Verbose) {
 | ||
|                     printf("inserted %s\n",table[val].MsgId);
 | ||
|                 }
 | ||
|             } else {
 | ||
|                 if( dw != ERROR_ALREADY_EXISTS ) 
 | ||
|                     DebugBreak() ;
 | ||
|                 printf("cannot insert %s error %x\n",table[val].MsgId, dw);
 | ||
|             }
 | ||
|         }
 | ||
| cont:
 | ||
|         LeaveCriticalSection( &Locks[lockNum] );
 | ||
|     }
 | ||
| 
 | ||
|     if ( InterlockedDecrement( &activeThreads ) == 0 ) {
 | ||
|         SetEvent(hTerminate);
 | ||
|     }
 | ||
| 
 | ||
|     printf("%d: Deletes %d Inserts %d\n",myNum,nDels, nAdds);
 | ||
| 
 | ||
|     return(1);
 | ||
| }
 | ||
| 
 | ||
| void
 | ||
| usage( )
 | ||
| {
 | ||
|     printf("hashme\n");
 | ||
|     printf("\t-i <iterations>  # of iterations to run (Def 1000)\n");
 | ||
|     printf("\t-v            verbose mode\n");
 | ||
|     printf("\t-t <threads>  number of threads (def 1)\n");
 | ||
|     printf("\t-m <msgid>    msg id file (def c:\\msgid)\n");
 | ||
|     printf("\t-d            delete old hash file\n");
 | ||
|     printf("\t-h            change type to History (def Artmap)\n");
 | ||
|     return;
 | ||
| }
 | ||
| 
 | ||
| int
 | ||
| _cdecl
 | ||
| main(
 | ||
|     int argc,
 | ||
|     char *argv[]
 | ||
|     )
 | ||
| {
 | ||
|     int cur = 1;
 | ||
|     PCHAR x;
 | ||
|     BOOL delOldHash = FALSE;
 | ||
|     BOOL haveMsgFile = FALSE;
 | ||
| 
 | ||
|     if ( argc == 1 ) {
 | ||
|         usage( );
 | ||
|         return 1;
 | ||
|     }
 | ||
| 
 | ||
|     while ( cur < argc ) {
 | ||
| 
 | ||
|         x=argv[cur++];
 | ||
|         if ( *(x++) == '-' ) {
 | ||
| 
 | ||
|             switch (*x) {
 | ||
|             case 'i':
 | ||
|                 if ( cur > argc ) {
 | ||
|                     usage( );
 | ||
|                     return 1;
 | ||
|                 }
 | ||
|                 Iter = atoi(argv[cur++]);
 | ||
|                 break;
 | ||
|             case 'v': Verbose = TRUE;
 | ||
|                 break;
 | ||
|             case 't':
 | ||
|                 if ( cur > argc ) {
 | ||
|                     usage( );
 | ||
|                     return 1;
 | ||
|                 }
 | ||
|                 nThreads=atoi(argv[cur++]);
 | ||
|                 if ( nThreads < 1 ) {
 | ||
|                     nThreads = 1;
 | ||
|                 }
 | ||
|                 break;
 | ||
|             case 'h':
 | ||
|                 hashtype = histmap;
 | ||
|                 break;
 | ||
|             case 'm':
 | ||
|                 if ( cur > argc ) {
 | ||
|                     usage( );
 | ||
|                     return 1;
 | ||
|                 }
 | ||
|                 lstrcpy( srcmsgid, argv[cur++]);
 | ||
|                 haveMsgFile = TRUE;
 | ||
|                 break;
 | ||
|             case 'd':
 | ||
|                 delOldHash = TRUE;
 | ||
|                 break;
 | ||
|             default:
 | ||
|                 usage( );
 | ||
|                 return 1;
 | ||
|             }
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     lstrcpy( ArticleTableFile, "c:\\afile" ) ;
 | ||
| 
 | ||
|     if (!haveMsgFile) {
 | ||
|         lstrcpy(srcmsgid,"c:\\msgid");
 | ||
|     }
 | ||
| 
 | ||
|     printf("Iters %d hashfile %s msgfile %s hashtype ",
 | ||
|         Iter, filelist[hashtype], srcmsgid);
 | ||
| 
 | ||
|     if ( hashtype == artmap ) {
 | ||
|         printf("Article Map\n");
 | ||
|         AMap = new CMsgArtMap;
 | ||
|         Map = AMap;
 | ||
|     } else {
 | ||
|         printf("History\n");
 | ||
|         HMap = new CHistory;
 | ||
|         Map = HMap;
 | ||
|     }
 | ||
| 
 | ||
|     if ( Map == NULL ) {
 | ||
|         printf("cannot allocate map object\n");
 | ||
|         return 1;
 | ||
|     }
 | ||
| 
 | ||
|     if ( delOldHash ) {
 | ||
|         if ( !DeleteFile(filelist[hashtype]) ) {
 | ||
|             printf("cannot delete hash file %s. Error %d\n",filelist[hashtype],
 | ||
|                 GetLastError());
 | ||
|         } else {
 | ||
|             printf("Hash file %s deleted\n",filelist[hashtype]);
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     printf("Iter %d Threads %d\n",Iter,nThreads);
 | ||
| 
 | ||
|     InitAsyncTrace( );
 | ||
|     if( hashtype == artmap ) {
 | ||
|         AMap->Initialize( );
 | ||
|     }   else    {
 | ||
|         HMap->Initialize( FALSE ) ;
 | ||
|     }
 | ||
|     if (!setuplookup( )) {
 | ||
|        goto exit;
 | ||
|     }
 | ||
| 
 | ||
|     hTerminate = CreateEvent( NULL, TRUE, FALSE, NULL );
 | ||
|     if ( hTerminate == NULL ) {
 | ||
|         printf("Error %d on CreateEvent\n",GetLastError());
 | ||
|         goto exit;
 | ||
|     }
 | ||
| 
 | ||
|     activeThreads = nThreads;
 | ||
| 
 | ||
|     if ( nThreads > 1 ) {
 | ||
| 
 | ||
|         HANDLE hThread;
 | ||
|         DWORD threadId;
 | ||
|         DWORD i;
 | ||
| 
 | ||
|         for (i=1;i<nThreads ;i++ ) {
 | ||
| 
 | ||
|             hThread = CreateThread(
 | ||
|                         NULL,               // attributes
 | ||
|                         0,                  // stack size
 | ||
|                         ChaCha,             // thread start
 | ||
|                         (PVOID)i,           // param
 | ||
|                         0,                  // creation params
 | ||
|                         &threadId
 | ||
|                         );
 | ||
| 
 | ||
|             if ( hThread != NULL ) {
 | ||
|                 CloseHandle(hThread);
 | ||
|             }
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     (VOID)ChaCha( 0 );
 | ||
| 
 | ||
|     printf("waiting for threads to terminate\n");
 | ||
|     WaitForSingleObject(hTerminate,INFINITE);
 | ||
| 
 | ||
| exit:
 | ||
|     Map->Shutdown( );
 | ||
|     delete Map;
 | ||
|     TermAsyncTrace( );
 | ||
|     return(1);
 | ||
| }
 | ||
| 
 |