基于双向循环链表构建的hash表

 


#CFLAGS=-O2 -Wall -g -lpthread  

CFLAGS=  -lpthread  
NAME=mbw
TARFILE=${NAME}.tar.gz

mbw: mbw.c

clean:
    rm -f mbw
    rm -f ${NAME}.tar.gz

${TARFILE}: clean
     tar cCzf .. ${NAME}.tar.gz --exclude-vcs ${NAME} || true

rpm: ${TARFILE}
     rpmbuild -ta ${NAME}.tar.gz 
 

 

 

 

/*
 * Copyright (C) 2008-2013 The Android Open Source Project
 *
 * 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 _CUTILS_LIST_H_
#define _CUTILS_LIST_H_

#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

struct listnode
{
    struct listnode *next;
    struct listnode *prev;
};

#define node_to_item(node, container, member) \
    (container *) (((char*) (node)) - offsetof(container, member))

#define list_declare(name) \
    struct listnode name = { \
        .next = &(name), \
        .prev = &(name), \
    }

#define list_for_each(node, list) \
    for ((node) = (list)->next; (node) != (list); (node) = (node)->next)

#define list_for_each_reverse(node, list) \
    for ((node) = (list)->prev; (node) != (list); (node) = (node)->prev)

#define list_for_each_safe(node, n, list) \
    for ((node) = (list)->next, (n) = (node)->next; \
         (node) != (list); \
         (node) = (n), (n) = (node)->next)

static inline void list_init(struct listnode *node)
{
    node->next = node;
    node->prev = node;
}

static inline void list_add_tail(struct listnode *head, struct listnode *item)
{
    item->next = head;
    item->prev = head->prev;
    head->prev->next = item;
    head->prev = item;
}

static inline void list_add_head(struct listnode *head, struct listnode *item)
{
    item->next = head->next;
    item->prev = head;
    head->next->prev = item;
    head->next = item;
}

static inline void list_remove(struct listnode *item)
{
    item->next->prev = item->prev;
    item->prev->next = item->next;
}

#define list_empty(list) ((list) == (list)->next)
#define list_head(list) ((list)->next)
#define list_tail(list) ((list)->prev)

#ifdef __cplusplus
};
#endif /* __cplusplus */

#endif

 

 

 

 

 

 

/*
 * vim: ai ts=4 sts=4 sw=4 cinoptions=>4 expandtab
 */
#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>


#include "list.h"


/* how many runs to average by default */
#define DEFAULT_NR_LOOPS 10

/* we have 3 tests at the moment */
#define MAX_TESTS 3

/* default block size for test 2, in bytes */
#define DEFAULT_BLOCK_SIZE 262144

/* test types */
#define TEST_MEMCPY 0
#define TEST_DUMB 1
#define TEST_MCBLOCK 2

/* version number */
#define VERSION "1.4"

/*
 * MBW memory bandwidth benchmark
 *
 * 2006, 2012 Andras.Horvath@gmail.com
 * 2013 j.m.slocum@gmail.com
 * (Special thanks to Stephen Pasich)
 *
 * http://github.com/raas/mbw
 *
 * compile with:
 *            gcc -O -o mbw mbw.c
 *
 * run with eg.:
 *
 *            ./mbw 300
 *
 * or './mbw -h' for help
 *
 * watch out for swap usage (or turn off swap)
 */

void usage()
{
    printf("mbw memory benchmark v%s, https://github.com/raas/mbw\n", VERSION);
    printf("Usage: mbw [options] array_size_in_MiB\n");
    printf("Options:\n");
    printf("    -n: number of runs per test (0 to run forever)\n");
    printf("    -a: Don't display average\n");
    printf("    -t%d: memcpy test\n", TEST_MEMCPY);
    printf("    -t%d: dumb (b[i]=a[i] style) test\n", TEST_DUMB);
    printf("    -t%d: memcpy test with fixed block size\n", TEST_MCBLOCK);
    printf("    -b <size>: block size in bytes for -t2 (default: %d)\n", DEFAULT_BLOCK_SIZE);
    printf("    -q: quiet (print statistics only)\n");
    printf("(will then use two arrays, watch out for swapping)\n");
    printf("'Bandwidth' is amount of data copied over the time this operation took.\n");
    printf("\nThe default is to run all tests available.\n");
}

