1179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Use of this source code is governed by a BSD-style license that can be 3179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// found in the LICENSE file. See the AUTHORS file for names of contributors. 4179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 5fbd97aa4c5325eace57d24b89845b9581bac9324jorlow@chromium.org#include "leveldb/table_builder.h" 6179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 7179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include <assert.h> 8fbd97aa4c5325eace57d24b89845b9581bac9324jorlow@chromium.org#include "leveldb/comparator.h" 9fbd97aa4c5325eace57d24b89845b9581bac9324jorlow@chromium.org#include "leveldb/env.h" 1099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com#include "leveldb/filter_policy.h" 1199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com#include "leveldb/options.h" 12179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "table/block_builder.h" 1399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com#include "table/filter_block.h" 14179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "table/format.h" 15179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "util/coding.h" 16179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "util/crc32c.h" 17179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 18179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgnamespace leveldb { 19179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 20179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstruct TableBuilder::Rep { 21179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Options options; 22179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Options index_block_options; 23179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org WritableFile* file; 24179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org uint64_t offset; 25179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Status status; 26179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org BlockBuilder data_block; 27179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org BlockBuilder index_block; 28179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org std::string last_key; 29179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org int64_t num_entries; 30179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org bool closed; // Either Finish() or Abandon() has been called. 3199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com FilterBlockBuilder* filter_block; 32179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 33179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // We do not emit the index entry for a block until we have seen the 34179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // first key for the next data block. This allows us to use shorter 35179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // keys in the index block. For example, consider a block boundary 36179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // between the keys "the quick brown fox" and "the who". We can use 37179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // "the r" as the key for the index block entry since it is >= all 38179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // entries in the first block and < all entries in subsequent 39179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // blocks. 40179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // 41179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Invariant: r->pending_index_entry is true only if data_block is empty. 42179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org bool pending_index_entry; 43179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org BlockHandle pending_handle; // Handle to add to index block 44179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 45179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org std::string compressed_output; 46179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 47179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Rep(const Options& opt, WritableFile* f) 48179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org : options(opt), 49179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org index_block_options(opt), 50179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org file(f), 51179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org offset(0), 52179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org data_block(&options), 53179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org index_block(&index_block_options), 54179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org num_entries(0), 55179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org closed(false), 5699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com filter_block(opt.filter_policy == NULL ? NULL 5799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com : new FilterBlockBuilder(opt.filter_policy)), 58179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org pending_index_entry(false) { 59179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org index_block_options.block_restart_interval = 1; 60179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 61179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}; 62179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 63179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTableBuilder::TableBuilder(const Options& options, WritableFile* file) 64179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org : rep_(new Rep(options, file)) { 6599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com if (rep_->filter_block != NULL) { 6699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com rep_->filter_block->StartBlock(0); 6799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 68179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 69179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 70179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgTableBuilder::~TableBuilder() { 71179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org assert(rep_->closed); // Catch errors where caller forgot to call Finish() 7299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com delete rep_->filter_block; 73179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org delete rep_; 74179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 75179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 76179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgStatus TableBuilder::ChangeOptions(const Options& options) { 77179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Note: if more fields are added to Options, update 78179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // this function to catch changes that should not be allowed to 79179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // change in the middle of building a Table. 80179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (options.comparator != rep_->options.comparator) { 81179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return Status::InvalidArgument("changing comparator while building table"); 82179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 83179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 84179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Note that any live BlockBuilders point to rep_->options and therefore 85179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // will automatically pick up the updated options. 86179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org rep_->options = options; 87179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org rep_->index_block_options = options; 88179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org rep_->index_block_options.block_restart_interval = 1; 89179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return Status::OK(); 90179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 91179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 92179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgvoid TableBuilder::Add(const Slice& key, const Slice& value) { 93179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Rep* r = rep_; 94179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org assert(!r->closed); 95179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (!ok()) return; 96179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (r->num_entries > 0) { 97179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org assert(r->options.comparator->Compare(key, Slice(r->last_key)) > 0); 98179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 99179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 100179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (r->pending_index_entry) { 101179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org assert(r->data_block.empty()); 102179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->options.comparator->FindShortestSeparator(&r->last_key, key); 103179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org std::string handle_encoding; 104179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->pending_handle.EncodeTo(&handle_encoding); 105179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->index_block.Add(r->last_key, Slice(handle_encoding)); 106179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->pending_index_entry = false; 107179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 108179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 10999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com if (r->filter_block != NULL) { 11099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com r->filter_block->AddKey(key); 11199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 11299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 113179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->last_key.assign(key.data(), key.size()); 114179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->num_entries++; 115179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->data_block.Add(key, value); 116179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 117179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org const size_t estimated_block_size = r->data_block.CurrentSizeEstimate(); 118179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (estimated_block_size >= r->options.block_size) { 119179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Flush(); 120179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 121179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 122179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 123179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgvoid TableBuilder::Flush() { 124179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Rep* r = rep_; 125179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org assert(!r->closed); 126179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (!ok()) return; 127179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (r->data_block.empty()) return; 128179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org assert(!r->pending_index_entry); 129179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org WriteBlock(&r->data_block, &r->pending_handle); 130179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (ok()) { 131179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->pending_index_entry = true; 132179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->status = r->file->Flush(); 133179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 13499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com if (r->filter_block != NULL) { 13599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com r->filter_block->StartBlock(r->offset); 13699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 137179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 138179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 139179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgvoid TableBuilder::WriteBlock(BlockBuilder* block, BlockHandle* handle) { 140179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // File format contains a sequence of blocks where each block has: 141179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // block_data: uint8[n] 142179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // type: uint8 143179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // crc: uint32 144179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org assert(ok()); 145179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Rep* r = rep_; 146179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Slice raw = block->Finish(); 147179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 148179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Slice block_contents; 149179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org CompressionType type = r->options.compression; 150179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // TODO(postrelease): Support more compression options: zlib? 151179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org switch (type) { 152179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org case kNoCompression: 153179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org block_contents = raw; 154179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org break; 155179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 15607f3bcfb9764be2a339cc02cf0a0d6edb151defbjorlow@chromium.org case kSnappyCompression: { 15707f3bcfb9764be2a339cc02cf0a0d6edb151defbjorlow@chromium.org std::string* compressed = &r->compressed_output; 15807f3bcfb9764be2a339cc02cf0a0d6edb151defbjorlow@chromium.org if (port::Snappy_Compress(raw.data(), raw.size(), compressed) && 15907f3bcfb9764be2a339cc02cf0a0d6edb151defbjorlow@chromium.org compressed->size() < raw.size() - (raw.size() / 8u)) { 16007f3bcfb9764be2a339cc02cf0a0d6edb151defbjorlow@chromium.org block_contents = *compressed; 16107f3bcfb9764be2a339cc02cf0a0d6edb151defbjorlow@chromium.org } else { 16207f3bcfb9764be2a339cc02cf0a0d6edb151defbjorlow@chromium.org // Snappy not supported, or compressed less than 12.5%, so just 16307f3bcfb9764be2a339cc02cf0a0d6edb151defbjorlow@chromium.org // store uncompressed form 164179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org block_contents = raw; 165179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org type = kNoCompression; 166179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 167179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org break; 168179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 169179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 17099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com WriteRawBlock(block_contents, type, handle); 17199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com r->compressed_output.clear(); 17299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com block->Reset(); 17399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com} 17499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 17599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.comvoid TableBuilder::WriteRawBlock(const Slice& block_contents, 17699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com CompressionType type, 17799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com BlockHandle* handle) { 17899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com Rep* r = rep_; 179179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org handle->set_offset(r->offset); 180179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org handle->set_size(block_contents.size()); 181179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->status = r->file->Append(block_contents); 182179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (r->status.ok()) { 183179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org char trailer[kBlockTrailerSize]; 184179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org trailer[0] = type; 185179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org uint32_t crc = crc32c::Value(block_contents.data(), block_contents.size()); 186179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org crc = crc32c::Extend(crc, trailer, 1); // Extend crc to cover block type 187179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org EncodeFixed32(trailer+1, crc32c::Mask(crc)); 188179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->status = r->file->Append(Slice(trailer, kBlockTrailerSize)); 189179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (r->status.ok()) { 190179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->offset += block_contents.size() + kBlockTrailerSize; 191179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 192179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 193179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 194179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 195179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgStatus TableBuilder::status() const { 196179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return rep_->status; 197179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 198179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 199179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgStatus TableBuilder::Finish() { 200179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Rep* r = rep_; 201179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Flush(); 202179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org assert(!r->closed); 203179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->closed = true; 20499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 20599a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com BlockHandle filter_block_handle, metaindex_block_handle, index_block_handle; 20699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 20799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Write filter block 20899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com if (ok() && r->filter_block != NULL) { 20999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com WriteRawBlock(r->filter_block->Finish(), kNoCompression, 21099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com &filter_block_handle); 21199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 21299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 21399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Write metaindex block 214179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (ok()) { 215179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org BlockBuilder meta_index_block(&r->options); 21699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com if (r->filter_block != NULL) { 21799a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Add mapping from "filter.Name" to location of filter data 21899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com std::string key = "filter."; 21999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com key.append(r->options.filter_policy->Name()); 22099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com std::string handle_encoding; 22199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com filter_block_handle.EncodeTo(&handle_encoding); 22299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com meta_index_block.Add(key, handle_encoding); 22399a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com } 22499a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 225179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // TODO(postrelease): Add stats and other meta blocks 226179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org WriteBlock(&meta_index_block, &metaindex_block_handle); 227179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 22899a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 22999a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Write index block 230179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (ok()) { 231179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (r->pending_index_entry) { 232179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->options.comparator->FindShortSuccessor(&r->last_key); 233179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org std::string handle_encoding; 234179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->pending_handle.EncodeTo(&handle_encoding); 235179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->index_block.Add(r->last_key, Slice(handle_encoding)); 236179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->pending_index_entry = false; 237179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 238179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org WriteBlock(&r->index_block, &index_block_handle); 239179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 24099a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com 24199a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com // Write footer 242179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (ok()) { 243179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Footer footer; 244179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org footer.set_metaindex_handle(metaindex_block_handle); 245179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org footer.set_index_handle(index_block_handle); 246179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org std::string footer_encoding; 247179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org footer.EncodeTo(&footer_encoding); 248179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->status = r->file->Append(footer_encoding); 249179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (r->status.ok()) { 250179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->offset += footer_encoding.size(); 251179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 252179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 253179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return r->status; 254179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 255179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 256179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgvoid TableBuilder::Abandon() { 257179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Rep* r = rep_; 258179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org assert(!r->closed); 259179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org r->closed = true; 260179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 261179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 262179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orguint64_t TableBuilder::NumEntries() const { 263179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return rep_->num_entries; 264179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 265179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 266179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orguint64_t TableBuilder::FileSize() const { 267179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return rep_->offset; 268179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org} 269179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 27045b9940be332834440bd5299419f396e38085ebehans@chromium.org} // namespace leveldb 271