#include "fielddb/meta.h" #include "util/coding.h" #include #include "leveldb/options.h" #include "leveldb/slice.h" #include "leveldb/write_batch.h" namespace fielddb { using namespace leveldb; // Slice MetaKV::metaKey() { // std::string buf; // PutLengthPrefixedSlice(&buf, Key); // PutFixed64(&buf, meta_seq); // PutFixed32(&buf, tag); // return Slice(buf); // } // Slice MetaKV::metaValue() { // return Slice(SerializeValue(Fields)); // } //对于含有index field的put/delete的meta编码为 (KV|Key,Value) void MetaKV::TransPut(std::string &MetaKey,std::string &MetaValue) { MetaKey.clear(); MetaValue.clear(); //这里的改动是为了防止潜在的段错误。原来的写法中,slice(buf)对应的buf是局部的,在函数返回后,buf被销毁 //但是slice中的指针指向的是析构的string对象的部分内存 std::string &buf = MetaKey; PutFixed32(&buf, KV_Creating); PutLengthPrefixedSlice(&buf, Slice(name)); // MetaKey = Slice(buf); // MetaValue = Slice(*value); } void MetaKV::TransDelete(std::string &MetaKey) { MetaKey.clear(); std::string &buf = MetaKey; PutFixed32(&buf, KV_Deleting); PutLengthPrefixedSlice(&buf, Slice(name)); // MetaKey = Slice(buf); } class CleanerHandler : public WriteBatch::Handler { public: WriteBatch *NeedClean; void Put(const Slice& key, const Slice& value) override { //将所有之前put的meta数据进行delete NeedClean->Delete(key); } void Delete(const Slice& key) override { //所有的传入的MetaBatch都是Put的 assert(0); } }; void MetaCleaner::Collect(WriteBatch &MetaBatch) { if(MetaBatch.ApproximateSize() <= 12) return; CleanerHandler Handler; Handler.NeedClean = &NeedClean; MetaBatch.Iterate(&Handler); } void MetaCleaner::CleanMetaBatch(DB *metaDB) { if(NeedClean.ApproximateSize() <= 12) return; metaDB->Write(WriteOptions(), &NeedClean); } }