#include "fielddb/meta.h"
#include "util/coding.h"
#include <string>
#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);
}
}