Line data Source code
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 115 : 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 115 : iter->SeekToFirst();
26 :
27 115 : std::string fname = TableFileName(dbname, meta->number);
28 115 : if (iter->Valid()) {
29 : WritableFile* file;
30 230 : s = env->NewWritableFile(fname, &file);
31 115 : if (!s.ok()) {
32 0 : return s;
33 : }
34 :
35 115 : TableBuilder* builder = new TableBuilder(options, file);
36 230 : meta->smallest.DecodeFrom(iter->key());
37 16833 : for (; iter->Valid(); iter->Next()) {
38 16718 : Slice key = iter->key();
39 16718 : meta->largest.DecodeFrom(key);
40 16718 : builder->Add(key, iter->value());
41 : }
42 :
43 : // Finish and check for builder errors
44 115 : if (s.ok()) {
45 230 : s = builder->Finish();
46 115 : if (s.ok()) {
47 115 : meta->file_size = builder->FileSize();
48 115 : assert(meta->file_size > 0);
49 : }
50 : } else {
51 0 : builder->Abandon();
52 : }
53 115 : delete builder;
54 :
55 : // Finish and check for file errors
56 115 : if (s.ok()) {
57 230 : s = file->Sync();
58 : }
59 115 : if (s.ok()) {
60 230 : s = file->Close();
61 : }
62 115 : delete file;
63 115 : file = NULL;
64 :
65 115 : if (s.ok()) {
66 : // Verify that the table is usable
67 : Iterator* it = table_cache->NewIterator(ReadOptions(),
68 : meta->number,
69 230 : meta->file_size);
70 230 : s = it->status();
71 115 : delete it;
72 : }
73 : }
74 :
75 : // Check for input iterator errors
76 345 : if (!iter->status().ok()) {
77 0 : s = iter->status();
78 : }
79 :
80 115 : if (s.ok() && meta->file_size > 0) {
81 : // Keep it
82 : } else {
83 0 : env->DeleteFile(fname);
84 : }
85 : return s;
86 : }
87 :
88 : } // namespace leveldb
|