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
15namespace leveldb {
16
17Status 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 Slice key;
34 for (; iter->Valid(); iter->Next()) {
35 key = iter->key();
36 builder->Add(key, iter->value());
37 }
38 if (!key.empty()) {
39 meta->largest.DecodeFrom(key);
40 }
41
42 // Finish and check for builder errors
43 s = builder->Finish();
44 if (s.ok()) {
45 meta->file_size = builder->FileSize();
46 assert(meta->file_size > 0);
47 }
48 delete builder;
49
50 // Finish and check for file errors
51 if (s.ok()) {
52 s = file->Sync();
53 }
54 if (s.ok()) {
55 s = file->Close();
56 }
57 delete file;
58 file = nullptr;
59
60 if (s.ok()) {
61 // Verify that the table is usable
62 Iterator* it = table_cache->NewIterator(ReadOptions(), meta->number,
63 meta->file_size);
64 s = it->status();
65 delete it;
66 }
67 }
68
69 // Check for input iterator errors
70 if (!iter->status().ok()) {
71 s = iter->status();
72 }
73
74 if (s.ok() && meta->file_size > 0) {
75 // Keep it
76 } else {
77 env->RemoveFile(fname);
78 }
79 return s;
80}
81
82} // namespace leveldb
83