/* ------------------------------------------------------ */

/* allocate a test array and fill it with data
 * so as to force Linux to _really_ allocate it */
long *make_array(unsigned long long asize)
{
    unsigned long long t;
    unsigned int long_size=sizeof(long);
    long *a;

    a=calloc(asize, long_size);

    if(NULL==a) {
        perror("Error allocating memory");
        exit(1);
    }

    /* make sure both arrays are allocated, fill with pattern */
    for(t=0; t<asize; t++) {
        a[t]=0xaa;
    }
    return a;
}

/* actual benchmark */
/* asize: number of type 'long' elements in test arrays
 * long_size: sizeof(long) cached
 * type: 0=use memcpy, 1=use dumb copy loop (whatever GCC thinks best)
 *
 * return value: elapsed time in seconds
 */
double worker(unsigned long long asize, long *a, long *b, int type, unsigned long long block_size)
{
    unsigned long long t;
    struct timeval starttime, endtime;
    double te;
    unsigned int long_size=sizeof(long);
    /* array size in bytes */
    unsigned long long array_bytes=asize*long_size;

    if(type==TEST_MEMCPY) { /* memcpy test */
        /* timer starts */
        gettimeofday(&starttime, NULL);
        memcpy(b, a, array_bytes);
        /* timer stops */
        gettimeofday(&endtime, NULL);
    } else if(type==TEST_MCBLOCK) { /* memcpy block test */
        char* aa = (char*)a;
        char* bb = (char*)b;
        gettimeofday(&starttime, NULL);
        for (t=array_bytes; t >= block_size; t-=block_size, aa+=block_size){
            bb=mempcpy(bb, aa, block_size);
        }
        if(t) {
            bb=mempcpy(bb, aa, t);
        }
        gettimeofday(&endtime, NULL);
    } else if(type==TEST_DUMB) { /* dumb test */
        gettimeofday(&starttime, NULL);
        for(t=0; t<asize; t++) {
            b[t]=a[t];
        }
        gettimeofday(&endtime, NULL);
    }

    te=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;

    return te;
}

/* ------------------------------------------------------ */

/* pretty print worker's output in human-readable terms */
/* te: elapsed time in seconds
 * mt: amount of transferred data in MiB
 * type: see 'worker' above
 *
 * return value: -
 */
void printout(double te, double mt, int type)
{
    switch(type) {
        case TEST_MEMCPY:
            printf("Method: MEMCPY\t");
            break;
        case TEST_DUMB:
            printf("Method: DUMB\t");
            break;
        case TEST_MCBLOCK:
            printf("Method: MCBLOCK\t");
            break;
    }
    printf("Elapsed: %.5f\t", te);
    printf("MiB: %.5f\t", mt);
    printf("Copy: %.3f MiB/s\n", mt/te);
    return;
}

/* ------------------------------------------------------ */

