// Copyright (c) 2011 The LevelDB Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. See the AUTHORS file for names of contributors. #include "db/builder.h" #include "db/dbformat.h" #include "db/filename.h" #include "db/table_cache.h" #include "db/version_edit.h" #include "leveldb/db.h" #include "leveldb/env.h" #include "leveldb/iterator.h" namespace leveldb { /** * description:目的,将内存中的数据写入一个新的 SSTable 文件 * @param dbname * @param env * @param options * @param table_cache * @param iter * @param meta :存储新sstable的相关元数据 * @return */ Status BuildTable(const std::string& dbname, Env* env, const Options& options, TableCache* table_cache, Iterator* iter, FileMetaData* meta) { Status s; meta->file_size = 0; iter->SeekToFirst(); std::string fname = TableFileName(dbname, meta->number); if (iter->Valid()) { WritableFile* file; s = env->NewWritableFile(fname, &file); if (!s.ok()) { return s; } TableBuilder* builder = new TableBuilder(options, file); meta->smallest.DecodeFrom(iter->key());//这里是internal_key auto tmp_ts = DecodeFixed64(iter->value().data() + iter->value().size() - kTSLength); meta->oldest_ts = tmp_ts; meta->newer_ts = tmp_ts; Slice key; for (; iter->Valid(); iter->Next()) { key = iter->key(); builder->Add(key, iter->value()); tmp_ts = DecodeFixed64(iter->value().data() + iter->value().size() - kTSLength); meta->oldest_ts = meta->oldest_ts > tmp_ts ? tmp_ts : meta->oldest_ts; meta->newer_ts = meta->newer_ts > tmp_ts ? meta->newer_ts : tmp_ts; } if (!key.empty()) { meta->largest.DecodeFrom(key); } // Finish and check for builder errors s = builder->Finish(); if (s.ok()) { meta->file_size = builder->FileSize(); assert(meta->file_size > 0); } delete builder; // Finish and check for file errors if (s.ok()) { s = file->Sync(); } if (s.ok()) { s = file->Close(); } delete file; file = nullptr; if (s.ok()) { // Verify that the table is usable Iterator* it = table_cache->NewIterator(ReadOptions(), meta->number, meta->file_size); s = it->status(); delete it; } } // Check for input iterator errors if (!iter->status().ok()) { s = iter->status(); } if (s.ok() && meta->file_size > 0) { // Keep it } else { env->RemoveFile(fname); } return s; } } // namespace leveldb