You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.6 KiB

  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/filename.h"
  6. #include "db/dbformat.h"
  7. #include "db/table_cache.h"
  8. #include "db/version_edit.h"
  9. #include "include/db.h"
  10. #include "include/env.h"
  11. #include "include/iterator.h"
  12. namespace leveldb {
  13. Status BuildTable(const std::string& dbname,
  14. Env* env,
  15. const Options& options,
  16. TableCache* table_cache,
  17. Iterator* iter,
  18. FileMetaData* meta,
  19. VersionEdit* edit) {
  20. Status s;
  21. meta->file_size = 0;
  22. iter->SeekToFirst();
  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. TableBuilder* builder = new TableBuilder(options, file);
  31. meta->smallest.DecodeFrom(iter->key());
  32. for (; iter->Valid(); iter->Next()) {
  33. Slice key = iter->key();
  34. meta->largest.DecodeFrom(key);
  35. if (ExtractValueType(key) == kTypeLargeValueRef) {
  36. if (iter->value().size() != LargeValueRef::ByteSize()) {
  37. s = Status::Corruption("invalid indirect reference hash value (L0)");
  38. break;
  39. }
  40. edit->AddLargeValueRef(LargeValueRef::FromRef(iter->value()),
  41. meta->number,
  42. iter->key());
  43. }
  44. builder->Add(key, iter->value());
  45. }
  46. // Finish and check for builder errors
  47. if (s.ok()) {
  48. s = builder->Finish();
  49. if (s.ok()) {
  50. meta->file_size = builder->FileSize();
  51. assert(meta->file_size > 0);
  52. }
  53. } else {
  54. builder->Abandon();
  55. }
  56. delete builder;
  57. // Finish and check for file errors
  58. if (s.ok()) {
  59. s = file->Sync();
  60. }
  61. if (s.ok()) {
  62. s = file->Close();
  63. }
  64. delete file;
  65. file = NULL;
  66. if (s.ok()) {
  67. // Verify that the table is usable
  68. Iterator* it = table_cache->NewIterator(ReadOptions(),
  69. meta->number,
  70. meta->file_size);
  71. s = it->status();
  72. delete it;
  73. }
  74. }
  75. // Check for input iterator errors
  76. if (!iter->status().ok()) {
  77. s = iter->status();
  78. }
  79. if (s.ok() && meta->file_size > 0) {
  80. edit->AddFile(0, meta->number, meta->file_size,
  81. meta->smallest, meta->largest);
  82. } else {
  83. env->DeleteFile(fname);
  84. }
  85. return s;
  86. }
  87. }