int main1(int argc, char **argv)
{
    unsigned int long_size=0;
    double te, te_sum; /* time elapsed */
    unsigned long long asize=0; /* array size (elements in array) */
    int i;
    long *a, *b; /* the two arrays to be copied from/to */
    int o; /* getopt options */
    unsigned long testno;

    /* options */

    /* how many runs to average? */
    int nr_loops=DEFAULT_NR_LOOPS;
    /* fixed memcpy block size for -t2 */
    unsigned long long block_size=DEFAULT_BLOCK_SIZE;
    /* show average, -a */
    int showavg=1;
    /* what tests to run (-t x) */
    int tests[MAX_TESTS];
    double mt=0; /* MiBytes transferred == array size in MiB */
    int quiet=0; /* suppress extra messages */

    tests[0]=0;
    tests[1]=0;
    tests[2]=0;

    while((o=getopt(argc, argv, "haqn:t:b:")) != EOF) {
        switch(o) {
            case 'h':
                usage();
                exit(1);
                break;
            case 'a': /* suppress printing average */
                showavg=0;
                break;
            case 'n': /* no. loops */
                nr_loops=strtoul(optarg, (char **)NULL, 10);
                break;
            case 't': /* test to run */
                testno=strtoul(optarg, (char **)NULL, 10);
                if(testno>MAX_TESTS-1) {
                    printf("Error: test number must be between 0 and %d\n", MAX_TESTS-1);
                    exit(1);
                }
                tests[testno]=1;
                break;
            case 'b': /* block size in bytes*/
                block_size=strtoull(optarg, (char **)NULL, 10);
                if(0>=block_size) {
                    printf("Error: what block size do you mean?\n");
                    exit(1);
                }
                break;
            case 'q': /* quiet */
                quiet=1;
                break;
            default:
                break;
        }
    }

    /* default is to run all tests if no specific tests were requested */
    if( (tests[0]+tests[1]+tests[2]) == 0) {
        tests[0]=1;
        tests[1]=1;
        tests[2]=1;
    }

    if( nr_loops==0 && ((tests[0]+tests[1]+tests[2]) != 1) ) {
        printf("Error: nr_loops can be zero if only one test selected!\n");
        exit(1);
    }

    if(optind<argc) {
        mt=strtoul(argv[optind++], (char **)NULL, 10);
    } else {
        printf("Error: no array size given!\n");
        exit(1);
    }

    if(0>=mt) {
        printf("Error: array size wrong!\n");
        exit(1);
    }

    /* ------------------------------------------------------ */

    long_size=sizeof(long); /* the size of long on this platform */
    asize=1024*1024/long_size*mt; /* how many longs then in one array? */

    if(asize*long_size < block_size) {
        printf("Error: array size larger than block size (%llu bytes)!\n", block_size);
        exit(1);
    }

    if(!quiet) {
        printf("Long uses %d bytes. ", long_size);
        printf("Allocating 2*%lld elements = %lld bytes of memory.\n", asize, 2*asize*long_size);
        if(tests[2]) {
            printf("Using %lld bytes as blocks for memcpy block copy test.\n", block_size);
        }
    }

    a=make_array(asize);
    b=make_array(asize);

    /* ------------------------------------------------------ */
    if(!quiet) {
        printf("Getting down to business... Doing %d runs per test.\n", nr_loops);
    }

    /* run all tests requested, the proper number of times */
    for(testno=0; testno<MAX_TESTS; testno++) {
        te_sum=0;
        if(tests[testno]) {
            for (i=0; nr_loops==0 || i<nr_loops; i++) {
                te=worker(asize, a, b, testno, block_size);
                te_sum+=te;
                printf("%d\t", i);
                printout(te, mt, testno);
            }
            if(showavg) {
                printf("AVG\t");
                printout(te_sum/nr_loops, mt, testno);
            }
        }
    }

    free(a);
    free(b);
    return 0;
}


unsigned long get_a_rand( void )  
{                   
    int i;
    unsigned long out;
    unsigned int rand1,rand2;
    int retval;
   


    struct timeval currentv;
    retval = gettimeofday( &currentv, NULL );    
    if( retval != 0 ){
        printf( "get time err\n");
        return 1;
    }
    
    


    //printf( "currentv.tv_sec = %d\n", currentv.tv_sec);
    //printf( "currentv.tv_sec = %d\n", currentv.tv_usec);

    
    //srand( currentv.tv_usec );
    rand1 = rand();
    rand2 = rand();
    //printf( "rand1 = %x\n", rand1 );
    //printf( "rand2 = %x\n", rand2 );                     
    out = (((unsigned long)rand1)<<12) | (rand2 & 0xfff);     
    //printf( "out = %llx\n", out );
    //printf( "sizeof(out) = %llx\n", sizeof(out) );
}

struct mytest_device {
    //pthread_mutex_t lock; /* see note below on mutex acquisition order */
    struct listnode list_node;
    unsigned int value;
};

#define HASH_BITS_20  true
//#define HASH_BITS_22  true
//#define HASH_BITS_24  true
//#define HASH_BITS_26  true


