|
|
@ -2,6 +2,7 @@ |
|
|
|
// 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 <string>
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
|
|
#include <atomic>
|
|
|
@ -49,37 +50,42 @@ using namespace fielddb; |
|
|
|
// sstables -- Print sstable info
|
|
|
|
// heapprofile -- Dump a heap profile (if supported by this port)
|
|
|
|
static const char* FLAGS_benchmarks = |
|
|
|
// "fillseq,"
|
|
|
|
// "fillsync,"
|
|
|
|
// "fillrandom,"
|
|
|
|
// "overwrite,"
|
|
|
|
// "readrandom,"
|
|
|
|
// "readrandom," // Extra run to allow previous compactions to quiesce
|
|
|
|
// "readseq,"
|
|
|
|
// "readreverse,"
|
|
|
|
// "compact,"
|
|
|
|
// "readrandom,"
|
|
|
|
// "readseq,"
|
|
|
|
// "readreverse,"
|
|
|
|
// "fill100K,"
|
|
|
|
// "crc32c,"
|
|
|
|
// "CreateIndex,"
|
|
|
|
// "FindKeysByField,"
|
|
|
|
// "QueryByIndex,"
|
|
|
|
// "DeleteIndex,"
|
|
|
|
// "compact,"
|
|
|
|
// "WriteSeqWhileCreating,"
|
|
|
|
// "WriteSeqWhileDeleting,"
|
|
|
|
// "compact,"
|
|
|
|
// "WriteRandomWhileCreating,"
|
|
|
|
// "WriteRandomWhileDeleting,"
|
|
|
|
// "compact,"
|
|
|
|
// "ReadSeqWhileCreating,"
|
|
|
|
// "ReadSeqWhileDeleting,"
|
|
|
|
// "ReadRandomWhileCreating,"
|
|
|
|
// "ReadRandomWhileDeleting,"
|
|
|
|
// "WriteRandomWithIndex,"
|
|
|
|
// "WriteSeqWithIndex,"
|
|
|
|
"fillseq," |
|
|
|
"fillsync," |
|
|
|
"fillrandom," |
|
|
|
"overwrite," |
|
|
|
"readrandom," |
|
|
|
"readrandom," // Extra run to allow previous compactions to quiesce
|
|
|
|
"readseq," |
|
|
|
"readreverse," |
|
|
|
"compact," |
|
|
|
"readrandom," |
|
|
|
"readseq," |
|
|
|
"readreverse," |
|
|
|
"fill100K," |
|
|
|
"crc32c," |
|
|
|
"CreateIndex," |
|
|
|
"FindKeysByField," |
|
|
|
"QueryByIndex," |
|
|
|
"DeleteIndex," |
|
|
|
"compact," |
|
|
|
"WriteSeqWhileCreating," |
|
|
|
"WriteSeqWhileDeleting," |
|
|
|
"compact," |
|
|
|
"WriteRandomWhileCreating," |
|
|
|
"WriteRandomWhileDeleting," |
|
|
|
"compact," |
|
|
|
"ReadSeqWhileCreating," |
|
|
|
"ReadSeqWhileDeleting," |
|
|
|
"ReadRandomWhileCreating," |
|
|
|
"ReadRandomWhileDeleting," |
|
|
|
"WriteRandomWithIndex," |
|
|
|
"WriteSeqWithIndex,"; |
|
|
|
"WriteSeqWhileIndependentCCD," |
|
|
|
"fillseq," |
|
|
|
"WriteSeqWhileCCD," |
|
|
|
; |
|
|
|
|
|
|
|
// Number of key/values to place in database
|
|
|
|
static int FLAGS_num = 1000000; |
|
|
@ -146,6 +152,8 @@ static const char* FLAGS_db = nullptr; |
|
|
|
// ZSTD compression level to try out
|
|
|
|
static int FLAGS_zstd_compression_level = 1; |
|
|
|
|
|
|
|
static bool FLAGS_contain_field_age = true; |
|
|
|
|
|
|
|
namespace leveldb { |
|
|
|
|
|
|
|
namespace { |
|
|
@ -348,8 +356,8 @@ class Stats { |
|
|
|
} |
|
|
|
AppendWithSpace(&extra, message_); |
|
|
|
|
|
|
|
std::fprintf(stdout, "%-12s : %11.3f micros/op;%s%s\n", |
|
|
|
name.ToString().c_str(), seconds_ * 1e6 / done_, |
|
|
|
std::fprintf(stdout, "%-12s : %11.3f micros/op(%10d);%s%s\n", |
|
|
|
name.ToString().c_str(), seconds_ * 1e6 / done_,done_, |
|
|
|
(extra.empty() ? "" : " "), extra.c_str()); |
|
|
|
if (FLAGS_histogram) { |
|
|
|
std::fprintf(stdout, "Microseconds per op:\n%s\n", |
|
|
@ -593,6 +601,9 @@ class Benchmark { |
|
|
|
bool fresh_db = false; |
|
|
|
int num_threads = FLAGS_threads; |
|
|
|
|
|
|
|
FLAGS_key_prefix = 0; |
|
|
|
FLAGS_contain_field_age = true; |
|
|
|
|
|
|
|
if (name == Slice("open")) { |
|
|
|
method = &Benchmark::OpenBench; |
|
|
|
num_ /= 10000; |
|
|
@ -686,6 +697,14 @@ class Benchmark { |
|
|
|
} else if (name == Slice("WriteSeqWithIndex")) { |
|
|
|
fresh_db = true; |
|
|
|
method = &Benchmark::WriteSeqWithIndex; |
|
|
|
} else if (name == Slice("WriteSeqWhileIndependentCCD")) { |
|
|
|
FLAGS_key_prefix = 1; |
|
|
|
FLAGS_contain_field_age = false; |
|
|
|
num_threads++; |
|
|
|
method = &Benchmark::WriteSeqWhileIndependentCCD; |
|
|
|
} else if (name == Slice("WriteSeqWhileCCD")) { |
|
|
|
num_threads++; |
|
|
|
method = &Benchmark::WriteSeqWhileCCD; |
|
|
|
} else if (name == Slice("snappycomp")) { |
|
|
|
method = &Benchmark::SnappyCompress; |
|
|
|
} else if (name == Slice("snappyuncomp")) { |
|
|
@ -792,6 +811,10 @@ class Benchmark { |
|
|
|
} |
|
|
|
shared.mu.Unlock(); |
|
|
|
|
|
|
|
for(int i = 0; i < n; i++) { |
|
|
|
arg[i].thread->stats.Report(name); |
|
|
|
} |
|
|
|
|
|
|
|
for (int i = 1; i < n; i++) { |
|
|
|
arg[0].thread->stats.Merge(arg[i].thread->stats); |
|
|
|
} |
|
|
@ -917,7 +940,7 @@ class Benchmark { |
|
|
|
std::string tag = gen.Generate(value_size_).ToString(); |
|
|
|
FieldArray fields = { |
|
|
|
{"name", name}, |
|
|
|
{"age", age}, |
|
|
|
{std::string("age") + (FLAGS_contain_field_age?"":"a"), age}, |
|
|
|
{"tag", tag} |
|
|
|
}; |
|
|
|
std::string value = SerializeValue(fields); |
|
|
@ -1174,6 +1197,52 @@ class Benchmark { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void ContinueCreatingDeleting(ThreadState* thread) { |
|
|
|
int flag = 1; |
|
|
|
while(true) { |
|
|
|
{ |
|
|
|
MutexLock L(&thread->shared->mu); |
|
|
|
if(thread->shared->num_done == thread->shared->total - 1) { |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
if(flag) { |
|
|
|
db_->CreateIndexOnField("age", write_options_); |
|
|
|
} else { |
|
|
|
db_->DeleteIndex("age", write_options_); |
|
|
|
} |
|
|
|
thread->stats.FinishedSingleOp(); |
|
|
|
flag ^= 1; |
|
|
|
g_env->SleepForMicroseconds(100000); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void WriteSeqWhileIndependentCCD(ThreadState* thread) { |
|
|
|
if (thread->tid > 0) { |
|
|
|
WriteSeq(thread); |
|
|
|
} else { |
|
|
|
// Special thread that keeps creating index until other threads are done.
|
|
|
|
if (db_->GetIndexStatus("age") != IndexStatus::NotExist) { |
|
|
|
std::fprintf(stderr, "index status error in WriteWhileCreating\n"); |
|
|
|
std::exit(1); |
|
|
|
} |
|
|
|
ContinueCreatingDeleting(thread); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void WriteSeqWhileCCD(ThreadState* thread) { |
|
|
|
if (thread->tid > 0) { |
|
|
|
WriteSeq(thread); |
|
|
|
} else { |
|
|
|
// Special thread that keeps creating index until other threads are done.
|
|
|
|
if (db_->GetIndexStatus("age") != IndexStatus::NotExist) { |
|
|
|
std::fprintf(stderr, "index status error in WriteWhileCreating\n"); |
|
|
|
std::exit(1); |
|
|
|
} |
|
|
|
ContinueCreatingDeleting(thread); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void WriteSeqWhileDeleting(ThreadState* thread) { |
|
|
|
if (thread->tid > 0) { |
|
|
|
WriteSeq(thread); |
|
|
@ -1221,7 +1290,7 @@ class Benchmark { |
|
|
|
while (true) { |
|
|
|
{ |
|
|
|
MutexLock l(&thread->shared->mu); |
|
|
|
if (thread->shared->num_done == 1) { |
|
|
|
if (thread->shared->num_done >= 1) { |
|
|
|
// 创删索引完成
|
|
|
|
delete iter; |
|
|
|
thread->stats.AddBytes(bytes); |
|
|
@ -1251,7 +1320,7 @@ class Benchmark { |
|
|
|
while (true) { |
|
|
|
{ |
|
|
|
MutexLock l(&thread->shared->mu); |
|
|
|
if (thread->shared->num_done == 1) { |
|
|
|
if (thread->shared->num_done >= 1) { |
|
|
|
// 创删索引完成
|
|
|
|
delete iter; |
|
|
|
thread->stats.AddBytes(bytes); |
|
|
@ -1281,7 +1350,7 @@ class Benchmark { |
|
|
|
while (true) { |
|
|
|
{ |
|
|
|
MutexLock l(&thread->shared->mu); |
|
|
|
if (thread->shared->num_done == 1) { |
|
|
|
if (thread->shared->num_done >= 1) { |
|
|
|
// 创删索引完成
|
|
|
|
break; |
|
|
|
} |
|
|
@ -1312,7 +1381,7 @@ class Benchmark { |
|
|
|
while (true) { |
|
|
|
{ |
|
|
|
MutexLock l(&thread->shared->mu); |
|
|
|
if (thread->shared->num_done == 1) { |
|
|
|
if (thread->shared->num_done >= 1) { |
|
|
|
// 创删索引完成
|
|
|
|
break; |
|
|
|
} |
|
|
@ -1398,6 +1467,8 @@ int main(int argc, char** argv) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// FLAGS_num = (FLAGS_num + FLAGS_threads - 1) / FLAGS_threads;
|
|
|
|
|
|
|
|
leveldb::g_env = leveldb::Env::Default(); |
|
|
|
|
|
|
|
// Choose a location for the test database if none given with --db=<path>
|
|
|
|