【问题标题】:Implementing a functional/persistent dictionary data structure实现功能/持久字典数据结构
【发布时间】:2012-04-21 14:06:25
【问题描述】:

我正在尝试在 C 中实现一个函数式字典。实现函数式列表或 b 树相当容易,但我几乎找不到任何关于字典/关联数组的引用。

我查看了 erlang 的 dict 实现 - 在源代码中他们参考了这篇论文:
The Design and Implementation of Dynamic Hashing for Sets and Tables in Icon

如果有人能简要解释一下 erlang 的方法或解决此问题的其他方法,那就太好了。

【问题讨论】:

    标签: c data-structures functional-programming


    【解决方案1】:

    在 C 中实现持久数据结构的工作方式与在函数式语言中的实现方式基本相同。 Chris Okasaki 的 Purely Functional Data Structures 是一个很好的参考。

    一般来说,将固定宽度的整数映射到对象就足够了,因为 虽然这本身并不能给你一个完整的字典,但你可以在上面构建一个字典:使用实际键的哈希作为底层映射的键,并让叶子指向 (key, value ) 对相同的哈希值。

    棘手的部分是内存管理,因为您通常不知道数据结构的某些部分何时变得无法访问。幸运的是,由于大多数持久数据结构都是基于树的,所以引用计数通常效果很好。为了能够管理数据结构引用的对象,您可以为当叶节点的引用计数变为 0 时调用的回调提供挂钩。

    例如,我的位图Patricia Trees 的 C 实现提供了以下 API:

    // Querying
    void *bpt_get(bpt_t bpt, bpt_key_t key);
    bool bpt_has_key(bpt_t bpt, bpt_key_t key);
    
    // Adding and Removing Entries
    bpt_t bpt_assoc(bpt_t bpt, bpt_key_t key, void *item);
    bpt_t bpt_dissoc(bpt_t bpt, bpt_key_t key);
    
    // Managing Memory
    void bpt_retain(bpt_t bpt);
    void bpt_release(bpt_t bpt);
    void bpt_dealloc(bpt_t bpt);
    void bpt_set_dealloc_hook(bpt_t bpt,
                              bpt_key_t key,
                              void (*hook)(bpt_key_t key,
                                           void* value));
    
    // Iteration
    void bpt_for_mappings(bpt_t bpt,
                          void (*thunk)(bpt_key_t, void*, void*),
                          void *user_data);
    
    // Making a Map Persistent (you can elide this if you don't
    // want to support transients)
    void bpt_seal(bpt_t bpt);
    

    implementation 也可能会给你一些想法。

    【讨论】:

    • 感谢您的回复!内存管理不是我的问题——我已经使用引用计数编写了一个树实现。我正在寻找的是一个功能字典实现 - 一种具有恒定查找时间的数据结构。树通常只给出对数查找复杂度。我在冈崎的论文中也找不到任何对字典的引用。
    • @mirkok 如果查找时间是唯一重要的事情,您当然可以简单地使用哈希表并在每次更新时复制它。这总是一个权衡。也就是说,可以通过使用位图在这方面调整尝试(我的实现可以;Clojure 的 PersistentHashMap 可以;其他人可能也可以)。使用位图,访问仍然是对数的,但基数更大。这(理论上,但在实践中并不总是)增加了复制开销,但减少了到达叶子所需的跳数。 (对于 32 位位图,2^32 个键对应最多 7 个级别。)
    猜你喜欢
    • 1970-01-01
    • 2014-07-16
    • 2012-04-18
    • 2018-12-31
    • 1970-01-01
    • 2013-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多