#ifdef HASH_BITS_20
#define ENTRY_NUMS   (1024*1024*1)
#define TABLE_LEN    (1024*1024*1)
#define INDEX_OFFSET (24)
#define VALUE_MASK   (0xffffff)
#elif defined   HASH_BITS_22
#define ENTRY_NUMS   (1024*1024*4)
#define TABLE_LEN    (1024*1024*4)
#define INDEX_OFFSET (22)
#define VALUE_MASK   (0x3fffff)

#elif defined HASH_BITS_24
#define ENTRY_NUMS   (1024*1024*16)
#define TABLE_LEN    (1024*1024*16)
#define INDEX_OFFSET (20)
#define VALUE_MASK   (0xfffff)


#elif defined HASH_BITS_26
#define ENTRY_NUMS   (1024*1024*64)
#define TABLE_LEN    (1024*1024*64)
#define INDEX_OFFSET (18)
#define VALUE_MASK   (0x3ffff)

#else
#define ENTRY_NUMS   (1024*1024*1)
#define TABLE_LEN    (1024*1024*1)
#define INDEX_OFFSET (24)
#define VALUE_MASK   (0xffffff)

#endif

void creat_hash_table(unsigned long int *table)
{     
    unsigned long rand_num;
    unsigned int table_index,table_value,clash_cnt;
    int i;
    struct listnode* list_node;
    struct listnode* head_list_node;
    struct listnode *node;
    struct mytest_device *test_device;
    clash_cnt = 0x00;        
    for( i=0x00; i<ENTRY_NUMS; i++ ){
            repeat_creat:    
         rand_num = get_a_rand();  
         //rand_num = test_rand[i];
         //printf( "rand_num = %11lx\n", rand_num );
         table_index = rand_num >> INDEX_OFFSET;
         //printf( "table_index = %x\n", table_index );
         table_value = rand_num & VALUE_MASK;
         //printf( "table_value = %x\n", table_value );
         if( table[table_index] == 0x00 ){
             test_device = (struct mytest_device*)malloc(sizeof(struct mytest_device));
             //list_node = (struct listnode*)malloc(sizeof(struct mytest_device));    

             list_node = &test_device->list_node;
             list_init(list_node);
             test_device->value = table_value;
             table[table_index] = (unsigned long int)test_device;
             //printf("list_node = %p.\n", list_node);
         }else{
             clash_cnt = clash_cnt + 1;
             test_device = (struct mytest_device*)table[table_index];
             head_list_node = (struct listnode*)&test_device->list_node;
             if( test_device->value == table_value ){
                  //printf( "hash cyt1\n" );
                  goto repeat_creat;
             }
             list_for_each(node,head_list_node){
                //printf( "node->value = %x\n", node->value );
                test_device = (struct mytest_device *)node_to_item(node, struct mytest_device, list_node);
                if( test_device->value == table_value ){
                    //printf( "hash cyt2\n" );
                    goto repeat_creat;
                }
             }
             test_device = (struct mytest_device*)malloc(sizeof(struct mytest_device));
             list_node = &test_device->list_node;
             list_init(list_node);
             test_device->value = table_value;  
             list_add_tail(head_list_node, list_node);
             //break;
          }
    }
    //printf( "i = %x\n", i );
    


    

}

void destroy_hash_table( unsigned long int *table )     
{                                        
    int i;
    struct listnode *head_list_node;    
    struct listnode *node, *n;        
    struct mytest_device *test_device;
    int free_cnt;

    free_cnt = 0x00;
    for( i=0x00; i<ENTRY_NUMS; i++ ){
         if( table[i] == 0x00 ){
             continue;
         }else{
             test_device = (struct mytest_device*)table[i];
             head_list_node = &test_device->list_node;
             list_for_each_safe(node, n, head_list_node){
                test_device = (struct mytest_device *)node_to_item(node, struct mytest_device, list_node);
                 list_remove(node);
                 if( test_device ){
                     free(test_device);
                     free_cnt++;
                     test_device = NULL;
                 }
             }
             table[i] = 0x00; 
             test_device = (struct mytest_device *)node_to_item(head_list_node, struct mytest_device, list_node);
             if( test_device ){
                 free(test_device);          
                 free_cnt++;
                 test_device = NULL;
             }
         }
    }
    //printf( "free_cnt = %x\n", free_cnt );
    
    free(table);   
}

