00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "StdAfx.h"
00029 #ifndef ONLY_LOCAL_PROXY
00030 #include "CADatabase.hpp"
00031 #include "CAUtil.hpp"
00032 #include "CAMsg.hpp"
00033
00034 CADatabase::CADatabase()
00035 {
00036 m_currDatabase=createDBInfo();
00037 m_prevDatabase=createDBInfo();
00038 m_nextDatabase=createDBInfo();
00039 m_lastSwitch=time(NULL);
00040 m_currentClock=0;
00041 m_pThread=NULL;
00042 m_pMutex=new CAMutex();
00043 }
00044
00045 t_databaseInfo* CADatabase::createDBInfo()
00046 {
00047 t_databaseInfo* pInfo=new t_databaseInfo;
00048 memset(pInfo,NULL,sizeof(t_databaseInfo));
00049 return pInfo;
00050 }
00051
00052 CADatabase::~CADatabase()
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 m_pMutex = NULL;
00062 }
00063
00064 SINT32 CADatabase::clearDB(t_databaseInfo* pDBInfo)
00065 {
00066 UINT16 tmp,tmp2;
00067 for(tmp=0;tmp<256;tmp++){
00068 for(tmp2=0;tmp2<256;tmp2++){
00069 while (pDBInfo->m_pHashTable[tmp][tmp2]!=NULL){
00070 t_databaseEntry* anker=pDBInfo->m_pHashTable[tmp][tmp2];
00071 pDBInfo->m_pHashTable[tmp][tmp2]=anker->next;
00072 delete anker;
00073 anker = NULL;
00074 }
00075 }
00076 }
00077 pDBInfo->m_u32Size=0;
00078 return E_SUCCESS;
00079 }
00080
00081 SINT32 CADatabase::deleteDB(t_databaseInfo*& pDBInfo)
00082 {
00083 clearDB(pDBInfo);
00084 delete pDBInfo;
00085 pDBInfo=NULL;
00086 return E_SUCCESS;
00087 }
00088
00090 SINT32 CADatabase::insert(UINT8 key[16],UINT64 timestamp)
00091 {
00092
00093 m_pMutex->lock();
00094
00095
00096
00097 if ((timestamp<(m_lastSwitch-SECONDS_PER_INTERVALL))||(timestamp>(time(NULL)+FUTURE_TOLERANCE))) {
00098
00099 m_pMutex->unlock();
00100 return E_UNKNOWN;
00101 }
00102
00103 t_databaseInfo* aktDB=NULL;
00104 t_databaseInfo* prevDB=NULL;
00105 t_databaseInfo* nextDB=NULL;
00106
00107 if(timestamp<m_lastSwitch){
00108 aktDB=m_prevDatabase;
00109 prevDB=NULL;
00110 nextDB=m_currDatabase;
00111 }
00112 else if(timestamp<(m_lastSwitch+SECONDS_PER_INTERVALL)){
00113 aktDB=m_currDatabase;
00114 prevDB=m_prevDatabase;
00115 nextDB=m_nextDatabase;
00116 }
00117 else {
00118 aktDB=m_nextDatabase;
00119 prevDB=m_currDatabase;
00120 nextDB=NULL;
00121 }
00122
00123 UINT64 hashkey= (((UINT64)key[2])<<56)+
00124 (((UINT64)key[3])<<48)+
00125 (((UINT64)key[4])<<40)+
00126 (((UINT64)key[5])<<32)+
00127 (((UINT64)key[6])<<24)+
00128 (((UINT64)key[7])<<16)+
00129 (((UINT64)key[8])<<8)+
00130 ((UINT64)key[9]);
00131
00132
00133 if (prevDB!=NULL){
00134 t_databaseEntry* tmp=prevDB->m_pHashTable[key[0]][key[1]];
00135
00136 while(tmp!=NULL){
00137 if (tmp->key!=hashkey) {
00138 tmp=tmp->next;
00139 }
00140 else {
00141
00142 m_pMutex->unlock();
00143 return E_UNKNOWN;
00144 }
00145 }
00146
00147
00148 tmp=new t_databaseEntry;
00149 tmp->next=prevDB->m_pHashTable[key[0]][key[1]];
00150 tmp->key=hashkey;
00151 prevDB->m_pHashTable[key[0]][key[1]]=tmp;
00152 prevDB->m_u32Size++;
00153 }
00154
00155 t_databaseEntry* tmp=aktDB->m_pHashTable[key[0]][key[1]];
00156
00157 while(tmp!=NULL){
00158 if (tmp->key!=hashkey) {
00159 tmp=tmp->next;
00160 }
00161 else {
00162
00163 m_pMutex->unlock();
00164 return E_UNKNOWN;
00165 }
00166 }
00167
00168
00169 tmp=new t_databaseEntry;
00170 tmp->next=aktDB->m_pHashTable[key[0]][key[1]];
00171 tmp->key=hashkey;
00172 aktDB->m_pHashTable[key[0]][key[1]]=tmp;
00173 aktDB->m_u32Size++;
00174
00175 if (nextDB!=NULL){
00176 t_databaseEntry* tmp=nextDB->m_pHashTable[key[0]][key[1]];
00177
00178 while(tmp!=NULL){
00179 if (tmp->key!=hashkey) {
00180 tmp=tmp->next;
00181 }
00182 else {
00183
00184 m_pMutex->unlock();
00185 return E_UNKNOWN;
00186 }
00187 }
00188
00189
00190 tmp=new t_databaseEntry;
00191 tmp->next=nextDB->m_pHashTable[key[0]][key[1]];
00192 tmp->key=hashkey;
00193 nextDB->m_pHashTable[key[0]][key[1]]=tmp;
00194 nextDB->m_u32Size++;
00195 }
00196
00197 m_pMutex->unlock();
00198 return E_SUCCESS;
00199
00200 }
00201
00202 SINT32 CADatabase::start()
00203 {
00204 m_pThread=new CAThread();
00205 m_bRun=true;
00206 m_pThread->setMainLoop(db_loopMaintenance);
00207 return m_pThread->start(this);
00208 }
00209
00210 SINT32 CADatabase::stop()
00211 {
00212 m_bRun=false;
00213 SINT32 ret=E_SUCCESS;
00214 if(m_pThread!=NULL)
00215 {
00216 ret=m_pThread->join();
00217 delete m_pThread;
00218 m_pThread=NULL;
00219 }
00220 return ret;
00221 }
00222
00223 THREAD_RETURN db_loopMaintenance(void *param)
00224 {
00225 INIT_STACK;
00226 BEGIN_STACK("CADatabase::db_loopMaintenance");
00227
00228 CADatabase* pDatabase=(CADatabase*)param;
00229 while(pDatabase->m_bRun)
00230 {
00231 sSleep(10);
00232 if (pDatabase->m_lastSwitch+SECONDS_PER_INTERVALL<=time(NULL)) {
00233 pDatabase->nextClock();
00234 }
00235 }
00236
00237 FINISH_STACK("CADatabase::db_loopMaintenance");
00238
00239 THREAD_RETURN_SUCCESS;
00240 }
00241
00242 SINT32 CADatabase::nextClock()
00243 {
00244 m_pMutex->lock();
00245 m_lastSwitch+=SECONDS_PER_INTERVALL;
00246 CAMsg::printMsg(LOG_DEBUG,"Replay DB Size was: %u\n",m_prevDatabase->m_u32Size);
00247 clearDB(m_prevDatabase);
00248 t_databaseInfo* tmpDB=m_prevDatabase;
00249 m_prevDatabase=m_currDatabase;
00250 m_currDatabase=m_nextDatabase;
00251 m_nextDatabase=tmpDB;
00252 m_pMutex->unlock();
00253 return E_SUCCESS;
00254 }
00255
00256
00257 SINT32 CADatabase::test()
00258 {
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 UINT32 entries=10000;
00277 fill(entries);
00278 return E_SUCCESS;
00279
00280 }
00281
00282
00283 SINT32 CADatabase::measurePerformance( UINT8* strLogFile,
00284 UINT32 lowerBoundEntries,
00285 UINT32 upperBoundEntries,
00286 UINT32 stepBy,
00287 UINT32 meassuresPerStep,
00288 UINT32 insertsPerMeasure)
00289 {
00290 initRandom();
00291 CADatabase* pDatabase=NULL;
00292 UINT32 aktNrOfEntries=lowerBoundEntries;
00293 UINT8* key=new UINT8[insertsPerMeasure*16];
00294 UINT8* aktKey;
00295 SINT32 file=open((char*)strLogFile,O_CREAT|O_WRONLY|O_LARGEFILE|O_TRUNC,S_IREAD|S_IWRITE);
00296 char buff[255];
00297 const char* atemplate="%u,%u,%u\n";
00298 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";
00299 write(file,header,strlen(header));
00300 while(aktNrOfEntries<=upperBoundEntries)
00301 {
00302 CAMsg::printMsg(LOG_DEBUG,"Starting measurement with %u entries in the replay database\n",aktNrOfEntries);
00303 for(UINT32 i=0;i<meassuresPerStep;i++)
00304 {
00305 pDatabase=new CADatabase();
00306 pDatabase->fill(aktNrOfEntries);
00307 UINT64 startTime,endTime;
00308 getRandom(key,insertsPerMeasure*16);
00309 aktKey=key;
00310 getcurrentTimeMicros(startTime);
00311 for(UINT32 j=0;j<insertsPerMeasure;j++)
00312 {
00313 pDatabase->simulateInsert(aktKey);
00314 aktKey+=16;
00315 }
00316 getcurrentTimeMicros(endTime);
00317 sprintf(buff,atemplate,aktNrOfEntries,insertsPerMeasure,diff64(endTime,startTime));
00318 write(file,buff,strlen(buff));
00319 printf("Start delete \n");
00320 getcurrentTimeMicros(startTime);
00321 delete pDatabase;
00322 pDatabase = NULL;
00323 getcurrentTimeMicros(endTime);
00324 printf("delete takes %u microsecs\n",diff64(endTime,startTime));
00325 }
00326 aktNrOfEntries+=stepBy;
00327 }
00328 delete[] key;
00329 key = NULL;
00330 return E_SUCCESS;
00331 }
00332
00333
00334 SINT32 CADatabase::fill(UINT32 nrOfEntries)
00335 {
00336 UINT32 i=0;
00337 UINT8 key[16];
00338 while(i<nrOfEntries)
00339 {
00340 getRandom(key,16);
00341 if(insert(key,time(NULL))==E_SUCCESS)
00342 i++;
00343 }
00344 return E_SUCCESS;
00345 }
00346
00347
00348 SINT32 CADatabase::simulateInsert(UINT8 key[16])
00349 {
00350 m_pMutex->lock();
00351 UINT16 timestamp=(key[14]<<8)|key[15];
00352 if(timestamp<m_currentClock-1||timestamp>m_currentClock+1)
00353 {
00354
00355
00356 }
00357 t_databaseInfo* aktDB=m_currDatabase;
00358 if(timestamp>m_currentClock)
00359 {
00360
00361 }
00362 else if(timestamp<m_currentClock)
00363 {
00364
00365 }
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375 aktDB->m_u32Size++;
00376 m_pMutex->unlock();
00377 return E_SUCCESS;
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 }
00418 #endif //Only_LOCAL_PROXY