@ -25,27 +25,27 @@ creating it if necessary:
#include < assert>
#include < assert>
#include "leveldb/db.h"
#include "leveldb/db.h"
level db::DB* db;
rocks db::DB* db;
level db::Options options;
rocks db::Options options;
options.create_if_missing = true;
options.create_if_missing = true;
leveldb::Status status = level db::DB::Open(options, "/tmp/testdb", & db);
rocksdb::Status status = rocks db::DB::Open(options, "/tmp/testdb", & db);
assert(status.ok());
assert(status.ok());
...
...
< / pre >
< / pre >
If you want to raise an error if the database already exists, add
If you want to raise an error if the database already exists, add
the following line before the < code > level db::DB::Open< / code > call:
the following line before the < code > rocks db::DB::Open< / code > call:
< pre >
< pre >
options.error_if_exists = true;
options.error_if_exists = true;
< / pre >
< / pre >
< h1 > Status< / h1 >
< h1 > Status< / h1 >
< p >
< p >
You may have noticed the < code > level db::Status< / code > type above. Values of this
You may have noticed the < code > rocks db::Status< / code > type above. Values of this
type are returned by most functions in < code > leveldb< / code > that may encounter an
type are returned by most functions in < code > leveldb< / code > that may encounter an
error. You can check if such a result is ok, and also print an
error. You can check if such a result is ok, and also print an
associated error message:
associated error message:
< p >
< p >
< pre >
< pre >
level db::Status s = ...;
rocks db::Status s = ...;
if (!s.ok()) cerr < < s.ToString() < < endl;
if (!s.ok()) cerr < < s.ToString() < < endl;
< / pre >
< / pre >
< h1 > Closing A Database< / h1 >
< h1 > Closing A Database< / h1 >
@ -65,9 +65,9 @@ modify/query the database. For example, the following code
moves the value stored under key1 to key2.
moves the value stored under key1 to key2.
< pre >
< pre >
std::string value;
std::string value;
leveldb::Status s = db-> Get(level db::ReadOptions(), key1, & value);
rocksdb::Status s = db-> Get(rocks db::ReadOptions(), key1, & value);
if (s.ok()) s = db-> Put(level db::WriteOptions(), key2, value);
if (s.ok()) s = db-> Put(rocks db::WriteOptions(), key2, value);
if (s.ok()) s = db-> Delete(level db::WriteOptions(), key1);
if (s.ok()) s = db-> Delete(rocks db::WriteOptions(), key1);
< / pre >
< / pre >
< h1 > Atomic Updates< / h1 >
< h1 > Atomic Updates< / h1 >
@ -81,12 +81,12 @@ atomically apply a set of updates:
#include "leveldb/write_batch.h"
#include "leveldb/write_batch.h"
...
...
std::string value;
std::string value;
leveldb::Status s = db-> Get(level db::ReadOptions(), key1, & value);
rocksdb::Status s = db-> Get(rocks db::ReadOptions(), key1, & value);
if (s.ok()) {
if (s.ok()) {
level db::WriteBatch batch;
rocks db::WriteBatch batch;
batch.Delete(key1);
batch.Delete(key1);
batch.Put(key2, value);
batch.Put(key2, value);
s = db-> Write(level db::WriteOptions(), & batch);
s = db-> Write(rocks db::WriteOptions(), & batch);
}
}
< / pre >
< / pre >
The < code > WriteBatch< / code > holds a sequence of edits to be made to the database,
The < code > WriteBatch< / code > holds a sequence of edits to be made to the database,
@ -109,7 +109,7 @@ persistent storage. (On Posix systems, this is implemented by calling
either < code > fsync(...)< / code > or < code > fdatasync(...)< / code > or
either < code > fsync(...)< / code > or < code > fdatasync(...)< / code > or
< code > msync(..., MS_SYNC)< / code > before the write operation returns.)
< code > msync(..., MS_SYNC)< / code > before the write operation returns.)
< pre >
< pre >
level db::WriteOptions write_options;
rocks db::WriteOptions write_options;
write_options.sync = true;
write_options.sync = true;
db-> Put(write_options, ...);
db-> Put(write_options, ...);
< / pre >
< / pre >
@ -144,7 +144,7 @@ the batch.
A database may only be opened by one process at a time.
A database may only be opened by one process at a time.
The < code > leveldb< / code > implementation acquires a lock from the
The < code > leveldb< / code > implementation acquires a lock from the
operating system to prevent misuse. Within a single process, the
operating system to prevent misuse. Within a single process, the
same < code > level db::DB< / code > object may be safely shared by multiple
same < code > rocks db::DB< / code > object may be safely shared by multiple
concurrent threads. I.e., different threads may write into or fetch
concurrent threads. I.e., different threads may write into or fetch
iterators or call < code > Get< / code > on the same database without any
iterators or call < code > Get< / code > on the same database without any
external synchronization (the leveldb implementation will
external synchronization (the leveldb implementation will
@ -160,7 +160,7 @@ The following example demonstrates how to print all key,value pairs
in a database.
in a database.
< p >
< p >
< pre >
< pre >
leveldb::Iterator* it = db-> NewIterator(level db::ReadOptions());
rocksdb::Iterator* it = db-> NewIterator(rocks db::ReadOptions());
for (it-> SeekToFirst(); it-> Valid(); it-> Next()) {
for (it-> SeekToFirst(); it-> Valid(); it-> Next()) {
cout < < it-> key().ToString() < < ": " < < it-> value().ToString() < < endl;
cout < < it-> key().ToString() < < ": " < < it-> value().ToString() < < endl;
}
}
@ -196,10 +196,10 @@ implicit snapshot of the current state.
Snapshots are created by the DB::GetSnapshot() method:
Snapshots are created by the DB::GetSnapshot() method:
< p >
< p >
< pre >
< pre >
level db::ReadOptions options;
rocks db::ReadOptions options;
options.snapshot = db-> GetSnapshot();
options.snapshot = db-> GetSnapshot();
... apply some updates to db ...
... apply some updates to db ...
level db::Iterator* iter = db-> NewIterator(options);
rocks db::Iterator* iter = db-> NewIterator(options);
... read using iter to view the state when the snapshot was created ...
... read using iter to view the state when the snapshot was created ...
delete iter;
delete iter;
db-> ReleaseSnapshot(options.snapshot);
db-> ReleaseSnapshot(options.snapshot);
@ -211,7 +211,7 @@ support reading as of that snapshot.
< h1 > Slice< / h1 >
< h1 > Slice< / h1 >
< p >
< p >
The return value of the < code > it->key()< / code > and < code > it->value()< / code > calls above
The return value of the < code > it->key()< / code > and < code > it->value()< / code > calls above
are instances of the < code > level db::Slice< / code > type. < code > Slice< / code > is a simple
are instances of the < code > rocks db::Slice< / code > type. < code > Slice< / code > is a simple
structure that contains a length and a pointer to an external byte
structure that contains a length and a pointer to an external byte
array. Returning a < code > Slice< / code > is a cheaper alternative to returning a
array. Returning a < code > Slice< / code > is a cheaper alternative to returning a
< code > std::string< / code > since we do not need to copy potentially large keys and
< code > std::string< / code > since we do not need to copy potentially large keys and
@ -223,10 +223,10 @@ C++ strings and null-terminated C-style strings can be easily converted
to a Slice:
to a Slice:
< p >
< p >
< pre >
< pre >
level db::Slice s1 = "hello";
rocks db::Slice s1 = "hello";
std::string str("world");
std::string str("world");
level db::Slice s2 = str;
rocks db::Slice s2 = str;
< / pre >
< / pre >
A Slice can be easily converted back to a C++ string:
A Slice can be easily converted back to a C++ string:
< pre >
< pre >
@ -238,7 +238,7 @@ the external byte array into which the Slice points remains live while
the Slice is in use. For example, the following is buggy:
the Slice is in use. For example, the following is buggy:
< p >
< p >
< pre >
< pre >
level db::Slice slice;
rocks db::Slice slice;
if (...) {
if (...) {
std::string str = ...;
std::string str = ...;
slice = str;
slice = str;
@ -255,16 +255,16 @@ which orders bytes lexicographically. You can however supply a custom
comparator when opening a database. For example, suppose each
comparator when opening a database. For example, suppose each
database key consists of two numbers and we should sort by the first
database key consists of two numbers and we should sort by the first
number, breaking ties by the second number. First, define a proper
number, breaking ties by the second number. First, define a proper
subclass of < code > level db::Comparator< / code > that expresses these rules:
subclass of < code > rocks db::Comparator< / code > that expresses these rules:
< p >
< p >
< pre >
< pre >
class TwoPartComparator : public level db::Comparator {
class TwoPartComparator : public rocks db::Comparator {
public:
public:
// Three-way comparison function:
// Three-way comparison function:
// if a < b: negative result
// if a < b: negative result
// if a > b: positive result
// if a > b: positive result
// else: zero result
// else: zero result
int Compare(const leveldb::Slice& a, const level db::Slice& b) const {
int Compare(const rocksdb::Slice& a, const rocks db::Slice& b) const {
int a1, a2, b1, b2;
int a1, a2, b1, b2;
ParseKey(a, & a1, & a2);
ParseKey(a, & a1, & a2);
ParseKey(b, & b1, & b2);
ParseKey(b, & b1, & b2);
@ -277,7 +277,7 @@ subclass of <code>leveldb::Comparator</code> that expresses these rules:
// Ignore the following methods for now:
// Ignore the following methods for now:
const char* Name() const { return "TwoPartComparator"; }
const char* Name() const { return "TwoPartComparator"; }
void FindShortestSeparator(std::string*, const level db::Slice& ) const { }
void FindShortestSeparator(std::string*, const rocks db::Slice& ) const { }
void FindShortSuccessor(std::string*) const { }
void FindShortSuccessor(std::string*) const { }
};
};
< / pre >
< / pre >
@ -285,18 +285,18 @@ Now create a database using this custom comparator:
< p >
< p >
< pre >
< pre >
TwoPartComparator cmp;
TwoPartComparator cmp;
level db::DB* db;
rocks db::DB* db;
level db::Options options;
rocks db::Options options;
options.create_if_missing = true;
options.create_if_missing = true;
options.comparator = & cmp;
options.comparator = & cmp;
leveldb::Status status = level db::DB::Open(options, "/tmp/testdb", & db);
rocksdb::Status status = rocks db::DB::Open(options, "/tmp/testdb", & db);
...
...
< / pre >
< / pre >
< h2 > Backwards compatibility< / h2 >
< h2 > Backwards compatibility< / h2 >
< p >
< p >
The result of the comparator's < code > Name< / code > method is attached to the
The result of the comparator's < code > Name< / code > method is attached to the
database when it is created, and is checked on every subsequent
database when it is created, and is checked on every subsequent
database open. If the name changes, the < code > level db::DB::Open< / code > call will
database open. If the name changes, the < code > rocks db::DB::Open< / code > call will
fail. Therefore, change the name if and only if the new key format
fail. Therefore, change the name if and only if the new key format
and comparison function are incompatible with existing databases, and
and comparison function are incompatible with existing databases, and
it is ok to discard the contents of all existing databases.
it is ok to discard the contents of all existing databases.
@ -339,9 +339,9 @@ compression entirely, but should only do so if benchmarks show a
performance improvement:
performance improvement:
< p >
< p >
< pre >
< pre >
level db::Options options;
rocks db::Options options;
options.compression = level db::kNoCompression;
options.compression = rocks db::kNoCompression;
... level db::DB::Open(options, name, ...) ....
... rocks db::DB::Open(options, name, ...) ....
< / pre >
< / pre >
< h2 > Cache< / h2 >
< h2 > Cache< / h2 >
< p >
< p >
@ -353,10 +353,10 @@ uncompressed block contents.
< pre >
< pre >
#include "leveldb/cache.h"
#include "leveldb/cache.h"
level db::Options options;
rocks db::Options options;
options.cache = level db::NewLRUCache(100 * 1048576); // 100MB cache
options.cache = rocks db::NewLRUCache(100 * 1048576); // 100MB cache
level db::DB* db;
rocks db::DB* db;
level db::DB::Open(options, name, &db);
rocks db::DB::Open(options, name, &db);
... use the db ...
... use the db ...
delete db
delete db
delete options.cache;
delete options.cache;
@ -373,9 +373,9 @@ displacing most of the cached contents. A per-iterator option can be
used to achieve this:
used to achieve this:
< p >
< p >
< pre >
< pre >
level db::ReadOptions options;
rocks db::ReadOptions options;
options.fill_cache = false;
options.fill_cache = false;
level db::Iterator* it = db-> NewIterator(options);
rocks db::Iterator* it = db-> NewIterator(options);
for (it-> SeekToFirst(); it-> Valid(); it-> Next()) {
for (it-> SeekToFirst(); it-> Valid(); it-> Next()) {
...
...
}
}
@ -407,10 +407,10 @@ a single <code>Get()</code> call may involve multiple reads from disk.
The optional < code > FilterPolicy< / code > mechanism can be used to reduce
The optional < code > FilterPolicy< / code > mechanism can be used to reduce
the number of disk reads substantially.
the number of disk reads substantially.
< pre >
< pre >
level db::Options options;
rocks db::Options options;
options.filter_policy = NewBloomFilter(10);
options.filter_policy = NewBloomFilter(10);
level db::DB* db;
rocks db::DB* db;
level db::DB::Open(options, "/tmp/testdb", & db);
rocks db::DB::Open(options, "/tmp/testdb", & db);
... use the database ...
... use the database ...
delete db;
delete db;
delete options.filter_policy;
delete options.filter_policy;
@ -434,7 +434,7 @@ consider a comparator that ignores trailing spaces when comparing keys.
Instead, the application should provide a custom filter policy that
Instead, the application should provide a custom filter policy that
also ignores trailing spaces. For example:
also ignores trailing spaces. For example:
< pre >
< pre >
class CustomFilterPolicy : public level db::FilterPolicy {
class CustomFilterPolicy : public rocks db::FilterPolicy {
private:
private:
FilterPolicy* builtin_policy_;
FilterPolicy* builtin_policy_;
public:
public:
@ -484,7 +484,7 @@ checksums are verified:
parts of its persistent storage have been corrupted.
parts of its persistent storage have been corrupted.
< p >
< p >
If a database is corrupted (perhaps it cannot be opened when
If a database is corrupted (perhaps it cannot be opened when
paranoid checking is turned on), the < code > level db::RepairDB< / code > function
paranoid checking is turned on), the < code > rocks db::RepairDB< / code > function
may be used to recover as much of the data as possible
may be used to recover as much of the data as possible
< p >
< p >
< / ul >
< / ul >
@ -494,11 +494,11 @@ The <code>GetApproximateSizes</code> method can used to get the approximate
number of bytes of file system space used by one or more key ranges.
number of bytes of file system space used by one or more key ranges.
< p >
< p >
< pre >
< pre >
level db::Range ranges[2];
rocks db::Range ranges[2];
ranges[0] = level db::Range("a", "c");
ranges[0] = rocks db::Range("a", "c");
ranges[1] = level db::Range("x", "z");
ranges[1] = rocks db::Range("x", "z");
uint64_t sizes[2];
uint64_t sizes[2];
level db::Status s = db-> GetApproximateSizes(ranges, 2, sizes);
rocks db::Status s = db-> GetApproximateSizes(ranges, 2, sizes);
< / pre >
< / pre >
The preceding call will set < code > sizes[0]< / code > to the approximate number of
The preceding call will set < code > sizes[0]< / code > to the approximate number of
bytes of file system space used by the key range < code > [a..c)< / code > and
bytes of file system space used by the key range < code > [a..c)< / code > and
@ -508,21 +508,21 @@ bytes of file system space used by the key range <code>[a..c)</code> and
< h1 > Environment< / h1 >
< h1 > Environment< / h1 >
< p >
< p >
All file operations (and other operating system calls) issued by the
All file operations (and other operating system calls) issued by the
< code > leveldb< / code > implementation are routed through a < code > level db::Env< / code > object.
< code > leveldb< / code > implementation are routed through a < code > rocks db::Env< / code > object.
Sophisticated clients may wish to provide their own < code > Env< / code >
Sophisticated clients may wish to provide their own < code > Env< / code >
implementation to get better control. For example, an application may
implementation to get better control. For example, an application may
introduce artificial delays in the file IO paths to limit the impact
introduce artificial delays in the file IO paths to limit the impact
of < code > leveldb< / code > on other activities in the system.
of < code > leveldb< / code > on other activities in the system.
< p >
< p >
< pre >
< pre >
class SlowEnv : public level db::Env {
class SlowEnv : public rocks db::Env {
.. implementation of the Env interface ...
.. implementation of the Env interface ...
};
};
SlowEnv env;
SlowEnv env;
level db::Options options;
rocks db::Options options;
options.env = & env;
options.env = & env;
Status s = level db::DB::Open(options, ...);
Status s = rocks db::DB::Open(options, ...);
< / pre >
< / pre >
< h1 > Porting< / h1 >
< h1 > Porting< / h1 >
< p >
< p >
@ -531,7 +531,7 @@ specific implementations of the types/methods/functions exported by
< code > leveldb/port/port.h< / code > . See < code > leveldb/port/port_example.h< / code > for more
< code > leveldb/port/port.h< / code > . See < code > leveldb/port/port_example.h< / code > for more
details.
details.
< p >
< p >
In addition, the new platform may need a new default < code > level db::Env< / code >
In addition, the new platform may need a new default < code > rocks db::Env< / code >
implementation. See < code > leveldb/util/env_posix.h< / code > for an example.
implementation. See < code > leveldb/util/env_posix.h< / code > for an example.
< h1 > Other Information< / h1 >
< h1 > Other Information< / h1 >