我们有一个表存储了一些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
法律声明:未经许可,任何模仿本站模板、转载本站内容等行为者,本站保留追究其法律责任的权利! 隐私权政策声明