Home | History | Annotate | Download | only in db
      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/filename.h"
      8 #include "db/dbformat.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,
     18                   Env* env,
     19                   const Options& options,
     20                   TableCache* table_cache,
     21                   Iterator* iter,
     22                   FileMetaData* meta) {
     23   Status s;
     24   meta->file_size = 0;
     25   iter->SeekToFirst();
     26 
     27   std::string fname = TableFileName(dbname, meta->number);
     28   if (iter->Valid()) {
     29     WritableFile* file;
     30     s = env->NewWritableFile(fname, &file);
     31     if (!s.ok()) {
     32       return s;
     33     }
     34 
     35     TableBuilder* builder = new TableBuilder(options, file);
     36     meta->smallest.DecodeFrom(iter->key());
     37     for (; iter->Valid(); iter->Next()) {
     38       Slice key = iter->key();
     39       meta->largest.DecodeFrom(key);
     40       builder->Add(key, iter->value());
     41     }
     42 
     43     // Finish and check for builder errors
     44     if (s.ok()) {
     45       s = builder->Finish();
     46       if (s.ok()) {
     47         meta->file_size = builder->FileSize();
     48         assert(meta->file_size > 0);
     49       }
     50     } else {
     51       builder->Abandon();
     52     }
     53     delete builder;
     54 
     55     // Finish and check for file errors
     56     if (s.ok()) {
     57       s = file->Sync();
     58     }
     59     if (s.ok()) {
     60       s = file->Close();
     61     }
     62     delete file;
     63     file = NULL;
     64 
     65     if (s.ok()) {
     66       // Verify that the table is usable
     67       Iterator* it = table_cache->NewIterator(ReadOptions(),
     68                                               meta->number,
     69                                               meta->file_size);
     70       s = it->status();
     71       delete it;
     72     }
     73   }
     74 
     75   // Check for input iterator errors
     76   if (!iter->status().ok()) {
     77     s = iter->status();
     78   }
     79 
     80   if (s.ok() && meta->file_size > 0) {
     81     // Keep it
     82   } else {
     83     env->DeleteFile(fname);
     84   }
     85   return s;
     86 }
     87 
     88 }  // namespace leveldb
     89