2012-04-21 66 views

回答

6

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

一般来说,将固定宽度的整数映射到对象就足够了,因为 虽然没有为您提供完整的字典本身,但您可以在顶部创建一个字典:使用实际密钥的散列作为基础地图的关键字,并让叶指向相同散列值的(键,值)对的列表。

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

例如,我的C位实现Patricia Trees提供了以下内容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可能会给你一些想法了。

+0

感谢您的回应!内存管理不是我的问题 - 我已经使用引用计数编写了一个树实现。 我正在寻找的是一个功能字典实现 - 一个具有不断查询时间的数据结构。树通常只给对数查找复杂度。 我在冈崎的论文中也找不到任何对辞典的参考。 – mirkokiefer 2012-04-22 12:07:22

+0

@mirkok如果查找时间是唯一重要的事情,那么当然,您可以简单地使用散列表并在每次更新时复制它。这总是一个折衷。也就是说,可以通过使用位图来调整尝试(我的实现可以; Clojure的PersistentHashMap可以;其他人可能也会这样做)。通过位图,访问仍为对数,但基数较大。这(从理论上讲,但并不总是在实践中)增加了复制开销,但是减少了跳到叶子所需的跳数。 (对于32位位图,2^32个键对应最多7个级别。) – 2012-04-22 13:15:18