builder.cc 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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. #include "db/builder.h"
  5. #include "db/dbformat.h"
  6. #include "db/filename.h"
  7. #include "db/table_cache.h"
  8. #include "db/version_edit.h"
  9. #include "leveldb/db.h"
  10. #include "leveldb/env.h"
  11. #include "leveldb/iterator.h"
  12. namespace leveldb {
  13. Status BuildTable(const std::string& dbname, Env* env, const Options& options,
  14. TableCache* table_cache, Iterator* iter, FileMetaData* meta) {
  15. Status s;
  16. meta->file_size = 0;
  17. iter->SeekToFirst();
  18. std::string fname = TableFileName(dbname, meta->number);
  19. if (iter->Valid()) {
  20. WritableFile* file;
  21. s = env->NewWritableFile(fname, &file);
  22. if (!s.ok()) {
  23. return s;
  24. }
  25. TableBuilder* builder = new TableBuilder(options, file);
  26. meta->smallest.DecodeFrom(iter->key());
  27. Slice key;
  28. for (; iter->Valid(); iter->Next()) {
  29. key = iter->key();
  30. builder->Add(key, iter->value());
  31. }
  32. if (!key.empty()) {
  33. meta->largest.DecodeFrom(key);
  34. }
  35. // Finish and check for builder errors
  36. s = builder->Finish();
  37. if (s.ok()) {
  38. meta->file_size = builder->FileSize();
  39. assert(meta->file_size > 0);
  40. }
  41. delete builder;
  42. // Finish and check for file errors
  43. if (s.ok()) {
  44. s = file->Sync();
  45. }
  46. if (s.ok()) {
  47. s = file->Close();
  48. }
  49. delete file;
  50. file = nullptr;
  51. if (s.ok()) {
  52. // Verify that the table is usable
  53. Iterator* it = table_cache->NewIterator(ReadOptions(), meta->number,
  54. meta->file_size);
  55. s = it->status();
  56. delete it;
  57. }
  58. }
  59. // Check for input iterator errors
  60. if (!iter->status().ok()) {
  61. s = iter->status();
  62. }
  63. if (s.ok() && meta->file_size > 0) {
  64. // Keep it
  65. } else {
  66. env->RemoveFile(fname);
  67. }
  68. return s;
  69. }
  70. } // namespace leveldb