void insert_a_record( unsigned long int *table, unsigned int table_index, unsigned int table_value ) 
{       
    struct listnode* list_node;
    struct listnode* head_list_node;
    struct mytest_device *test_device;

    test_device = (struct mytest_device*)table[table_index];
    head_list_node = &test_device->list_node;
             
    
    if( table[table_index] == 0x00 ){
        test_device = (struct mytest_device*)malloc(sizeof(struct mytest_device));
        list_node = &test_device->list_node;
        list_init(list_node);
        test_device->value = table_value;
        table[table_index] = (unsigned long int)test_device;
    }else{
        test_device = (struct mytest_device*)malloc(sizeof(struct mytest_device));
        list_node = &test_device->list_node;
        list_init(list_node);
        test_device->value = table_value;  
        list_add_tail(head_list_node, list_node);
    }
}          

int g_last_dump_entry = 0x00;

void dump_a_table( unsigned long int *table )          
{                    
    int i;
    struct listnode* head_list_node;
    struct listnode* node;
    struct mytest_device *test_device;
    
    
    for( i=0x00; i<ENTRY_NUMS; i++ ){
         if( table[i] == 0x00 ){
             continue;
         }else{
             test_device = (struct mytest_device*)table[i];

             printf( "record test_device = 0x%p\n", test_device );
             
             head_list_node = &test_device->list_node;
             g_last_dump_entry = i;
             printf( "record num = 0x%x\n", i );
             printf( "head_list_node->value = %x\n", test_device->value );     
             list_for_each(node,head_list_node){
                  test_device = (struct mytest_device *)node_to_item(node, struct mytest_device, list_node);
                 printf( "node->value = %x\n", test_device->value );            
             }
             printf( "\n");
         }
    }
}


void dump_a_table_entry( unsigned long int *table, int index )          
{                    
    struct listnode* head_list_node;
    struct listnode* node;    
    struct mytest_device *test_device;
    if( table[index] == 0x00 ){
        printf( "entry is empty\n");
    }else{
        test_device = (struct mytest_device*)table[index];
        head_list_node = &test_device->list_node;
    
        printf( "record num = 0x%x\n", index );
        printf( "head_list_node->value = %x\n", test_device->value );     
        list_for_each(node, head_list_node){
            test_device = (struct mytest_device *)node_to_item(node, struct mytest_device, list_node);
            printf( "node->value = %x\n", test_device->value );            
        }
        printf( "\n");
    }
}


int match_a_entry( unsigned long int *tableA, int table_index, unsigned int table_value, unsigned long int *tableC )
{       
    struct mytest_device *test_deviceA;
    struct mytest_device *test_deviceA_N;
    struct listnode *head_list_nodeA;    
    struct listnode *nodeA;
    struct listnode *nodeA_N;
    int match;
    match = 0x00;
    if( tableA[table_index] ){                          
        test_deviceA = (struct mytest_device *)tableA[table_index];
        head_list_nodeA = &(test_deviceA->list_node);
        if( test_deviceA->value == table_value ){     
            insert_a_record(tableC, table_index, table_value );
            if( list_empty(head_list_nodeA) ){
                //printf( "list_empty = %p\n", head_list_nodeA ); 
                tableA[table_index] = 0x00;
                if( test_deviceA ){
                    free(test_deviceA);
                    test_deviceA = NULL;
                }
            }else{
                
                test_deviceA = (struct mytest_device *)node_to_item(head_list_nodeA, struct mytest_device, list_node);
                //待删除的节点

                nodeA_N = head_list_nodeA->next;
                test_deviceA_N = (struct mytest_device *)node_to_item(nodeA_N, struct mytest_device, list_node);
                tableA[table_index] = (unsigned long int)test_deviceA_N;
                
                
                //printf("ready to rm a node: %p\n", test_deviceA );
                //printf("test_deviceA value: 0x%x\n", test_deviceA->value );
                //dump_a_table_entry( tableA, table_index);
                list_remove(head_list_nodeA);
                if( test_deviceA ){
                    free(test_deviceA);
                    test_deviceA = NULL;
                }
            }
            match = 0x01;
            return match;
        }
        list_for_each(nodeA,head_list_nodeA){
            test_deviceA = (struct mytest_device *)node_to_item(nodeA, struct mytest_device, list_node);
            if( test_deviceA->value == table_value ){
                //printf( "table_index = %x\n", table_index ); 
                //printf( "node->value = %x\n", node->value );
                //printf("\n");
                insert_a_record(tableC, table_index, table_value );
                list_remove(nodeA);
                if( test_deviceA ){
                    free(test_deviceA);
                    test_deviceA = NULL;
                }
                match = 0x02;
                break;
            }
        }
    }
    return match;
}


