Mixe for Privacy and Anonymity in the Internet
Public Member Functions | Private Member Functions | Private Attributes
CAChainTable Class Reference

#include <CAChainTable.hpp>

Collaboration diagram for CAChainTable:
[legend]

List of all members.

Public Member Functions

 CAChainTable (void)
 ~CAChainTable (void)
CAChaingetEntry (UINT8 *a_chainId)
CAChaincreateEntry ()
void deleteEntry (UINT8 *a_chainId)
UINT32 getSize ()
CAChaingetFirstEntry ()
CAChaingetNextEntry ()

Private Member Functions

t_chaintableEntrygetEntryInternal (UINT8 *a_chainId)
void removeEntryInternal (t_chaintableEntry *a_entry)
void getNextEntryInternal (t_chaintableIterator *a_iterator)

Private Attributes

t_chaintableEntry ** m_pChainTable
CAMutexm_pMutex
UINT32 m_chaintableSize
t_chaintableIteratorm_pChaintableIterator

Detailed Description

Definition at line 52 of file CAChainTable.hpp.


Constructor & Destructor Documentation

Definition at line 39 of file CAChainTable.cpp.

References m_chaintableSize, m_pChainTable, m_pChaintableIterator, m_pMutex, and MAX_POLLFD.

                               {
  m_pChainTable = new (t_chaintableEntry*[0x10000]);
  for (UINT32 i = 0; i < 0x10000; i++) {
    m_pChainTable[i] = NULL;
  }
  m_pMutex = new CAMutex();
  m_chaintableSize = 0;
  m_pChaintableIterator = NULL;
  #ifdef DELAY_CHANNELS
    m_initialBucketSize = DELAY_CHANNEL_TRAFFIC;
    m_delayBucketGrow = DELAY_BUCKET_GROW;
    m_delayBucketGrowInterval = DELAY_BUCKET_GROW_INTERVALL;
    m_pDelayBucketMutex = new CAMutex();
    m_pDelayBuckets = new SINT32[MAX_POLLFD];
    for (UINT32 i = 0; i < MAX_POLLFD; i++) {
      m_pDelayBuckets[i] = -1;
    }
    /* start the delay-buckets-refill loop */
    m_delayBucketsLoopRun = true;
    m_pDelayBucketsLoop = new CAThread((UINT8*)"CAChainTable: delay-buckets refill thread");
    m_pDelayBucketsLoop->setMainLoop(lml_chaintableDelayBucketsLoop);
    m_pDelayBucketsLoop->start(this);
  #endif
}

Definition at line 64 of file CAChainTable.cpp.

References getFirstEntry(), getNextEntry(), m_pChainTable, m_pChaintableIterator, m_pMutex, and t_chaintableIterator::removeEntry.

                                {
  /* use the iterator to clean the table */
  getFirstEntry();
  while (m_pChaintableIterator != NULL) {
    /* chaintable iterator is removed, if last entry is reached */
    m_pChaintableIterator->removeEntry = true;
    /* entry is removed automatically, when the iterator points to the next
     * entry
     */
    getNextEntry();
  }
  #ifdef DELAY_CHANNELS
    m_delayBucketsLoopRun = false;
    /* wait for the delay-buckets-refill loop */
    m_pDelayBucketsLoop->join();
    delete m_pDelayBucketsLoop;
    m_pDelayBucketsLoop = NULL;
    delete m_pDelayBucketMutex;
    m_pDelayBucketMutex = NULL;
    delete []m_pDelayBuckets;
    m_pDelayBuckets = NULL;
  #endif
  delete m_pMutex;
  m_pMutex = NULL;
  delete []m_pChainTable;
  m_pChainTable = NULL;
}

Here is the call graph for this function:


Member Function Documentation

Definition at line 172 of file CAChainTable.cpp.

