// 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 { 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; } time_t nowTime; time(&nowTime); assert(nowTime > 0); TableBuilder* builder = new TableBuilder(options, file); meta->smallest.DecodeFrom(iter->key()); Slice key; ParsedInternalKey parsed; meta->smallest_deadtime = UINT64_MAX; meta->largest_deadtime = 0; for (; iter->Valid(); iter->Next()) { key = iter->key(); builder->Add(key, iter->value()); //在构建sstable文件的时候,记录当前文件的生存期最大和最小值, //这里要注意internalkey和metadata中对于没有生存期的表示的转换 ParseInternalKey(key,&parsed); if(parsed.deadTime == 0) parsed.deadTime = UINT64_MAX; if(parsed.deadTime < nowTime) { static int count = 0; if(count % 10 == 0) { std::cout<<"count "<number); } meta->smallest_deadtime = std::min(meta->smallest_deadtime,parsed.deadTime); meta->largest_deadtime = std::max(meta->largest_deadtime,parsed.deadTime); } 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