int main_test( void *arg )
{    
    unsigned long int *tableA;
    unsigned long int *tableB;
    unsigned long int *tableC;
    unsigned int table_index,table_value;
    int i;
    struct listnode* head_list_nodeB;
    struct listnode *nodeB;    
    struct mytest_device *test_deviceB;
    int match;
    struct timeval starttime, endtime;
    double te;
                                                                                                             
    gettimeofday(&starttime, NULL);
    srand( (unsigned int)time(NULL) );             
    tableA = malloc(TABLE_LEN*8); 
    if( tableA == NULL ){
        printf("malloc failed!!!\n");
        return 1;
    }                                         
    memset( tableA, 0x00, TABLE_LEN*8 );
    creat_hash_table(tableA);
    //创建hash表A

    tableB = malloc(TABLE_LEN*8); 
    if( tableB == NULL ){
        printf("malloc failed!!!\n");
        return 1;
    }                                         
    memset( tableB, 0x00, TABLE_LEN*8 );
    creat_hash_table(tableB);
    //创建hash表B

    tableC = malloc(TABLE_LEN*8); 
    //printf("table = %p.\n", table);
    if( tableC == NULL ){
        printf("malloc failed!!!\n");
        return 1;
    }                                         
    memset( tableC, 0x00, TABLE_LEN*8 );
    //创建hash表C 存储A与B的交集

    gettimeofday(&endtime, NULL);
    te=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
    printf( "pid = %d, Elapsed creat rand: %.5f\n", getpid(), te );
    gettimeofday(&starttime, NULL);
    

    //B n A = C
    //A表中的匹配项被删除,B表中的匹配项没有删除
    //所有匹配记录存储于C表中
    for( table_index=0x00; table_index<TABLE_LEN; table_index++ ){
         if( tableB[table_index] == 0x00 ){
             continue;
         }else{  
             test_deviceB = (struct mytest_device*)tableB[table_index];
             head_list_nodeB = &test_deviceB->list_node;
             table_value = test_deviceB->value;  
             if( list_empty(head_list_nodeB) ){       
                 match = match_a_entry( tableA, table_index, table_value, tableC );
                 continue;
             }else{
                 match = match_a_entry( tableA, table_index, table_value, tableC );
                 if( match ){
                     continue;
                 } 
                 list_for_each(nodeB, head_list_nodeB){ 
                     test_deviceB = (struct mytest_device *)node_to_item(nodeB, struct mytest_device, list_node);
                     table_value = test_deviceB->value;  
                     match = match_a_entry( tableA, table_index, table_value, tableC );
                     if( match ){
                         break;
                     }
                 }
             }
       }
         
    }

    gettimeofday(&endtime, NULL);
    te=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
    printf( "pid = %d, Elapsed calc over: %.5f\n", getpid(), te );
    gettimeofday(&starttime, NULL);

    //printf("dump table 3:\n");
    //g_last_dump_entry = 0x00;
    //dump_a_table(tableC);


    #if 0
    for( i=0x00; i<1024*1024; i++ ){

         if(tableC[i]==0x00){
            continue;
         }
         //printf("dump table 1:\n");
         //dump_a_table_entry( tableA, i);
    }
    #endif
    
    destroy_hash_table(tableA);
    destroy_hash_table(tableB);
    destroy_hash_table(tableC);
    
    
    gettimeofday(&endtime, NULL);
    te=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
    printf( "pid = %d, del rand: %.5f\n", getpid(), te );
}


