我们有一个表存储了一些Record,我们使用MemTable表示在内存中的表,DiskTable表示在硬盘上的表。

struct MemTable {
char* buf;
size_t len;
};
struct DiskTable {
char* filename;
};
DataReader是一个中间层,可以顺序读取内存表的Record和磁盘表的Record。
class DataReader {
public:
int Init(const MemTable& memtable);
int Init(const char* filename);
int GetOneRecord(Record* record);
};
DataMerge做实际的Merge工作,有三个Init函数。
class DataMerger {
public:
void Init(MemTable& m1, MemTable& m2);
void Init(DiskTable& f1, DiskTable& f2);
void Init(MemTable& m, MemTable& f);
int DoMerge();
private:
enum MergeType{MEM_TO_MEM, DISK_TO_DISK, FILE_TO_FILE};
int MergeMemoryMemory();
int MergeDiskDisk();
int MergeMemoryDisk();
};
上面的设计是一个非常糟糕的设计
一种很好的设计模式是:使用Iterator设计模式可以让代码变得非常容易维护
Iteartor模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
对于上面提到的三点我们分别进行处理
class Iterator {
public:
virtual bool Valid() const = 0;
virtual void SeekToFirst() const = 0;
virtual void Next() = 0;
virtual const Record& GetRecord() = 0;
};
class MemTable {
public:
// 由MemTable生成Iterator,来做具体的数据读取工作
// 去掉DataReader 类
Iterator* NewIterator() const;
// 其他的数据操作
// Append Delete Find
private:
// 这时我们已经不关注MemTable的具体实现方式了
char* buf;
size_t len;
};
class DiskTable {
public:
// 由DiskTable管理具体的数据读取工作,去掉DataReader类
Iterator* NewIterator() const;
int Init(char* filename);
private:
char* filename;
};
// 这里我们去掉了DataMerger类,数据的Merge操作全部完全不依赖于Table具体的实现方式
// 非常容易扩展,增加任意多的Table类型对Merge算法都没有影响
Iterator* NewMergingIterator(Iterator** list, int n);
|
评论加载中...
|
Copyright@ 2011-2017 版权所有:大连仟亿科技有限公司 辽ICP备11013762-1号 google网站地图 百度网站地图 网站地图
公司地址:大连市沙河口区中山路692号辰熙星海国际2215 客服电话:0411-39943997 QQ:2088827823 42286563
法律声明:未经许可,任何模仿本站模板、转载本站内容等行为者,本站保留追究其法律责任的权利! 隐私权政策声明