leveldb-ruby 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +17 -0
- data/ext/leveldb/extconf.rb +10 -0
- data/ext/leveldb/leveldb.cc +181 -0
- data/leveldb/Makefile +172 -0
- data/leveldb/db/builder.cc +90 -0
- data/leveldb/db/builder.h +36 -0
- data/leveldb/db/corruption_test.cc +354 -0
- data/leveldb/db/db_bench.cc +677 -0
- data/leveldb/db/db_impl.cc +1236 -0
- data/leveldb/db/db_impl.h +180 -0
- data/leveldb/db/db_iter.cc +298 -0
- data/leveldb/db/db_iter.h +26 -0
- data/leveldb/db/db_test.cc +1192 -0
- data/leveldb/db/dbformat.cc +87 -0
- data/leveldb/db/dbformat.h +165 -0
- data/leveldb/db/dbformat_test.cc +112 -0
- data/leveldb/db/filename.cc +135 -0
- data/leveldb/db/filename.h +80 -0
- data/leveldb/db/filename_test.cc +122 -0
- data/leveldb/db/log_format.h +35 -0
- data/leveldb/db/log_reader.cc +254 -0
- data/leveldb/db/log_reader.h +108 -0
- data/leveldb/db/log_test.cc +500 -0
- data/leveldb/db/log_writer.cc +103 -0
- data/leveldb/db/log_writer.h +48 -0
- data/leveldb/db/memtable.cc +108 -0
- data/leveldb/db/memtable.h +85 -0
- data/leveldb/db/repair.cc +384 -0
- data/leveldb/db/skiplist.h +378 -0
- data/leveldb/db/skiplist_test.cc +378 -0
- data/leveldb/db/snapshot.h +66 -0
- data/leveldb/db/table_cache.cc +95 -0
- data/leveldb/db/table_cache.h +50 -0
- data/leveldb/db/version_edit.cc +268 -0
- data/leveldb/db/version_edit.h +106 -0
- data/leveldb/db/version_edit_test.cc +46 -0
- data/leveldb/db/version_set.cc +1060 -0
- data/leveldb/db/version_set.h +306 -0
- data/leveldb/db/write_batch.cc +138 -0
- data/leveldb/db/write_batch_internal.h +45 -0
- data/leveldb/db/write_batch_test.cc +89 -0
- data/leveldb/include/leveldb/cache.h +99 -0
- data/leveldb/include/leveldb/comparator.h +63 -0
- data/leveldb/include/leveldb/db.h +148 -0
- data/leveldb/include/leveldb/env.h +302 -0
- data/leveldb/include/leveldb/iterator.h +100 -0
- data/leveldb/include/leveldb/options.h +198 -0
- data/leveldb/include/leveldb/slice.h +109 -0
- data/leveldb/include/leveldb/status.h +100 -0
- data/leveldb/include/leveldb/table.h +70 -0
- data/leveldb/include/leveldb/table_builder.h +91 -0
- data/leveldb/include/leveldb/write_batch.h +64 -0
- data/leveldb/port/port.h +23 -0
- data/leveldb/port/port_android.cc +64 -0
- data/leveldb/port/port_android.h +150 -0
- data/leveldb/port/port_chromium.cc +80 -0
- data/leveldb/port/port_chromium.h +97 -0
- data/leveldb/port/port_example.h +115 -0
- data/leveldb/port/port_osx.cc +50 -0
- data/leveldb/port/port_osx.h +125 -0
- data/leveldb/port/port_posix.cc +50 -0
- data/leveldb/port/port_posix.h +94 -0
- data/leveldb/port/sha1_portable.cc +298 -0
- data/leveldb/port/sha1_portable.h +25 -0
- data/leveldb/port/sha1_test.cc +39 -0
- data/leveldb/port/win/stdint.h +24 -0
- data/leveldb/table/block.cc +263 -0
- data/leveldb/table/block.h +43 -0
- data/leveldb/table/block_builder.cc +109 -0
- data/leveldb/table/block_builder.h +57 -0
- data/leveldb/table/format.cc +131 -0
- data/leveldb/table/format.h +103 -0
- data/leveldb/table/iterator.cc +67 -0
- data/leveldb/table/iterator_wrapper.h +63 -0
- data/leveldb/table/merger.cc +197 -0
- data/leveldb/table/merger.h +26 -0
- data/leveldb/table/table.cc +175 -0
- data/leveldb/table/table_builder.cc +227 -0
- data/leveldb/table/table_test.cc +845 -0
- data/leveldb/table/two_level_iterator.cc +182 -0
- data/leveldb/table/two_level_iterator.h +34 -0
- data/leveldb/util/arena.cc +68 -0
- data/leveldb/util/arena.h +68 -0
- data/leveldb/util/arena_test.cc +68 -0
- data/leveldb/util/cache.cc +255 -0
- data/leveldb/util/cache_test.cc +169 -0
- data/leveldb/util/coding.cc +194 -0
- data/leveldb/util/coding.h +104 -0
- data/leveldb/util/coding_test.cc +173 -0
- data/leveldb/util/comparator.cc +72 -0
- data/leveldb/util/crc32c.cc +332 -0
- data/leveldb/util/crc32c.h +45 -0
- data/leveldb/util/crc32c_test.cc +72 -0
- data/leveldb/util/env.cc +77 -0
- data/leveldb/util/env_chromium.cc +612 -0
- data/leveldb/util/env_posix.cc +606 -0
- data/leveldb/util/env_test.cc +102 -0
- data/leveldb/util/hash.cc +45 -0
- data/leveldb/util/hash.h +19 -0
- data/leveldb/util/histogram.cc +128 -0
- data/leveldb/util/histogram.h +41 -0
- data/leveldb/util/logging.cc +81 -0
- data/leveldb/util/logging.h +47 -0
- data/leveldb/util/mutexlock.h +39 -0
- data/leveldb/util/options.cc +28 -0
- data/leveldb/util/random.h +59 -0
- data/leveldb/util/status.cc +75 -0
- data/leveldb/util/testharness.cc +65 -0
- data/leveldb/util/testharness.h +129 -0
- data/leveldb/util/testutil.cc +51 -0
- data/leveldb/util/testutil.h +53 -0
- data/lib/leveldb.rb +36 -0
- metadata +183 -0
@@ -0,0 +1,39 @@
|
|
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
|
+
|
10
|
+
namespace leveldb {
|
11
|
+
|
12
|
+
// Helper class that locks a mutex on construction and unlocks the mutex when
|
13
|
+
// the destructor of the MutexLock object is invoked.
|
14
|
+
//
|
15
|
+
// Typical usage:
|
16
|
+
//
|
17
|
+
// void MyClass::MyMethod() {
|
18
|
+
// MutexLock l(&mu_); // mu_ is an instance variable
|
19
|
+
// ... some complex code, possibly with multiple return paths ...
|
20
|
+
// }
|
21
|
+
|
22
|
+
class MutexLock {
|
23
|
+
public:
|
24
|
+
explicit MutexLock(port::Mutex *mu) : mu_(mu) {
|
25
|
+
this->mu_->Lock();
|
26
|
+
}
|
27
|
+
~MutexLock() { this->mu_->Unlock(); }
|
28
|
+
|
29
|
+
private:
|
30
|
+
port::Mutex *const mu_;
|
31
|
+
// No copying allowed
|
32
|
+
MutexLock(const MutexLock&);
|
33
|
+
void operator=(const MutexLock&);
|
34
|
+
};
|
35
|
+
|
36
|
+
}
|
37
|
+
|
38
|
+
|
39
|
+
#endif // STORAGE_LEVELDB_UTIL_MUTEXLOCK_H_
|
@@ -0,0 +1,28 @@
|
|
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
|
+
}
|
26
|
+
|
27
|
+
|
28
|
+
}
|
@@ -0,0 +1,59 @@
|
|
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_RANDOM_H_
|
6
|
+
#define STORAGE_LEVELDB_UTIL_RANDOM_H_
|
7
|
+
|
8
|
+
#include <stdint.h>
|
9
|
+
|
10
|
+
namespace leveldb {
|
11
|
+
|
12
|
+
// A very simple random number generator. Not especially good at
|
13
|
+
// generating truly random bits, but good enough for our needs in this
|
14
|
+
// package.
|
15
|
+
class Random {
|
16
|
+
private:
|
17
|
+
uint32_t seed_;
|
18
|
+
public:
|
19
|
+
explicit Random(uint32_t s) : seed_(s & 0x7fffffffu) { }
|
20
|
+
uint32_t Next() {
|
21
|
+
static const uint32_t M = 2147483647L; // 2^31-1
|
22
|
+
static const uint64_t A = 16807; // bits 14, 8, 7, 5, 2, 1, 0
|
23
|
+
// We are computing
|
24
|
+
// seed_ = (seed_ * A) % M, where M = 2^31-1
|
25
|
+
//
|
26
|
+
// seed_ must not be zero or M, or else all subsequent computed values
|
27
|
+
// will be zero or M respectively. For all other values, seed_ will end
|
28
|
+
// up cycling through every number in [1,M-1]
|
29
|
+
uint64_t product = seed_ * A;
|
30
|
+
|
31
|
+
// Compute (product % M) using the fact that ((x << 31) % M) == x.
|
32
|
+
seed_ = static_cast<uint32_t>((product >> 31) + (product & M));
|
33
|
+
// The first reduction may overflow by 1 bit, so we may need to
|
34
|
+
// repeat. mod == M is not possible; using > allows the faster
|
35
|
+
// sign-bit-based test.
|
36
|
+
if (seed_ > M) {
|
37
|
+
seed_ -= M;
|
38
|
+
}
|
39
|
+
return seed_;
|
40
|
+
}
|
41
|
+
// Returns a uniformly distributed value in the range [0..n-1]
|
42
|
+
// REQUIRES: n > 0
|
43
|
+
uint32_t Uniform(int n) { return Next() % n; }
|
44
|
+
|
45
|
+
// Randomly returns true ~"1/n" of the time, and false otherwise.
|
46
|
+
// REQUIRES: n > 0
|
47
|
+
bool OneIn(int n) { return (Next() % n) == 0; }
|
48
|
+
|
49
|
+
// Skewed: pick "base" uniformly from range [0,max_log] and then
|
50
|
+
// return "base" random bits. The effect is to pick a number in the
|
51
|
+
// range [0,2^max_log-1] with exponential bias towards smaller numbers.
|
52
|
+
uint32_t Skewed(int max_log) {
|
53
|
+
return Uniform(1 << Uniform(max_log + 1));
|
54
|
+
}
|
55
|
+
};
|
56
|
+
|
57
|
+
}
|
58
|
+
|
59
|
+
#endif // STORAGE_LEVELDB_UTIL_RANDOM_H_
|
@@ -0,0 +1,75 @@
|
|
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 <stdio.h>
|
6
|
+
#include "port/port.h"
|
7
|
+
#include "leveldb/status.h"
|
8
|
+
|
9
|
+
namespace leveldb {
|
10
|
+
|
11
|
+
const char* Status::CopyState(const char* state) {
|
12
|
+
uint32_t size;
|
13
|
+
memcpy(&size, state, sizeof(size));
|
14
|
+
char* result = new char[size + 5];
|
15
|
+
memcpy(result, state, size + 5);
|
16
|
+
return result;
|
17
|
+
}
|
18
|
+
|
19
|
+
Status::Status(Code code, const Slice& msg, const Slice& msg2) {
|
20
|
+
assert(code != kOk);
|
21
|
+
const uint32_t len1 = msg.size();
|
22
|
+
const uint32_t len2 = msg2.size();
|
23
|
+
const uint32_t size = len1 + (len2 ? (2 + len2) : 0);
|
24
|
+
char* result = new char[size + 5];
|
25
|
+
memcpy(result, &size, sizeof(size));
|
26
|
+
result[4] = static_cast<char>(code);
|
27
|
+
memcpy(result + 5, msg.data(), len1);
|
28
|
+
if (len2) {
|
29
|
+
result[5 + len1] = ':';
|
30
|
+
result[6 + len1] = ' ';
|
31
|
+
memcpy(result + 7 + len1, msg2.data(), len2);
|
32
|
+
}
|
33
|
+
state_ = result;
|
34
|
+
}
|
35
|
+
|
36
|
+
std::string Status::ToString() const {
|
37
|
+
if (state_ == NULL) {
|
38
|
+
return "OK";
|
39
|
+
} else {
|
40
|
+
char tmp[30];
|
41
|
+
const char* type;
|
42
|
+
switch (code()) {
|
43
|
+
case kOk:
|
44
|
+
type = "OK";
|
45
|
+
break;
|
46
|
+
case kNotFound:
|
47
|
+
type = "NotFound: ";
|
48
|
+
break;
|
49
|
+
case kCorruption:
|
50
|
+
type = "Corruption: ";
|
51
|
+
break;
|
52
|
+
case kNotSupported:
|
53
|
+
type = "Not implemented: ";
|
54
|
+
break;
|
55
|
+
case kInvalidArgument:
|
56
|
+
type = "Invalid argument: ";
|
57
|
+
break;
|
58
|
+
case kIOError:
|
59
|
+
type = "IO error: ";
|
60
|
+
break;
|
61
|
+
default:
|
62
|
+
snprintf(tmp, sizeof(tmp), "Unknown code(%d): ",
|
63
|
+
static_cast<int>(code()));
|
64
|
+
type = tmp;
|
65
|
+
break;
|
66
|
+
}
|
67
|
+
std::string result(type);
|
68
|
+
uint32_t length;
|
69
|
+
memcpy(&length, state_, sizeof(length));
|
70
|
+
result.append(state_ + 5, length);
|
71
|
+
return result;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
}
|
@@ -0,0 +1,65 @@
|
|
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/testharness.h"
|
6
|
+
|
7
|
+
#include <sys/stat.h>
|
8
|
+
#include <sys/types.h>
|
9
|
+
|
10
|
+
namespace leveldb {
|
11
|
+
namespace test {
|
12
|
+
|
13
|
+
namespace {
|
14
|
+
struct Test {
|
15
|
+
const char* base;
|
16
|
+
const char* name;
|
17
|
+
void (*func)();
|
18
|
+
};
|
19
|
+
std::vector<Test>* tests;
|
20
|
+
}
|
21
|
+
|
22
|
+
bool RegisterTest(const char* base, const char* name, void (*func)()) {
|
23
|
+
if (tests == NULL) {
|
24
|
+
tests = new std::vector<Test>;
|
25
|
+
}
|
26
|
+
Test t;
|
27
|
+
t.base = base;
|
28
|
+
t.name = name;
|
29
|
+
t.func = func;
|
30
|
+
tests->push_back(t);
|
31
|
+
return true;
|
32
|
+
}
|
33
|
+
|
34
|
+
int RunAllTests() {
|
35
|
+
int num = 0;
|
36
|
+
if (tests != NULL) {
|
37
|
+
for (int i = 0; i < tests->size(); i++) {
|
38
|
+
const Test& t = (*tests)[i];
|
39
|
+
fprintf(stderr, "==== Test %s.%s\n", t.base, t.name);
|
40
|
+
(*t.func)();
|
41
|
+
++num;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
fprintf(stderr, "==== PASSED %d tests\n", num);
|
45
|
+
return 0;
|
46
|
+
}
|
47
|
+
|
48
|
+
std::string TmpDir() {
|
49
|
+
std::string dir;
|
50
|
+
Status s = Env::Default()->GetTestDirectory(&dir);
|
51
|
+
ASSERT_TRUE(s.ok()) << s.ToString();
|
52
|
+
return dir;
|
53
|
+
}
|
54
|
+
|
55
|
+
int RandomSeed() {
|
56
|
+
const char* env = getenv("TEST_RANDOM_SEED");
|
57
|
+
int result = (env != NULL ? atoi(env) : 301);
|
58
|
+
if (result <= 0) {
|
59
|
+
result = 301;
|
60
|
+
}
|
61
|
+
return result;
|
62
|
+
}
|
63
|
+
|
64
|
+
}
|
65
|
+
}
|
@@ -0,0 +1,129 @@
|
|
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_TESTHARNESS_H_
|
6
|
+
#define STORAGE_LEVELDB_UTIL_TESTHARNESS_H_
|
7
|
+
|
8
|
+
#include <stdio.h>
|
9
|
+
#include <stdlib.h>
|
10
|
+
#include <sstream>
|
11
|
+
#include "leveldb/env.h"
|
12
|
+
#include "leveldb/slice.h"
|
13
|
+
#include "util/random.h"
|
14
|
+
|
15
|
+
namespace leveldb {
|
16
|
+
namespace test {
|
17
|
+
|
18
|
+
// Run all tests registered by the TEST() macro.
|
19
|
+
// Returns 0 if all tests pass.
|
20
|
+
// Dies or returns a non-zero value if some test fails.
|
21
|
+
extern int RunAllTests();
|
22
|
+
|
23
|
+
// Return the directory to use for temporary storage.
|
24
|
+
extern std::string TmpDir();
|
25
|
+
|
26
|
+
// Return a randomization seed for this run. Typically returns the
|
27
|
+
// same number on repeated invocations of this binary, but automated
|
28
|
+
// runs may be able to vary the seed.
|
29
|
+
extern int RandomSeed();
|
30
|
+
|
31
|
+
// An instance of Tester is allocated to hold temporary state during
|
32
|
+
// the execution of an assertion.
|
33
|
+
class Tester {
|
34
|
+
private:
|
35
|
+
bool ok_;
|
36
|
+
const char* fname_;
|
37
|
+
int line_;
|
38
|
+
std::stringstream ss_;
|
39
|
+
|
40
|
+
public:
|
41
|
+
Tester(const char* f, int l)
|
42
|
+
: ok_(true), fname_(f), line_(l) {
|
43
|
+
}
|
44
|
+
|
45
|
+
~Tester() {
|
46
|
+
if (!ok_) {
|
47
|
+
fprintf(stderr, "%s:%d:%s\n", fname_, line_, ss_.str().c_str());
|
48
|
+
exit(1);
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
Tester& Is(bool b, const char* msg) {
|
53
|
+
if (!b) {
|
54
|
+
ss_ << " Assertion failure " << msg;
|
55
|
+
ok_ = false;
|
56
|
+
}
|
57
|
+
return *this;
|
58
|
+
}
|
59
|
+
|
60
|
+
Tester& IsOk(const Status& s) {
|
61
|
+
if (!s.ok()) {
|
62
|
+
ss_ << " " << s.ToString();
|
63
|
+
ok_ = false;
|
64
|
+
}
|
65
|
+
return *this;
|
66
|
+
}
|
67
|
+
|
68
|
+
#define BINARY_OP(name,op) \
|
69
|
+
template <class X, class Y> \
|
70
|
+
Tester& name(const X& x, const Y& y) { \
|
71
|
+
if (! (x op y)) { \
|
72
|
+
ss_ << " failed: " << x << (" " #op " ") << y; \
|
73
|
+
ok_ = false; \
|
74
|
+
} \
|
75
|
+
return *this; \
|
76
|
+
}
|
77
|
+
|
78
|
+
BINARY_OP(IsEq, ==)
|
79
|
+
BINARY_OP(IsNe, !=)
|
80
|
+
BINARY_OP(IsGe, >=)
|
81
|
+
BINARY_OP(IsGt, >)
|
82
|
+
BINARY_OP(IsLe, <=)
|
83
|
+
BINARY_OP(IsLt, <)
|
84
|
+
#undef BINARY_OP
|
85
|
+
|
86
|
+
// Attach the specified value to the error message if an error has occurred
|
87
|
+
template <class V>
|
88
|
+
Tester& operator<<(const V& value) {
|
89
|
+
if (!ok_) {
|
90
|
+
ss_ << " " << value;
|
91
|
+
}
|
92
|
+
return *this;
|
93
|
+
}
|
94
|
+
};
|
95
|
+
|
96
|
+
#define ASSERT_TRUE(c) ::leveldb::test::Tester(__FILE__, __LINE__).Is((c), #c)
|
97
|
+
#define ASSERT_OK(s) ::leveldb::test::Tester(__FILE__, __LINE__).IsOk((s))
|
98
|
+
#define ASSERT_EQ(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsEq((a),(b))
|
99
|
+
#define ASSERT_NE(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsNe((a),(b))
|
100
|
+
#define ASSERT_GE(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsGe((a),(b))
|
101
|
+
#define ASSERT_GT(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsGt((a),(b))
|
102
|
+
#define ASSERT_LE(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsLe((a),(b))
|
103
|
+
#define ASSERT_LT(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsLt((a),(b))
|
104
|
+
|
105
|
+
#define TCONCAT(a,b) TCONCAT1(a,b)
|
106
|
+
#define TCONCAT1(a,b) a##b
|
107
|
+
|
108
|
+
#define TEST(base,name) \
|
109
|
+
class TCONCAT(_Test_,name) : public base { \
|
110
|
+
public: \
|
111
|
+
void _Run(); \
|
112
|
+
static void _RunIt() { \
|
113
|
+
TCONCAT(_Test_,name) t; \
|
114
|
+
t._Run(); \
|
115
|
+
} \
|
116
|
+
}; \
|
117
|
+
bool TCONCAT(_Test_ignored_,name) = \
|
118
|
+
::leveldb::test::RegisterTest(#base, #name, &TCONCAT(_Test_,name)::_RunIt); \
|
119
|
+
void TCONCAT(_Test_,name)::_Run()
|
120
|
+
|
121
|
+
// Register the specified test. Typically not used directly, but
|
122
|
+
// invoked via the macro expansion of TEST.
|
123
|
+
extern bool RegisterTest(const char* base, const char* name, void (*func)());
|
124
|
+
|
125
|
+
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
129
|
+
#endif // STORAGE_LEVELDB_UTIL_TESTHARNESS_H_
|
@@ -0,0 +1,51 @@
|
|
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/testutil.h"
|
6
|
+
|
7
|
+
#include "util/random.h"
|
8
|
+
|
9
|
+
namespace leveldb {
|
10
|
+
namespace test {
|
11
|
+
|
12
|
+
Slice RandomString(Random* rnd, int len, std::string* dst) {
|
13
|
+
dst->resize(len);
|
14
|
+
for (int i = 0; i < len; i++) {
|
15
|
+
(*dst)[i] = static_cast<char>(' ' + rnd->Uniform(95)); // ' ' .. '~'
|
16
|
+
}
|
17
|
+
return Slice(*dst);
|
18
|
+
}
|
19
|
+
|
20
|
+
std::string RandomKey(Random* rnd, int len) {
|
21
|
+
// Make sure to generate a wide variety of characters so we
|
22
|
+
// test the boundary conditions for short-key optimizations.
|
23
|
+
static const char kTestChars[] = {
|
24
|
+
'\0', '\1', 'a', 'b', 'c', 'd', 'e', '\xfd', '\xfe', '\xff'
|
25
|
+
};
|
26
|
+
std::string result;
|
27
|
+
for (int i = 0; i < len; i++) {
|
28
|
+
result += kTestChars[rnd->Uniform(sizeof(kTestChars))];
|
29
|
+
}
|
30
|
+
return result;
|
31
|
+
}
|
32
|
+
|
33
|
+
|
34
|
+
extern Slice CompressibleString(Random* rnd, double compressed_fraction,
|
35
|
+
int len, std::string* dst) {
|
36
|
+
int raw = static_cast<int>(len * compressed_fraction);
|
37
|
+
if (raw < 1) raw = 1;
|
38
|
+
std::string raw_data;
|
39
|
+
RandomString(rnd, raw, &raw_data);
|
40
|
+
|
41
|
+
// Duplicate the random data until we have filled "len" bytes
|
42
|
+
dst->clear();
|
43
|
+
while (dst->size() < len) {
|
44
|
+
dst->append(raw_data);
|
45
|
+
}
|
46
|
+
dst->resize(len);
|
47
|
+
return Slice(*dst);
|
48
|
+
}
|
49
|
+
|
50
|
+
}
|
51
|
+
}
|