leveldb 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +95 -0
- data/ext/Rakefile +11 -0
- data/ext/leveldb/LICENSE +27 -0
- data/ext/leveldb/Makefile +206 -0
- data/ext/leveldb/build_config.mk +13 -0
- data/ext/leveldb/db/builder.cc +88 -0
- data/ext/leveldb/db/builder.h +34 -0
- data/ext/leveldb/db/c.cc +595 -0
- data/ext/leveldb/db/c_test.c +390 -0
- data/ext/leveldb/db/corruption_test.cc +359 -0
- data/ext/leveldb/db/db_bench.cc +979 -0
- data/ext/leveldb/db/db_impl.cc +1485 -0
- data/ext/leveldb/db/db_impl.h +203 -0
- data/ext/leveldb/db/db_iter.cc +299 -0
- data/ext/leveldb/db/db_iter.h +26 -0
- data/ext/leveldb/db/db_test.cc +2092 -0
- data/ext/leveldb/db/dbformat.cc +140 -0
- data/ext/leveldb/db/dbformat.h +227 -0
- data/ext/leveldb/db/dbformat_test.cc +112 -0
- data/ext/leveldb/db/filename.cc +139 -0
- data/ext/leveldb/db/filename.h +80 -0
- data/ext/leveldb/db/filename_test.cc +122 -0
- data/ext/leveldb/db/leveldb_main.cc +238 -0
- data/ext/leveldb/db/log_format.h +35 -0
- data/ext/leveldb/db/log_reader.cc +259 -0
- data/ext/leveldb/db/log_reader.h +108 -0
- data/ext/leveldb/db/log_test.cc +500 -0
- data/ext/leveldb/db/log_writer.cc +103 -0
- data/ext/leveldb/db/log_writer.h +48 -0
- data/ext/leveldb/db/memtable.cc +145 -0
- data/ext/leveldb/db/memtable.h +91 -0
- data/ext/leveldb/db/repair.cc +389 -0
- data/ext/leveldb/db/skiplist.h +379 -0
- data/ext/leveldb/db/skiplist_test.cc +378 -0
- data/ext/leveldb/db/snapshot.h +66 -0
- data/ext/leveldb/db/table_cache.cc +121 -0
- data/ext/leveldb/db/table_cache.h +61 -0
- data/ext/leveldb/db/version_edit.cc +266 -0
- data/ext/leveldb/db/version_edit.h +107 -0
- data/ext/leveldb/db/version_edit_test.cc +46 -0
- data/ext/leveldb/db/version_set.cc +1443 -0
- data/ext/leveldb/db/version_set.h +383 -0
- data/ext/leveldb/db/version_set_test.cc +179 -0
- data/ext/leveldb/db/write_batch.cc +147 -0
- data/ext/leveldb/db/write_batch_internal.h +49 -0
- data/ext/leveldb/db/write_batch_test.cc +120 -0
- data/ext/leveldb/doc/bench/db_bench_sqlite3.cc +718 -0
- data/ext/leveldb/doc/bench/db_bench_tree_db.cc +528 -0
- data/ext/leveldb/helpers/memenv/memenv.cc +384 -0
- data/ext/leveldb/helpers/memenv/memenv.h +20 -0
- data/ext/leveldb/helpers/memenv/memenv_test.cc +232 -0
- data/ext/leveldb/include/leveldb/c.h +291 -0
- data/ext/leveldb/include/leveldb/cache.h +99 -0
- data/ext/leveldb/include/leveldb/comparator.h +63 -0
- data/ext/leveldb/include/leveldb/db.h +161 -0
- data/ext/leveldb/include/leveldb/env.h +333 -0
- data/ext/leveldb/include/leveldb/filter_policy.h +70 -0
- data/ext/leveldb/include/leveldb/iterator.h +100 -0
- data/ext/leveldb/include/leveldb/options.h +195 -0
- data/ext/leveldb/include/leveldb/slice.h +109 -0
- data/ext/leveldb/include/leveldb/status.h +106 -0
- data/ext/leveldb/include/leveldb/table.h +85 -0
- data/ext/leveldb/include/leveldb/table_builder.h +92 -0
- data/ext/leveldb/include/leveldb/write_batch.h +64 -0
- data/ext/leveldb/issues/issue178_test.cc +92 -0
- data/ext/leveldb/port/atomic_pointer.h +224 -0
- data/ext/leveldb/port/port.h +19 -0
- data/ext/leveldb/port/port_example.h +135 -0
- data/ext/leveldb/port/port_posix.cc +54 -0
- data/ext/leveldb/port/port_posix.h +157 -0
- data/ext/leveldb/port/thread_annotations.h +59 -0
- data/ext/leveldb/port/win/stdint.h +24 -0
- data/ext/leveldb/table/block.cc +268 -0
- data/ext/leveldb/table/block.h +44 -0
- data/ext/leveldb/table/block_builder.cc +109 -0
- data/ext/leveldb/table/block_builder.h +57 -0
- data/ext/leveldb/table/filter_block.cc +111 -0
- data/ext/leveldb/table/filter_block.h +68 -0
- data/ext/leveldb/table/filter_block_test.cc +128 -0
- data/ext/leveldb/table/format.cc +145 -0
- data/ext/leveldb/table/format.h +108 -0
- data/ext/leveldb/table/iterator.cc +67 -0
- data/ext/leveldb/table/iterator_wrapper.h +63 -0
- data/ext/leveldb/table/merger.cc +197 -0
- data/ext/leveldb/table/merger.h +26 -0
- data/ext/leveldb/table/table.cc +275 -0
- data/ext/leveldb/table/table_builder.cc +270 -0
- data/ext/leveldb/table/table_test.cc +868 -0
- data/ext/leveldb/table/two_level_iterator.cc +182 -0
- data/ext/leveldb/table/two_level_iterator.h +34 -0
- data/ext/leveldb/util/arena.cc +68 -0
- data/ext/leveldb/util/arena.h +68 -0
- data/ext/leveldb/util/arena_test.cc +68 -0
- data/ext/leveldb/util/bloom.cc +95 -0
- data/ext/leveldb/util/bloom_test.cc +160 -0
- data/ext/leveldb/util/cache.cc +325 -0
- data/ext/leveldb/util/cache_test.cc +186 -0
- data/ext/leveldb/util/coding.cc +194 -0
- data/ext/leveldb/util/coding.h +104 -0
- data/ext/leveldb/util/coding_test.cc +196 -0
- data/ext/leveldb/util/comparator.cc +81 -0
- data/ext/leveldb/util/crc32c.cc +332 -0
- data/ext/leveldb/util/crc32c.h +45 -0
- data/ext/leveldb/util/crc32c_test.cc +72 -0
- data/ext/leveldb/util/env.cc +96 -0
- data/ext/leveldb/util/env_posix.cc +698 -0
- data/ext/leveldb/util/env_test.cc +104 -0
- data/ext/leveldb/util/filter_policy.cc +11 -0
- data/ext/leveldb/util/hash.cc +52 -0
- data/ext/leveldb/util/hash.h +19 -0
- data/ext/leveldb/util/histogram.cc +139 -0
- data/ext/leveldb/util/histogram.h +42 -0
- data/ext/leveldb/util/logging.cc +81 -0
- data/ext/leveldb/util/logging.h +47 -0
- data/ext/leveldb/util/mutexlock.h +41 -0
- data/ext/leveldb/util/options.cc +29 -0
- data/ext/leveldb/util/posix_logger.h +98 -0
- data/ext/leveldb/util/random.h +59 -0
- data/ext/leveldb/util/status.cc +75 -0
- data/ext/leveldb/util/testharness.cc +77 -0
- data/ext/leveldb/util/testharness.h +138 -0
- data/ext/leveldb/util/testutil.cc +51 -0
- data/ext/leveldb/util/testutil.h +53 -0
- data/lib/leveldb/version.rb +3 -0
- data/lib/leveldb.rb +1006 -0
- metadata +228 -0
|
@@ -0,0 +1,104 @@
|
|
|
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
|
+
|
|
5
|
+
#include "leveldb/env.h"
|
|
6
|
+
|
|
7
|
+
#include "port/port.h"
|
|
8
|
+
#include "util/testharness.h"
|
|
9
|
+
|
|
10
|
+
namespace leveldb {
|
|
11
|
+
|
|
12
|
+
static const int kDelayMicros = 100000;
|
|
13
|
+
|
|
14
|
+
class EnvPosixTest {
|
|
15
|
+
private:
|
|
16
|
+
port::Mutex mu_;
|
|
17
|
+
std::string events_;
|
|
18
|
+
|
|
19
|
+
public:
|
|
20
|
+
Env* env_;
|
|
21
|
+
EnvPosixTest() : env_(Env::Default()) { }
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
static void SetBool(void* ptr) {
|
|
25
|
+
reinterpret_cast<port::AtomicPointer*>(ptr)->NoBarrier_Store(ptr);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
TEST(EnvPosixTest, RunImmediately) {
|
|
29
|
+
port::AtomicPointer called (NULL);
|
|
30
|
+
env_->Schedule(&SetBool, &called);
|
|
31
|
+
Env::Default()->SleepForMicroseconds(kDelayMicros);
|
|
32
|
+
ASSERT_TRUE(called.NoBarrier_Load() != NULL);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
TEST(EnvPosixTest, RunMany) {
|
|
36
|
+
port::AtomicPointer last_id (NULL);
|
|
37
|
+
|
|
38
|
+
struct CB {
|
|
39
|
+
port::AtomicPointer* last_id_ptr; // Pointer to shared slot
|
|
40
|
+
uintptr_t id; // Order# for the execution of this callback
|
|
41
|
+
|
|
42
|
+
CB(port::AtomicPointer* p, int i) : last_id_ptr(p), id(i) { }
|
|
43
|
+
|
|
44
|
+
static void Run(void* v) {
|
|
45
|
+
CB* cb = reinterpret_cast<CB*>(v);
|
|
46
|
+
void* cur = cb->last_id_ptr->NoBarrier_Load();
|
|
47
|
+
ASSERT_EQ(cb->id-1, reinterpret_cast<uintptr_t>(cur));
|
|
48
|
+
cb->last_id_ptr->Release_Store(reinterpret_cast<void*>(cb->id));
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// Schedule in different order than start time
|
|
53
|
+
CB cb1(&last_id, 1);
|
|
54
|
+
CB cb2(&last_id, 2);
|
|
55
|
+
CB cb3(&last_id, 3);
|
|
56
|
+
CB cb4(&last_id, 4);
|
|
57
|
+
env_->Schedule(&CB::Run, &cb1);
|
|
58
|
+
env_->Schedule(&CB::Run, &cb2);
|
|
59
|
+
env_->Schedule(&CB::Run, &cb3);
|
|
60
|
+
env_->Schedule(&CB::Run, &cb4);
|
|
61
|
+
|
|
62
|
+
Env::Default()->SleepForMicroseconds(kDelayMicros);
|
|
63
|
+
void* cur = last_id.Acquire_Load();
|
|
64
|
+
ASSERT_EQ(4, reinterpret_cast<uintptr_t>(cur));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
struct State {
|
|
68
|
+
port::Mutex mu;
|
|
69
|
+
int val;
|
|
70
|
+
int num_running;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
static void ThreadBody(void* arg) {
|
|
74
|
+
State* s = reinterpret_cast<State*>(arg);
|
|
75
|
+
s->mu.Lock();
|
|
76
|
+
s->val += 1;
|
|
77
|
+
s->num_running -= 1;
|
|
78
|
+
s->mu.Unlock();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
TEST(EnvPosixTest, StartThread) {
|
|
82
|
+
State state;
|
|
83
|
+
state.val = 0;
|
|
84
|
+
state.num_running = 3;
|
|
85
|
+
for (int i = 0; i < 3; i++) {
|
|
86
|
+
env_->StartThread(&ThreadBody, &state);
|
|
87
|
+
}
|
|
88
|
+
while (true) {
|
|
89
|
+
state.mu.Lock();
|
|
90
|
+
int num = state.num_running;
|
|
91
|
+
state.mu.Unlock();
|
|
92
|
+
if (num == 0) {
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
Env::Default()->SleepForMicroseconds(kDelayMicros);
|
|
96
|
+
}
|
|
97
|
+
ASSERT_EQ(state.val, 3);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
} // namespace leveldb
|
|
101
|
+
|
|
102
|
+
int main(int argc, char** argv) {
|
|
103
|
+
return leveldb::test::RunAllTests();
|
|
104
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Copyright (c) 2012 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
|
+
|
|
5
|
+
#include "leveldb/filter_policy.h"
|
|
6
|
+
|
|
7
|
+
namespace leveldb {
|
|
8
|
+
|
|
9
|
+
FilterPolicy::~FilterPolicy() { }
|
|
10
|
+
|
|
11
|
+
} // namespace leveldb
|
|
@@ -0,0 +1,52 @@
|
|
|
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
|
+
|
|
5
|
+
#include <string.h>
|
|
6
|
+
#include "util/coding.h"
|
|
7
|
+
#include "util/hash.h"
|
|
8
|
+
|
|
9
|
+
// The FALLTHROUGH_INTENDED macro can be used to annotate implicit fall-through
|
|
10
|
+
// between switch labels. The real definition should be provided externally.
|
|
11
|
+
// This one is a fallback version for unsupported compilers.
|
|
12
|
+
#ifndef FALLTHROUGH_INTENDED
|
|
13
|
+
#define FALLTHROUGH_INTENDED do { } while (0)
|
|
14
|
+
#endif
|
|
15
|
+
|
|
16
|
+
namespace leveldb {
|
|
17
|
+
|
|
18
|
+
uint32_t Hash(const char* data, size_t n, uint32_t seed) {
|
|
19
|
+
// Similar to murmur hash
|
|
20
|
+
const uint32_t m = 0xc6a4a793;
|
|
21
|
+
const uint32_t r = 24;
|
|
22
|
+
const char* limit = data + n;
|
|
23
|
+
uint32_t h = seed ^ (n * m);
|
|
24
|
+
|
|
25
|
+
// Pick up four bytes at a time
|
|
26
|
+
while (data + 4 <= limit) {
|
|
27
|
+
uint32_t w = DecodeFixed32(data);
|
|
28
|
+
data += 4;
|
|
29
|
+
h += w;
|
|
30
|
+
h *= m;
|
|
31
|
+
h ^= (h >> 16);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Pick up remaining bytes
|
|
35
|
+
switch (limit - data) {
|
|
36
|
+
case 3:
|
|
37
|
+
h += data[2] << 16;
|
|
38
|
+
FALLTHROUGH_INTENDED;
|
|
39
|
+
case 2:
|
|
40
|
+
h += data[1] << 8;
|
|
41
|
+
FALLTHROUGH_INTENDED;
|
|
42
|
+
case 1:
|
|
43
|
+
h += data[0];
|
|
44
|
+
h *= m;
|
|
45
|
+
h ^= (h >> r);
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
return h;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
} // namespace leveldb
|
|
@@ -0,0 +1,19 @@
|
|
|
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
|
+
//
|
|
5
|
+
// Simple hash function used for internal data structures
|
|
6
|
+
|
|
7
|
+
#ifndef STORAGE_LEVELDB_UTIL_HASH_H_
|
|
8
|
+
#define STORAGE_LEVELDB_UTIL_HASH_H_
|
|
9
|
+
|
|
10
|
+
#include <stddef.h>
|
|
11
|
+
#include <stdint.h>
|
|
12
|
+
|
|
13
|
+
namespace leveldb {
|
|
14
|
+
|
|
15
|
+
extern uint32_t Hash(const char* data, size_t n, uint32_t seed);
|
|
16
|
+
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
#endif // STORAGE_LEVELDB_UTIL_HASH_H_
|
|
@@ -0,0 +1,139 @@
|
|
|
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
|
+
|
|
5
|
+
#include <math.h>
|
|
6
|
+
#include <stdio.h>
|
|
7
|
+
#include "port/port.h"
|
|
8
|
+
#include "util/histogram.h"
|
|
9
|
+
|
|
10
|
+
namespace leveldb {
|
|
11
|
+
|
|
12
|
+
const double Histogram::kBucketLimit[kNumBuckets] = {
|
|
13
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 25, 30, 35, 40, 45,
|
|
14
|
+
50, 60, 70, 80, 90, 100, 120, 140, 160, 180, 200, 250, 300, 350, 400, 450,
|
|
15
|
+
500, 600, 700, 800, 900, 1000, 1200, 1400, 1600, 1800, 2000, 2500, 3000,
|
|
16
|
+
3500, 4000, 4500, 5000, 6000, 7000, 8000, 9000, 10000, 12000, 14000,
|
|
17
|
+
16000, 18000, 20000, 25000, 30000, 35000, 40000, 45000, 50000, 60000,
|
|
18
|
+
70000, 80000, 90000, 100000, 120000, 140000, 160000, 180000, 200000,
|
|
19
|
+
250000, 300000, 350000, 400000, 450000, 500000, 600000, 700000, 800000,
|
|
20
|
+
900000, 1000000, 1200000, 1400000, 1600000, 1800000, 2000000, 2500000,
|
|
21
|
+
3000000, 3500000, 4000000, 4500000, 5000000, 6000000, 7000000, 8000000,
|
|
22
|
+
9000000, 10000000, 12000000, 14000000, 16000000, 18000000, 20000000,
|
|
23
|
+
25000000, 30000000, 35000000, 40000000, 45000000, 50000000, 60000000,
|
|
24
|
+
70000000, 80000000, 90000000, 100000000, 120000000, 140000000, 160000000,
|
|
25
|
+
180000000, 200000000, 250000000, 300000000, 350000000, 400000000,
|
|
26
|
+
450000000, 500000000, 600000000, 700000000, 800000000, 900000000,
|
|
27
|
+
1000000000, 1200000000, 1400000000, 1600000000, 1800000000, 2000000000,
|
|
28
|
+
2500000000.0, 3000000000.0, 3500000000.0, 4000000000.0, 4500000000.0,
|
|
29
|
+
5000000000.0, 6000000000.0, 7000000000.0, 8000000000.0, 9000000000.0,
|
|
30
|
+
1e200,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
void Histogram::Clear() {
|
|
34
|
+
min_ = kBucketLimit[kNumBuckets-1];
|
|
35
|
+
max_ = 0;
|
|
36
|
+
num_ = 0;
|
|
37
|
+
sum_ = 0;
|
|
38
|
+
sum_squares_ = 0;
|
|
39
|
+
for (int i = 0; i < kNumBuckets; i++) {
|
|
40
|
+
buckets_[i] = 0;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
void Histogram::Add(double value) {
|
|
45
|
+
// Linear search is fast enough for our usage in db_bench
|
|
46
|
+
int b = 0;
|
|
47
|
+
while (b < kNumBuckets - 1 && kBucketLimit[b] <= value) {
|
|
48
|
+
b++;
|
|
49
|
+
}
|
|
50
|
+
buckets_[b] += 1.0;
|
|
51
|
+
if (min_ > value) min_ = value;
|
|
52
|
+
if (max_ < value) max_ = value;
|
|
53
|
+
num_++;
|
|
54
|
+
sum_ += value;
|
|
55
|
+
sum_squares_ += (value * value);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
void Histogram::Merge(const Histogram& other) {
|
|
59
|
+
if (other.min_ < min_) min_ = other.min_;
|
|
60
|
+
if (other.max_ > max_) max_ = other.max_;
|
|
61
|
+
num_ += other.num_;
|
|
62
|
+
sum_ += other.sum_;
|
|
63
|
+
sum_squares_ += other.sum_squares_;
|
|
64
|
+
for (int b = 0; b < kNumBuckets; b++) {
|
|
65
|
+
buckets_[b] += other.buckets_[b];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
double Histogram::Median() const {
|
|
70
|
+
return Percentile(50.0);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
double Histogram::Percentile(double p) const {
|
|
74
|
+
double threshold = num_ * (p / 100.0);
|
|
75
|
+
double sum = 0;
|
|
76
|
+
for (int b = 0; b < kNumBuckets; b++) {
|
|
77
|
+
sum += buckets_[b];
|
|
78
|
+
if (sum >= threshold) {
|
|
79
|
+
// Scale linearly within this bucket
|
|
80
|
+
double left_point = (b == 0) ? 0 : kBucketLimit[b-1];
|
|
81
|
+
double right_point = kBucketLimit[b];
|
|
82
|
+
double left_sum = sum - buckets_[b];
|
|
83
|
+
double right_sum = sum;
|
|
84
|
+
double pos = (threshold - left_sum) / (right_sum - left_sum);
|
|
85
|
+
double r = left_point + (right_point - left_point) * pos;
|
|
86
|
+
if (r < min_) r = min_;
|
|
87
|
+
if (r > max_) r = max_;
|
|
88
|
+
return r;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return max_;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
double Histogram::Average() const {
|
|
95
|
+
if (num_ == 0.0) return 0;
|
|
96
|
+
return sum_ / num_;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
double Histogram::StandardDeviation() const {
|
|
100
|
+
if (num_ == 0.0) return 0;
|
|
101
|
+
double variance = (sum_squares_ * num_ - sum_ * sum_) / (num_ * num_);
|
|
102
|
+
return sqrt(variance);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
std::string Histogram::ToString() const {
|
|
106
|
+
std::string r;
|
|
107
|
+
char buf[200];
|
|
108
|
+
snprintf(buf, sizeof(buf),
|
|
109
|
+
"Count: %.0f Average: %.4f StdDev: %.2f\n",
|
|
110
|
+
num_, Average(), StandardDeviation());
|
|
111
|
+
r.append(buf);
|
|
112
|
+
snprintf(buf, sizeof(buf),
|
|
113
|
+
"Min: %.4f Median: %.4f Max: %.4f\n",
|
|
114
|
+
(num_ == 0.0 ? 0.0 : min_), Median(), max_);
|
|
115
|
+
r.append(buf);
|
|
116
|
+
r.append("------------------------------------------------------\n");
|
|
117
|
+
const double mult = 100.0 / num_;
|
|
118
|
+
double sum = 0;
|
|
119
|
+
for (int b = 0; b < kNumBuckets; b++) {
|
|
120
|
+
if (buckets_[b] <= 0.0) continue;
|
|
121
|
+
sum += buckets_[b];
|
|
122
|
+
snprintf(buf, sizeof(buf),
|
|
123
|
+
"[ %7.0f, %7.0f ) %7.0f %7.3f%% %7.3f%% ",
|
|
124
|
+
((b == 0) ? 0.0 : kBucketLimit[b-1]), // left
|
|
125
|
+
kBucketLimit[b], // right
|
|
126
|
+
buckets_[b], // count
|
|
127
|
+
mult * buckets_[b], // percentage
|
|
128
|
+
mult * sum); // cumulative percentage
|
|
129
|
+
r.append(buf);
|
|
130
|
+
|
|
131
|
+
// Add hash marks based on percentage; 20 marks for 100%.
|
|
132
|
+
int marks = static_cast<int>(20*(buckets_[b] / num_) + 0.5);
|
|
133
|
+
r.append(marks, '#');
|
|
134
|
+
r.push_back('\n');
|
|
135
|
+
}
|
|
136
|
+
return r;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
} // namespace leveldb
|
|
@@ -0,0 +1,42 @@
|
|
|
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
|
+
|
|
5
|
+
#ifndef STORAGE_LEVELDB_UTIL_HISTOGRAM_H_
|
|
6
|
+
#define STORAGE_LEVELDB_UTIL_HISTOGRAM_H_
|
|
7
|
+
|
|
8
|
+
#include <string>
|
|
9
|
+
|
|
10
|
+
namespace leveldb {
|
|
11
|
+
|
|
12
|
+
class Histogram {
|
|
13
|
+
public:
|
|
14
|
+
Histogram() { }
|
|
15
|
+
~Histogram() { }
|
|
16
|
+
|
|
17
|
+
void Clear();
|
|
18
|
+
void Add(double value);
|
|
19
|
+
void Merge(const Histogram& other);
|
|
20
|
+
|
|
21
|
+
std::string ToString() const;
|
|
22
|
+
|
|
23
|
+
private:
|
|
24
|
+
double min_;
|
|
25
|
+
double max_;
|
|
26
|
+
double num_;
|
|
27
|
+
double sum_;
|
|
28
|
+
double sum_squares_;
|
|
29
|
+
|
|
30
|
+
enum { kNumBuckets = 154 };
|
|
31
|
+
static const double kBucketLimit[kNumBuckets];
|
|
32
|
+
double buckets_[kNumBuckets];
|
|
33
|
+
|
|
34
|
+
double Median() const;
|
|
35
|
+
double Percentile(double p) const;
|
|
36
|
+
double Average() const;
|
|
37
|
+
double StandardDeviation() const;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
} // namespace leveldb
|
|
41
|
+
|
|
42
|
+
#endif // STORAGE_LEVELDB_UTIL_HISTOGRAM_H_
|
|
@@ -0,0 +1,81 @@
|
|
|
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
|
+
|
|
5
|
+
#include "util/logging.h"
|
|
6
|
+
|
|
7
|
+
#include <errno.h>
|
|
8
|
+
#include <stdarg.h>
|
|
9
|
+
#include <stdio.h>
|
|
10
|
+
#include <stdlib.h>
|
|
11
|
+
#include "leveldb/env.h"
|
|
12
|
+
#include "leveldb/slice.h"
|
|
13
|
+
|
|
14
|
+
namespace leveldb {
|
|
15
|
+
|
|
16
|
+
void AppendNumberTo(std::string* str, uint64_t num) {
|
|
17
|
+
char buf[30];
|
|
18
|
+
snprintf(buf, sizeof(buf), "%llu", (unsigned long long) num);
|
|
19
|
+
str->append(buf);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
void AppendEscapedStringTo(std::string* str, const Slice& value) {
|
|
23
|
+
for (size_t i = 0; i < value.size(); i++) {
|
|
24
|
+
char c = value[i];
|
|
25
|
+
if (c >= ' ' && c <= '~') {
|
|
26
|
+
str->push_back(c);
|
|
27
|
+
} else {
|
|
28
|
+
char buf[10];
|
|
29
|
+
snprintf(buf, sizeof(buf), "\\x%02x",
|
|
30
|
+
static_cast<unsigned int>(c) & 0xff);
|
|
31
|
+
str->append(buf);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
std::string NumberToString(uint64_t num) {
|
|
37
|
+
std::string r;
|
|
38
|
+
AppendNumberTo(&r, num);
|
|
39
|
+
return r;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
std::string EscapeString(const Slice& value) {
|
|
43
|
+
std::string r;
|
|
44
|
+
AppendEscapedStringTo(&r, value);
|
|
45
|
+
return r;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
bool ConsumeChar(Slice* in, char c) {
|
|
49
|
+
if (!in->empty() && (*in)[0] == c) {
|
|
50
|
+
in->remove_prefix(1);
|
|
51
|
+
return true;
|
|
52
|
+
} else {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
bool ConsumeDecimalNumber(Slice* in, uint64_t* val) {
|
|
58
|
+
uint64_t v = 0;
|
|
59
|
+
int digits = 0;
|
|
60
|
+
while (!in->empty()) {
|
|
61
|
+
char c = (*in)[0];
|
|
62
|
+
if (c >= '0' && c <= '9') {
|
|
63
|
+
++digits;
|
|
64
|
+
const int delta = (c - '0');
|
|
65
|
+
static const uint64_t kMaxUint64 = ~static_cast<uint64_t>(0);
|
|
66
|
+
if (v > kMaxUint64/10 ||
|
|
67
|
+
(v == kMaxUint64/10 && delta > kMaxUint64%10)) {
|
|
68
|
+
// Overflow
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
v = (v * 10) + delta;
|
|
72
|
+
in->remove_prefix(1);
|
|
73
|
+
} else {
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
*val = v;
|
|
78
|
+
return (digits > 0);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
} // namespace leveldb
|
|
@@ -0,0 +1,47 @@
|
|
|
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
|
+
//
|
|
5
|
+
// Must not be included from any .h files to avoid polluting the namespace
|
|
6
|
+
// with macros.
|
|
7
|
+
|
|
8
|
+
#ifndef STORAGE_LEVELDB_UTIL_LOGGING_H_
|
|
9
|
+
#define STORAGE_LEVELDB_UTIL_LOGGING_H_
|
|
10
|
+
|
|
11
|
+
#include <stdio.h>
|
|
12
|
+
#include <stdint.h>
|
|
13
|
+
#include <string>
|
|
14
|
+
#include "port/port.h"
|
|
15
|
+
|
|
16
|
+
namespace leveldb {
|
|
17
|
+
|
|
18
|
+
class Slice;
|
|
19
|
+
class WritableFile;
|
|
20
|
+
|
|
21
|
+
// Append a human-readable printout of "num" to *str
|
|
22
|
+
extern void AppendNumberTo(std::string* str, uint64_t num);
|
|
23
|
+
|
|
24
|
+
// Append a human-readable printout of "value" to *str.
|
|
25
|
+
// Escapes any non-printable characters found in "value".
|
|
26
|
+
extern void AppendEscapedStringTo(std::string* str, const Slice& value);
|
|
27
|
+
|
|
28
|
+
// Return a human-readable printout of "num"
|
|
29
|
+
extern std::string NumberToString(uint64_t num);
|
|
30
|
+
|
|
31
|
+
// Return a human-readable version of "value".
|
|
32
|
+
// Escapes any non-printable characters found in "value".
|
|
33
|
+
extern std::string EscapeString(const Slice& value);
|
|
34
|
+
|
|
35
|
+
// If *in starts with "c", advances *in past the first character and
|
|
36
|
+
// returns true. Otherwise, returns false.
|
|
37
|
+
extern bool ConsumeChar(Slice* in, char c);
|
|
38
|
+
|
|
39
|
+
// Parse a human-readable number from "*in" into *value. On success,
|
|
40
|
+
// advances "*in" past the consumed number and sets "*val" to the
|
|
41
|
+
// numeric value. Otherwise, returns false and leaves *in in an
|
|
42
|
+
// unspecified state.
|
|
43
|
+
extern bool ConsumeDecimalNumber(Slice* in, uint64_t* val);
|
|
44
|
+
|
|
45
|
+
} // namespace leveldb
|
|
46
|
+
|
|
47
|
+
#endif // STORAGE_LEVELDB_UTIL_LOGGING_H_
|
|
@@ -0,0 +1,41 @@
|
|
|
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
|
+
|
|
5
|
+
#ifndef STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_
|
|
6
|
+
#define STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_
|
|
7
|
+
|
|
8
|
+
#include "port/port.h"
|
|
9
|
+
#include "port/thread_annotations.h"
|
|
10
|
+
|
|
11
|
+
namespace leveldb {
|
|
12
|
+
|
|
13
|
+
// Helper class that locks a mutex on construction and unlocks the mutex when
|
|
14
|
+
// the destructor of the MutexLock object is invoked.
|
|
15
|
+
//
|
|
16
|
+
// Typical usage:
|
|
17
|
+
//
|
|
18
|
+
// void MyClass::MyMethod() {
|
|
19
|
+
// MutexLock l(&mu_); // mu_ is an instance variable
|
|
20
|
+
// ... some complex code, possibly with multiple return paths ...
|
|
21
|
+
// }
|
|
22
|
+
|
|
23
|
+
class SCOPED_LOCKABLE MutexLock {
|
|
24
|
+
public:
|
|
25
|
+
explicit MutexLock(port::Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu)
|
|
26
|
+
: mu_(mu) {
|
|
27
|
+
this->mu_->Lock();
|
|
28
|
+
}
|
|
29
|
+
~MutexLock() UNLOCK_FUNCTION() { this->mu_->Unlock(); }
|
|
30
|
+
|
|
31
|
+
private:
|
|
32
|
+
port::Mutex *const mu_;
|
|
33
|
+
// No copying allowed
|
|
34
|
+
MutexLock(const MutexLock&);
|
|
35
|
+
void operator=(const MutexLock&);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
} // namespace leveldb
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
#endif // STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_
|
|
@@ -0,0 +1,29 @@
|
|
|
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
|
+
|
|
5
|
+
#include "leveldb/options.h"
|
|
6
|
+
|
|
7
|
+
#include "leveldb/comparator.h"
|
|
8
|
+
#include "leveldb/env.h"
|
|
9
|
+
|
|
10
|
+
namespace leveldb {
|
|
11
|
+
|
|
12
|
+
Options::Options()
|
|
13
|
+
: comparator(BytewiseComparator()),
|
|
14
|
+
create_if_missing(false),
|
|
15
|
+
error_if_exists(false),
|
|
16
|
+
paranoid_checks(false),
|
|
17
|
+
env(Env::Default()),
|
|
18
|
+
info_log(NULL),
|
|
19
|
+
write_buffer_size(4<<20),
|
|
20
|
+
max_open_files(1000),
|
|
21
|
+
block_cache(NULL),
|
|
22
|
+
block_size(4096),
|
|
23
|
+
block_restart_interval(16),
|
|
24
|
+
compression(kSnappyCompression),
|
|
25
|
+
filter_policy(NULL) {
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
} // namespace leveldb
|
|
@@ -0,0 +1,98 @@
|
|
|
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
|
+
//
|
|
5
|
+
// Logger implementation that can be shared by all environments
|
|
6
|
+
// where enough posix functionality is available.
|
|
7
|
+
|
|
8
|
+
#ifndef STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_
|
|
9
|
+
#define STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_
|
|
10
|
+
|
|
11
|
+
#include <algorithm>
|
|
12
|
+
#include <stdio.h>
|
|
13
|
+
#include <sys/time.h>
|
|
14
|
+
#include <time.h>
|
|
15
|
+
#include "leveldb/env.h"
|
|
16
|
+
|
|
17
|
+
namespace leveldb {
|
|
18
|
+
|
|
19
|
+
class PosixLogger : public Logger {
|
|
20
|
+
private:
|
|
21
|
+
FILE* file_;
|
|
22
|
+
uint64_t (*gettid_)(); // Return the thread id for the current thread
|
|
23
|
+
public:
|
|
24
|
+
PosixLogger(FILE* f, uint64_t (*gettid)()) : file_(f), gettid_(gettid) { }
|
|
25
|
+
virtual ~PosixLogger() {
|
|
26
|
+
fclose(file_);
|
|
27
|
+
}
|
|
28
|
+
virtual void Logv(const char* format, va_list ap) {
|
|
29
|
+
const uint64_t thread_id = (*gettid_)();
|
|
30
|
+
|
|
31
|
+
// We try twice: the first time with a fixed-size stack allocated buffer,
|
|
32
|
+
// and the second time with a much larger dynamically allocated buffer.
|
|
33
|
+
char buffer[500];
|
|
34
|
+
for (int iter = 0; iter < 2; iter++) {
|
|
35
|
+
char* base;
|
|
36
|
+
int bufsize;
|
|
37
|
+
if (iter == 0) {
|
|
38
|
+
bufsize = sizeof(buffer);
|
|
39
|
+
base = buffer;
|
|
40
|
+
} else {
|
|
41
|
+
bufsize = 30000;
|
|
42
|
+
base = new char[bufsize];
|
|
43
|
+
}
|
|
44
|
+
char* p = base;
|
|
45
|
+
char* limit = base + bufsize;
|
|
46
|
+
|
|
47
|
+
struct timeval now_tv;
|
|
48
|
+
gettimeofday(&now_tv, NULL);
|
|
49
|
+
const time_t seconds = now_tv.tv_sec;
|
|
50
|
+
struct tm t;
|
|
51
|
+
localtime_r(&seconds, &t);
|
|
52
|
+
p += snprintf(p, limit - p,
|
|
53
|
+
"%04d/%02d/%02d-%02d:%02d:%02d.%06d %llx ",
|
|
54
|
+
t.tm_year + 1900,
|
|
55
|
+
t.tm_mon + 1,
|
|
56
|
+
t.tm_mday,
|
|
57
|
+
t.tm_hour,
|
|
58
|
+
t.tm_min,
|
|
59
|
+
t.tm_sec,
|
|
60
|
+
static_cast<int>(now_tv.tv_usec),
|
|
61
|
+
static_cast<long long unsigned int>(thread_id));
|
|
62
|
+
|
|
63
|
+
// Print the message
|
|
64
|
+
if (p < limit) {
|
|
65
|
+
va_list backup_ap;
|
|
66
|
+
va_copy(backup_ap, ap);
|
|
67
|
+
p += vsnprintf(p, limit - p, format, backup_ap);
|
|
68
|
+
va_end(backup_ap);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Truncate to available space if necessary
|
|
72
|
+
if (p >= limit) {
|
|
73
|
+
if (iter == 0) {
|
|
74
|
+
continue; // Try again with larger buffer
|
|
75
|
+
} else {
|
|
76
|
+
p = limit - 1;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Add newline if necessary
|
|
81
|
+
if (p == base || p[-1] != '\n') {
|
|
82
|
+
*p++ = '\n';
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
assert(p <= limit);
|
|
86
|
+
fwrite(base, 1, p - base, file_);
|
|
87
|
+
fflush(file_);
|
|
88
|
+
if (base != buffer) {
|
|
89
|
+
delete[] base;
|
|
90
|
+
}
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
} // namespace leveldb
|
|
97
|
+
|
|
98
|
+
#endif // STORAGE_LEVELDB_UTIL_POSIX_LOGGER_H_
|