References t_chaintableEntry::chain, CHAIN_ID_LENGTH, chainId, E_SUCCESS, getEntryInternal(), getRandom(), CAMutex::lock(), m_chaintableSize, m_pChainTable, m_pMutex, MAX_POLLFD, t_chaintableEntry::rightEntry, t_chaintableEntry::rightEntryPointerOfLeftEntry, and CAMutex::unlock().

Referenced by CALastMixB::loop().

                                   {
  m_pMutex->lock();
  if (m_chaintableSize >= MAX_POLLFD) {
    /* we cannot create more chains because we are not able to handle more
     * sockets
     */
    m_pMutex->unlock();
    return NULL;
  }
  /* create a unique chain-id */
  UINT8* chainId = new UINT8[CHAIN_ID_LENGTH];
  do {
    if (getRandom(chainId, CHAIN_ID_LENGTH) != E_SUCCESS) {
      m_pMutex->unlock();
      delete []chainId;
      chainId = NULL;
      return NULL;
    }
  }
  while (getEntryInternal(chainId) != NULL);
  t_chaintableEntry* newEntry = new t_chaintableEntry;
  #ifndef DELAY_CHANNELS
    newEntry->chain = new CAChain(chainId);
  #else
    /* find an unused delay-bucket */
    m_pDelayBucketMutex->lock();
    UINT32 i = 0;
    bool bucketFound = false;
    while ((!bucketFound) && (i < MAX_POLLFD)) {
      if (m_pDelayBuckets[i] == -1) {
        bucketFound = true;
      }
      else {
        i++;
      }
    }
    if (!bucketFound) {
      /* we found no bucket -> this shouldn't happen because there cannot be
       * more chains than buckets
       */
      m_pDelayBucketMutex->unlock();
      delete newEntry;
      newEntry = NULL;
      delete []chainId;
      chainId = NULL;
      m_pMutex->unlock();
      return NULL;
    }
    /* initalize our bucket */
    m_pDelayBuckets[i] = (SINT32)m_initialBucketSize;
    m_pDelayBucketMutex->unlock();
    newEntry->chain = new CAChain(chainId, m_pDelayBucketMutex, &(m_pDelayBuckets[i]));
  #endif
  /* take the lower 16 bits as key for the hashtable */
  UINT16 hashKey = (((UINT16)(chainId[CHAIN_ID_LENGTH - 2])) << 8) | (UINT16)(chainId[CHAIN_ID_LENGTH - 1]);
  /* now add the entry at the begin of the hashtable-line */
  newEntry->rightEntry = m_pChainTable[hashKey];
  newEntry->rightEntryPointerOfLeftEntry = &(m_pChainTable[hashKey]);
  m_pChainTable[hashKey] = newEntry;
  if (newEntry->rightEntry != NULL) {
    newEntry->rightEntry->rightEntryPointerOfLeftEntry = &(newEntry->rightEntry);
  }
  m_chaintableSize++;
  m_pMutex->unlock();
  return (newEntry->chain);
}

Here is the call graph for this function:

void CAChainTable::deleteEntry ( UINT8 a_chainId)

Definition at line 103 of file CAChainTable.cpp.

References t_chaintableIterator::currentEntry, getEntryInternal(), CAMutex::lock(), m_pChaintableIterator, m_pMutex, t_chaintableIterator::removeEntry, removeEntryInternal(), and CAMutex::unlock().

Referenced by CALastMixB::loop().

                                               {
  m_pMutex->lock();
  t_chaintableEntry* chaintableEntry = getEntryInternal(a_chainId);
  if (chaintableEntry != NULL) {
    /* we have found an entry with the specified ID -> check whether the
     * iterator points to it
     */
    if (m_pChaintableIterator != NULL) {
      if (m_pChaintableIterator->currentEntry == chaintableEntry) {
        /* don't remove the entry but set the remove-flag for the iterator */
        m_pChaintableIterator->removeEntry = true;
      }
      else {
        removeEntryInternal(chaintableEntry);
      }
    }
    else {
      removeEntryInternal(chaintableEntry);
    }
  }
  m_pMutex->unlock();
}

