builder.cc raw

   1  // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
   2  // Use of this source code is governed by a BSD-style license that can be
   3  // found in the LICENSE file. See the AUTHORS file for names of contributors.
   4  
   5  #include "db/builder.h"
   6  
   7  #include "db/dbformat.h"
   8  #include "db/filename.h"
   9  #include "db/table_cache.h"
  10  #include "db/version_edit.h"
  11  #include "leveldb/db.h"
  12  #include "leveldb/env.h"
  13  #include "leveldb/iterator.h"
  14  
  15  namespace leveldb {
  16  
  17  Status BuildTable(const std::string& dbname, Env* env, const Options& options,
  18                    TableCache* table_cache, Iterator* iter, FileMetaData* meta) {
  19    Status s;
  20    meta->file_size = 0;
  21    iter->SeekToFirst();
  22  
  23    std::string fname = TableFileName(dbname, meta->number);
  24    if (iter->Valid()) {
  25      WritableFile* file;
  26      s = env->NewWritableFile(fname, &file);
  27      if (!s.ok()) {
  28        return s;
  29      }
  30  
  31      TableBuilder* builder = new TableBuilder(options, file);
  32      meta->smallest.DecodeFrom(iter->key());
  33      for (; iter->Valid(); iter->Next()) {
  34        Slice key = iter->key();
  35        meta->largest.DecodeFrom(key);
  36        builder->Add(key, iter->value());
  37      }
  38  
  39      // Finish and check for builder errors
  40      s = builder->Finish();
  41      if (s.ok()) {
  42        meta->file_size = builder->FileSize();
  43        assert(meta->file_size > 0);
  44      }
  45      delete builder;
  46  
  47      // Finish and check for file errors
  48      if (s.ok()) {
  49        s = file->Sync();
  50      }
  51      if (s.ok()) {
  52        s = file->Close();
  53      }
  54      delete file;
  55      file = nullptr;
  56  
  57      if (s.ok()) {
  58        // Verify that the table is usable
  59        Iterator* it = table_cache->NewIterator(ReadOptions(), meta->number,
  60                                                meta->file_size);
  61        s = it->status();
  62        delete it;
  63      }
  64    }
  65  
  66    // Check for input iterator errors
  67    if (!iter->status().ok()) {
  68      s = iter->status();
  69    }
  70  
  71    if (s.ok() && meta->file_size > 0) {
  72      // Keep it
  73    } else {
  74      env->DeleteFile(fname);
  75    }
  76    return s;
  77  }
  78  
  79  }  // namespace leveldb
  80