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
BuildTable(const std::string & dbname,Env * env,const Options & options,TableCache * table_cache,Iterator * iter,FileMetaData * meta)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