Mixe for Privacy and Anonymity in the Internet
CAReplayDatabase.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000, The JAP-Team 
00003 All rights reserved.
00004 Redistribution and use in source and binary forms, with or without modification, 
00005 are permitted provided that the following conditions are met:
00006 
00007   - Redistributions of source code must retain the above copyright notice, 
00008     this list of conditions and the following disclaimer.
00009 
00010   - Redistributions in binary form must reproduce the above copyright notice, 
00011     this list of conditions and the following disclaimer in the documentation and/or 
00012     other materials provided with the distribution.
00013 
00014   - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors 
00015     may be used to endorse or promote products derived from this software without specific 
00016     prior written permission. 
00017 
00018   
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS 
00020 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
00021 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
00022 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 
00025 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
00026 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00027 */
00028 #include "StdAfx.h"
00029 #ifndef ONLY_LOCAL_PROXY
00030 #include "CAReplayDatabase.hpp"
00031 #include "CAUtil.hpp"
00032 #include "CAMsg.hpp"
00033 
00034 CAReplayDatabase::CAReplayDatabase()
00035   {
00036     m_currDatabase=createDBInfo();
00037     m_prevDatabase=createDBInfo();
00038     m_nextDatabase=createDBInfo();
00039     m_refTime=time(NULL);
00040     m_currentClock=0;
00041     m_pThread=NULL;
00042     m_pMutex=new CAMutex();
00043   }
00044 
00045 t_replay_databaseInfo* CAReplayDatabase::createDBInfo()
00046   {
00047     t_replay_databaseInfo* pInfo=new t_replay_databaseInfo;
00048     memset(pInfo,0,sizeof(t_replay_databaseInfo));
00049     return pInfo;
00050   }
00051   
00052 CAReplayDatabase::~CAReplayDatabase()
00053   {
00054     m_pMutex->lock();
00055     stop();
00056     deleteDB(m_currDatabase);
00057     deleteDB(m_nextDatabase);
00058     deleteDB(m_prevDatabase);
00059     m_pMutex->unlock();
00060     delete m_pMutex;
00061   }
00062 
00063 SINT32 CAReplayDatabase::clearDB(t_replay_databaseInfo* pDBInfo)
00064   {
00065     while(pDBInfo->m_pHeap!=NULL)
00066       {
00067         pDBInfo->m_pLastHeap=pDBInfo->m_pHeap;
00068         pDBInfo->m_pHeap=pDBInfo->m_pHeap->next;
00069         delete pDBInfo->m_pLastHeap;
00070       }
00071     memset(pDBInfo,0,sizeof(t_replay_databaseInfo));
00072     return E_SUCCESS;
00073   }
00074 
00075 SINT32 CAReplayDatabase::deleteDB(t_replay_databaseInfo*& pDBInfo)
00076   {
00077     clearDB(pDBInfo);
00078     delete pDBInfo;
00079     pDBInfo=NULL;
00080     return E_SUCCESS;
00081   }
00082   
00084 SINT32 CAReplayDatabase::insert(UINT8 key[16])
00085   {
00086     m_pMutex->lock();
00087     UINT16 timestamp=(key[14]<<8)|key[15];
00088     if(timestamp<m_currentClock-1||timestamp>m_currentClock+1)
00089       {
00090         m_pMutex->unlock();
00091         return E_UNKNOWN;
00092       }
00093     t_replay_databaseInfo* aktDB=m_currDatabase;
00094     if(timestamp>m_currentClock)
00095       {
00096         aktDB=m_nextDatabase;
00097       }
00098     else if(timestamp<m_currentClock)
00099       {
00100         aktDB=m_prevDatabase;
00101       }
00102     UINT16 hashKey=(key[8]<<8)|key[9];
00103     LP_replay_databaseEntry hashList=aktDB->m_pHashTable[hashKey];
00104     if(hashList==NULL)
00105       {
00106         LP_replay_databaseEntry newEntry=getNewDBEntry(aktDB);
00107         newEntry->left=NULL;
00108         newEntry->right=NULL;
00109         newEntry->key=key[0]<<24|key[1]<<16|key[2]<<8|key[3];
00110         aktDB->m_pHashTable[hashKey]=newEntry;
00111         aktDB->m_u32Size++;
00112         m_pMutex->unlock();
00113         return E_SUCCESS;
00114       }
00115     else
00116       {
00117         UINT32 ret=key[0]<<24|key[1]<<16|key[2]<<8|key[3];;
00118         LP_replay_databaseEntry before=NULL;
00119         do
00120           {
00121             //newEntry->keymemcmp(key,hashList->key,6);
00122             if(ret==hashList->key)
00123               {
00124                 m_pMutex->unlock();
00125                 return E_UNKNOWN;
00126               }
00127             before=hashList;  
00128             if(hashList->key<ret)
00129               {
00130                 hashList=hashList->right;
00131               }
00132             else
00133               {
00134                 hashList=hashList->left;
00135               }
00136           } while(hashList!=NULL);
00137         LP_replay_databaseEntry newEntry=getNewDBEntry(aktDB);
00138         newEntry->left=newEntry->right=NULL;
00139         //memcpy(newEntry->key,key,6);        
00140         newEntry->key=ret;
00141         if(before->key<ret)
00142           {
00143             before->right=newEntry;
00144           }
00145         else
00146             before->left=newEntry;
00147 
00148       }
00149     aktDB->m_u32Size++; 
00150     m_pMutex->unlock();
00151     return E_SUCCESS;
00152   }
00153 
00154 SINT32 CAReplayDatabase::start()
00155   {
00156     m_pThread=new CAThread((UINT8*)"DB Maintenance Thread");
00157     m_bRun=true;
00158     m_pThread->setMainLoop(replaydb_loopMaintenance);
00159     return m_pThread->start(this);
00160   }
00161 
00162 SINT32 CAReplayDatabase::stop()
00163   {
00164     m_bRun=false;
00165     SINT32 ret=E_SUCCESS;
00166     if(m_pThread!=NULL)
00167       {
00168         ret=m_pThread->join();
00169         delete m_pThread;
00170         m_pThread=NULL;
00171       }
00172     return ret;
00173   }
00174 
00175 THREAD_RETURN replaydb_loopMaintenance(void *param)
00176   {
00177     INIT_STACK;
00178     BEGIN_STACK("CADatabase::db_loopMaintenance");
00179     
00180     CAReplayDatabase* pDatabase=(CAReplayDatabase*)param;
00181     tReplayTimestamp rt;
00182     pDatabase->getCurrentReplayTimestamp(rt);
00183     pDatabase->m_currentClock=rt.interval;
00184     while(pDatabase->m_bRun)
00185       {
00186         sSleep(10);
00187         SINT32 secondsTilNextClock=((pDatabase->m_currentClock+1)*SECONDS_PER_INTERVALL)+pDatabase->m_refTime-time(NULL);
00188         if(secondsTilNextClock<=0&&pDatabase->m_bRun)
00189           pDatabase->nextClock();
00190       }
00191       
00192     FINISH_STACK("CADatabase::db_loopMaintenance");
00193       
00194     THREAD_RETURN_SUCCESS;
00195   }
00196 
00197 SINT32 CAReplayDatabase::nextClock()
00198   {
00199     m_pMutex->lock();
00200     tReplayTimestamp rt;
00201     getCurrentReplayTimestamp(rt);
00202     m_currentClock=rt.interval;
00203     CAMsg::printMsg(LOG_DEBUG,"Replay DB Size was: %u\n",m_prevDatabase->m_u32Size);
00204     clearDB(m_prevDatabase);
00205     t_replay_databaseInfo* tmpDB=m_prevDatabase;
00206     m_prevDatabase=m_currDatabase;
00207     m_currDatabase=m_nextDatabase;
00208     m_nextDatabase=tmpDB;
00209     m_pMutex->unlock();
00210     return E_SUCCESS;
00211   }
00212 
00213 SINT32 CAReplayDatabase::test()
00214   {
00215     CAReplayDatabase oDatabase;
00216     oDatabase.start();
00217     UINT8 key[16];
00218     memset(key,0,16);
00219     UINT32 i;
00220     for(i=0;i<20;i++)
00221       {
00222         getRandom(key,1);
00223         oDatabase.insert(key);
00224       }
00225     for(i=0;i<200000;i++)
00226       {
00227         getRandom(key,16);
00228         oDatabase.insert(key);//TODO WRONG - Fixme
00229       }
00230     oDatabase.stop();
00231 //check it
00232 //TODO fixme!
00233 /*    for(i=0;i<0x10000;i++)
00234       {
00235         LP_databaseEntry tmp=oDatabase.m_currDatabase[i];
00236         while(tmp!=NULL&&tmp->next!=NULL)
00237           {
00238             if(memcmp(tmp->key,tmp->next->key,14)>=0)
00239               return E_UNKNOWN;
00240             tmp=tmp->next;
00241           }
00242       }*/
00243     return E_SUCCESS;
00244   }
00245 
00249 SINT32 CAReplayDatabase::getCurrentReplayTimestamp(tReplayTimestamp& replayTimestamp) const
00250   {
00251     return getReplayTimestampForTime(replayTimestamp,time(NULL),m_refTime);
00252   }
00253 
00254 
00255 SINT32 CAReplayDatabase::getReplayTimestampForTime(tReplayTimestamp& replayTimestamp,UINT32 aktTime,UINT32 refTime)
00256   {
00257     UINT32 timeDiff=aktTime-refTime;
00258     replayTimestamp.interval=timeDiff/SECONDS_PER_INTERVALL;
00259     replayTimestamp.offset=timeDiff%SECONDS_PER_INTERVALL;
00260     return E_SUCCESS;
00261   }
00262 
00263 
00264 SINT32 CAReplayDatabase::measurePerformance(  UINT8* strLogFile,
00265                                         UINT32 lowerBoundEntries,
00266                                         UINT32 upperBoundEntries,
00267                                         UINT32 stepBy,
00268                                         UINT32 meassuresPerStep,
00269                                         UINT32 insertsPerMeasure)
00270   {
00271     initRandom();
00272     CAReplayDatabase* pDatabase=NULL;
00273     UINT32 aktNrOfEntries=lowerBoundEntries;
00274     UINT8* key=new UINT8[insertsPerMeasure*16];
00275     UINT8* aktKey;
00276     SINT32 file=open((char*)strLogFile,O_CREAT|O_WRONLY|O_LARGEFILE|O_TRUNC,S_IREAD|S_IWRITE);
00277     char buff[255];
00278     const char* atemplate="%u,%u,%u\n";
00279     const char* header="#The format is as follows: Number of Entries in DB, Number of Inserts done, Total time for Inserts (in micro seconds)\n";
00280     write(file,header,strlen(header));
00281     while(aktNrOfEntries<=upperBoundEntries)
00282       {
00283         CAMsg::printMsg(LOG_DEBUG,"Starting measurement with %u entries in the replay database\n",aktNrOfEntries);
00284         for(UINT32 i=0;i<meassuresPerStep;i++)
00285           {
00286             pDatabase=new CAReplayDatabase();
00287             pDatabase->m_currentClock=0;
00288             pDatabase->fill(aktNrOfEntries);
00289             UINT64 startTime,endTime;
00290             getRandom(key,insertsPerMeasure*16);
00291             aktKey=key+14;
00292             for(UINT32 j=0;j<insertsPerMeasure;j++)
00293               {
00294                 *aktKey=0;
00295                 aktKey++;
00296                 *aktKey=0;
00297                 aktKey+=15;
00298               }
00299             aktKey=key;
00300             getcurrentTimeMicros(startTime);
00301             for(UINT32 j=0;j<insertsPerMeasure;j++)
00302               {
00303                 pDatabase->simulateInsert(aktKey);
00304                 aktKey+=16;
00305               }
00306             getcurrentTimeMicros(endTime);
00307             sprintf(buff,atemplate,aktNrOfEntries,insertsPerMeasure,diff64(endTime,startTime));
00308             write(file,buff,strlen(buff));
00309             printf("Start delete \n");
00310             getcurrentTimeMicros(startTime);
00311             delete pDatabase;
00312             getcurrentTimeMicros(endTime);
00313             printf("delete takes %u microsecs\n",diff64(endTime,startTime));
00314           }
00315         aktNrOfEntries+=stepBy;
00316       }
00317     delete[] key;
00318     return E_SUCCESS;
00319   }
00320 
00321 SINT32 CAReplayDatabase::fill(UINT32 nrOfEntries)
00322   {
00323     UINT32 i=0;
00324     UINT8 key[16];
00325     key[14]=0;
00326     key[15]=0;
00327     while(i<nrOfEntries)
00328       {
00329         getRandom(key,14);
00330         if(insert(key)==E_SUCCESS)
00331           i++;
00332       }
00333     return E_SUCCESS;
00334   }
00335 
00336 SINT32 CAReplayDatabase::simulateInsert(UINT8 key[16])
00337   {
00338     m_pMutex->lock();
00339     UINT16 timestamp=(key[14]<<8)|key[15];
00340     if(timestamp<m_currentClock-1||timestamp>m_currentClock+1)
00341       {
00342         m_pMutex->unlock();
00343         return E_UNKNOWN;
00344       }
00345     t_replay_databaseInfo* aktDB=m_currDatabase;
00346     if(timestamp>m_currentClock)
00347       {
00348         aktDB=m_nextDatabase;
00349       }
00350     else if(timestamp<m_currentClock)
00351       {
00352         aktDB=m_prevDatabase;
00353       }
00354     UINT16 hashKey=(key[8]<<8)|key[9];
00355     LP_replay_databaseEntry hashList=aktDB->m_pHashTable[hashKey];
00356     if(hashList==NULL)
00357       {
00358         LP_replay_databaseEntry newEntry=getNewDBEntry(aktDB);
00359         newEntry->left=NULL;
00360         newEntry->right=NULL;
00361         newEntry->key=key[0]<<24|key[1]<<16|key[2]<<8|key[3];
00362         m_nextDatabase->m_pHashTable[hashKey]=newEntry; //we simply use the 'next' Database to simulate insert while not inserting anythign in the current db
00363         aktDB->m_u32Size++;
00364         m_pMutex->unlock();
00365         return E_SUCCESS;
00366       }
00367     else
00368       {
00369         UINT32 ret=key[0]<<24|key[1]<<16|key[2]<<8|key[3];
00370         LP_replay_databaseEntry before=NULL;
00371         do
00372           {
00373             //newEntry->keymemcmp(key,hashList->key,6);
00374             if(ret==hashList->key)
00375               {
00376                 m_pMutex->unlock();
00377                 return E_UNKNOWN;
00378               }
00379             before=hashList;  
00380             if(hashList->key<ret)
00381               {
00382                 hashList=hashList->right;
00383               }
00384             else
00385               {
00386                 hashList=hashList->left;
00387               }
00388           } while(hashList!=NULL);
00389         LP_replay_databaseEntry newEntry=getNewDBEntry(aktDB);
00390         newEntry->left=newEntry->right=NULL;
00391         //memcpy(newEntry->key,key,6);        
00392         newEntry->key=ret;
00393         if(before->key<ret)
00394           {
00395             newEntry->right=newEntry; //do the pointer operation without actually changing the DB
00396           }
00397         else
00398           {
00399             newEntry->left=newEntry; //do the pointer operation without actually changing the DB
00400           }
00401       }
00402     aktDB->m_u32Size++; 
00403     m_pMutex->unlock();
00404     return E_SUCCESS; 
00405   }
00406 #endif //Only_LOCAL_PROXY