bool InnerNode::write_msgbuf(BlockWriter& writer, MsgBuf *mb, Slice buffer) { if (tree_->compressor_) { // 1. write to buffer Block block(buffer, 0, 0); BlockWriter wr(&block); if (!mb->write_to(wr)) return false; // 2. compress assert(tree_->compressor_->max_compressed_length(block.size()) <= writer.remain()); size_t compressed_length; if (!tree_->compressor_->compress(buffer.data(), block.size(), writer.addr(), &compressed_length)) { LOG_ERROR("compress msgbuf error, nid " << nid_); return false; } // 3. skip writer.skip(compressed_length); return true; } else { return mb->write_to(writer); } }
bool LeafNode::write_bucket(BlockWriter& writer, RecordBucket *bucket, Slice buffer) { if (tree_->compressor_) { // 1. write to buffer Block block(buffer, 0, 0); BlockWriter wr(&block); if (!write_bucket(wr, bucket)) return false; // 2. compress assert(tree_->compressor_->max_compressed_length(block.size()) <= writer.remain()); size_t compressed_length; if (!tree_->compressor_->compress(buffer.data(), block.size(), writer.addr(), &compressed_length)) { LOG_ERROR("compress msgbuf error, nid " << nid_); return false; } // 3. skip writer.skip(compressed_length); return true; } else { return write_bucket(writer, bucket); } }
bool LeafNode::write_to(BlockWriter& writer, size_t& skeleton_size) { assert(status_ == kNew || status_ == kFullLoaded); size_t skeleton_pos = writer.pos(); skeleton_size = 8 + 8 + buckets_info_size_; if (!writer.skip(skeleton_size)) return false; Slice buffer; if (tree_->compressor_) { size_t buffer_length = 0; for (size_t i = 0; i < records_.buckets_number(); i++) { if (buffer_length < records_.bucket_length(i)) { buffer_length = records_.bucket_length(i); } } buffer = Slice::alloc(buffer_length); } assert(records_.buckets_number() == buckets_info_.size()); for (size_t i = 0; i < records_.buckets_number(); i++ ) { RecordBucket* bucket = records_.bucket(i); buckets_info_[i].offset = writer.pos(); if (!write_bucket(writer, bucket, buffer)) { if (buffer.size()) { buffer.destroy(); } return false; } buckets_info_[i].length = writer.pos() - buckets_info_[i].offset; buckets_info_[i].uncompressed_length = records_.bucket_length(i); } size_t last_pos = writer.pos(); if (buffer.size()) { buffer.destroy(); } writer.seek(skeleton_pos); if (!writer.writeUInt64(left_sibling_)) return false; if (!writer.writeUInt64(right_sibling_)) return false; if (!write_buckets_info(writer)) { LOG_ERROR("write buckets info error, nid " << nid_); return false; } writer.seek(last_pos); return true; }
bool InnerNode::write_to(BlockWriter& writer, size_t& skeleton_size) { // get length of skeleton and reserve space for skeleton size_t skeleton_offset = writer.pos(); size_t skeleton_length = 1 + 4 + 8 + 4 + 4 + 4; for (size_t i = 0; i < pivots_.size(); i++) { skeleton_length += pivot_size(pivots_[i].key); } if (!writer.skip(skeleton_length)) return false; // prepare buffer if compression is enabled Slice buffer; if (tree_->compressor_) { // get buffer length to serialize msgbuf size_t buffer_length = first_msgbuf_->size(); for (size_t i = 0; i < pivots_.size(); i++) { if (pivots_[i].msgbuf->size() > buffer_length) buffer_length = pivots_[i].msgbuf->size(); } buffer = Slice::alloc(buffer_length); } // write the first msgbuf first_msgbuf_offset_ = writer.pos(); if (!write_msgbuf(writer, first_msgbuf_, buffer)) return false; first_msgbuf_length_ = writer.pos() - first_msgbuf_offset_; first_msgbuf_uncompressed_length_ = first_msgbuf_->size(); // write rest msgbufs for (size_t i = 0; i < pivots_.size(); i++) { pivots_[i].offset = writer.pos(); if (!write_msgbuf(writer, pivots_[i].msgbuf, buffer)) return false; pivots_[i].length = writer.pos() - pivots_[i].offset; pivots_[i].uncompressed_length = pivots_[i].msgbuf->size(); } if (buffer.size()) { buffer.destroy(); } size_t last_offset = writer.pos(); // seek to the head and write index writer.seek(skeleton_offset); if (!writer.writeBool(bottom_)) return false; if (!writer.writeUInt32(pivots_.size())) return false; if (!writer.writeUInt64(first_child_)) return false; if (!writer.writeUInt32(first_msgbuf_offset_)) return false; if (!writer.writeUInt32(first_msgbuf_length_)) return false; if (!writer.writeUInt32(first_msgbuf_uncompressed_length_)) return false; for (size_t i = 0; i < pivots_.size(); i++) { if (!writer.writeSlice(pivots_[i].key)) return false; if (!writer.writeUInt64(pivots_[i].child)) return false; if (!writer.writeUInt32(pivots_[i].offset)) return false; if (!writer.writeUInt32(pivots_[i].length)) return false; if (!writer.writeUInt32(pivots_[i].uncompressed_length)) return false; } writer.seek(last_offset); skeleton_size = skeleton_length; return true; }