Mixe for Privacy and Anonymity in the Internet
CAReplayDatabase.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2000, The JAP-Team
3 All rights reserved.
4 Redistribution and use in source and binary forms, with or without modification,
5 are permitted provided that the following conditions are met:
6 
7  - Redistributions of source code must retain the above copyright notice,
8  this list of conditions and the following disclaimer.
9 
10  - Redistributions in binary form must reproduce the above copyright notice,
11  this list of conditions and the following disclaimer in the documentation and/or
12  other materials provided with the distribution.
13 
14  - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors
15  may be used to endorse or promote products derived from this software without specific
16  prior written permission.
17 
18 
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
20 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
22 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
27 */
28 #include "StdAfx.h"
29 #ifndef ONLY_LOCAL_PROXY
30 #include "CAReplayDatabase.hpp"
31 #include "CAUtil.hpp"
32 #include "CAMsg.hpp"
33 
35  {
39  m_refTime=time(NULL);
41  m_pThread=NULL;
42  m_pMutex=new CAMutex();
43  }
44 
46  {
48  memset(pInfo,0,sizeof(t_replay_databaseInfo));
49  return pInfo;
50  }
51 
53  {
54  m_pMutex->lock();
55  stop();
59  m_pMutex->unlock();
60  delete m_pMutex;
61  }
62 
64  {
65  while(pDBInfo->m_pHeap!=NULL)
66  {
67  pDBInfo->m_pLastHeap=pDBInfo->m_pHeap;
68  pDBInfo->m_pHeap=pDBInfo->m_pHeap->next;
69  delete pDBInfo->m_pLastHeap;
70  }
71  memset(pDBInfo,0,sizeof(t_replay_databaseInfo));
72  return E_SUCCESS;
73  }
74 
76  {
77  clearDB(pDBInfo);
78  delete pDBInfo;
79  pDBInfo=NULL;
80  return E_SUCCESS;
81  }
82 
85  {
86  m_pMutex->lock();
87  UINT16 timestamp=(key[14]<<8)|key[15];
88  if(timestamp<m_currentClock-1||timestamp>m_currentClock+1)
89  {
90  m_pMutex->unlock();
91  return E_UNKNOWN;
92  }
94  if(timestamp>m_currentClock)
95  {
96  aktDB=m_nextDatabase;
97  }
98  else if(timestamp<m_currentClock)
99  {
100  aktDB=m_prevDatabase;
101  }
102  UINT16 hashKey=(key[8]<<8)|key[9];
103  LP_replay_databaseEntry hashList=aktDB->m_pHashTable[hashKey];
104  if(hashList==NULL)
105  {
106  LP_replay_databaseEntry newEntry=getNewDBEntry(aktDB);
107  newEntry->left=NULL;
108  newEntry->right=NULL;
109  newEntry->key=key[0]<<24|key[1]<<16|key[2]<<8|key[3];
110  aktDB->m_pHashTable[hashKey]=newEntry;
111  aktDB->m_u32Size++;
112  m_pMutex->unlock();
113  return E_SUCCESS;
114  }
115  else
116  {
117  UINT32 ret=key[0]<<24|key[1]<<16|key[2]<<8|key[3];;
118  LP_replay_databaseEntry before=NULL;
119  do
120  {
121  //newEntry->keymemcmp(key,hashList->key,6);
122  if(ret==hashList->key)
123  {
124  m_pMutex->unlock();
125  return E_UNKNOWN;
126  }
127  before=hashList;
128  if(hashList->key<ret)
129  {
130  hashList=hashList->right;
131  }
132  else
133  {
134  hashList=hashList->left;
135  }
136  } while(hashList!=NULL);
137  LP_replay_databaseEntry newEntry=getNewDBEntry(aktDB);
138  newEntry->left=newEntry->right=NULL;
139  //memcpy(newEntry->key,key,6);
140  newEntry->key=ret;
141  if(before->key<ret)
142  {
143  before->right=newEntry;
144  }
145  else
146  before->left=newEntry;
147 
148  }
149  aktDB->m_u32Size++;
150  m_pMutex->unlock();
151  return E_SUCCESS;
152  }
153 
155  {
156  m_pThread=new CAThread((UINT8*)"DB Maintenance Thread");
157  m_bRun=true;
159  return m_pThread->start(this);
160  }
161 
163  {
164  m_bRun=false;
165  SINT32 ret=E_SUCCESS;
166  if(m_pThread!=NULL)
167  {
168  ret=m_pThread->join();
169  delete m_pThread;
170  m_pThread=NULL;
171  }
172  return ret;
173  }
174 
176  {
177  INIT_STACK;
178  BEGIN_STACK("CADatabase::db_loopMaintenance");
179 
180  CAReplayDatabase* pDatabase=(CAReplayDatabase*)param;
181  tReplayTimestamp rt;
182  pDatabase->getCurrentReplayTimestamp(rt);
183  pDatabase->m_currentClock=rt.interval;
184  while(pDatabase->m_bRun)
185  {
186  sSleep(10);
187  SINT32 secondsTilNextClock=((pDatabase->m_currentClock+1)*SECONDS_PER_INTERVALL)+pDatabase->m_refTime-time(NULL);
188  if(secondsTilNextClock<=0&&pDatabase->m_bRun)
189  pDatabase->nextClock();
190  }
191 
192  FINISH_STACK("CADatabase::db_loopMaintenance");
193 
195  }
196 
198  {
199  m_pMutex->lock();
200  tReplayTimestamp rt;
203  CAMsg::printMsg(LOG_DEBUG,"Replay DB Size was: %u\n",m_prevDatabase->m_u32Size);
208  m_nextDatabase=tmpDB;
209  m_pMutex->unlock();
210  return E_SUCCESS;
211  }
212 
214  {
215  CAReplayDatabase oDatabase;
216  oDatabase.start();
217  UINT8 key[16];
218  memset(key,0,16);
219  UINT32 i;
220  for(i=0;i<20;i++)
221  {
222  getRandom(key,1);
223  oDatabase.insert(key);
224  }
225  for(i=0;i<200000;i++)
226  {
227  getRandom(key,16);
228  oDatabase.insert(key);//TODO WRONG - Fixme
229  }
230  oDatabase.stop();
231 //check it
232 //TODO fixme!
233 /* for(i=0;i<0x10000;i++)
234  {
235  LP_databaseEntry tmp=oDatabase.m_currDatabase[i];
236  while(tmp!=NULL&&tmp->next!=NULL)
237  {
238  if(memcmp(tmp->key,tmp->next->key,14)>=0)
239  return E_UNKNOWN;
240  tmp=tmp->next;
241  }
242  }*/
243  return E_SUCCESS;
244  }
245 
250  {
251  return getReplayTimestampForTime(replayTimestamp,time(NULL),m_refTime);
252  }
253 
254 
256  {
257  UINT32 timeDiff=aktTime-refTime;
258  replayTimestamp.interval=timeDiff/SECONDS_PER_INTERVALL;
259  replayTimestamp.offset=timeDiff%SECONDS_PER_INTERVALL;
260  return E_SUCCESS;
261  }
262 
263 
265  UINT32 lowerBoundEntries,
266  UINT32 upperBoundEntries,
267  UINT32 stepBy,
268  UINT32 meassuresPerStep,
269  UINT32 insertsPerMeasure)
270  {
271  initRandom();
272  CAReplayDatabase* pDatabase=NULL;
273  UINT32 aktNrOfEntries=lowerBoundEntries;
274  UINT8* key=new UINT8[insertsPerMeasure*16];
275  UINT8* aktKey;
276  SINT32 file=open((char*)strLogFile,O_CREAT|O_WRONLY|O_LARGEFILE|O_TRUNC,S_IREAD|S_IWRITE);
277  char buff[255];
278  const char* atemplate="%u,%u,%u\n";
279  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";
280  myfilewrite(file,header,strlen(header));
281  while(aktNrOfEntries<=upperBoundEntries)
282  {
283  CAMsg::printMsg(LOG_DEBUG,"Starting measurement with %u entries in the replay database\n",aktNrOfEntries);
284  for(UINT32 i=0;i<meassuresPerStep;i++)
285  {
286  pDatabase=new CAReplayDatabase();
287  pDatabase->m_currentClock=0;
288  pDatabase->fill(aktNrOfEntries);
289  UINT64 startTime,endTime;
290  getRandom(key,insertsPerMeasure*16);
291  aktKey=key+14;
292  for(UINT32 j=0;j<insertsPerMeasure;j++)
293  {
294  *aktKey=0;
295  aktKey++;
296  *aktKey=0;
297  aktKey+=15;
298  }
299  aktKey=key;
300  getcurrentTimeMicros(startTime);
301  for(UINT32 j=0;j<insertsPerMeasure;j++)
302  {
303  pDatabase->simulateInsert(aktKey);
304  aktKey+=16;
305  }
306  getcurrentTimeMicros(endTime);
307  sprintf(buff,atemplate,aktNrOfEntries,insertsPerMeasure,diff64(endTime,startTime));
308  myfilewrite(file,buff,strlen(buff));
309  printf("Start delete \n");
310  getcurrentTimeMicros(startTime);
311  delete pDatabase;
312  getcurrentTimeMicros(endTime);
313  printf("delete takes %u microsecs\n",diff64(endTime,startTime));
314  }
315  aktNrOfEntries+=stepBy;
316  }
317  delete[] key;
318  return E_SUCCESS;
319  }
320 
322  {
323  UINT32 i=0;
324  UINT8 key[16];
325  key[14]=0;
326  key[15]=0;
327  while(i<nrOfEntries)
328  {
329  getRandom(key,14);
330  if(insert(key)==E_SUCCESS)
331  i++;
332  }
333  return E_SUCCESS;
334  }
335 
337  {
338  m_pMutex->lock();
339  UINT16 timestamp=(key[14]<<8)|key[15];
340  if(timestamp<m_currentClock-1||timestamp>m_currentClock+1)
341  {
342  m_pMutex->unlock();
343  return E_UNKNOWN;
344  }
346  if(timestamp>m_currentClock)
347  {
348  aktDB=m_nextDatabase;
349  }
350  else if(timestamp<m_currentClock)
351  {
352  aktDB=m_prevDatabase;
353  }
354  UINT16 hashKey=(key[8]<<8)|key[9];
355  LP_replay_databaseEntry hashList=aktDB->m_pHashTable[hashKey];
356  if(hashList==NULL)
357  {
358  LP_replay_databaseEntry newEntry=getNewDBEntry(aktDB);
359  newEntry->left=NULL;
360  newEntry->right=NULL;
361  newEntry->key=key[0]<<24|key[1]<<16|key[2]<<8|key[3];
362  m_nextDatabase->m_pHashTable[hashKey]=newEntry; //we simply use the 'next' Database to simulate insert while not inserting anythign in the current db
363  aktDB->m_u32Size++;
364  m_pMutex->unlock();
365  return E_SUCCESS;
366  }
367  else
368  {
369  UINT32 ret=key[0]<<24|key[1]<<16|key[2]<<8|key[3];
370  LP_replay_databaseEntry before=NULL;
371  do
372  {
373  //newEntry->keymemcmp(key,hashList->key,6);
374  if(ret==hashList->key)
375  {
376  m_pMutex->unlock();
377  return E_UNKNOWN;
378  }
379  before=hashList;
380  if(hashList->key<ret)
381  {
382  hashList=hashList->right;
383  }
384  else
385  {
386  hashList=hashList->left;
387  }
388  } while(hashList!=NULL);
389  LP_replay_databaseEntry newEntry=getNewDBEntry(aktDB);
390  newEntry->left=newEntry->right=NULL;
391  //memcpy(newEntry->key,key,6);
392  newEntry->key=ret;
393  if(before->key<ret)
394  {
395  newEntry->right=newEntry; //do the pointer operation without actually changing the DB
396  }
397  else
398  {
399  newEntry->left=newEntry; //do the pointer operation without actually changing the DB
400  }
401  }
402  aktDB->m_u32Size++;
403  m_pMutex->unlock();
404  return E_SUCCESS;
405  }
406 #endif //Only_LOCAL_PROXY
#define SECONDS_PER_INTERVALL
Definition: CADatabase.hpp:47
THREAD_RETURN replaydb_loopMaintenance(void *param)
struct __t_database_info t_replay_databaseInfo
#define INIT_STACK
Definition: CAThread.hpp:48
#define BEGIN_STACK(methodName)
Definition: CAThread.hpp:49
#define FINISH_STACK(methodName)
Definition: CAThread.hpp:50
SINT32 getcurrentTimeMicros(UINT64 &u64Time)
Gets the current Systemtime in micros seconds.
Definition: CAUtil.cpp:280
SINT32 initRandom()
Definition: CAUtil.cpp:302
SINT32 sSleep(UINT32 sec)
Sleeps sec Seconds.
Definition: CAUtil.cpp:425
SINT32 getRandom(UINT32 *val)
Gets 32 random bits.
Definition: CAUtil.cpp:346
UINT32 diff64(const UINT64 &bigop, const UINT64 &smallop)
Definition: CAUtil.hpp:398
#define myfilewrite
Definition: StdAfx.h:493
#define O_LARGEFILE
Definition: StdAfx.h:635
#define S_IWRITE
Definition: StdAfx.h:491
#define THREAD_RETURN
Definition: StdAfx.h:540
#define THREAD_RETURN_SUCCESS
Definition: StdAfx.h:542
#define S_IREAD
Definition: StdAfx.h:488
unsigned short UINT16
Definition: basetypedefs.h:133
signed int SINT32
Definition: basetypedefs.h:132
unsigned char UINT8
Definition: basetypedefs.h:135
unsigned int UINT32
Definition: basetypedefs.h:131
static SINT32 printMsg(UINT32 typ, const char *format,...)
Writes a given message to the log.
Definition: CAMsg.cpp:251
SINT32 unlock()
Definition: CAMutex.hpp:52
SINT32 lock()
Definition: CAMutex.hpp:41
static SINT32 test()
SINT32 getCurrentReplayTimestamp(tReplayTimestamp &replayTimestamp) const
Returns the current Replay timestamp for this database.
t_replay_databaseInfo * m_currDatabase
t_replay_databaseInfo * m_prevDatabase
friend THREAD_RETURN replaydb_loopMaintenance(void *param)
SINT32 insert(UINT8 key[16])
Inserts this key in the replay DB.
static SINT32 measurePerformance(UINT8 *strLogFile, UINT32 lowerBoundEntries, UINT32 upperBoundEntries, UINT32 stepBy, UINT32 meassuresPerStep, UINT32 insertsPerMeasure)
This mehtod can be used to measure the performance of the Replay database.
SINT32 deleteDB(t_replay_databaseInfo *&pDB)
Deletes the whole database pDB.
t_replay_databaseInfo * createDBInfo()
Creates and initialises a dbinfo struct.
SINT32 simulateInsert(UINT8 key[16])
This is a modified copy of insert() which simulates the insert() function as close as possible withou...
t_replay_databaseInfo * m_nextDatabase
SINT32 clearDB(t_replay_databaseInfo *pDB)
clears the whole database pDB - but does not delete the hashtable pDB
SINT32 fill(UINT32 nrOfEntries)
Pre fills the database with nrOfEntries random entries.
volatile bool m_bRun
LP_replay_databaseEntry getNewDBEntry(t_replay_databaseInfo *pDB)
volatile SINT32 m_currentClock
static SINT32 getReplayTimestampForTime(tReplayTimestamp &replayTimestamp, UINT32 aktTime, UINT32 refTime)
Returns the replay timestamp for this reference time (seconds since epoch) and time.
SINT32 start(void *param, bool bDaemon=false, bool bSilent=false)
Starts the execution of the main function of this thread.
Definition: CAThread.cpp:115
SINT32 setMainLoop(THREAD_MAIN_TYP fnc)
Sets the main function which will be executed within this thread.
Definition: CAThread.hpp:148
SINT32 join()
Waits for the main function to finish execution.
Definition: CAThread.cpp:187
const SINT32 E_SUCCESS
Definition: errorcodes.hpp:2
#define E_UNKNOWN
Definition: errorcodes.hpp:3
t_replay_databaseHeap * m_pHeap
t_replay_databaseHeap * m_pLastHeap
LP_replay_databaseEntry m_pHashTable[0x10000]
__t_replay_database_entry * right
UINT32 key
__t_replay_database_entry * left
__t_replay_database_heap * next
the Replaytimestamp type
Definition: typedefs.hpp:206