zoukankan      html  css  js  c++  java
  • 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
    ",hf);
        return 100;
    }
    
    int hashfCmp(int  *a,int  *b)
    {
        return *a > *b;
        
    }
    
    void printArg(int *a,char *b)
    {
        printf("doall_arg: %d  %s
    ",*a,b);
    }
    
    void printValue(int *value)
    {
        printf("doall: %d
    ",*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
    ");
        }
        
        
        int *fd = 0;
        fd = OPENSSL_LH_retrieve(lh,&item2);
        if (*fd == item2) {
            printf("find value PASS
    ");
        }
        
        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
    ");
        }
        
        
        int numLen = OPENSSL_LH_num_items(lh);
        printf("len=%d
    ");
        
        
        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

  • 相关阅读:
    Python注释及变量
    MySQL期末测试
    SQL查询第三次训练(重点关照对象)
    MySQL内置函数
    聚类-kmeans
    《达.芬奇密码》丹-布朗
    皮克定理与证明
    常见设计模式的种类与一些原则
    时间序列(二)分解、各部分计算方法
    ADF检验
  • 原文地址:https://www.cnblogs.com/cocoajin/p/6141079.html
Copyright © 2011-2022 走看看