在开发中,可能会有这样的需求: 需要在内存中维护一颗树,并且该树可以同步的持久化。
此文给出一种简单的解决思路。使用C#作为范例。
一般的持久化无非是写文件 或者数据库,本文采用MYSQL数据库。
对于每个节点,记录其父节点id。
表结构如下:
int id 主键
int parentid not null
XXXX 其他数据
内存中数据结构如下:
class Node{
Node parent;
List<Node> children;
XXXX 其他数据
}
所以最主要考虑的问题就是对树的应用以及其导致的持久化读写的时机。
对于应用程序来说,数据库层对其应是透明的。就是应用开发的程序员只需要使用树提供的相关接口,而不必理解其如何被持久。结构如下:

那么我们的程序在启动的时候就应该读入整颗树,以保证其是对数据库的映射。
每次对树的操作(通过树相关API),都应该修改树节点并同步持久(如何持久?这里涉及到效率问题。)
同时,我们的树应该还是支持多线程访问,那么多线程的情景下,持久又要如何进行?如何保证线程安全?
在我的实现中,树实例是由TreeNode链来维护的,没有一个诸如 Tree 的对象,而根节点维护在TreeManager中。
很多情况下,我们的“树实例”是一个树的集合(森林),而不是单独的一棵树,所以在TreeManager中我设置了一个虚拟的根节点,令所有树的根节点均作为虚拟根节点的叶子,统一管理整个森林。这很好理解。
由于树实例是唯一维护,所以我的TreeManager选择了singleton模式。(注意这里使用到安全的多线程singleton构建方法)
接下来就是对持久过程加互斥锁。
持久分为整体持久和部分持久,应该提供不同的方法(如修改一个叶子不用持久整棵树,而只需要持久该叶子节点即可),下文给出简单的整树持久和叶子持久的示例。
对于整颗树的持久过程,应该使用数据库事务,否则若在其中某叶子失败,而导致整个持久化数据混乱。
下面给出TreeManager主要代码,DB层的无非就是读库写库,此处不再赘述:

本文介绍了一种使用C#实现树结构数据在内存中维护并与MySQL数据库同步持久化的方法。通过构建树节点类Node及管理器TreeManager,实现了树的加载、更新等操作,确保了线程安全及数据一致性。
2966

被折叠的 条评论
为什么被折叠?



