比较器 - Comparators
比较器 - Comparators
前面的例子使用了按照字典序的默认排序函数对key进行排序。然而,你也可以在打开一个数据库时为其提供一个自定义的比较器。例如,假设数据库的每个key由两个数字著称,我们应该先按照第一个数字排序,如果相等再按照第二个数字进行排序。首先,定义一个满足如下规则的leveldb::Conmparator的子类:
1. class TwoPartComparator : public leveldb::Comparator {2. public:3. // Three-way comparison function:4. // if a < b: negative result5. // if a > b: positive result6. // else: zero result7. int Compare(const leveldb::Slice& a, const leveldb::Slice& b) const {8. int a1, a2, b1, b2;9. ParseKey(a, &a1, &a2);10. ParseKey(b, &b1, &b2);11. if (a1 < b1) return -1;12. if (a1 > b1) return +1;13. if (a2 < b2) return -1;14. if (a2 > b2) return +1;15. return 0;16. }18. // Ignore the following methods for now:19. const char* Name() const { return "TwoPartComparator"; }20. void FindShortestSeparator(std::string*, const leveldb::Slice&) const { }21. void FindShortSuccessor(std::string*) const { }22. };
现在使用这个自定义的比较器创建数据库:
1. TwoPartComparator cmp;2. leveldb::DB* db;3. leveldb::Options options;4. options.create_if_missing = true;5. options.comparator = &cmp;6. leveldb::Status status = leveldb::DB::Open(options, "/tmp/testdb", &db);7. ...
向后兼容性 - Backwards compatibility
比较器的Name方法的返回值将会在数据库创建时与之绑定,并且在以后每次打开数据库的时候进行检查。如果name发生变化,那么leveldb::DB::Open将会调用失败。因此,只有在新的key格式及比较函数和现在的数据库不兼容时才需要修改name,同时所有现有的数据库数据将会被丢弃。
当然,你也可以通过预先的计划来逐步改变你的key格式。例如,你可以在每个key的末尾存储一个版本号(一个字节的应该可以满足大多数用途)。当希望使用一种新的key格式时(比如,给TwoPartComparator增加一个可选的第三块内容),(a) 保持 comparator的name不变,(b) 给新的key增加版本号,(c) 改变比较器函数,使得它可以通过key里的版本号来决定如何解释它们。
