本人属菜鸟,如有错误请指正
接口定义在list.h 里, 内容如下
#ifndef _LIST_H_H_
#define _LIST_H_H_
typedef struct List* List_t;
/** @defgroup List
* MY LIST
* @{
*/
/** @} */
#ifdef __cplusplus
extern "C" {
#endif
/**@ingroup List
*@brief List_new creates a new List structure with no bindings within it.
*@return List_t If not enough memory is available, it will return a NULL pointer, else it
*will return a pointer to the Structure.
*/
List_t List_new( void );
/**@ingroup List
*@brief List_free frees all the memory occupied by the symbol table.
*@param [in] oList the symbol table pointed to by oList,including all
*the allocated structure fields, bindings, and buckets (if applicable).
*/
void List_free( List_t oList );
/**@ingroup List
*@brief List_getLength return the total number of bindings within oList.
*/
int List_getLength( List_t oList );
/**@ingroup List
*@brief List_put creates a binding consisting of pcKey and pvValue, inserts it into the symbol table.
*@param [in] oList the symbol table pointed to by oList
*@param [in] pcKey the key of binding
*@param [in] pvValue the value of binding
*@return int If a pcKey isn’t already in the symbol table pointed to by oList,inserts it
*into the symbol table and returns 1. If not enough memory is available or pcKey already is in the List,
*the function will leave oList unchanged and return 0.
*/
int List_put( List_t oList, const char* pcKey, const void* pvValue );
/**@ingroup List
*@brief List_replace replaces the binding’s old value with pvValue and returns an opaque pointer to the old value.
*@param [in] oList the symbol table pointed to by oList
*@param [in] pcKey the key of binding
*@param [in] pvValue the value of binding
*@return void* If successful, the function replaces the binding’s old value with pvValue and returns
*an opaque pointer to the old value. If the binding with pcKey is not found, the function leaves oList
*unchanged and returns a NULL pointer.
*/
void* List_replace( List_t oList, const char* pcKey, const void* pvValue );
/**@ingroup List
*@brief List_replace searches through oList to locate the binding with pcKey.
*In all cases, oList is unchanged.
*@param [in] oList the symbol table pointed to by oList
*@param [in] pcKey the key of binding
*@return int If successful, returns 1. else returns 0.
*/
int List_contains( List_t oList, const char* pcKey );
/**@ingroup List
*@brief List_get gets the binding’s value.
*In all cases, oList is unchanged.
*@param [in] oList the symbol table pointed to by oList
*@param [in] pcKey the key of binding
*@return void* If successful, the function returns the binding’s value. If not found,
*the function leaves returns a NULL pointer.
*/
void* List_get( List_t oList, const char* pcKey );
/**@ingroup List
*@brief List_remove removes the binding from oList.
*List_remove searches through oList to locate the binding with pcKey. If successful,
*the function removes the binding from oList and returns an opaque pointer to the binding’s old value.
*If the binding is not found, the function will return a NULL pointer.
*@param [in] oList the symbol table pointed to by oList
*@param [in] pcKey the key of binding
*/
void* List_remove( List_t oList, const char* pcKey );
/**@ingroup List
*@brief List_map iterates through the entire List and applies pfApply on each binding.
*pfApply takes a third parameter that is passed in from the map function.
*/
void List_map( List_t oList,
void ( *pfApply )( const char* pcKey, const void* pvValue, void* pvExtra ),
const void* pvExtra
);
#ifdef __cplusplus
}
#endif
#endif //_LIST_H_H_
list.cpp 实现
#include "list.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
/* ListNode to identify the data unit under processing */
typedef struct ListNode
{
char* key; // Current node key
void* value; // Pointer to the value which binds to the key
struct ListNode* next; // Next node
} ListNode;
/* List to collect the list data */
typedef struct List
{
struct ListNode* head_node;
struct ListNode* tail_node;
unsigned long uiNodeLength; // The length of linked list
} List;
/*
* Use calloc to allocate the memory,
* because it will initialize all memory bits to zero.
*/
static void* MyAlloc ( unsigned long size )
{
void* tmp;
tmp = ( void* ) calloc ( size, sizeof ( char ) );
assert( tmp );
return tmp;
}
List_t List_new( void )
{
return ( List_t ) MyAlloc ( sizeof ( List ) );
}
void List_free( List_t oList )
{
assert ( oList );
ListNode* temp = oList->head_node;
while ( temp )
{
oList->head_node = oList->head_node->next;
if ( temp->key )
{
free ( temp->key );
}
free ( temp );
temp = oList->head_node;
}
free ( oList );
oList = NULL;
}
int List_getLength( List_t oList )
{
return oList->uiNodeLength;
}
/**
*Local function, if find out the pcKey return the ListNode*,
*other return NULL
*/
static ListNode* List_getKey( List_t oList,
const char* pcKey )
{
assert ( oList );
assert ( pcKey );
if ( 0 == strlen( pcKey ) )
{
return NULL;
}
ListNode* temp = oList->head_node;
while ( temp )
{
if ( 0 == strcmp ( pcKey, temp->key ) )
{
return temp;
}
temp = temp->next;
}
return NULL;
}
int List_put( List_t oList, const char* pcKey,
const void* pvValue )
{
assert ( oList );
assert ( pcKey );
assert ( pvValue );
if ( 0 == strlen( pcKey ) )
{
return 0;
}
if ( List_getKey( oList, pcKey ) )
{
return 0;
}
else
{
ListNode* new_node = ( ListNode* )MyAlloc ( sizeof( ListNode ) );
if ( NULL == new_node )
{
return 0;
}
char* key = ( char* ) MyAlloc ( strlen ( pcKey ) + 1 );
if ( NULL == key )
{
free( new_node );
return 0;
}
new_node->key = key;
strcpy ( new_node->key, pcKey );
new_node->value = ( void* )pvValue; //????
if ( 0 == oList->uiNodeLength ) // The list is empty
{
oList->head_node = new_node;
oList->tail_node = new_node;
oList->uiNodeLength = 1;
return 1;
}
if ( 1 == oList->uiNodeLength )// Only one key-value in list
{
oList->head_node->next = new_node;
oList->tail_node = new_node;
oList->uiNodeLength = 2;
return 1;
}
else // More than one key-value in list
{
oList->tail_node->next = new_node;
oList->tail_node = new_node;
oList->uiNodeLength += 1;
return 1;
}
}
}
int List_contains( List_t oList, const char* pcKey )
{
assert ( oList );
assert ( pcKey );
if ( List_getKey( oList, pcKey ) )
{
return 1;
}
return 0;
}
void* List_get( List_t oList, const char* pcKey )
{
assert ( oList );
assert ( pcKey );
ListNode* temp = List_getKey( oList, pcKey );
if ( temp )
{
return temp->value;
}
return NULL;
}
void List_map( List_t oList,
void ( *pfApply )( const char* pcKey,
const void* pvValue, void* pvExtra ),
const void* pvExtra )
{
assert ( oList );
assert ( pfApply );
assert ( pvExtra );
ListNode* temp = oList->head_node;
while ( temp )
{
assert ( temp->key );
assert ( temp->value );
pfApply( temp->key, temp->value, ( void* )pvExtra );
temp = temp->next;
}
return;
}
void* List_replace( List_t oList, const char* pcKey,
const void* pvValue )
{
assert ( oList );
assert ( pcKey );
void* value = NULL;
ListNode* temp = List_getKey( oList, pcKey );
if ( temp )
{
value = temp->value;
temp->value = ( void* )pvValue;
}
return value;
}
void* List_remove( List_t oList, const char* pcKey )
{
assert ( oList );
assert ( pcKey );
void* value = NULL;
ListNode* temp = oList->head_node;
ListNode* pre_node = NULL;
/*
*The key-value maybe has been removed
*or has not been inserted successfully
*/
if ( NULL == temp )
{
return NULL;
}
if ( 0 == strlen( pcKey ) )
{
return NULL;
}
// Head node is the node which need to be removed
if ( 0 == strcmp ( pcKey, temp->key ) )
{
value = temp->value;
oList->head_node = temp->next;
free ( temp->key );
free ( temp );
oList->uiNodeLength = oList->uiNodeLength - 1;
return value;
}
while ( 1 )
{
pre_node = temp;
temp = temp->next;
if ( NULL == temp )
{
return NULL;
}
if ( 0 == strcmp ( pcKey, temp->key ) ) // Find it
{
pre_node->next = temp->next;
value = temp->value;
free ( temp->key );
free ( temp );
oList->uiNodeLength = oList->uiNodeLength - 1;
return value;
}
}
return NULL;
}
测试代码如下:
#include "list.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdarg.h>
// You can enlarge the value of LOOPS,LOOPS0 and LOOPS1 to perform pressure test
#define LOOPS 1
#define LOOPS0 1
#define LOOPS1 100
#define ARRAY_SIZE 7
#define PRINT_ERROR(...) fprintf(stderr, __VA_ARGS__)
#define MY_ASSERT(value) if(!(value)) { PRINT_ERROR("\"%s\" failed at %s:%d %s \n",\
#value,__FILE__,__LINE__,__FUNCTION__);}
#define BINDINGS_LOG
#define UNUSED(x) (void)x
static unsigned long g_BindingsCount; // Count the bindings
static FILE* g_out_file = NULL; // For bindings into log
static int gTest = 10;
// Store the keys
static const char* kArrayString[ARRAY_SIZE] = {"Hello", "TTTT",
"Parallel", "Serial", "MyProject",
"Good Luck", "222222@qq.com"
};
static void InitLog( const char* file_name )
{
#ifdef BINDINGS_LOG
MY_ASSERT( file_name );
if ( g_out_file == NULL )
{
g_out_file = fopen( file_name, "w" );
}
if ( g_out_file == NULL )
{
printf( "Create %s failed\n", file_name );
}
printf( "Bindings were written into %s, please check it for details.\n", file_name );
#endif
return ;
}
static void LogMessage( const char* format, ... )
{
va_list ap;
va_start( ap, format );
#ifdef BINDINGS_LOG
vfprintf( g_out_file, format, ap );
fflush( g_out_file );
#else
vfprintf( stderr, format, ap );
#endif
va_end( ap );
}
static void CloseLog()
{
#ifdef BINDINGS_LOG
if ( g_out_file )
{
fclose( g_out_file );
g_out_file = NULL;
}
#endif
return ;
}
static List_t HelpFunc( void )
{
int i = 0;
List_t mList = List_new();
MY_ASSERT( mList );
MY_ASSERT( 0 == List_getLength( mList ) );
for ( i = 0; i < ARRAY_SIZE; ++i )
{
// Test List_put
MY_ASSERT( 1 == List_put( mList, kArrayString[i], &gTest ) );
MY_ASSERT( ( i + 1 ) == List_getLength( mList ) );
}
return mList;
}
void test_List_new_and_List_free()
{
int i = 0;
printf( "=======================================================\n" );
for ( i = 0; i < LOOPS; ++i )
{
List_t mNew = List_new();
MY_ASSERT( mNew );
MY_ASSERT( 0 == List_getLength( mNew ) );
List_free( mNew );
}
printf( "Test new and free, Done !! \n" );
return ;
}
void test_List_put()
{
int i = 0;
int j = 0;
char temp[100];
char* testString = "GoodBoy";
printf( "=======================================================\n" );
for ( i = 0; i < LOOPS0; ++i )
{
List_t mList0 = List_new();
MY_ASSERT( mList0 );
for ( j = 0; j < LOOPS1; ++j )
{
sprintf( temp, "%d", j );
MY_ASSERT( 1 == List_put( mList0, ( const char* )&temp, &i ) );// Test List_put
MY_ASSERT( 0 == List_put( mList0, ( const char* )&temp, &i ) );// put again
MY_ASSERT( ( j + 1 ) == List_getLength( mList0 ) );
}
MY_ASSERT( ( LOOPS1 ) == List_getLength( mList0 ) );
// Test List_put with NULL key
MY_ASSERT( 0 == List_put( mList0, "", &i ) );
MY_ASSERT( ( LOOPS1 ) == List_getLength( mList0 ) );
/*
*Simulate the complex scenes, the main purpose is to test stability.
*Here I call List_replace/get/remove, may be more interfaces called here
*is more preferably.
*/
sprintf( temp, "%d", i );
int* pResult = ( int* )List_replace( mList0, temp, testString ); // replace
MY_ASSERT( pResult );
MY_ASSERT( i == *pResult );
char* result_string = ( char* )List_get( mList0, temp );
MY_ASSERT( result_string );
MY_ASSERT( 0 == strcmp( result_string, testString ) ); // check the result of replace
MY_ASSERT( ( LOOPS1 ) == List_getLength( mList0 ) );
if ( i < ( LOOPS1 - 1 ) ) // make sure i+1 is valid
{
sprintf( temp, "%d", i + 1 );
pResult = ( int* )List_remove( mList0, temp );
MY_ASSERT( pResult );
MY_ASSERT( i == *pResult );
MY_ASSERT( ( LOOPS1 - 1 ) == List_getLength( mList0 ) );
}
List_free( mList0 );
}
printf( "Test List_put, Done !! \n" );
return ;
}
void test_List_contains()
{
int i = 0;
int j = 0;
printf( "=======================================================\n" );
for ( i = 0; i < LOOPS; ++i )
{
List_t mNew = HelpFunc();
MY_ASSERT( mNew );
for ( j = 0; j < ARRAY_SIZE; ++j )
{
MY_ASSERT( 1 == List_contains( mNew, kArrayString[j] ) ); // Test List_contains
MY_ASSERT( 0 == List_contains( mNew, "" ) ); // Test List_contains with NULL key
MY_ASSERT( ARRAY_SIZE == List_getLength( mNew ) );
}
MY_ASSERT( 0 == List_contains( mNew, "Who" ) ); // Test List_contains
List_free( mNew );
}
printf( "Test List_contains, Done !! \n" );
return ;
}
void test_List_get()
{
int i = 0;
int j = 0;
printf( "=======================================================\n" );
for ( i = 0; i < LOOPS; ++i )
{
List_t mNew = HelpFunc();
MY_ASSERT( mNew );
for ( j = 0; j < ARRAY_SIZE; ++j )
{
// Test List_get
int* pResult = ( int* )List_get( mNew, kArrayString[j] );
MY_ASSERT( pResult );
//MY_ASSERT( gTest == *pResult );
// Test it with NULL key
pResult = ( int* )List_get( mNew, "" );
MY_ASSERT( NULL == pResult );
MY_ASSERT( ARRAY_SIZE == List_getLength( mNew ) );
}
List_free( mNew );
}
printf( "Test List_get, Done !! \n" );
return ;
}
void TestMapFunc1( const char* pcKey, const void* pvValue, void* pvExtra )
{
MY_ASSERT( pcKey );
MY_ASSERT( pvValue );
int* pInt = ( int* )pvExtra;
if ( *pInt > 0 ) // If *pInt > 0, print out the key and value(adress)
{
printf( "Key is %s, the Value is %d \n", pcKey, *( int* )pvValue );
}
return ;
}
void TestMapFunc2( const char* pcKey, const void* pvValue, void* pvExtra )
{
MY_ASSERT( pcKey );
MY_ASSERT( pvValue );
char* mString = ( char* )pvExtra;
// If the two strings are equal(the *pvExtra and Key), print out the key and the value(adress)
if ( 0 == strcmp( mString, pcKey ) )
{
printf( "Found out the Key, the Key is %s, the Value is %d \n", pcKey, *( int* )pvValue );
}
return ;
}
void test_List_map()
{
int i = 0;
int j = 1;
char* testString = "GoodBoy";
printf( "=======================================================\n" );
List_t mNew = HelpFunc();
MY_ASSERT( mNew );
// Use TestMapFunc1 test
printf( "test List_map with TestMapFunc1\n" );
printf( "print out the key and the value(adress),\n" );
List_map( mNew, TestMapFunc1, ( void* )&j ); // Test List_map
printf( "\ntest List_map with TestMapFunc1\n" );
printf( "print out nothing\n" );
List_map( mNew, TestMapFunc1, ( void* )&i ); // Test List_map
// Use TestMapFunc2 test
printf( "\n\ntest List_map with TestMapFunc2----\n" );
printf( "print out the key and the value(adress),\n" );
List_map( mNew, TestMapFunc2, ( void* )kArrayString[5] ); // Test List_map
printf( "\ntest List_map with TestMapFunc2-----\n" );
printf( "print out nothing\n" );
List_map( mNew, TestMapFunc2, ( void* )testString ); // Test List_map
List_free( mNew );
printf( "\nTest List_map, Done !! \n" );
return ;
}
void test_List_replace()
{
int j = 0;
char* testString = "GoodBoy";
printf( "=======================================================\n" );
List_t mNew = HelpFunc();
MY_ASSERT( mNew );
for ( j = 0; j < ARRAY_SIZE; ++j )
{
int* pResult = ( int* )List_replace( mNew, kArrayString[j], testString ); // Replace
MY_ASSERT( pResult );
MY_ASSERT( gTest == *pResult );
char* result_string = ( char* )List_get( mNew, kArrayString[j] );
MY_ASSERT( result_string );
MY_ASSERT( 0 == strcmp( result_string, testString ) ); // Check the result of replace
MY_ASSERT( ARRAY_SIZE == List_getLength( mNew ) );
}
// List_replace, pass the wrong key-value
MY_ASSERT( 0 == List_replace( mNew, "Who", testString ) );
MY_ASSERT( 0 == List_replace( mNew, "", testString ) );
MY_ASSERT( ARRAY_SIZE == List_getLength( mNew ) );
List_free( mNew );
printf( "Test List_replace, Done !! \n" );
return ;
}
void test_List_remove()
{
int j = 0;
printf( "=======================================================\n" );
List_t mNew = HelpFunc();
MY_ASSERT( mNew );
for ( j = 0; j < ARRAY_SIZE; ++j )
{
// List_remove, remove it from the head one by one
int* pResult = ( int* )List_remove( mNew, kArrayString[j] );
MY_ASSERT( pResult );
MY_ASSERT( gTest == *pResult );
MY_ASSERT( ( ARRAY_SIZE - j - 1 ) == List_getLength( mNew ) );
}
// List_remove, the key does not in the List
MY_ASSERT( 0 == List_remove( mNew, kArrayString[0] ) );
List_free( mNew );
mNew = HelpFunc();
MY_ASSERT( mNew );
for ( j = 0; j < ARRAY_SIZE; ++j )
{
// List_remove, remove it from the tail one by one
int* pResult = ( int* )List_remove( mNew, kArrayString[ARRAY_SIZE - j - 1] );
MY_ASSERT( pResult );
MY_ASSERT( gTest == *pResult );
MY_ASSERT( ( ARRAY_SIZE - j - 1 ) == List_getLength( mNew ) );
}
// List_remove, the key does not in the List
MY_ASSERT( 0 == List_remove( mNew, kArrayString[0] ) );
MY_ASSERT( 0 == List_remove( mNew, "" ) );
List_free( mNew );
mNew = HelpFunc();
MY_ASSERT( mNew );
{
// List_remove, remove it from middle
int* pResult = ( int* )List_remove( mNew, kArrayString[3] );
MY_ASSERT( pResult );
MY_ASSERT( gTest == *pResult );
MY_ASSERT( ( ARRAY_SIZE - 1 ) == List_getLength( mNew ) );
// List_remove, the key does not in the List
MY_ASSERT( 0 == List_remove( mNew, kArrayString[3] ) );
MY_ASSERT( ( ARRAY_SIZE - 1 ) == List_getLength( mNew ) );
// List_remove, remove it from middle
pResult = ( int* )List_remove( mNew, kArrayString[2] );
MY_ASSERT( pResult );
MY_ASSERT( gTest == *pResult );
MY_ASSERT( ( ARRAY_SIZE - 2 ) == List_getLength( mNew ) );
// List_remove, the key does not in the List
MY_ASSERT( 0 == List_remove( mNew, kArrayString[2] ) );
MY_ASSERT( ( ARRAY_SIZE - 2 ) == List_getLength( mNew ) );
// List_remove, remove it from head
pResult = ( int* )List_remove( mNew, kArrayString[0] );
MY_ASSERT( pResult );
MY_ASSERT( gTest == *pResult );
MY_ASSERT( ( ARRAY_SIZE - 3 ) == List_getLength( mNew ) );
// List_remove, the key does not in the List
MY_ASSERT( 0 == List_remove( mNew, kArrayString[0] ) );
MY_ASSERT( ( ARRAY_SIZE - 3 ) == List_getLength( mNew ) );
// List_remove, remove it from tail
pResult = ( int* )List_remove( mNew, kArrayString[6] );
MY_ASSERT( pResult );
MY_ASSERT( gTest == *pResult );
MY_ASSERT( ( ARRAY_SIZE - 4 ) == List_getLength( mNew ) );
// List_remove, the key does not in the List
MY_ASSERT( 0 == List_remove( mNew, kArrayString[6] ) );
MY_ASSERT( ( ARRAY_SIZE - 4 ) == List_getLength( mNew ) );
}
List_free( mNew );
printf( "Test List_remove, Done !! \n" );
return ;
}
// Test the interfaces with a empty List
void test_List_empty()
{
int i = 0;
int j = 1;
char* testString = "GoodBoy";
printf( "=======================================================\n" );
List_t mNew = List_new();
MY_ASSERT( mNew );
MY_ASSERT( 0 == List_getLength( mNew ) );
void* pResult = List_get( mNew, testString );
MY_ASSERT( NULL == pResult );
MY_ASSERT( 0 == List_contains( mNew, testString ) );
pResult = List_replace( mNew, testString, "hello" ); // replace
MY_ASSERT( NULL == pResult );
pResult = List_remove( mNew, testString );
MY_ASSERT( NULL == pResult );
MY_ASSERT( 0 == List_getLength( mNew ) );
// Use TestMapFunc1 test
List_map( mNew, TestMapFunc1, ( void* )&j );
List_map( mNew, TestMapFunc1, ( void* )&i );
// Use TestMapFunc2 test
List_map( mNew, TestMapFunc2, ( void* )kArrayString[2] );
List_map( mNew, TestMapFunc2, ( void* )testString );
MY_ASSERT( 0 == List_getLength( mNew ) );
List_free( mNew );
printf( "Test test_List_empty, Done !! \n" );
return ;
}
void performance_test()
{
int i = 0;
int j = 0;
int k = 0;
int m = 0;
int n = 0;
int p = 0;// random number
int table_length = -1;
int outer_times = 1;
int inner_loop_times = 65523;
char temp[100];
char* testString = "GoodBoy";
clock_t start, finish;
double duration;
printf( "=======================================================\n" );
/*
*Try to insert 65523 random bindings into the List,
*and almost the List interfaces will be used in the case.
*/
printf( "This case is used to test the performance of List, \
it will output the run time of each interface separately.\n" );
srand( ( unsigned )time( NULL ) ); // random seed /
List_t mList0 = List_new();
MY_ASSERT( mList0 );
for ( i = 0; i < outer_times; ++i )
{
start = clock();
// test List_put
for ( j = 0; j < inner_loop_times; ++j )
{
p = rand() % ( 65523 ) + 1; // p is a random number that between 1 and 65523
sprintf( temp, "%d", p );
table_length = List_getLength( mList0 );
if ( List_put( mList0, ( const char* )&temp, &i ) )
{
MY_ASSERT( ( table_length + 1 ) == List_getLength( mList0 ) );
}
else
{
MY_ASSERT( table_length == List_getLength( mList0 ) );
}
}
finish = clock();
duration = ( double )( finish - start ) / CLOCKS_PER_SEC;
printf( "Try to insert %d random bindings into the List, \n", inner_loop_times );
printf( "and there are %d bindings were inserted into the List. \n", List_getLength( mList0 ) );
printf( "List_put costs \t %f seconds\n", duration );
start = clock();
// replace
for ( k = 0; k < inner_loop_times; ++k )
{
p = rand() % ( 65523 ) + 1; // p is a random number that between 1 and 65523
sprintf( temp, "%d", p );
table_length = List_getLength( mList0 );
if ( List_replace( mList0, temp, testString ) )
{
char* result_string = ( char* )List_get( mList0, temp );
MY_ASSERT( result_string );
MY_ASSERT( 0 == strcmp( result_string, testString ) ); // check the result of replace
MY_ASSERT( table_length == List_getLength( mList0 ) );
}
else
{
MY_ASSERT( table_length == List_getLength( mList0 ) );
}
}
finish = clock();
duration = ( double )( finish - start ) / CLOCKS_PER_SEC;
printf( "List_replace costs \t %f seconds\n", duration );
start = clock();
// get
table_length = List_getLength( mList0 );
for ( m = 0; m < inner_loop_times; ++m )
{
p = rand() % ( 65523 ) + 1; // p is a random number that between 1 and 65523
sprintf( temp, "%d", p );
List_get( mList0, temp );
MY_ASSERT( table_length == List_getLength( mList0 ) );
}
finish = clock();
duration = ( double )( finish - start ) / CLOCKS_PER_SEC;
printf( "List_get costs \t %f seconds\n", duration );
start = clock();
// remove
for ( n = 0; n < inner_loop_times; ++n )
{
p = rand() % ( 65523 ) + 1; // p is a random number that between 1 and 65523
sprintf( temp, "%d", p );
table_length = List_getLength( mList0 );
if ( List_remove( mList0, temp ) )
{
MY_ASSERT( ( table_length - 1 ) == List_getLength( mList0 ) );
}
else
{
MY_ASSERT( table_length == List_getLength( mList0 ) );
}
}
finish = clock();
duration = ( double )( finish - start ) / CLOCKS_PER_SEC;
printf( "List_remove costs \t %f seconds\n", duration );
}
List_free( mList0 );
return ;
}
void run_test()
{
test_List_new_and_List_free();
test_List_put();
test_List_contains();
test_List_get();
test_List_map();
test_List_replace();
test_List_remove();
test_List_empty();
return ;
}
int main( int argc, char* argv[] )
{
UNUSED( argc );
run_test();
performance_test();
printf( "\n\n" );
return 0;
}