unsigned long test_rand[32] = {
    0x0112233,
    0x1112244,
    0x2112255,
    0x2112266,
    0x2112277,
    0x2112288,
    0x2112299,
    0x2112256,
};


void test_creat_hash_table(unsigned long int *table)
{     
    unsigned long rand_num;
    unsigned int table_index,table_value,clash_cnt;
    int i;
    struct listnode* list_node;
    struct listnode* head_list_node;
    struct listnode *node;
    struct mytest_device *test_device;
    clash_cnt = 0x00;        
    for( i=0x00; i<8; i++ ){
            repeat_creat:    
         //rand_num = get_a_rand();
         rand_num = test_rand[i];
         //printf( "rand_num = %11lx\n", rand_num );
         table_index = rand_num >> 24;
         //printf( "table_index = %x\n", table_index );
         table_value = rand_num & 0xffffff;
         //printf( "table_value = %x\n", table_value );
         if( table[table_index] == 0x00 ){
             test_device = (struct mytest_device*)malloc(sizeof(struct mytest_device));
             //list_node = (struct listnode*)malloc(sizeof(struct mytest_device));    

             list_node = &test_device->list_node;
             list_init(list_node);
             test_device->value = table_value;
             table[table_index] = (unsigned long int)test_device;
             //printf("list_node = %p.\n", list_node);
         }else{
             clash_cnt = clash_cnt + 1;
             test_device = (struct mytest_device*)table[table_index];
             head_list_node = (struct listnode*)&test_device->list_node;
             if( test_device->value == table_value ){
                  //printf( "hash cyt1\n" );
                  goto repeat_creat;
             }
             list_for_each(node,head_list_node){
                //printf( "node->value = %x\n", node->value );
                test_device = (struct mytest_device *)node_to_item(node, struct mytest_device, list_node);
                if( test_device->value == table_value ){
                    //printf( "hash cyt2\n" );
                    goto repeat_creat;
                }
             }
             test_device = (struct mytest_device*)malloc(sizeof(struct mytest_device));
             list_node = &test_device->list_node;
             list_init(list_node);
             test_device->value = table_value;  
             list_add_tail(head_list_node, list_node);
             //break;
          }
    }
    //printf( "i = %x\n", i );
    


    

}  

typedef int (* func_pointer)(void *arg);


int do_create_thread(func_pointer thread_func, void *arg)
{   
    int Threaderr, ret;
    pthread_attr_t attr;
    pthread_t tmp_thread_id;
    pthread_attr_init (&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    Threaderr = pthread_create( &tmp_thread_id, NULL, (void *(*)(void *))thread_func, arg );
    ret = pthread_detach( tmp_thread_id );
    if( Threaderr != 0 ){
        printf("pthread_create error.\n");
    }
    return tmp_thread_id;
    //当线程为joinable时,使用pthread_join来获取线程返回值,并释放资源
    //当线程为非joinable时,也可在线程中调用 pthread_detach(pthread_self())来分离自己
}

void print_exit(void )
{
    printf("tuichu!!!\n");

}


int thread_test( void *arg )
{    
    //在线程里面fork比较容易受控制
    pid_t pid; 
    pid = fork(); 
    if( pid == 0 ){  
        main_test(0);
    }
}

int main( int argc, char **argv )
{
    int i;
    unsigned long int *tableA;
    int arg[8];

    for( i=0x00; i<8; i++ ){
         do_create_thread(thread_test, &arg[i]); 
    }
     
    printf("1main exit!!!\n");
    while(1){
      sleep(1);
    }

}

//scp -r  xxx@192.168.0.107:/home/xxx/mbw/* ./


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值