Here is the call graph for this function:

CAChain * CAChainTable::getEntry ( UINT8 a_chainId)

Definition at line 92 of file CAChainTable.cpp.

References t_chaintableEntry::chain, getEntryInternal(), CAMutex::lock(), m_pMutex, and CAMutex::unlock().

Referenced by CALastMixB::loop().

                                                {
  m_pMutex->lock();
  CAChain* returnedChain = NULL;
  t_chaintableEntry* chaintableEntry = getEntryInternal(a_chainId);
  if (chaintableEntry != NULL) {
    returnedChain = chaintableEntry->chain;
  }
  m_pMutex->unlock();
  return returnedChain;
}

Here is the call graph for this function:

Definition at line 248 of file CAChainTable.cpp.

References t_chaintableEntry::chain, CHAIN_ID_LENGTH, t_chaintableIterator::currentEntry, CAChain::getChainId(), m_pChainTable, m_pChaintableIterator, t_chaintableIterator::removeEntry, and t_chaintableEntry::rightEntry.

Referenced by createEntry(), deleteEntry(), and getEntry().

                                                                  {
  /* mutex must be already locked */
  /* take the lower 16 bits as key for the hashtable */
  UINT16 hashKey = (((UINT16)(a_chainId[CHAIN_ID_LENGTH - 2])) << 8) | (UINT16)(a_chainId[CHAIN_ID_LENGTH - 1]);
  bool entryFound = false;
  t_chaintableEntry* currentEntry = m_pChainTable[hashKey];
  while ((currentEntry != NULL) && !entryFound) {
    /* a removed entry could be in the table, if the iterator points to it ->
     * we have to check it
     */
    bool entryVirtualRemoved = false;
    if (m_pChaintableIterator != NULL) {
      if ((m_pChaintableIterator->currentEntry == currentEntry) && (m_pChaintableIterator->removeEntry)) {
        entryVirtualRemoved = true;
        /* skip this entry */
        currentEntry = currentEntry->rightEntry;
      }
    }
    if (!entryVirtualRemoved) {
      /* compare the Chain-IDs (lower 2 bytes are identical because of the same
       * hashkey -> don't compare them)
       */
      if (memcmp(currentEntry->chain->getChainId(), a_chainId, CHAIN_ID_LENGTH - 2) == 0) {
        /* we have found the entry */
        entryFound = true;
      }
      else {
        currentEntry = currentEntry->rightEntry;
      }
    }
  }
  return currentEntry;
}

Here is the call graph for this function:

Definition at line 126 of file CAChainTable.cpp.

References t_chaintableEntry::chain, t_chaintableIterator::currentEntry, getNextEntryInternal(), CAMutex::lock(), m_pChaintableIterator, m_pMutex, t_chaintableIterator::nextHashkey, t_chaintableIterator::removeEntry, removeEntryInternal(), and CAMutex::unlock().

Referenced by CALastMixB::loop(), and ~CAChainTable().

                                     {
  CAChain* firstChain = NULL;
  m_pMutex->lock();
  if (m_pChaintableIterator == NULL) {
    m_pChaintableIterator = new t_chaintableIterator;
  }
  else {
    /* look whether we shall remove our last entry */
    if (m_pChaintableIterator->removeEntry) {
      removeEntryInternal(m_pChaintableIterator->currentEntry);
    }
  }
  m_pChaintableIterator->nextHashkey = 0;
  m_pChaintableIterator->removeEntry = false;
  m_pChaintableIterator->currentEntry = NULL;
  getNextEntryInternal(m_pChaintableIterator);
  if (m_pChaintableIterator->currentEntry == NULL) {
    /* no entries in the table */
    delete m_pChaintableIterator;
    m_pChaintableIterator = NULL;
  }
  else {
    firstChain = m_pChaintableIterator->currentEntry->chain;
  }
  m_pMutex->unlock();
  return firstChain;
}

Here is the call graph for this function:

