• 「工具箱」Hash


    工具箱之哈希表。这个肯定会很常用了。这里主要说一下,对于哈希表的设计理念,以及具体的接口设计与实现。由于经验不丰富,这里肯定存在某些问题,因此,我只是站在现阶段自身的水平和需求上做考虑、实现,大家批判着看了。

    哈希表,核心在于生成、以及检索算法。这部分内容可以折腾得很复杂。哈希表又俗称「散列表」,即,将散列排布的对象,映射在有限的空间上,以达到存储空间和检索时间的折衷。很多前辈们也研究过,什么样的哈希算法,可以尽量好地完成上述「折衷」。我这里就不弄那么深入了,毕竟现阶段而言,我对性能的要求并不高。

    哈希生成的接口如下。

    typedef void *(*func_copy_value)(void *value);
    int hash_str_install(
    char *key, void *value, func_copy_value copy,
    struct hnode **installed,
    int modifiable
    );

    之所以是 hash_str 的前缀,是因为哈希的键值都是字符串。各个参数,基本都可以顾名思义。key->value 组合,value 值是指向 void * 型的指针,copy 函数用于重新申请内存、并存储值(避免作用域切换后,出现野指针),modifiable 参数较关键,下文再解释,安装成功后,存储在 installed 指针中。
    对于最后一个参数,即 modifiable 参数,多罗嗦两句。哈希表是通用的(只要键值是字符串),然而用途却不固定,可能某些应用里,哈希表允许被覆盖,某些则不可以被覆盖。故而,这里设定了一个「是否可以被修改」的标记。

    如果出错,如,试图覆盖一个不可以被覆盖的键值组合,或者内存分配失败,都会返回相应的负数值。

    哈希检索的接口如下。

    struct hnode *hash_str_lookup(char *key);

    这个很好理解,不多啰嗦了。

    最后,附上测试用例。这里用到了一个小型的「单元测试框架」。额,好吧。其实不算是框架,是今天写的一个很小型的、能够勉强用的基本测试模型(下一篇博客会介绍)。后续,还是要参考更高深的测试框架,看看牛人们是怎么做的。

    /*
    * test_hash_str.c
    *
    * Created on: 3 Dec 2010
    * Author: jtuki
    *
    * Usage:
    * void test_hash_str(void);
    */

    #include <string.h>
    #include "test_common.h"
    #include "../lib/hash_str.h"

    static int errorCount = 0;

    /*
    Use strdup as `func_copy_value', i.e. key->value is string->string.
    */
    static int test_hash_str_functions(void)
    {
    int error_orig = errorCount;

    char *keys[188] = {
    "p650095575.jpg", "p650095667.jpg", "p650096116.jpg", "p650556171.jpg",
    "p650096210.jpg", "p650096291.jpg", "p650098338.jpg", "p650098407.jpg",
    "p650098594.jpg", "p650098720.jpg", "p650098829.jpg", "p650100185.jpg",
    "p650100316.jpg", "p650100451.jpg", "p650100495.jpg", "p650100612.jpg",
    "p650101828.jpg", "p650101928.jpg", "p650101957.jpg", "p650102117.jpg",
    "p650102223.jpg", "p650103438.jpg", "p650103673.jpg", "p650103814.jpg",
    "p650104090.jpg", "p650104415.jpg", "p650107234.jpg", "p650107384.jpg",
    "p650107684.jpg", "p650107917.jpg", "p650108156.jpg", "p650109655.jpg",
    "p650109808.jpg", "p650109898.jpg", "p650110090.jpg", "p650110214.jpg",
    "p650113124.jpg", "p650113197.jpg", "p650113277.jpg", "p650113468.jpg",
    "p650113595.jpg", "p650138728.jpg", "p650138809.jpg", "p650138902.jpg",
    "p650138963.jpg", "p650139076.jpg", "p650140375.jpg", "p650140425.jpg",
    "p650140511.jpg", "p650140593.jpg", "p650140676.jpg", "p650141945.jpg",
    "p650142018.jpg", "p650142105.jpg", "p650142185.jpg", "p650142294.jpg",
    "p650144499.jpg", "p650144652.jpg", "p650144763.jpg", "p650144894.jpg",
    "p650144951.jpg", "p650147743.jpg", "p650147852.jpg", "p650147985.jpg",
    "p650148082.jpg", "p650148182.jpg", "p650149582.jpg", "p650149645.jpg",
    "p650149719.jpg", "p650149803.jpg", "p650149897.jpg", "p650152921.jpg",
    "p650152973.jpg", "p650153069.jpg", "p650153159.jpg", "p650153226.jpg",
    "p650154660.jpg", "p650154748.jpg", "p650154792.jpg", "p650154933.jpg",
    "p650155015.jpg", "p650155737.jpg", "p650155848.jpg", "p650155924.jpg",
    "p650156067.jpg", "p650156208.jpg", "p650156940.jpg", "p650157115.jpg",
    "p650157393.jpg", "p650157647.jpg", "p650157940.jpg", "p650158884.jpg",
    "p650159056.jpg", "p650159199.jpg", "p650159384.jpg", "p650159528.jpg",
    "p650160497.jpg", "p650160626.jpg", "p650161001.jpg", "p650161177.jpg",
    "p650161270.jpg", "p650542907.jpg", "p650542968.jpg", "p650543026.jpg",
    "p650543081.jpg", "p650543130.jpg", "p650543404.jpg", "p650543437.jpg",
    "p650543479.jpg", "p650543519.jpg", "p650543571.jpg", "p650544242.jpg",
    "p650544354.jpg", "p650544376.jpg", "p650544438.jpg", "p650544508.jpg",
    "p650545143.jpg", "p650545181.jpg", "p650545247.jpg", "p650545294.jpg",
    "p650545340.jpg", "p650547364.jpg", "p650547394.jpg", "p650547453.jpg",
    "p650547529.jpg", "p650547553.jpg", "p650548038.jpg", "p650548140.jpg",
    "p650548181.jpg", "p650548256.jpg", "p650548279.jpg", "p650548554.jpg",
    "p650548597.jpg", "p650548667.jpg", "p650548750.jpg", "p650548800.jpg",
    "p650549265.jpg", "p650549364.jpg", "p650549439.jpg", "p650549510.jpg",
    "p650549589.jpg", "p650550176.jpg", "p650550290.jpg", "p650550324.jpg",
    "p650550395.jpg", "p650550464.jpg", "p650550922.jpg", "p650551026.jpg",
    "p650551068.jpg", "p650551134.jpg", "p650551192.jpg", "p650551629.jpg",
    "p650551678.jpg", "p650551776.jpg", "p650551810.jpg", "p650551865.jpg",
    "p650552385.jpg", "p650552470.jpg", "p650552535.jpg", "p650552568.jpg",
    "p650552617.jpg", "p650553172.jpg", "p650553239.jpg", "p650553290.jpg",
    "p650553343.jpg", "p650553366.jpg", "p650553630.jpg", "p650553678.jpg",
    "p650553692.jpg", "p650553771.jpg", "p650553807.jpg", "p650554352.jpg",
    "p650554419.jpg", "p650554453.jpg", "p650554487.jpg", "p650554513.jpg",
    "p650554959.jpg", "p650555018.jpg", "p650555032.jpg", "p650555054.jpg",
    "p650555099.jpg", "p650555736.jpg", "p650555808.jpg", "p650555862.jpg",
    "p650555887.jpg", "p650555913.jpg", "p650556090.jpg", "p650556154.jpg"
    };
    char *values[188] = {
    "p650556171.jpg", "p650095575.jpg", "p650095667.jpg", "p650096116.jpg",
    "p650555887.jpg", "p650555913.jpg", "p650556090.jpg", "p650556154.jpg",
    "p650555099.jpg", "p650555736.jpg", "p650555808.jpg", "p650555862.jpg",
    "p650554959.jpg", "p650555018.jpg", "p650555032.jpg", "p650555054.jpg",
    "p650554419.jpg", "p650554453.jpg", "p650554487.jpg", "p650554513.jpg",
    "p650553692.jpg", "p650553771.jpg", "p650553807.jpg", "p650554352.jpg",
    "p650553343.jpg", "p650553366.jpg", "p650553630.jpg", "p650553678.jpg",
    "p650552617.jpg", "p650553172.jpg", "p650553239.jpg", "p650553290.jpg",
    "p650552385.jpg", "p650552470.jpg", "p650552535.jpg", "p650552568.jpg",
    "p650551678.jpg", "p650551776.jpg", "p650551810.jpg", "p650551865.jpg",
    "p650551068.jpg", "p650551134.jpg", "p650551192.jpg", "p650551629.jpg",
    "p650550395.jpg", "p650550464.jpg", "p650550922.jpg", "p650551026.jpg",
    "p650549589.jpg", "p650550176.jpg", "p650550290.jpg", "p650550324.jpg",
    "p650549265.jpg", "p650549364.jpg", "p650549439.jpg", "p650549510.jpg",
    "p650548597.jpg", "p650548667.jpg", "p650548750.jpg", "p650548800.jpg",
    "p650548181.jpg", "p650548256.jpg", "p650548279.jpg", "p650548554.jpg",
    "p650547529.jpg", "p650547553.jpg", "p650548038.jpg", "p650548140.jpg",
    "p650545340.jpg", "p650547364.jpg", "p650547394.jpg", "p650547453.jpg",
    "p650545143.jpg", "p650545181.jpg", "p650545247.jpg", "p650545294.jpg",
    "p650544354.jpg", "p650544376.jpg", "p650544438.jpg", "p650544508.jpg",
    "p650543479.jpg", "p650543519.jpg", "p650543571.jpg", "p650544242.jpg",
    "p650543081.jpg", "p650543130.jpg", "p650543404.jpg", "p650543437.jpg",
    "p650161270.jpg", "p650542907.jpg", "p650542968.jpg", "p650543026.jpg",
    "p650160497.jpg", "p650160626.jpg", "p650161001.jpg", "p650161177.jpg",
    "p650159056.jpg", "p650159199.jpg", "p650159384.jpg", "p650159528.jpg",
    "p650157393.jpg", "p650157647.jpg", "p650157940.jpg", "p650158884.jpg",
    "p650156067.jpg", "p650156208.jpg", "p650156940.jpg", "p650157115.jpg",
    "p650155015.jpg", "p650155737.jpg", "p650155848.jpg", "p650155924.jpg",
    "p650154660.jpg", "p650154748.jpg", "p650154792.jpg", "p650154933.jpg",
    "p650152973.jpg", "p650153069.jpg", "p650153159.jpg", "p650153226.jpg",
    "p650149719.jpg", "p650149803.jpg", "p650149897.jpg", "p650152921.jpg",
    "p650148082.jpg", "p650148182.jpg", "p650149582.jpg", "p650149645.jpg",
    "p650144951.jpg", "p650147743.jpg", "p650147852.jpg", "p650147985.jpg",
    "p650144499.jpg", "p650144652.jpg", "p650144763.jpg", "p650144894.jpg",
    "p650142018.jpg", "p650142105.jpg", "p650142185.jpg", "p650142294.jpg",
    "p650140511.jpg", "p650140593.jpg", "p650140676.jpg", "p650141945.jpg",
    "p650138963.jpg", "p650139076.jpg", "p650140375.jpg", "p650140425.jpg",
    "p650113595.jpg", "p650138728.jpg", "p650138809.jpg", "p650138902.jpg",
    "p650113124.jpg", "p650113197.jpg", "p650113277.jpg", "p650113468.jpg",
    "p650109808.jpg", "p650109898.jpg", "p650110090.jpg", "p650110214.jpg",
    "p650107684.jpg", "p650107917.jpg", "p650108156.jpg", "p650109655.jpg",
    "p650104090.jpg", "p650104415.jpg", "p650107234.jpg", "p650107384.jpg",
    "p650102223.jpg", "p650103438.jpg", "p650103673.jpg", "p650103814.jpg",
    "p650101828.jpg", "p650101928.jpg", "p650101957.jpg", "p650102117.jpg",
    "p650100316.jpg", "p650100451.jpg", "p650100495.jpg", "p650100612.jpg",
    "p650098594.jpg", "p650098720.jpg", "p650098829.jpg", "p650100185.jpg",
    "p650096210.jpg", "p650096291.jpg", "p650098338.jpg", "p650098407.jpg"
    };
    struct hnode *np[188];

    int i;
    for (i = 0; i < 188; i++)
    // Modifiable.
    assertTrue(
    hash_str_install(keys[i], values[i],
    (void * (*)(void *)) strdup, &np[i], True) == 0
    );
    for (i = 0; i < 188; i++) {
    assertEqual(hash_str_lookup(keys[i]), np[i]);
    assertTrue(strcmp((char*)(np[i]->value), values[i]) == 0);
    }

    return (error_orig == errorCount) ? True:False;
    }

    int test_hash_str_modifiability(void)
    {
    int error_orig = errorCount;
    struct hnode *node;
    int ret;

    hash_str_install("key_foobar", "value_foobar",
    (void * (*)(void *)) strdup, &node, False);
    ret = hash_str_install("key_foobar", "value_foobar1",
    (void * (*)(void *)) strdup, &node, False);
    assertEqual(ret, -1);

    return (error_orig == errorCount) ? True:False;
    }

    void test_hash_str(void)
    {
    run(test_hash_str_functions);
    run(test_hash_str_modifiability);
    TestResult();
    }

    最后,感谢豆瓣上《哆啦A梦之工具箱图鉴》相册,为我提供了上述测试用例中,用于哈希的素材。并感谢创造了哆啦A梦的藤子不二雄,你创造的形象,是我(甚至是我们这一代人)很美好的回忆。

    - EOF -

  • 相关阅读:
    centos pptp client 配置
    hadoop hdfs 权限修改
    cdh Host Monitor 启动失败
    cdh yarn 启动失败
    hive 存储
    docker修改默认存储位置
    centos新增磁盘
    zookeeper服务部署数量
    实时人群计算——设想
    docker容器多服务——Supervisor
  • 原文地址:https://www.cnblogs.com/jtuki/p/toolbox_hash_str.html
Copyright © 2020-2023  润新知