log::Writer-levelDB源码解析


writer的工作就是将上层拼装好的数据,按照log format的格式,进行二次拼装,然后写进文件里面。

【数据成员介绍】

block_offset_:当前block的偏移位,通过它就能知道目前数据写到这一块的什么位置了;

dest_:增加记录,就是将数据追加到dest_;

type_crc_:因为每个record都会有一个header,而header里面就会有checksum,在调用这个类的构造函数的时候,就会预先将RecordType的crc生成好,然后保存在type_crc_;


【方法成员介绍】

Status Writer::AddRecord(const Slice& slice)

作用:将记录按照log format的方式组装,并刷到磁盘。

  Status Writer::AddRecord(const Slice& slice) {

     //获取数据的开始位置

    const char* ptr = slice.data();

    //数据的剩余大小

    size_t left = slice.size();

  

    

    Status s;

    //数据在这块中开始

    bool begin = true;

    do {

    //当前块的剩余大小

      const int leftover = kBlockSize - block_offset_;

      assert(leftover >= 0);

        //当块的剩余大小不足header的大小时,用\x00填充块剩余的空间,并重新开始一个新的block,block_offset_=0

      if (leftover < kHeaderSize) {

        if (leftover > 0) {

          // Fill the trailer (literal below relies on kHeaderSize being 7)

          assert(kHeaderSize == 7);

          dest_->Append(Slice("\x00\x00\x00\x00\x00\x00", leftover));

        }

        block_offset_ = 0;

      }

  

      assert(kBlockSize - block_offset_ - kHeaderSize >= 0);

  

      //当前块可用的大小

      const size_t avail = kBlockSize - block_offset_ - kHeaderSize;

      //数据在当前块中还要写的长度,或者说本次实际写入数据的长度

      const size_t fragment_length = (left < avail) ? left : avail;

  

      RecordType type;

      //如果数据在当前快还要写的长度==数据剩余还没写的长度,表示数据在该块结束;

      const bool end = (left == fragment_length);

        //数据在这块中开始,也在这块中结束,那么数据整个都在这块中,那么类型自然就是kFullType

      if (begin && end) {

        type = kFullType;

         //数据只是在这块中开始,并没有结束,那么数据整个都在这块中,那么类型自然就是kFirstType

      } else if (begin) {

        type = kFirstType;

         //数据只是在这块中结束,并没有开始,那么数据整个都在这块中,那么类型自然就是kLastType

      } else if (end) {

        type = kLastType;

       //数据在当前块即没有开始,也没有结束,那自然就是中间了kMiddleType

      } else {

        type = kMiddleType;

      }

  

      s = EmitPhysicalRecord(type, ptr, fragment_length);

      ptr += fragment_length;

      left -= fragment_length;

      begin = false;

    } while (s.ok() && left > 0);

    return s;

  }

这个方法的重点就是,始终把当前块当做参照物,注意当前block在record中的type和block_offset_就可以了;

每次写一个record,要么是把整个record写完,要么是把整个block写完。


Status Writer::EmitPhysicalRecord(RecordType t, const char* ptr, size_t n)

作用:根据本次写的数据,生成header,并将数据刷到磁盘上。

  Status Writer::EmitPhysicalRecord(RecordType t, const char* ptr, size_t n) {

    assert(n <= 0xffff);

    assert(block_offset_ + kHeaderSize + n <= kBlockSize);

  

    // 填充header

    char buf[kHeaderSize];

    //本次写入data的大小,即fragment_length,小端方式保存

    buf[4] = static_cast<char>(n & 0xff);

    buf[5] = static_cast<char>(n >> 8);

    //RecordType

    buf[6] = static_cast<char>(t);

  

    // 计算数据的crc

    uint32_t crc = crc32c::Extend(type_crc_[t], ptr, n);

    crc = crc32c::Mask(crc);  

    //将校验码插入header中

    EncodeFixed32(buf, crc);

  

    // 将header和数据追加到dest_,并写到磁盘

    Status s = dest_->Append(Slice(buf, kHeaderSize));

    if (s.ok()) {

      s = dest_->Append(Slice(ptr, n));

      if (s.ok()) {

        s = dest_->Flush();

      }

    }

    block_offset_ += kHeaderSize + n;

    return s;

  }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
