// 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 "<<count++<<" drop dead in L0: "<<parsed.user_key.ToString()<<" "<<parsed.deadTime<<std::endl;
|
|
}
|
|
continue;
|
|
}
|
|
if(parsed.user_key.ToString() == "16636") {
|
|
printf("specific insert %s deadtime %lu file num %lu\n",parsed.user_key.ToString().c_str(),parsed.deadTime,meta->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
|