Add Google's LevelDB support
[novacoin.git] / src / leveldb / db / 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/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 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