openssl lhash 数据结构哈希表

哈希表是一种数据结构,通过在记录的存储位置和它的关键字之间建立确定的对应关系,来快速查询表中的数据;

openssl lhash.h 为我们提供了哈希表OPENSSL_LHASH 的相关接口,我们可以直接使用,用来存放各种数据;

哈希表类似前面提到的栈,但是哈希表的优势是查询速度快。

1. lhash.h 提供的哈希表主要接口有

//创建哈希表,参数为两个回调函数,分别可自定义哈希值计算方法,排序方法
OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c);

//释放哈希表内存,但是不释放表中数据的内存,需要调用下面的doall方法遍历表中数据去释放
void OPENSSL_LH_free(OPENSSL_LHASH *lh);

//在表中插入一条记录,当表中有该数据时,会进行替换,成功返回插入的数据地址
void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data);

//从表中删除一条记录,成功返回删除的该数据地址
void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data);

//从表中查询一条记录,参数为要查询数据的地址,成功返回表中该数据的地址
void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data);

//遍历表中的数据记录,回调函数可处理遍历每条记录
void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func);

//遍历表中的数据记录,多了一个arg参数,可看下面的测试
void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNCARG func, void *arg);

//计算一条数据的哈希值 unsigned
long OPENSSL_LH_strhash(const char *c);

//哈希表中元素个数 unsigned
long OPENSSL_LH_num_items(const OPENSSL_LHASH *lh);

//查看哈希表的状态,输出到FILE
void OPENSSL_LH_stats(const OPENSSL_LHASH *lh, FILE *fp);

//查看哈希表节点的状态,输出到FILE
void OPENSSL_LH_node_stats(const OPENSSL_LHASH *lh, FILE *fp);

//查看哈希表节点的使用状态,输出到FILE
void OPENSSL_LH_node_usage_stats(const OPENSSL_LHASH *lh, FILE *fp);
//以下接口为哈希表状态,输出到BIO
void OPENSSL_LH_stats_bio(const OPENSSL_LHASH *lh, BIO *out); void OPENSSL_LH_node_stats_bio(const OPENSSL_LHASH *lh, BIO *out); void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH *lh, BIO *out);

2. 测试代码

   

unsigned long hashff(void *hf)
{
    printf("%s\n",hf);
    return 100;
}

int hashfCmp(int  *a,int  *b)
{
    return *a > *b;
    
}

void printArg(int *a,char *b)
{
    printf("doall_arg: %d  %s\n",*a,b);
}

void printValue(int *value)
{
    printf("doall: %d\n",*value);
}


int main(int argc, const char * argv[]) {
    
    
    OPENSSL_LHASH *lh = OPENSSL_LH_new(NULL, NULL);
    
    int item = 1;
    OPENSSL_LH_insert(lh, &item);
    
    
    int item2 = 10;
    OPENSSL_LH_insert(lh, &item2);
    
    int item3 = 5;
    OPENSSL_LH_insert(lh, &item3);
    
    
    //因为表中已经存在数据5,如果再插入,将会替换之前的数据5
    int item4 = 5;
    int *ret=0;
    ret = OPENSSL_LH_insert(lh, &item4);
    if (*ret==item4) {
        printf("insert replace PASS\n");
    }
    
    
    int *fd = 0;
    fd = OPENSSL_LH_retrieve(lh,&item2);
    if (*fd == item2) {
        printf("find value PASS\n");
    }
    
    OPENSSL_LH_doall(lh, printValue);
    OPENSSL_LH_doall_arg(lh, printArg, "arg");
    
    
    int *delRet = 0;
    delRet = OPENSSL_LH_delete(lh, &item4);
    if (*delRet==item4) {
        printf("delete value PASS\n");
    }
    
    
    int numLen = OPENSSL_LH_num_items(lh);
    printf("len=%d\n");
    
    
    OPENSSL_LH_stats(lh, stdout);
    
    
    OPENSSL_LH_free(lh);
    
    
    
    return 0;
}

 输出日志

insert replace PASS
find value PASS
doall: 10
doall: 1
doall: 5
doall_arg: 10  arg
doall_arg: 1  arg
doall_arg: 5  arg
delete value PASS
len=73832
num_items             = 2
num_nodes             = 8
num_alloc_nodes       = 16
num_expands           = 0
num_expand_reallocs   = 0
num_contracts         = 0
num_contract_reallocs = 0
num_hash_calls        = 6
num_comp_calls        = 3
num_insert            = 3
num_replace           = 1
num_delete            = 1
num_no_delete         = 0
num_retrieve          = 1
num_retrieve_miss     = 0
num_hash_comps        = 6
Program ended with exit code: 0
View Code

 

测试使用 openssl 1.1.0c

参考:https://www.openssl.org/docs/man1.0.2/crypto/lhash.html

 

posted @ 2016-12-07 14:34  cocoajin  阅读(1450)  评论(0编辑  收藏  举报