Commit ea8d74b9 authored by John Selbie's avatar John Selbie

Refactoring for upcoming TCP support

parent 5007dd15
/*
* File: main.cpp
* Author: jselbie
*
* Created on December 3, 2011, 11:18 PM
*/
#ifndef FASTHASH_H
#define FASTHASH_H
// FastHash is a cheap and dirty hash table template class
// It is "fast" because it never allocates memory beyond the static arrays inside each instance
// Hence, it can be used off the stack or in cases where memory allocations impact performance
// Limitations:
// Fixed number of insertions (specified by FSIZE)
// Does not support removals
// Made for simple types and structs of simple types - as items are pre-allocated (no regards to constructors or destructors)
// Duplicate key insertions will not remove the previous item
// Additional:
// FastHash keeps a static array of items inserted (in insertion order)
// Then a hash table of <K,int> to map keys back to index values
// This allows calling code to be able to iterate over the table in insertion order
// Template parameters
// K = key type
// V = value type
// FSIZE = max number of items in the hash table (default is 100)
// TSIZE = hash table width (higher value reduces collisions, but with extra memory overhead - default is 37). Usually a prime number.
inline size_t FastHash_Hash(unsigned int x)
{
return (size_t)x;
}
inline size_t FastHash_Hash(signed int x)
{
return (size_t)x;
}
const size_t FAST_HASH_DEFAULT_CAPACITY = 100;
const size_t FASH_HASH_DEFAULT_TABLE_SIZE = 37;
template <class K, class V, size_t FSIZE=FAST_HASH_DEFAULT_CAPACITY, size_t TSIZE=FASH_HASH_DEFAULT_TABLE_SIZE>
class FastHash
{
private:
struct ItemNode
{
K key;
int index; // index into _list where this item is stored
ItemNode* pNext;
};
V _list[FSIZE]; // list of items
size_t _count; // number of items inserted so far
ItemNode _tablenodes[FSIZE];
ItemNode* _table[TSIZE];
public:
FastHash()
{
Reset();
}
void Reset()
{
_count = 0;
memset(_table, '\0', sizeof(_table));
}
size_t Size()
{
return _count;
}
HRESULT Insert(K key, const V& val)
{
size_t tableindex = FastHash_Hash(key) % TSIZE;
if (_count >= FSIZE)
{
return false;
}
_list[_count] = val;
_tablenodes[_count].index = _count;
_tablenodes[_count].key = key;
_tablenodes[_count].pNext = _table[tableindex];
_table[tableindex] = &_tablenodes[_count];
_count++;
return true;
}
V* Lookup(K key, int* pIndex=NULL)
{
size_t tableindex = FastHash_Hash(key) % TSIZE;
V* pFoundItem = NULL;
ItemNode* pHead = _table[tableindex];
if (pIndex)
{
*pIndex = -1;
}
while (pHead)
{
if (pHead->key == key)
{
pFoundItem = &_list[pHead->index];
if (pIndex)
{
*pIndex = pHead->index;
}
break;
}
pHead = pHead->pNext;
}
return pFoundItem;
}
bool Exists(K key)
{
V* pItem = Lookup(key);
return (pItem != NULL);
}
V* GetItemByIndex(int index)
{
if ((index < 0) || (((size_t)index) >= _count))
{
return NULL;
}
return &_list[index];
}
};
#endif
\ No newline at end of file
/*
Copyright 2011 John Selbie
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef STUN_SERVER_H
#define STUN_SERVER_H
#include "stunsocket.h"
#include "stunauth.h"
#include "server.h"
#endif /* SERVER_H */
/*
Copyright 2011 John Selbie
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef STUN_SERVER_H
#define STUN_SERVER_H
#include "stunsocket.h"
#include "stunauth.h"
#include "server.h"
#endif /* SERVER_H */
This diff is collapsed.
......@@ -24,6 +24,7 @@
#include "stuntypes.h"
#include "datastream.h"
#include "socketaddress.h"
#include "fasthash.h"
class CStunMessageReader
......@@ -46,8 +47,13 @@ private:
ReaderParseState _state;
static const size_t MAX_NUM_ATTRIBUTES = 30;
StunAttribute _attributes[MAX_NUM_ATTRIBUTES];
size_t _nAttributeCount;
//StunAttribute _attributes[MAX_NUM_ATTRIBUTES];
//size_t _nAttributeCount;
typedef FastHash<uint16_t, StunAttribute, MAX_NUM_ATTRIBUTES, 53> AttributeHashTable; // 53 is a prime number for a reasonable table width
AttributeHashTable _mapAttributes;
StunTransactionId _transactionid;
uint16_t _msgTypeNormalized;
......
include ../common.inc
PROJECT_TARGET := stuntestcode
PROJECT_OBJS := testbuilder.o testclientlogic.o testcmdline.o testcode.o testdatastream.o testintegrity.o testmessagehandler.o testreader.o testrecvfromex.o
PROJECT_OBJS := testbuilder.o testclientlogic.o testcmdline.o testcode.o testdatastream.o testfasthash.o testintegrity.o testmessagehandler.o testreader.o testrecvfromex.o
INCLUDES := $(BOOST_INCLUDE) $(OPENSSL_INCLUDE) -I../common -I../stuncore -I../networkutils
LIB_PATH := -L../networkutils -L../stuncore -L../common
......
......@@ -26,6 +26,7 @@
#include "testintegrity.h"
#include "testclientlogic.h"
#include "testrecvfromex.h"
#include "testfasthash.h"
#include "cmdlineparser.h"
#include "oshelper.h"
#include "prettyprint.h"
......@@ -76,6 +77,7 @@ void RunUnitTests()
boost::shared_ptr<CTestCmdLineParser> spTestCmdLineParser(new CTestCmdLineParser);
boost::shared_ptr<CTestClientLogic> spTestClientLogic(new CTestClientLogic);
boost::shared_ptr<CTestRecvFromEx> spTestRecvFromEx(new CTestRecvFromEx);
boost::shared_ptr<CTestFastHash> spTestFastHash(new CTestFastHash);
vecTests.push_back(spTestDataStream.get());
vecTests.push_back(spTestReader.get());
......@@ -85,6 +87,8 @@ void RunUnitTests()
vecTests.push_back(spTestCmdLineParser.get());
vecTests.push_back(spTestClientLogic.get());
vecTests.push_back(spTestRecvFromEx.get());
vecTests.push_back(spTestFastHash.get());
for (size_t index = 0; index < vecTests.size(); index++)
{
......
/*
Copyright 2011 John Selbie
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "commonincludes.h"
#include "testfasthash.h"
#include "fasthash.h"
HRESULT CTestFastHash::Run()
{
return TestFastHash();
}
HRESULT CTestFastHash::TestFastHash()
{
HRESULT hr = S_OK;
const size_t c_maxsize = 500;
FastHash<int, Item, c_maxsize> hash;
for (size_t index = 0; index < c_maxsize; index++)
{
Item item;
item.key = (int)index;
ChkA(hash.Insert((int)index, item));
}
// validate that all the items are in the table
for (size_t index = 0; index < c_maxsize; index++)
{
Item* pItem = NULL;
Item* pItemDirect = NULL;
int insertindex = -1;
ChkIfA(hash.Exists(index)==false, E_FAIL);
pItem = hash.Lookup((int)index, &insertindex);
ChkIfA(pItem == NULL, E_FAIL);
ChkIfA(pItem->key != (int)index, E_FAIL);
ChkIfA((int)index != insertindex, E_FAIL);
pItemDirect = hash.GetItemByIndex((int)index);
ChkIfA(pItemDirect != pItem, E_FAIL);
}
// validate that items aren't in the table don't get returned
for (size_t index = c_maxsize; index < (c_maxsize*2); index++)
{
ChkIfA(hash.Exists((int)index), E_FAIL);
ChkIfA(hash.Lookup((int)index)!=NULL, E_FAIL);
ChkIfA(hash.GetItemByIndex((int)index)!=NULL, E_FAIL);
}
Cleanup:
return hr;
}
/*
Copyright 2011 John Selbie
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef TEST_FAST_HASH_H
#define TEST_FAST_HASH_H
#include "commonincludes.h"
#include "unittest.h"
class CTestFastHash : public IUnitTest
{
private:
HRESULT TestFastHash();
struct Item
{
int key;
};
public:
virtual HRESULT Run();
UT_DECLARE_TEST_NAME("CTestFastHash");
};
#endif
/*
Copyright 2011 John Selbie
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "commonincludes.h"
#include "stuncore.h"
#include "testintegrity.h"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment