/ src / leveldb / db / builder.cc
builder.cc
 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