xref: /aosp_15_r20/external/leveldb/db/builder.cc (revision 9507f98c5f32dee4b5f9e4a38cd499f3ff5c4490)
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 
BuildTable(const std::string & dbname,Env * env,const Options & options,TableCache * table_cache,Iterator * iter,FileMetaData * meta)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     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