leveldb实现解析 淘宝-核心系统研发-存储 那岩 neveray@gmail.com 2011-12-13 目录 一、 代码目录结构 ....................................................................... 1 1. doc/ ............................................................................ 1 2. include/leveldb/ ................................................................. 1 3. db/ ............................................................................. 1 4. table/........................................................................... 1 5. port/ ........................................................................... 1 6. util/ ........................................................................... 1 7. helper/memenv/ ................................................................... 1 二、 基本概念 .......................................................................... 1 1. Slice (include/leveldb/slice.h) .................................................. 1 2. Option (include/leveldb/option.h) .............................................. 2 3. Env (include/leveldb/env.h util/env_posix.h) .................................... 3 4. varint (util/coding.h) ........................................................... 3 5. ValueType (db/dbformat.h) ...................................................... 3 6. SequnceNnumber (db/dbformat.h) ................................................. 4 7. user key......................................................................... 4 8. ParsedInternalKey (db/dbformat.h) .............................................. 4 9. InternalKey (db/dbformat.h) ...................................................... 4 10. LookupKey (db/dbformat.h) ........................................................ 4 11. Comparator (include/leveldb/comparator.h util/comparator.cc) .................... 4 12. InternalKeyComparator (db/dbformat.h) ............................................ 5 13. WriteBatch (db/write_batch.cc) ................................................. 5 14. Memtable (db/memtable.cc db/skiplist.h) .......................................... 5 15. Sstable (table/table.cc) ......................................................... 5 16. FileMetaData (db/version_edit.h) ............................................... 5 17. block (table/block.cc) ........................................................... 6 18. BlockHandle(table/format.h) ...................................................... 6 19. FileNumber(db/dbformat.h) ...................................................... 6 20. filename (db/filename.cc) ........................................................ 6 21. level-n (db/version_set.h) ....................................................... 7 22. Compact (db/db_impl.cc db/version_set.cc) ........................................ 7 23. Compaction(db/version_set.cc) .................................................... 7 24. Version (db/version_set.cc) ...................................................... 8 25. VersionSet (db/version_set.cc) ................................................. 9 26. VersionEdit(db/version_edit.cc) ................................................. 10 27. VersionSet::Builder (db/version_set.cc) ......................................... 11 28. Manifest(descriptor)(db/version_set.cc)...................................... 12 29. TableBuilder/BlockBuilder(table/table_builder.cc table/block_builder.cc) ......... 12 30. Iterator (include/leveldb/iterator.h) ........................................... 12 三、 存储结构的格式定义与操作 .......................................................... 12 1. memtable (db/skiplist.h db/memtable) ............................................ 12 2. block of sstable (table/block_builder.cc table/block.cc) ......................... 14 3. sstable (table/table_bulder.cc/table.cc) ........................................ 16 4. block of log (db/log_format.h db/log_writer.cc db/log_reader.cc) .............. 18 5. log (db/log_format.h db/log_writer.cc db/log_reader.cc) ........................ 18 6. cache(util/cache.cc) .......................................................... 19 7. Snapshot (include/leveldb/snapshot.h) ......................................... 19 8. Iterator (include/leveldb/iterator.h) ........................................... 19 四、 主要流程 ......................................................................... 24 1. open ........................................................................... 24 2. put ............................................................................ 25 3. get ............................................................................ 25 4. delete.......................................................................... 26 5. snapshot........................................................................ 26 6. NewIterator ..................................................................... 26 7. compact......................................................................... 26 五、 总结 ............................................................................. 30 1. 设计/实现中的优化 ............................................................... 30 2. 可以做的优化 .................................................................... 31

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值