内存中的树实例同步持久化的实现

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

在开发中,可能会有这样的需求: 需要在内存中维护一颗树,并且该树可以同步的持久化。

此文给出一种简单的解决思路。使用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层的无非就是读库写库,此处不再赘述:

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值