Definition at line 154 of file CAChainTable.cpp.

References t_chaintableEntry::chain, t_chaintableIterator::currentEntry, getNextEntryInternal(), CAMutex::lock(), m_pChaintableIterator, m_pMutex, and CAMutex::unlock().

Referenced by CALastMixB::loop(), and ~CAChainTable().

                                    {
  CAChain* nextChain = NULL;
  m_pMutex->lock();
  if (m_pChaintableIterator != NULL) {
    getNextEntryInternal(m_pChaintableIterator);
    if (m_pChaintableIterator->currentEntry == NULL) {
      /* no more entries in the table */
      delete m_pChaintableIterator;
      m_pChaintableIterator = NULL;
    }
    else {
      nextChain = m_pChaintableIterator->currentEntry->chain;
    }
  }
  m_pMutex->unlock();
  return nextChain;
}

Here is the call graph for this function:

void CAChainTable::getNextEntryInternal ( t_chaintableIterator a_iterator) [private]

Definition at line 297 of file CAChainTable.cpp.

References t_chaintableIterator::currentEntry, m_pChainTable, t_chaintableIterator::nextHashkey, t_chaintableIterator::removeEntry, removeEntryInternal(), and t_chaintableEntry::rightEntry.

Referenced by getFirstEntry(), and getNextEntry().

                                                                        {
  /* mutex must be already locked */
  t_chaintableEntry* nextEntry;
  if (a_iterator->currentEntry == NULL) {
    nextEntry = NULL;
  }
  else {
    nextEntry = a_iterator->currentEntry->rightEntry;
    /* look whether we shall remove our last entry */
    if (a_iterator->removeEntry) {
      removeEntryInternal(a_iterator->currentEntry);
      a_iterator->removeEntry = false;
    }
  }
  if (nextEntry == NULL) {
    /* we have to start at the current hashtable-line until we find a
     * hashtable-line with entries or reach again the top of the table
     */
    do {
      a_iterator->currentEntry = m_pChainTable[a_iterator->nextHashkey];
      (a_iterator->nextHashkey)++;
    }
    while ((a_iterator->currentEntry == NULL) && (a_iterator->nextHashkey != 0));
    if (a_iterator->nextHashkey == 0) {
      /* we have reached the top of the table again */
      a_iterator->currentEntry = NULL;
    }
  }
  else {
    /* we have another entry in the same hashtable-line */
    a_iterator->currentEntry = nextEntry;
  }
}

Here is the call graph for this function:

Definition at line 239 of file CAChainTable.cpp.

References CAMutex::lock(), m_chaintableSize, m_pMutex, and CAMutex::unlock().

Referenced by CALastMixB::loop().

                             {
  UINT32 chaintableSize;
  m_pMutex->lock();
  chaintableSize = m_chaintableSize;
  m_pMutex->unlock();
  return chaintableSize;
}

Here is the call graph for this function:

Definition at line 282 of file CAChainTable.cpp.

References t_chaintableEntry::chain, m_chaintableSize, t_chaintableEntry::rightEntry, and t_chaintableEntry::rightEntryPointerOfLeftEntry.

Referenced by deleteEntry(), getFirstEntry(), and getNextEntryInternal().

                                                                 {
  /* mutex must be already locked */
  *(a_entry->rightEntryPointerOfLeftEntry) = a_entry->rightEntry;
  if (a_entry->rightEntry != NULL) {
    a_entry->rightEntry->rightEntryPointerOfLeftEntry = a_entry->rightEntryPointerOfLeftEntry;
  }
  /* delete the chain */
  delete a_entry->chain;
  a_entry->chain = NULL;
  /* delete the table-entry */
  delete a_entry;
  a_entry = NULL;
  m_chaintableSize--;
}

Member Data Documentation

Definition at line 69 of file CAChainTable.hpp.

Referenced by CAChainTable(), createEntry(), getSize(), and removeEntryInternal().


The documentation for this class was generated from the following files: