Implement the FB-Assoc API via thrift.

Summary:

Test Plan:

Reviewers:

CC:

Task ID: #

Blame Rev:
main
Dhruba Borthakur 13 years ago
parent 4abf94eeb4
commit b40ad060e0
  1. 4
      build_detect_platform
  2. 450
      thrift/assoc.h
  3. 70
      thrift/folly/Preprocessor.h
  4. 158
      thrift/folly/ScopeGuard.h
  5. 2135
      thrift/gen-cpp/AssocService.cpp
  6. 1132
      thrift/gen-cpp/AssocService.h
  7. 193
      thrift/gen-cpp/DB.cpp
  8. 38
      thrift/gen-cpp/DB.h
  9. 316
      thrift/gen-cpp/leveldb_types.cpp
  10. 168
      thrift/gen-cpp/leveldb_types.h
  11. 198
      thrift/if/leveldb.thrift
  12. 35
      thrift/lib/cpp/EventHandlerBase.h
  13. 6
      thrift/lib/cpp/Thrift.h
  14. 1
      thrift/lib/cpp/async/TAsyncSSLSocket.h
  15. 4
      thrift/lib/cpp/async/TAsyncServerSocket.h
  16. 9
      thrift/lib/cpp/async/TAsyncSocket.h
  17. 9
      thrift/lib/cpp/async/TAsyncTimeout.h
  18. 3
      thrift/lib/cpp/async/TAsyncTransport.h
  19. 31
      thrift/lib/cpp/async/TEventServer.h
  20. 10
      thrift/lib/cpp/protocol/THeaderProtocol.h
  21. 52
      thrift/lib/cpp/transport/TBufferTransports.h
  22. 6
      thrift/lib/cpp/transport/THttpTransport.h
  23. 3
      thrift/lib/cpp/util/ServerCreatorBase.h
  24. 61
      thrift/lib/cpp/util/TEventServerCreator.h
  25. BIN
      thrift/libs/libasync.a
  26. BIN
      thrift/libs/libasync_base.a
  27. BIN
      thrift/libs/libasync_ssl.a
  28. BIN
      thrift/libs/libconcurrency.a
  29. BIN
      thrift/libs/libexample.a
  30. BIN
      thrift/libs/libheader.a
  31. BIN
      thrift/libs/libhttpparser.a
  32. BIN
      thrift/libs/libinternal_util.a
  33. BIN
      thrift/libs/libprocessor.a
  34. BIN
      thrift/libs/libprotocol.a
  35. 1
      thrift/libs/libreflection.a
  36. BIN
      thrift/libs/libserver.a
  37. BIN
      thrift/libs/libthrift.a
  38. BIN
      thrift/libs/libthrift_base.a
  39. BIN
      thrift/libs/libthrift_exception.a
  40. BIN
      thrift/libs/libtransport.a
  41. BIN
      thrift/libs/libtransport_ssl.a
  42. BIN
      thrift/libs/libutil.a
  43. 18
      thrift/openhandles.h
  44. 11
      thrift/server_options.cpp
  45. 25
      thrift/server_options.h
  46. 99
      thrift/server_utils.cpp
  47. 147
      thrift/test/simpletest.cpp

@ -102,7 +102,7 @@ esac
# prune take effect.
DIRS="util db table"
if test "$USE_THRIFT"; then
DIRS+=" thrift/gen-cpp thrift/server_utils.cpp thrift/server_options.cpp"
DIRS+=" thrift/gen-cpp thrift/server_utils.cpp "
THRIFTSERVER=leveldb_server
fi
set -f # temporarily disable globbing so that our patterns aren't expanded
@ -192,7 +192,7 @@ fi
# shall we build thrift server
if test "$USE_THRIFT"; then
THRIFT_CCFLAGS=" -I./thrift -I./thrift/gen-cpp -I./thrift/lib/cpp -I/usr/include -std=gnu++0x"
THRIFT_LDFLAGS=" -lserver -lthrift_base -ltransport -lthrift_exception -lutil -L./thrift/libs "
THRIFT_LDFLAGS=" -lexample -lserver -lthrift_base -ltransport -lthrift_exception -lutil -L./thrift/libs "
COMMON_FLAGS+=$THRIFT_CCFLAGS
PLATFORM_LDFLAGS+=$THRIFT_LDFLAGS
fi

@ -0,0 +1,450 @@
/**
* Thrift server that supports operations on the
* Facebook TAO Graph database
* @author Dhruba Borthakur (dhruba@gmail.com)
* Copyright 2012 Facebook
*/
#ifndef THRIFT_LEVELDB_ASSOC_SERVER_H_
#define THRIFT_LEVELDB_ASSOC_SERVER_H_
#include <AssocService.h>
#include <leveldb_types.h>
#include "openhandles.h"
#include "server_options.h"
#include "leveldb/db.h"
#include "leveldb/write_batch.h"
#include "util/testharness.h"
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace apache::thrift::server;
using boost::shared_ptr;
using namespace ::Tleveldb;
//
// These are the service methods that processes Association Data.
class AssocServiceHandler : virtual public AssocServiceIf {
public:
AssocServiceHandler(OpenHandles* openhandles) {
openhandles_ = openhandles;
}
int64_t taoAssocPut(const Text& tableName, int64_t assocType, int64_t id1,
int64_t id2, int64_t id1Type, int64_t id2Type,
int64_t timestamp, AssocVisibility visibility,
bool update_count, int64_t dataVersion, const Text& data,
const Text& wormhole_comment) {
leveldb::DB* db = openhandles_->get(tableName, NULL);
if (db == NULL) {
return Code::kNotFound;
}
int64_t ret = assocPutInternal(tableName,
db, assocType, id1, id2, id1Type, id2Type,
timestamp, visibility, update_count, dataVersion,
data, wormhole_comment);
return ret;
}
int64_t taoAssocDelete(const Text& tableName, int64_t assocType, int64_t id1,
int64_t id2, AssocVisibility visibility, bool update_count,
const Text& wormhole_comment) {
printf("taoAssocDelete\n");
}
void taoAssocRangeGet(std::vector<TaoAssocGetResult> & _return,
const Text& tableName, int64_t assocType, int64_t id1,
int64_t start_time, int64_t end_time, int64_t offset,
int64_t limit) {
printf("taoAssocRangeGet\n");
}
void taoAssocGet(std::vector<TaoAssocGetResult> & _return,
const Text& tableName, int64_t assocType, int64_t id1,
const std::vector<int64_t> & id2s) {
leveldb::DB* db = openhandles_->get(tableName, NULL);
if (db == NULL) {
throw generate_exception(tableName, Code::kNotFound,
"Unable to database " ,
assocType, id1, 0, 0, 0, 0, Tleveldb::UNUSED1);
}
taoAssocGetInternal(_return, tableName, db, assocType, id1, id2s);
}
int64_t taoAssocCount(const Text& tableName, int64_t assocType, int64_t id1) {
leveldb::DB* db = openhandles_->get(tableName, NULL);
if (db == NULL) {
return Code::kNotFound;
}
return taoAssocCountInternal(tableName, db, assocType, id1);
}
private:
OpenHandles* openhandles_;
//
// inserts an assoc
// Returns true if the iinsertion is successful, otherwise return false.
//
bool assocPutInternal(const Text& tableName, leveldb::DB* db,
int64_t assocType, int64_t id1,
int64_t id2, int64_t id1Type, int64_t id2Type,
int64_t ts, AssocVisibility vis,
bool update_count, int64_t dataVersion, const Text& data,
const Text& wormhole_comment) {
leveldb::WriteOptions woptions;
woptions.sync = true;
// create the payload for this assoc
int payloadsize = sizeof(id1Type) + sizeof(id2Type) +
sizeof(dataVersion) + data.size() + wormhole_comment.size();
std::string payload;
payload.reserve(payloadsize);
payload.resize(payloadsize);
makePayload(&payload[0], id1Type, id2Type, dataVersion, data,
wormhole_comment);
leveldb::Slice payload_slice(payload);
// create RowKey with plenty of space at the end to query
// all columns 'c', 'm', 'p, etc.
int maxkeysize = sizeof(id1) + sizeof(assocType) +
1 + // 'c', 'p' or 'm'
sizeof(ts) +
sizeof(id2);
std::string dummy;
dummy.reserve(maxkeysize);
dummy.resize(maxkeysize);
char* keybuf = &dummy[0];
int rowkeysize = makeRowKey(keybuf, id1, assocType);
leveldb::ReadOptions roptions;
leveldb::Status status;
std::string value;
int keysize;
int64_t count = 0;
int64_t oldts;
int8_t oldvis;
bool newassoc = false; // is this assoc new or an overwrite
// make a key for count
keysize = appendRowKeyForCount(rowkeysize, keybuf);
leveldb::Slice ckey(keybuf, keysize);
// Scan 'c' to get $count if $update_count == true
if (update_count) {
status = db->Get(roptions, ckey, &value);
if (status.IsNotFound()) {
// nothing to do
} else if (!status.ok() || (value.size() != sizeof(int64_t))) {
throw generate_exception(tableName, Code::kNotFound,
"Unable to find count ",
assocType, id1, id2, id1Type, id2Type, ts, vis);
} else {
extract_int64(&count, (char *)value.c_str());
}
}
// Scan 'm'$id2 to get $ts and $vis
keysize = appendRowKeyForMeta(rowkeysize, keybuf, id2);
leveldb::Slice mkey(keybuf, keysize);
status = db->Get(roptions, mkey, &value);
if (status.IsNotFound()) {
newassoc = true;
} else if (!status.ok() ||
(value.size() != sizeof(int64_t) + sizeof(int8_t))) {
throw generate_exception(tableName, Code::kNotFound,
"Unable to find m$id2 ",
assocType, id1, id2, id1Type, id2Type, ts, vis);
}
// make the key 'p'$old_ts$id2
keysize = appendRowKeyForPayload(rowkeysize, keybuf, oldts, id2);
leveldb::Slice pkey(keybuf, keysize);
// if ts != oldts, then delete 'p'$old_ts$id2
if (!newassoc) {
char* val = (char *)value.c_str();
extract_int64(&oldts, val);
extract_int8(&oldvis, val + sizeof(int64_t));
if (ts != oldts) {
if (!db->Delete(woptions, pkey).ok()) {
throw generate_exception(tableName, Code::kNotFound,
"Unable to delete from p$oldts$id2 ",
assocType, id1, id2, id1Type, id2Type, ts, vis);
}
}
}
// store in m$id2 the value of $ts$vis
std::string myvalue;
appendRowKeyForMeta(rowkeysize, keybuf, id2);
myvalue.reserve(sizeof(int64_t) + sizeof(int8_t));
myvalue.resize(sizeof(int64_t) + sizeof(int8_t));
makeTsVisString(&myvalue[0], ts, vis);
leveldb::Slice sl(myvalue);
if (!db->Put(woptions, mkey, sl).ok()) {
// throw exception;
throw generate_exception(tableName, Code::kNotFound,
"Unable to put into m$id2",
assocType, id1, id2, id1Type, id2Type, ts, vis);
}
// store in p$ts$id2 the payload
appendRowKeyForPayload(rowkeysize, keybuf, ts, id2);
if (!db->Put(woptions, pkey, payload_slice).ok()) {
throw generate_exception(tableName, Code::kNotFound,
"Unable to put into p$ts$id2",
assocType, id1, id2, id1Type, id2Type, ts, vis);
}
// increment count
if (update_count && (newassoc || oldvis != VISIBLE)) {
assert(count >= 0);
count++;
appendRowKeyForCount(rowkeysize, keybuf);
myvalue.reserve(sizeof(int64_t));
myvalue.resize(sizeof(int64_t));
makeCountString(&myvalue[0], count);
leveldb::Slice count_slice(myvalue);
if (!db->Put(woptions, ckey, count_slice).ok()) {
throw generate_exception(tableName, Code::kNotFound,
"Unable to insert into count",
assocType, id1, id2, id1Type, id2Type, ts, vis);
}
}
if (update_count) {
assert(count > 0);
return count;
}
return 0;
}
int64_t taoAssocCountInternal(const Text& tableName, leveldb::DB* db,
int64_t assocType, int64_t id1) {
// create key to query
int maxkeysize = sizeof(id1) + sizeof(assocType) + 1;
std::string dummy;
dummy.reserve(maxkeysize);
dummy.resize(maxkeysize);
char* keybuf = &dummy[0];
int rowkeysize = makeRowKey(keybuf, id1, assocType);
int keysize = appendRowKeyForCount(rowkeysize, keybuf); // column 'c'
leveldb::Slice ckey(keybuf, keysize);
// query database to find value
leveldb::ReadOptions roptions;
leveldb::Status status;
std::string value;
int64_t count;
status = db->Get(roptions, ckey, &value);
// parse results retrieved from database
if (status.IsNotFound()) {
return 0; // non existant assoc
} else if (!status.ok()) {
throw generate_exception(tableName, Code::kNotFound,
"Unable to find count ",
assocType, id1, 0, 0, 0, 0, Tleveldb::UNUSED1);
}
if (value.size() != sizeof(int64_t)) {
printf("expected %lld got %lld\n", sizeof(int64_t), value.size());
throw generate_exception(tableName, Code::kNotFound,
"Bad sizes for count ",
assocType, id1, 0, 0, 0, 0, Tleveldb::UNUSED1);
}
extract_int64(&count, (char *)value.c_str());
return count;
}
void taoAssocGetInternal(std::vector<TaoAssocGetResult> & _return,
const Text& tableName,
leveldb::DB* db,
int64_t assocType, int64_t id1,
const std::vector<int64_t> & id2s) {
int64_t ts, id2;
int8_t oldvis;
leveldb::ReadOptions roptions;
leveldb::Status status;
std::string value;
int numout = 0;
// create max key to query
int maxkeysize = sizeof(id1) + sizeof(assocType) + 1 + sizeof(ts) +
sizeof(id2);
std::string dummy;
dummy.reserve(maxkeysize);
dummy.resize(maxkeysize);
// create rowkey
char* keybuf = &dummy[0];
int rowkeysize = makeRowKey(keybuf, id1, assocType);
for (int index = 0; index < id2s.size(); index++) {
int64_t id2 = id2s[index];
// query column 'm'$id2
int keysize = appendRowKeyForMeta(rowkeysize, keybuf, id2);
leveldb::Slice ckey(keybuf, keysize);
status = db->Get(roptions, ckey, &value);
// parse results retrieved from database
if (status.IsNotFound()) {
continue; // non existant assoc
} else if (!status.ok() ||
value.size() != sizeof(int64_t) + sizeof(int8_t)) {
throw generate_exception(tableName, Code::kNotFound,
"Unable to find m$id2 ",
assocType, id1, id2, 0, 0, 0, Tleveldb::UNUSED1);
}
extractTsVisString(&ts, &oldvis, &value[0]);
if(oldvis != AssocVisibility::VISIBLE) {
continue;
}
ASSERT_NE(ts, 0);
printf("XXX ts = %lld\n", ts);
// this assoc is visible, scan 'p'$ts$id2 to retrieve payload.
keysize = appendRowKeyForPayload(rowkeysize, keybuf, ts, id2);
leveldb::Slice pkey(keybuf, keysize);
status = db->Get(roptions, pkey, &value);
// parse results retrieved from database
if (status.IsNotFound()) {
printf("XXX2");
continue; // non existant assoc
} else if (!status.ok()) {
throw generate_exception(tableName, Code::kNotFound,
"Unable to find m$id2 ",
assocType, id1, id2, 0, 0, 0, Tleveldb::UNUSED1);
}
// update return values
_return[numout].id2 = id2;
_return[numout].data = value;
// un-encoded from the payload XXX
_return[numout].id1Type = 0;
_return[numout].id2Type = 0;
_return[numout].dataVersion = 0;
numout++;
}
}
// fill the row key and returns the size of the key
inline int makeRowKey(char* dest, int64_t id1, int64_t assocType) {
dest = copy_int64_switch_endian(dest, id1);
dest = copy_int64_switch_endian(dest, assocType);
return sizeof(id1) + sizeof(assocType);
}
// fill the row key +'c' and returns the size of the key
inline int appendRowKeyForCount(int rowkeysize, char* dest) {
dest += rowkeysize;
*dest = 'c';
return rowkeysize + 1;
}
// fill the row key +'p' + $ts$id2 and returns the size of the key
inline int appendRowKeyForPayload(int rowkeysize, char* dest,
int64_t ts, int64_t id2) {
dest += rowkeysize;
*dest++ = 'p';
dest = copy_int64_switch_endian(dest, ts);
dest = copy_int64_switch_endian(dest, id2);
return rowkeysize + sizeof(ts) + sizeof(id2) + 1;
}
// fill the row key +'m' + id2 and returns the size of the key
inline int appendRowKeyForMeta(int rowkeysize, char* dest,
int64_t id2) {
dest += rowkeysize;
*dest++ = 'm';
dest = copy_int64_switch_endian(dest, id2);
return rowkeysize + sizeof(id2) + 1;
}
//
// encode id1Type, id2Type, dataversion, etc into the payload
inline void makePayload(char* dest, int64_t id1Type, int64_t id2Type,
int64_t dataVersion, const Text& data,
const Text& wormhole_comment) {
dest = copy_int64_switch_endian(dest, id1Type);
dest = copy_int64_switch_endian(dest, id2Type);
dest = copy_int64_switch_endian(dest, dataVersion);
memcpy(dest, data.data(), data.size());
dest += data.size();
memcpy(dest, wormhole_comment.data(), wormhole_comment.size());
dest += wormhole_comment.size();
}
// fill the timestamp and visibility
inline void makeTsVisString(char* dest, int64_t ts, int8_t vis) {
dest = copy_int64_switch_endian(dest, ts);
*dest = vis;
}
// extracts the timestamp and visibility from a byte stream
inline void extractTsVisString(int64_t* ts, int8_t* vis, char* src) {
extract_int64(ts, src);
extract_int8(vis, src + sizeof(*ts));
}
// fill the count value
inline void makeCountString(char* dest, int64_t count) {
dest = copy_int64_switch_endian(dest, count);
}
//
// Switch endianess of the id and copy it to dest.
// Returns the updated destination address
//
inline char* copy_int64_switch_endian(char* dest, int64_t id) {
char* src = (char *)&id + sizeof(id) - 1;
for (int i = 0; i < sizeof(id); i++) {
*dest++ = *src--;
}
return dest;
}
// extracts a int64 type from the char stream. Swaps endianness.
inline void extract_int64(int64_t* dest, char* src) {
src += sizeof(int64_t) - 1;
for (int i = 0; i < sizeof(uint64_t); i++) {
*dest++ = *src--;
}
}
// extracts a 1 byte integer from the char stream.
inline void extract_int8(int8_t* dest, char* src) {
*dest = *(int8_t *)src;
}
// generate an exception message
LeveldbException generate_exception(const Text& tableName,
Code errorCode, const char* message,
int64_t assocType, int64_t id1,
int64_t id2, int64_t id1Type, int64_t id2Type,
int64_t ts, AssocVisibility vis) {
char result[1024];
sprintf(result,
"id1=%d assocType=%d id2=%d id1Type=%d id2Type=%d ts=%d vis=%d ",
id1, assocType, id2, id1Type, id2Type, ts, vis);
fprintf(stderr, "assoc_server error table %s: %s errorCode=%d %s",
tableName.c_str(), message, errorCode, result);
LeveldbException e;
e.errorCode = errorCode;
e.message = message;
throw e;
}
};
#endif // THRIFT_LEVELDB_ASSOC_SERVER_H_

@ -0,0 +1,70 @@
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// @author: Andrei Alexandrescu
#ifndef FOLLY_PREPROCESSOR_
#define FOLLY_PREPROCESSOR_
/**
* Necessarily evil preprocessor-related amenities.
*/
/**
* FB_ONE_OR_NONE(hello, world) expands to hello and
* FB_ONE_OR_NONE(hello) expands to nothing. This macro is used to
* insert or eliminate text based on the presence of another argument.
*/
#define FB_ONE_OR_NONE(a, ...) FB_THIRD(a, ## __VA_ARGS__, a)
#define FB_THIRD(a, b, ...) __VA_ARGS__
/**
* Helper macro that extracts the first argument out of a list of any
* number of arguments.
*/
#define FB_ARG_1(a, ...) a
/**
* Helper macro that extracts the second argument out of a list of any
* number of arguments. If only one argument is given, it returns
* that.
*/
#define FB_ARG_2_OR_1(...) FB_ARG_2_OR_1_IMPL(__VA_ARGS__, __VA_ARGS__)
// Support macro for the above
#define FB_ARG_2_OR_1_IMPL(a, b, ...) b
/**
* FB_ANONYMOUS_VARIABLE(str) introduces an identifier starting with
* str and ending with a number that varies with the line.
*/
#ifndef FB_ANONYMOUS_VARIABLE
#define FB_CONCATENATE_IMPL(s1, s2) s1##s2
#define FB_CONCATENATE(s1, s2) FB_CONCATENATE_IMPL(s1, s2)
#ifdef __COUNTER__
#define FB_ANONYMOUS_VARIABLE(str) FB_CONCATENATE(str, __COUNTER__)
#else
#define FB_ANONYMOUS_VARIABLE(str) FB_CONCATENATE(str, __LINE__)
#endif
#endif
/**
* Use FB_STRINGIZE(name) when you'd want to do what #name does inside
* another macro expansion.
*/
#define FB_STRINGIZE(name) #name
#endif // FOLLY_PREPROCESSOR_

@ -0,0 +1,158 @@
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FOLLY_SCOPEGUARD_H_
#define FOLLY_SCOPEGUARD_H_
#include <cstddef>
#include <iostream>
#include <functional>
#include <new>
//#include <glog/logging.h>
#include "folly/Preprocessor.h"
namespace folly {
/**
* ScopeGuard is a general implementation of the "Initilization is
* Resource Acquisition" idiom. Basically, it guarantees that a function
* is executed upon leaving the currrent scope unless otherwise told.
*
* The makeGuard() function is used to create a new ScopeGuard object.
* It can be instantiated with a lambda function, a std::function<void()>,
* a functor, or a void(*)() function pointer.
*
*
* Usage example: Add a friend to memory iff it is also added to the db.
*
* void User::addFriend(User& newFriend) {
* // add the friend to memory
* friends_.push_back(&newFriend);
*
* // If the db insertion that follows fails, we should
* // remove it from memory.
* // (You could also declare this as "auto guard = makeGuard(...)")
* ScopeGuard guard = makeGuard([&] { friends_.pop_back(); });
*
* // this will throw an exception upon error, which
* // makes the ScopeGuard execute UserCont::pop_back()
* // once the Guard's destructor is called.
* db_->addFriend(GetName(), newFriend.GetName());
*
* // an exception was not thrown, so don't execute
* // the Guard.
* guard.dismiss();
* }
*
* Examine ScopeGuardTest.cpp for some more sample usage.
*
* Stolen from:
* Andrei's and Petru Marginean's CUJ article:
* http://drdobbs.com/184403758
* and the loki library:
* http://loki-lib.sourceforge.net/index.php?n=Idioms.ScopeGuardPointer
* and triendl.kj article:
* http://www.codeproject.com/KB/cpp/scope_guard.aspx
*/
class ScopeGuardImplBase {
public:
void dismiss() noexcept {
dismissed_ = true;
}
protected:
ScopeGuardImplBase()
: dismissed_(false) {}
ScopeGuardImplBase(ScopeGuardImplBase&& other)
: dismissed_(other.dismissed_) {
other.dismissed_ = true;
}
bool dismissed_;
};
template<typename FunctionType>
class ScopeGuardImpl : public ScopeGuardImplBase {
public:
explicit ScopeGuardImpl(const FunctionType& fn)
: function_(fn) {}
explicit ScopeGuardImpl(FunctionType&& fn)
: function_(std::move(fn)) {}
ScopeGuardImpl(ScopeGuardImpl&& other)
: ScopeGuardImplBase(std::move(other)),
function_(std::move(other.function_)) {
}
~ScopeGuardImpl() noexcept {
if (!dismissed_) {
execute();
}
}
private:
void* operator new(size_t) = delete;
void execute() noexcept {
try {
function_();
} catch (const std::exception& ex) {
std::cout << "ScopeGuard cleanup function threw a " <<
typeid(ex).name() << "exception: " << ex.what();
} catch (...) {
std::cout << "ScopeGuard cleanup function threw a non-exception object";
}
}
FunctionType function_;
};
template<typename FunctionType>
ScopeGuardImpl<typename std::decay<FunctionType>::type>
makeGuard(FunctionType&& fn) {
return ScopeGuardImpl<typename std::decay<FunctionType>::type>(
std::forward<FunctionType>(fn));
}
/**
* This is largely unneeded if you just use auto for your guards.
*/
typedef ScopeGuardImplBase&& ScopeGuard;
namespace detail {
/**
* Internal use for the macro SCOPE_EXIT below
*/
enum class ScopeGuardOnExit {};
template <typename FunctionType>
ScopeGuardImpl<typename std::decay<FunctionType>::type>
operator+(detail::ScopeGuardOnExit, FunctionType&& fn) {
return ScopeGuardImpl<typename std::decay<FunctionType>::type>(
std::forward<FunctionType>(fn));
}
} // namespace detail
} // folly
#define SCOPE_EXIT \
auto FB_ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE) \
= ::folly::detail::ScopeGuardOnExit() + [&]
#endif // FOLLY_SCOPEGUARD_H_

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -5,6 +5,7 @@
* @generated
*/
#include "DB.h"
#include "folly/ScopeGuard.h"
namespace Tleveldb {
@ -2246,16 +2247,16 @@ uint32_t DB_CompactRange_args::read(apache::thrift::protocol::TProtocol* iprot)
break;
case 2:
if (ftype == apache::thrift::protocol::T_STRUCT) {
xfer += this->begin.read(iprot);
this->__isset.begin = true;
xfer += this->start.read(iprot);
this->__isset.start = true;
} else {
xfer += iprot->skip(ftype);
}
break;
case 3:
if (ftype == apache::thrift::protocol::T_STRUCT) {
xfer += this->end.read(iprot);
this->__isset.end = true;
xfer += this->endhere.read(iprot);
this->__isset.endhere = true;
} else {
xfer += iprot->skip(ftype);
}
@ -2278,11 +2279,11 @@ uint32_t DB_CompactRange_args::write(apache::thrift::protocol::TProtocol* oprot)
xfer += oprot->writeFieldBegin("dbhandle", apache::thrift::protocol::T_STRUCT, 1);
xfer += this->dbhandle.write(oprot);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("begin", apache::thrift::protocol::T_STRUCT, 2);
xfer += this->begin.write(oprot);
xfer += oprot->writeFieldBegin("start", apache::thrift::protocol::T_STRUCT, 2);
xfer += this->start.write(oprot);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("end", apache::thrift::protocol::T_STRUCT, 3);
xfer += this->end.write(oprot);
xfer += oprot->writeFieldBegin("endhere", apache::thrift::protocol::T_STRUCT, 3);
xfer += this->endhere.write(oprot);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldStop();
xfer += oprot->writeStructEnd();
@ -2295,11 +2296,11 @@ uint32_t DB_CompactRange_pargs::write(apache::thrift::protocol::TProtocol* oprot
xfer += oprot->writeFieldBegin("dbhandle", apache::thrift::protocol::T_STRUCT, 1);
xfer += (*(this->dbhandle)).write(oprot);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("begin", apache::thrift::protocol::T_STRUCT, 2);
xfer += (*(this->begin)).write(oprot);
xfer += oprot->writeFieldBegin("start", apache::thrift::protocol::T_STRUCT, 2);
xfer += (*(this->start)).write(oprot);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("end", apache::thrift::protocol::T_STRUCT, 3);
xfer += (*(this->end)).write(oprot);
xfer += oprot->writeFieldBegin("endhere", apache::thrift::protocol::T_STRUCT, 3);
xfer += (*(this->endhere)).write(oprot);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldStop();
xfer += oprot->writeStructEnd();
@ -2418,20 +2419,20 @@ int32_t DBClient::getNextRecvSequenceId()
void DBClient::Open(DBHandle& _return, const Text& dbname, const DBOptions& dboptions)
{
std::unique_ptr<apache::thrift::ContextStack> ctx(this->getContextStack("DB.Open", NULL));
folly::ScopeGuard g = folly::makeGuard([&] { this->clearClientContextStack(); });
this->generateClientContextStack("DB.Open", NULL);
try {
this->setContextStack(ctx.get());
send_Open(dbname, dboptions);
recv_Open(_return);
} catch(apache::thrift::transport::TTransportException& ex) {
this->handlerError(ctx.get(), "DB.Open");
this->handlerError(this->getClientContextStack(), "DB.Open");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
throw;
} catch(apache::thrift::TApplicationException& ex) {
if (ex.getType() == apache::thrift::TApplicationException::BAD_SEQUENCE_ID) {
this->handlerError(ctx.get(), "DB.Open");
this->handlerError(this->getClientContextStack(), "DB.Open");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
}
@ -2441,7 +2442,7 @@ void DBClient::Open(DBHandle& _return, const Text& dbname, const DBOptions& dbop
void DBClient::send_Open(const Text& dbname, const DBOptions& dboptions)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
this->preWrite(ctx, "DB.Open");
oprot_->writeMessageBegin("Open", apache::thrift::protocol::T_CALL, getNextSendSequenceId());
@ -2459,7 +2460,7 @@ void DBClient::send_Open(const Text& dbname, const DBOptions& dboptions)
void DBClient::recv_Open(DBHandle& _return)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
uint32_t bytes;
int32_t rseqid = 0;
int32_t eseqid = getNextRecvSequenceId();
@ -2512,20 +2513,20 @@ void DBClient::recv_Open(DBHandle& _return)
Code DBClient::Close(const DBHandle& dbhandle, const Text& dbname)
{
std::unique_ptr<apache::thrift::ContextStack> ctx(this->getContextStack("DB.Close", NULL));
folly::ScopeGuard g = folly::makeGuard([&] { this->clearClientContextStack(); });
this->generateClientContextStack("DB.Close", NULL);
try {
this->setContextStack(ctx.get());
send_Close(dbhandle, dbname);
return recv_Close();
} catch(apache::thrift::transport::TTransportException& ex) {
this->handlerError(ctx.get(), "DB.Close");
this->handlerError(this->getClientContextStack(), "DB.Close");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
throw;
} catch(apache::thrift::TApplicationException& ex) {
if (ex.getType() == apache::thrift::TApplicationException::BAD_SEQUENCE_ID) {
this->handlerError(ctx.get(), "DB.Close");
this->handlerError(this->getClientContextStack(), "DB.Close");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
}
@ -2535,7 +2536,7 @@ Code DBClient::Close(const DBHandle& dbhandle, const Text& dbname)
void DBClient::send_Close(const DBHandle& dbhandle, const Text& dbname)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
this->preWrite(ctx, "DB.Close");
oprot_->writeMessageBegin("Close", apache::thrift::protocol::T_CALL, getNextSendSequenceId());
@ -2553,7 +2554,7 @@ void DBClient::send_Close(const DBHandle& dbhandle, const Text& dbname)
Code DBClient::recv_Close()
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
uint32_t bytes;
int32_t rseqid = 0;
int32_t eseqid = getNextRecvSequenceId();
@ -2603,20 +2604,20 @@ Code DBClient::recv_Close()
Code DBClient::Put(const DBHandle& dbhandle, const kv& keyvalue, const WriteOptions& options)
{
std::unique_ptr<apache::thrift::ContextStack> ctx(this->getContextStack("DB.Put", NULL));
folly::ScopeGuard g = folly::makeGuard([&] { this->clearClientContextStack(); });
this->generateClientContextStack("DB.Put", NULL);
try {
this->setContextStack(ctx.get());
send_Put(dbhandle, keyvalue, options);
return recv_Put();
} catch(apache::thrift::transport::TTransportException& ex) {
this->handlerError(ctx.get(), "DB.Put");
this->handlerError(this->getClientContextStack(), "DB.Put");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
throw;
} catch(apache::thrift::TApplicationException& ex) {
if (ex.getType() == apache::thrift::TApplicationException::BAD_SEQUENCE_ID) {
this->handlerError(ctx.get(), "DB.Put");
this->handlerError(this->getClientContextStack(), "DB.Put");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
}
@ -2626,7 +2627,7 @@ Code DBClient::Put(const DBHandle& dbhandle, const kv& keyvalue, const WriteOpti
void DBClient::send_Put(const DBHandle& dbhandle, const kv& keyvalue, const WriteOptions& options)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
this->preWrite(ctx, "DB.Put");
oprot_->writeMessageBegin("Put", apache::thrift::protocol::T_CALL, getNextSendSequenceId());
@ -2645,7 +2646,7 @@ void DBClient::send_Put(const DBHandle& dbhandle, const kv& keyvalue, const Writ
Code DBClient::recv_Put()
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
uint32_t bytes;
int32_t rseqid = 0;
int32_t eseqid = getNextRecvSequenceId();
@ -2695,20 +2696,20 @@ Code DBClient::recv_Put()
Code DBClient::Delete(const DBHandle& dbhandle, const Slice& key, const WriteOptions& options)
{
std::unique_ptr<apache::thrift::ContextStack> ctx(this->getContextStack("DB.Delete", NULL));
folly::ScopeGuard g = folly::makeGuard([&] { this->clearClientContextStack(); });
this->generateClientContextStack("DB.Delete", NULL);
try {
this->setContextStack(ctx.get());
send_Delete(dbhandle, key, options);
return recv_Delete();
} catch(apache::thrift::transport::TTransportException& ex) {
this->handlerError(ctx.get(), "DB.Delete");
this->handlerError(this->getClientContextStack(), "DB.Delete");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
throw;
} catch(apache::thrift::TApplicationException& ex) {
if (ex.getType() == apache::thrift::TApplicationException::BAD_SEQUENCE_ID) {
this->handlerError(ctx.get(), "DB.Delete");
this->handlerError(this->getClientContextStack(), "DB.Delete");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
}
@ -2718,7 +2719,7 @@ Code DBClient::Delete(const DBHandle& dbhandle, const Slice& key, const WriteOpt
void DBClient::send_Delete(const DBHandle& dbhandle, const Slice& key, const WriteOptions& options)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
this->preWrite(ctx, "DB.Delete");
oprot_->writeMessageBegin("Delete", apache::thrift::protocol::T_CALL, getNextSendSequenceId());
@ -2737,7 +2738,7 @@ void DBClient::send_Delete(const DBHandle& dbhandle, const Slice& key, const Wri
Code DBClient::recv_Delete()
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
uint32_t bytes;
int32_t rseqid = 0;
int32_t eseqid = getNextRecvSequenceId();
@ -2787,20 +2788,20 @@ Code DBClient::recv_Delete()
Code DBClient::Write(const DBHandle& dbhandle, const std::vector<kv> & batch, const WriteOptions& options)
{
std::unique_ptr<apache::thrift::ContextStack> ctx(this->getContextStack("DB.Write", NULL));
folly::ScopeGuard g = folly::makeGuard([&] { this->clearClientContextStack(); });
this->generateClientContextStack("DB.Write", NULL);
try {
this->setContextStack(ctx.get());
send_Write(dbhandle, batch, options);
return recv_Write();
} catch(apache::thrift::transport::TTransportException& ex) {
this->handlerError(ctx.get(), "DB.Write");
this->handlerError(this->getClientContextStack(), "DB.Write");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
throw;
} catch(apache::thrift::TApplicationException& ex) {
if (ex.getType() == apache::thrift::TApplicationException::BAD_SEQUENCE_ID) {
this->handlerError(ctx.get(), "DB.Write");
this->handlerError(this->getClientContextStack(), "DB.Write");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
}
@ -2810,7 +2811,7 @@ Code DBClient::Write(const DBHandle& dbhandle, const std::vector<kv> & batch, co
void DBClient::send_Write(const DBHandle& dbhandle, const std::vector<kv> & batch, const WriteOptions& options)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
this->preWrite(ctx, "DB.Write");
oprot_->writeMessageBegin("Write", apache::thrift::protocol::T_CALL, getNextSendSequenceId());
@ -2829,7 +2830,7 @@ void DBClient::send_Write(const DBHandle& dbhandle, const std::vector<kv> & batc
Code DBClient::recv_Write()
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
uint32_t bytes;
int32_t rseqid = 0;
int32_t eseqid = getNextRecvSequenceId();
@ -2879,20 +2880,20 @@ Code DBClient::recv_Write()
void DBClient::Get(ResultItem& _return, const DBHandle& dbhandle, const Slice& inputkey, const ReadOptions& options)
{
std::unique_ptr<apache::thrift::ContextStack> ctx(this->getContextStack("DB.Get", NULL));
folly::ScopeGuard g = folly::makeGuard([&] { this->clearClientContextStack(); });
this->generateClientContextStack("DB.Get", NULL);
try {
this->setContextStack(ctx.get());
send_Get(dbhandle, inputkey, options);
recv_Get(_return);
} catch(apache::thrift::transport::TTransportException& ex) {
this->handlerError(ctx.get(), "DB.Get");
this->handlerError(this->getClientContextStack(), "DB.Get");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
throw;
} catch(apache::thrift::TApplicationException& ex) {
if (ex.getType() == apache::thrift::TApplicationException::BAD_SEQUENCE_ID) {
this->handlerError(ctx.get(), "DB.Get");
this->handlerError(this->getClientContextStack(), "DB.Get");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
}
@ -2902,7 +2903,7 @@ void DBClient::Get(ResultItem& _return, const DBHandle& dbhandle, const Slice& i
void DBClient::send_Get(const DBHandle& dbhandle, const Slice& inputkey, const ReadOptions& options)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
this->preWrite(ctx, "DB.Get");
oprot_->writeMessageBegin("Get", apache::thrift::protocol::T_CALL, getNextSendSequenceId());
@ -2921,7 +2922,7 @@ void DBClient::send_Get(const DBHandle& dbhandle, const Slice& inputkey, const R
void DBClient::recv_Get(ResultItem& _return)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
uint32_t bytes;
int32_t rseqid = 0;
int32_t eseqid = getNextRecvSequenceId();
@ -2971,20 +2972,20 @@ void DBClient::recv_Get(ResultItem& _return)
void DBClient::NewIterator(ResultIterator& _return, const DBHandle& dbhandle, const ReadOptions& options, IteratorType iteratorType, const Slice& target)
{
std::unique_ptr<apache::thrift::ContextStack> ctx(this->getContextStack("DB.NewIterator", NULL));
folly::ScopeGuard g = folly::makeGuard([&] { this->clearClientContextStack(); });
this->generateClientContextStack("DB.NewIterator", NULL);
try {
this->setContextStack(ctx.get());
send_NewIterator(dbhandle, options, iteratorType, target);
recv_NewIterator(_return);
} catch(apache::thrift::transport::TTransportException& ex) {
this->handlerError(ctx.get(), "DB.NewIterator");
this->handlerError(this->getClientContextStack(), "DB.NewIterator");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
throw;
} catch(apache::thrift::TApplicationException& ex) {
if (ex.getType() == apache::thrift::TApplicationException::BAD_SEQUENCE_ID) {
this->handlerError(ctx.get(), "DB.NewIterator");
this->handlerError(this->getClientContextStack(), "DB.NewIterator");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
}
@ -2994,7 +2995,7 @@ void DBClient::NewIterator(ResultIterator& _return, const DBHandle& dbhandle, co
void DBClient::send_NewIterator(const DBHandle& dbhandle, const ReadOptions& options, IteratorType iteratorType, const Slice& target)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
this->preWrite(ctx, "DB.NewIterator");
oprot_->writeMessageBegin("NewIterator", apache::thrift::protocol::T_CALL, getNextSendSequenceId());
@ -3014,7 +3015,7 @@ void DBClient::send_NewIterator(const DBHandle& dbhandle, const ReadOptions& opt
void DBClient::recv_NewIterator(ResultIterator& _return)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
uint32_t bytes;
int32_t rseqid = 0;
int32_t eseqid = getNextRecvSequenceId();
@ -3064,20 +3065,20 @@ void DBClient::recv_NewIterator(ResultIterator& _return)
Code DBClient::DeleteIterator(const DBHandle& dbhandle, const Iterator& iterator)
{
std::unique_ptr<apache::thrift::ContextStack> ctx(this->getContextStack("DB.DeleteIterator", NULL));
folly::ScopeGuard g = folly::makeGuard([&] { this->clearClientContextStack(); });
this->generateClientContextStack("DB.DeleteIterator", NULL);
try {
this->setContextStack(ctx.get());
send_DeleteIterator(dbhandle, iterator);
return recv_DeleteIterator();
} catch(apache::thrift::transport::TTransportException& ex) {
this->handlerError(ctx.get(), "DB.DeleteIterator");
this->handlerError(this->getClientContextStack(), "DB.DeleteIterator");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
throw;
} catch(apache::thrift::TApplicationException& ex) {
if (ex.getType() == apache::thrift::TApplicationException::BAD_SEQUENCE_ID) {
this->handlerError(ctx.get(), "DB.DeleteIterator");
this->handlerError(this->getClientContextStack(), "DB.DeleteIterator");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
}
@ -3087,7 +3088,7 @@ Code DBClient::DeleteIterator(const DBHandle& dbhandle, const Iterator& iterator
void DBClient::send_DeleteIterator(const DBHandle& dbhandle, const Iterator& iterator)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
this->preWrite(ctx, "DB.DeleteIterator");
oprot_->writeMessageBegin("DeleteIterator", apache::thrift::protocol::T_CALL, getNextSendSequenceId());
@ -3105,7 +3106,7 @@ void DBClient::send_DeleteIterator(const DBHandle& dbhandle, const Iterator& ite
Code DBClient::recv_DeleteIterator()
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
uint32_t bytes;
int32_t rseqid = 0;
int32_t eseqid = getNextRecvSequenceId();
@ -3155,20 +3156,20 @@ Code DBClient::recv_DeleteIterator()
void DBClient::GetNext(ResultPair& _return, const DBHandle& dbhandle, const Iterator& iterator)
{
std::unique_ptr<apache::thrift::ContextStack> ctx(this->getContextStack("DB.GetNext", NULL));
folly::ScopeGuard g = folly::makeGuard([&] { this->clearClientContextStack(); });
this->generateClientContextStack("DB.GetNext", NULL);
try {
this->setContextStack(ctx.get());
send_GetNext(dbhandle, iterator);
recv_GetNext(_return);
} catch(apache::thrift::transport::TTransportException& ex) {
this->handlerError(ctx.get(), "DB.GetNext");
this->handlerError(this->getClientContextStack(), "DB.GetNext");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
throw;
} catch(apache::thrift::TApplicationException& ex) {
if (ex.getType() == apache::thrift::TApplicationException::BAD_SEQUENCE_ID) {
this->handlerError(ctx.get(), "DB.GetNext");
this->handlerError(this->getClientContextStack(), "DB.GetNext");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
}
@ -3178,7 +3179,7 @@ void DBClient::GetNext(ResultPair& _return, const DBHandle& dbhandle, const Iter
void DBClient::send_GetNext(const DBHandle& dbhandle, const Iterator& iterator)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
this->preWrite(ctx, "DB.GetNext");
oprot_->writeMessageBegin("GetNext", apache::thrift::protocol::T_CALL, getNextSendSequenceId());
@ -3196,7 +3197,7 @@ void DBClient::send_GetNext(const DBHandle& dbhandle, const Iterator& iterator)
void DBClient::recv_GetNext(ResultPair& _return)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
uint32_t bytes;
int32_t rseqid = 0;
int32_t eseqid = getNextRecvSequenceId();
@ -3246,20 +3247,20 @@ void DBClient::recv_GetNext(ResultPair& _return)
void DBClient::GetPrev(ResultPair& _return, const DBHandle& dbhandle, const Iterator& iterator)
{
std::unique_ptr<apache::thrift::ContextStack> ctx(this->getContextStack("DB.GetPrev", NULL));
folly::ScopeGuard g = folly::makeGuard([&] { this->clearClientContextStack(); });
this->generateClientContextStack("DB.GetPrev", NULL);
try {
this->setContextStack(ctx.get());
send_GetPrev(dbhandle, iterator);
recv_GetPrev(_return);
} catch(apache::thrift::transport::TTransportException& ex) {
this->handlerError(ctx.get(), "DB.GetPrev");
this->handlerError(this->getClientContextStack(), "DB.GetPrev");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
throw;
} catch(apache::thrift::TApplicationException& ex) {
if (ex.getType() == apache::thrift::TApplicationException::BAD_SEQUENCE_ID) {
this->handlerError(ctx.get(), "DB.GetPrev");
this->handlerError(this->getClientContextStack(), "DB.GetPrev");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
}
@ -3269,7 +3270,7 @@ void DBClient::GetPrev(ResultPair& _return, const DBHandle& dbhandle, const Iter
void DBClient::send_GetPrev(const DBHandle& dbhandle, const Iterator& iterator)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
this->preWrite(ctx, "DB.GetPrev");
oprot_->writeMessageBegin("GetPrev", apache::thrift::protocol::T_CALL, getNextSendSequenceId());
@ -3287,7 +3288,7 @@ void DBClient::send_GetPrev(const DBHandle& dbhandle, const Iterator& iterator)
void DBClient::recv_GetPrev(ResultPair& _return)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
uint32_t bytes;
int32_t rseqid = 0;
int32_t eseqid = getNextRecvSequenceId();
@ -3337,20 +3338,20 @@ void DBClient::recv_GetPrev(ResultPair& _return)
void DBClient::GetSnapshot(ResultSnapshot& _return, const DBHandle& dbhandle)
{
std::unique_ptr<apache::thrift::ContextStack> ctx(this->getContextStack("DB.GetSnapshot", NULL));
folly::ScopeGuard g = folly::makeGuard([&] { this->clearClientContextStack(); });
this->generateClientContextStack("DB.GetSnapshot", NULL);
try {
this->setContextStack(ctx.get());
send_GetSnapshot(dbhandle);
recv_GetSnapshot(_return);
} catch(apache::thrift::transport::TTransportException& ex) {
this->handlerError(ctx.get(), "DB.GetSnapshot");
this->handlerError(this->getClientContextStack(), "DB.GetSnapshot");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
throw;
} catch(apache::thrift::TApplicationException& ex) {
if (ex.getType() == apache::thrift::TApplicationException::BAD_SEQUENCE_ID) {
this->handlerError(ctx.get(), "DB.GetSnapshot");
this->handlerError(this->getClientContextStack(), "DB.GetSnapshot");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
}
@ -3360,7 +3361,7 @@ void DBClient::GetSnapshot(ResultSnapshot& _return, const DBHandle& dbhandle)
void DBClient::send_GetSnapshot(const DBHandle& dbhandle)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
this->preWrite(ctx, "DB.GetSnapshot");
oprot_->writeMessageBegin("GetSnapshot", apache::thrift::protocol::T_CALL, getNextSendSequenceId());
@ -3377,7 +3378,7 @@ void DBClient::send_GetSnapshot(const DBHandle& dbhandle)
void DBClient::recv_GetSnapshot(ResultSnapshot& _return)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
uint32_t bytes;
int32_t rseqid = 0;
int32_t eseqid = getNextRecvSequenceId();
@ -3427,20 +3428,20 @@ void DBClient::recv_GetSnapshot(ResultSnapshot& _return)
Code DBClient::ReleaseSnapshot(const DBHandle& dbhandle, const Snapshot& snapshot)
{
std::unique_ptr<apache::thrift::ContextStack> ctx(this->getContextStack("DB.ReleaseSnapshot", NULL));
folly::ScopeGuard g = folly::makeGuard([&] { this->clearClientContextStack(); });
this->generateClientContextStack("DB.ReleaseSnapshot", NULL);
try {
this->setContextStack(ctx.get());
send_ReleaseSnapshot(dbhandle, snapshot);
return recv_ReleaseSnapshot();
} catch(apache::thrift::transport::TTransportException& ex) {
this->handlerError(ctx.get(), "DB.ReleaseSnapshot");
this->handlerError(this->getClientContextStack(), "DB.ReleaseSnapshot");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
throw;
} catch(apache::thrift::TApplicationException& ex) {
if (ex.getType() == apache::thrift::TApplicationException::BAD_SEQUENCE_ID) {
this->handlerError(ctx.get(), "DB.ReleaseSnapshot");
this->handlerError(this->getClientContextStack(), "DB.ReleaseSnapshot");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
}
@ -3450,7 +3451,7 @@ Code DBClient::ReleaseSnapshot(const DBHandle& dbhandle, const Snapshot& snapsho
void DBClient::send_ReleaseSnapshot(const DBHandle& dbhandle, const Snapshot& snapshot)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
this->preWrite(ctx, "DB.ReleaseSnapshot");
oprot_->writeMessageBegin("ReleaseSnapshot", apache::thrift::protocol::T_CALL, getNextSendSequenceId());
@ -3468,7 +3469,7 @@ void DBClient::send_ReleaseSnapshot(const DBHandle& dbhandle, const Snapshot& sn
Code DBClient::recv_ReleaseSnapshot()
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
uint32_t bytes;
int32_t rseqid = 0;
int32_t eseqid = getNextRecvSequenceId();
@ -3516,22 +3517,22 @@ Code DBClient::recv_ReleaseSnapshot()
throw apache::thrift::TApplicationException(apache::thrift::TApplicationException::MISSING_RESULT, "ReleaseSnapshot failed: unknown result");
}
Code DBClient::CompactRange(const DBHandle& dbhandle, const Slice& begin, const Slice& end)
Code DBClient::CompactRange(const DBHandle& dbhandle, const Slice& start, const Slice& endhere)
{
std::unique_ptr<apache::thrift::ContextStack> ctx(this->getContextStack("DB.CompactRange", NULL));
folly::ScopeGuard g = folly::makeGuard([&] { this->clearClientContextStack(); });
this->generateClientContextStack("DB.CompactRange", NULL);
try {
this->setContextStack(ctx.get());
send_CompactRange(dbhandle, begin, end);
send_CompactRange(dbhandle, start, endhere);
return recv_CompactRange();
} catch(apache::thrift::transport::TTransportException& ex) {
this->handlerError(ctx.get(), "DB.CompactRange");
this->handlerError(this->getClientContextStack(), "DB.CompactRange");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
throw;
} catch(apache::thrift::TApplicationException& ex) {
if (ex.getType() == apache::thrift::TApplicationException::BAD_SEQUENCE_ID) {
this->handlerError(ctx.get(), "DB.CompactRange");
this->handlerError(this->getClientContextStack(), "DB.CompactRange");
iprot_->getTransport()->close();
oprot_->getTransport()->close();
}
@ -3539,16 +3540,16 @@ Code DBClient::CompactRange(const DBHandle& dbhandle, const Slice& begin, const
}
}
void DBClient::send_CompactRange(const DBHandle& dbhandle, const Slice& begin, const Slice& end)
void DBClient::send_CompactRange(const DBHandle& dbhandle, const Slice& start, const Slice& endhere)
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
this->preWrite(ctx, "DB.CompactRange");
oprot_->writeMessageBegin("CompactRange", apache::thrift::protocol::T_CALL, getNextSendSequenceId());
DB_CompactRange_pargs args;
args.dbhandle = &dbhandle;
args.begin = &begin;
args.end = &end;
args.start = &start;
args.endhere = &endhere;
args.write(oprot_);
oprot_->writeMessageEnd();
@ -3560,7 +3561,7 @@ void DBClient::send_CompactRange(const DBHandle& dbhandle, const Slice& begin, c
Code DBClient::recv_CompactRange()
{
apache::thrift::ContextStack* ctx = this->getContextStack();
apache::thrift::ContextStack* ctx = this->getClientContextStack();
uint32_t bytes;
int32_t rseqid = 0;
int32_t eseqid = getNextRecvSequenceId();
@ -4125,7 +4126,7 @@ void DBProcessor::process_CompactRange(int32_t seqid, apache::thrift::protocol::
DB_CompactRange_result result;
try {
result.success = iface_->CompactRange(args.dbhandle, args.begin, args.end);
result.success = iface_->CompactRange(args.dbhandle, args.start, args.endhere);
result.__isset.success = true;
} catch (const std::exception& e) {
this->handlerError(ctx.get(), "DB.CompactRange");

@ -27,7 +27,7 @@ class DBIf {
virtual void GetPrev(ResultPair& _return, const DBHandle& dbhandle, const Iterator& iterator) = 0;
virtual void GetSnapshot(ResultSnapshot& _return, const DBHandle& dbhandle) = 0;
virtual Code ReleaseSnapshot(const DBHandle& dbhandle, const Snapshot& snapshot) = 0;
virtual Code CompactRange(const DBHandle& dbhandle, const Slice& begin, const Slice& end) = 0;
virtual Code CompactRange(const DBHandle& dbhandle, const Slice& start, const Slice& endhere) = 0;
};
class DBIfFactory {
@ -99,7 +99,7 @@ class DBNull : virtual public DBIf {
Code _return = (Code)0;
return _return;
}
Code CompactRange(const DBHandle& /* dbhandle */, const Slice& /* begin */, const Slice& /* end */) {
Code CompactRange(const DBHandle& /* dbhandle */, const Slice& /* start */, const Slice& /* endhere */) {
Code _return = (Code)0;
return _return;
}
@ -1808,36 +1808,36 @@ class DB_CompactRange_args {
void __clear() {
dbhandle.__clear();
begin.__clear();
end.__clear();
start.__clear();
endhere.__clear();
__isset.__clear();
}
virtual ~DB_CompactRange_args() throw() {}
DBHandle dbhandle;
Slice begin;
Slice end;
Slice start;
Slice endhere;
struct __isset {
__isset() { __clear(); }
void __clear() {
dbhandle = false;
begin = false;
end = false;
start = false;
endhere = false;
}
bool dbhandle;
bool begin;
bool end;
bool start;
bool endhere;
} __isset;
bool operator == (const DB_CompactRange_args & rhs) const
{
if (!(this->dbhandle == rhs.dbhandle))
return false;
if (!(this->begin == rhs.begin))
if (!(this->start == rhs.start))
return false;
if (!(this->end == rhs.end))
if (!(this->endhere == rhs.endhere))
return false;
return true;
}
@ -1861,8 +1861,8 @@ class DB_CompactRange_pargs {
virtual ~DB_CompactRange_pargs() throw() {}
const DBHandle* dbhandle;
const Slice* begin;
const Slice* end;
const Slice* start;
const Slice* endhere;
uint32_t write(apache::thrift::protocol::TProtocol* oprot) const;
@ -1999,8 +1999,8 @@ class DBClient : virtual public DBIf, virtual public apache::thrift::TClientBase
Code ReleaseSnapshot(const DBHandle& dbhandle, const Snapshot& snapshot);
void send_ReleaseSnapshot(const DBHandle& dbhandle, const Snapshot& snapshot);
Code recv_ReleaseSnapshot();
Code CompactRange(const DBHandle& dbhandle, const Slice& begin, const Slice& end);
void send_CompactRange(const DBHandle& dbhandle, const Slice& begin, const Slice& end);
Code CompactRange(const DBHandle& dbhandle, const Slice& start, const Slice& endhere);
void send_CompactRange(const DBHandle& dbhandle, const Slice& start, const Slice& endhere);
Code recv_CompactRange();
/**
@ -2209,13 +2209,13 @@ class DBMultiface : virtual public DBIf {
return ifaces_[i]->ReleaseSnapshot(dbhandle, snapshot);
}
Code CompactRange(const DBHandle& dbhandle, const Slice& begin, const Slice& end) {
Code CompactRange(const DBHandle& dbhandle, const Slice& start, const Slice& endhere) {
uint32_t i;
uint32_t sz = ifaces_.size();
for (i = 0; i < sz - 1; ++i) {
ifaces_[i]->CompactRange(dbhandle, begin, end);
ifaces_[i]->CompactRange(dbhandle, start, endhere);
}
return ifaces_[i]->CompactRange(dbhandle, begin, end);
return ifaces_[i]->CompactRange(dbhandle, start, endhere);
}
};

@ -107,6 +107,42 @@ return findValue( ::Tleveldb::_IteratorType_NAMES_TO_VALUES, name, out);
}
}} // apache::thrift
namespace Tleveldb {
int _kAssocVisibilityValues[] = {
VISIBLE,
DELETED,
UNUSED1,
HIDDEN,
UNUSED2,
HARD_DELETE
};
const char* _kAssocVisibilityNames[] = {
"VISIBLE",
"DELETED",
"UNUSED1",
"HIDDEN",
"UNUSED2",
"HARD_DELETE"
};
const std::map<int, const char*> _AssocVisibility_VALUES_TO_NAMES(apache::thrift::TEnumIterator<int>(6, _kAssocVisibilityValues, _kAssocVisibilityNames), apache::thrift::TEnumIterator<int>(-1, NULL, NULL));
const std::map<const char*, int, apache::thrift::ltstr> _AssocVisibility_NAMES_TO_VALUES(apache::thrift::TEnumInverseIterator<int>(6, _kAssocVisibilityValues, _kAssocVisibilityNames), apache::thrift::TEnumInverseIterator<int>(-1, NULL, NULL));
} // namespace
namespace apache { namespace thrift {
template<>
const char* TEnumTraits< ::Tleveldb::AssocVisibility>::findName( ::Tleveldb::AssocVisibility value) {
return findName( ::Tleveldb::_AssocVisibility_VALUES_TO_NAMES, value);
}
template<>
bool TEnumTraits< ::Tleveldb::AssocVisibility>::findValue(const char* name, ::Tleveldb::AssocVisibility* out) {
return findValue( ::Tleveldb::_AssocVisibility_NAMES_TO_VALUES, name, out);
}
}} // apache::thrift
namespace Tleveldb {
// Reflection initializer for struct leveldb.Slice
namespace {
@ -831,13 +867,6 @@ void reflectionInitializer_8973827971994157004(::apache::thrift::reflection::Sch
f.name = "dbname";
dt.fields[1] = f;
}
{
::apache::thrift::reflection::StructField f;
f.isRequired = true;
f.type = 6U;
f.name = "handleid";
dt.fields[2] = f;
}
schema.dataTypes[id] = dt;
schema.names[dt.name] = id;
}
@ -875,14 +904,6 @@ uint32_t DBHandle::read(apache::thrift::protocol::TProtocol* iprot) {
xfer += iprot->skip(ftype);
}
break;
case 2:
if (ftype == apache::thrift::protocol::T_I64) {
xfer += iprot->readI64(this->handleid);
this->__isset.handleid = true;
} else {
xfer += iprot->skip(ftype);
}
break;
default:
xfer += iprot->skip(ftype);
break;
@ -901,9 +922,6 @@ uint32_t DBHandle::write(apache::thrift::protocol::TProtocol* oprot) const {
xfer += oprot->writeFieldBegin("dbname", apache::thrift::protocol::T_STRING, 1);
xfer += oprot->writeBinary(this->dbname);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("handleid", apache::thrift::protocol::T_I64, 2);
xfer += oprot->writeI64(this->handleid);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldStop();
xfer += oprot->writeStructEnd();
return xfer;
@ -914,7 +932,6 @@ void swap(DBHandle &a, DBHandle &b) {
(void)a;
(void)b;
swap(a.dbname, b.dbname);
swap(a.handleid, b.handleid);
swap(a.__isset, b.__isset);
}
@ -1653,4 +1670,265 @@ void swap(LeveldbException &a, LeveldbException &b) {
swap(a.__isset, b.__isset);
}
// Reflection initializer for struct leveldb.IOError
namespace {
void reflectionInitializer_8460881927871070060(::apache::thrift::reflection::Schema& schema) {
const uint64_t id = 8460881927871070060U;
if (schema.dataTypes.count(id)) return;
::apache::thrift::reflection::DataType dt;
dt.name = "struct leveldb.IOError";
dt.__isset.fields = true;
{
::apache::thrift::reflection::StructField f;
f.isRequired = true;
f.type = 1U;
f.name = "message";
dt.fields[1] = f;
}
schema.dataTypes[id] = dt;
schema.names[dt.name] = id;
}
} // namespace
const uint64_t IOError::_reflection_id;
void IOError::_reflection_register(::apache::thrift::reflection::Schema& schema) {
reflectionInitializer_8460881927871070060(schema);
}
uint32_t IOError::read(apache::thrift::protocol::TProtocol* iprot) {
uint32_t xfer = 0;
std::string fname;
apache::thrift::protocol::TType ftype;
int16_t fid;
xfer += iprot->readStructBegin(fname);
using apache::thrift::protocol::TProtocolException;
while (true)
{
xfer += iprot->readFieldBegin(fname, ftype, fid);
if (ftype == apache::thrift::protocol::T_STOP) {
break;
}
switch (fid)
{
case 1:
if (ftype == apache::thrift::protocol::T_STRING) {
xfer += iprot->readString(this->message);
this->__isset.message = true;
} else {
xfer += iprot->skip(ftype);
}
break;
default:
xfer += iprot->skip(ftype);
break;
}
xfer += iprot->readFieldEnd();
}
xfer += iprot->readStructEnd();
return xfer;
}
uint32_t IOError::write(apache::thrift::protocol::TProtocol* oprot) const {
uint32_t xfer = 0;
xfer += oprot->writeStructBegin("IOError");
xfer += oprot->writeFieldBegin("message", apache::thrift::protocol::T_STRING, 1);
xfer += oprot->writeString(this->message);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldStop();
xfer += oprot->writeStructEnd();
return xfer;
}
void swap(IOError &a, IOError &b) {
using ::std::swap;
(void)a;
(void)b;
swap(a.message, b.message);
swap(a.__isset, b.__isset);
}
// Reflection initializer for struct leveldb.TaoAssocGetResult
namespace {
void reflectionInitializer_6301164048086986412(::apache::thrift::reflection::Schema& schema) {
const uint64_t id = 6301164048086986412U;
if (schema.dataTypes.count(id)) return;
::apache::thrift::reflection::DataType dt;
dt.name = "struct leveldb.TaoAssocGetResult";
dt.__isset.fields = true;
{
::apache::thrift::reflection::StructField f;
f.isRequired = true;
f.type = 6U;
f.name = "id2";
dt.fields[1] = f;
}
{
::apache::thrift::reflection::StructField f;
f.isRequired = true;
f.type = 6U;
f.name = "id1Type";
dt.fields[2] = f;
}
{
::apache::thrift::reflection::StructField f;
f.isRequired = true;
f.type = 6U;
f.name = "id2Type";
dt.fields[3] = f;
}
{
::apache::thrift::reflection::StructField f;
f.isRequired = true;
f.type = 6U;
f.name = "time";
dt.fields[4] = f;
}
{
::apache::thrift::reflection::StructField f;
f.isRequired = true;
f.type = 6U;
f.name = "dataVersion";
dt.fields[5] = f;
}
{
::apache::thrift::reflection::StructField f;
f.isRequired = true;
f.type = 1U;
f.name = "data";
dt.fields[6] = f;
}
schema.dataTypes[id] = dt;
schema.names[dt.name] = id;
}
} // namespace
const uint64_t TaoAssocGetResult::_reflection_id;
void TaoAssocGetResult::_reflection_register(::apache::thrift::reflection::Schema& schema) {
reflectionInitializer_6301164048086986412(schema);
}
uint32_t TaoAssocGetResult::read(apache::thrift::protocol::TProtocol* iprot) {
uint32_t xfer = 0;
std::string fname;
apache::thrift::protocol::TType ftype;
int16_t fid;
xfer += iprot->readStructBegin(fname);
using apache::thrift::protocol::TProtocolException;
while (true)
{
xfer += iprot->readFieldBegin(fname, ftype, fid);
if (ftype == apache::thrift::protocol::T_STOP) {
break;
}
switch (fid)
{
case 1:
if (ftype == apache::thrift::protocol::T_I64) {
xfer += iprot->readI64(this->id2);
this->__isset.id2 = true;
} else {
xfer += iprot->skip(ftype);
}
break;
case 2:
if (ftype == apache::thrift::protocol::T_I64) {
xfer += iprot->readI64(this->id1Type);
this->__isset.id1Type = true;
} else {
xfer += iprot->skip(ftype);
}
break;
case 3:
if (ftype == apache::thrift::protocol::T_I64) {
xfer += iprot->readI64(this->id2Type);
this->__isset.id2Type = true;
} else {
xfer += iprot->skip(ftype);
}
break;
case 4:
if (ftype == apache::thrift::protocol::T_I64) {
xfer += iprot->readI64(this->time);
this->__isset.time = true;
} else {
xfer += iprot->skip(ftype);
}
break;
case 5:
if (ftype == apache::thrift::protocol::T_I64) {
xfer += iprot->readI64(this->dataVersion);
this->__isset.dataVersion = true;
} else {
xfer += iprot->skip(ftype);
}
break;
case 6:
if (ftype == apache::thrift::protocol::T_STRING) {
xfer += iprot->readBinary(this->data);
this->__isset.data = true;
} else {
xfer += iprot->skip(ftype);
}
break;
default:
xfer += iprot->skip(ftype);
break;
}
xfer += iprot->readFieldEnd();
}
xfer += iprot->readStructEnd();
return xfer;
}
uint32_t TaoAssocGetResult::write(apache::thrift::protocol::TProtocol* oprot) const {
uint32_t xfer = 0;
xfer += oprot->writeStructBegin("TaoAssocGetResult");
xfer += oprot->writeFieldBegin("id2", apache::thrift::protocol::T_I64, 1);
xfer += oprot->writeI64(this->id2);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("id1Type", apache::thrift::protocol::T_I64, 2);
xfer += oprot->writeI64(this->id1Type);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("id2Type", apache::thrift::protocol::T_I64, 3);
xfer += oprot->writeI64(this->id2Type);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("time", apache::thrift::protocol::T_I64, 4);
xfer += oprot->writeI64(this->time);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("dataVersion", apache::thrift::protocol::T_I64, 5);
xfer += oprot->writeI64(this->dataVersion);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldBegin("data", apache::thrift::protocol::T_STRING, 6);
xfer += oprot->writeBinary(this->data);
xfer += oprot->writeFieldEnd();
xfer += oprot->writeFieldStop();
xfer += oprot->writeStructEnd();
return xfer;
}
void swap(TaoAssocGetResult &a, TaoAssocGetResult &b) {
using ::std::swap;
(void)a;
(void)b;
swap(a.id2, b.id2);
swap(a.id1Type, b.id1Type);
swap(a.id2Type, b.id2Type);
swap(a.time, b.time);
swap(a.dataVersion, b.dataVersion);
swap(a.data, b.data);
swap(a.__isset, b.__isset);
}
} // namespace

@ -90,6 +90,32 @@ return ::Tleveldb::IteratorType::seekToKey;
}
}} // apache:thrift
namespace Tleveldb {
enum AssocVisibility {
VISIBLE = 0,
DELETED = 1,
UNUSED1 = 2,
HIDDEN = 3,
UNUSED2 = 4,
HARD_DELETE = 4
};
extern const std::map<int, const char*> _AssocVisibility_VALUES_TO_NAMES;
extern const std::map<const char*, int, apache::thrift::ltstr> _AssocVisibility_NAMES_TO_VALUES;
} // namespace
namespace apache { namespace thrift {
template<>
inline constexpr ::Tleveldb::AssocVisibility TEnumTraits< ::Tleveldb::AssocVisibility>::min() {
return ::Tleveldb::AssocVisibility::VISIBLE;
}
template<>
inline constexpr ::Tleveldb::AssocVisibility TEnumTraits< ::Tleveldb::AssocVisibility>::max() {
return ::Tleveldb::AssocVisibility::HARD_DELETE;
}
}} // apache:thrift
namespace Tleveldb {
typedef std::string Text;
@ -460,7 +486,7 @@ class DBHandle {
static const uint64_t _reflection_id = 8973827971994157004U;
static void _reflection_register(::apache::thrift::reflection::Schema&);
DBHandle() : dbname(""), handleid(0) {
DBHandle() : dbname("") {
}
DBHandle(const DBHandle&) = default;
@ -470,31 +496,25 @@ class DBHandle {
void __clear() {
dbname = "";
handleid = 0;
__isset.__clear();
}
virtual ~DBHandle() throw() {}
Text dbname;
int64_t handleid;
struct __isset {
__isset() { __clear(); }
void __clear() {
dbname = false;
handleid = false;
}
bool dbname;
bool handleid;
} __isset;
bool operator == (const DBHandle & rhs) const
{
if (!(this->dbname == rhs.dbname))
return false;
if (!(this->handleid == rhs.handleid))
return false;
return true;
}
bool operator != (const DBHandle &rhs) const {
@ -901,6 +921,140 @@ class LeveldbException : public apache::thrift::TException {
class LeveldbException;
void swap(LeveldbException &a, LeveldbException &b);
class IOError : public apache::thrift::TException {
public:
static const uint64_t _reflection_id = 8460881927871070060U;
static void _reflection_register(::apache::thrift::reflection::Schema&);
IOError() : message("") {
}
IOError(const IOError&) = default;
IOError& operator=(const IOError&) = default;
IOError(IOError&&) = default;
IOError& operator=(IOError&&) = default;
void __clear() {
message = "";
__isset.__clear();
}
virtual ~IOError() throw() {}
std::string message;
struct __isset {
__isset() { __clear(); }
void __clear() {
message = false;
}
bool message;
} __isset;
bool operator == (const IOError & rhs) const
{
if (!(this->message == rhs.message))
return false;
return true;
}
bool operator != (const IOError &rhs) const {
return !(*this == rhs);
}
bool operator < (const IOError & ) const;
uint32_t read(apache::thrift::protocol::TProtocol* iprot);
uint32_t write(apache::thrift::protocol::TProtocol* oprot) const;
virtual const char* what() const throw() {
return "IOError";
}
};
class IOError;
void swap(IOError &a, IOError &b);
class TaoAssocGetResult {
public:
static const uint64_t _reflection_id = 6301164048086986412U;
static void _reflection_register(::apache::thrift::reflection::Schema&);
TaoAssocGetResult() : id2(0), id1Type(0), id2Type(0), time(0), dataVersion(0), data("") {
}
TaoAssocGetResult(const TaoAssocGetResult&) = default;
TaoAssocGetResult& operator=(const TaoAssocGetResult&) = default;
TaoAssocGetResult(TaoAssocGetResult&&) = default;
TaoAssocGetResult& operator=(TaoAssocGetResult&&) = default;
void __clear() {
id2 = 0;
id1Type = 0;
id2Type = 0;
time = 0;
dataVersion = 0;
data = "";
__isset.__clear();
}
virtual ~TaoAssocGetResult() throw() {}
int64_t id2;
int64_t id1Type;
int64_t id2Type;
int64_t time;
int64_t dataVersion;
Text data;
struct __isset {
__isset() { __clear(); }
void __clear() {
id2 = false;
id1Type = false;
id2Type = false;
time = false;
dataVersion = false;
data = false;
}
bool id2;
bool id1Type;
bool id2Type;
bool time;
bool dataVersion;
bool data;
} __isset;
bool operator == (const TaoAssocGetResult & rhs) const
{
if (!(this->id2 == rhs.id2))
return false;
if (!(this->id1Type == rhs.id1Type))
return false;
if (!(this->id2Type == rhs.id2Type))
return false;
if (!(this->time == rhs.time))
return false;
if (!(this->dataVersion == rhs.dataVersion))
return false;
if (!(this->data == rhs.data))
return false;
return true;
}
bool operator != (const TaoAssocGetResult &rhs) const {
return !(*this == rhs);
}
bool operator < (const TaoAssocGetResult & ) const;
uint32_t read(apache::thrift::protocol::TProtocol* iprot);
uint32_t write(apache::thrift::protocol::TProtocol* oprot) const;
};
class TaoAssocGetResult;
void swap(TaoAssocGetResult &a, TaoAssocGetResult &b);
} // namespace
#endif

@ -67,10 +67,9 @@ struct ReadOptions {
3:Snapshot snapshot
}
// Represents a open database object
// Represents a database object
struct DBHandle {
1:Text dbname; //name of the database
2:i64 handleid // server generated
1:Text dbname //name of the database
}
struct Iterator {
@ -177,5 +176,196 @@ service DB {
// compact a range of keys
// begin.size == 0 to start at a range earlier than the first existing key
// end.size == 0 to end at a range later than the last existing key
Code CompactRange(1:DBHandle dbhandle, 2:Slice begin, 3:Slice end),
Code CompactRange(1:DBHandle dbhandle, 2:Slice start, 3:Slice endhere),
}
// ****************** FACEBOOK specific stuff ********************
//
// An IOError exception from an assoc operation
//
exception IOError {
1:string message
}
//
// Visibility state for assoc
//
enum AssocVisibility
{
VISIBLE = 0, // live object, include in lookups and count
DELETED = 1, // exclude from lookup queries and count, ok to
// delete permanently from persistent store
UNUSED1 = 2, // not used
HIDDEN = 3, // exclude from lookup queries and count
UNUSED2 = 4, // not used
HARD_DELETE = 4 // deleted by calling expunge, will be swept
// as soon as possible
}
/**
* Holds the assoc get result of a id2
*/
struct TaoAssocGetResult {
/** id2 of assoc */
1:i64 id2,
/** id1 type of assoc */
2:i64 id1Type,
/** id2 type of assoc */
3:i64 id2Type,
/** time stamp of the assoc */
4:i64 time,
/** version of the data blob */
5:i64 dataVersion,
/** serialized data of the asoc */
6:Text data,
}
//
// Service
//
service AssocService {
/**
* TAO Assoc Put operation.
* Note that currently the argument visibility has no effect.
*
* @if update_count is true, then return the updated count for this assoc
* @if update_count is false, then return 0
* @return negative number if failure
*/
i64 taoAssocPut(
/** name of table */
1:Text tableName,
/** type assoc */
2:i64 assocType,
/** id1 of assoc */
3:i64 id1,
/** id2 of assoc */
4:i64 id2,
/** id1Type of assoc */
5:i64 id1Type,
/** id2Type of assoc */
6:i64 id2Type,
/** timestamp of assoc */
7:i64 timestamp,
/** visibility */
8:AssocVisibility visibility,
/** whether to keep the count or not */
9:bool update_count,
/** version of the data blob */
10:i64 dataVersion,
/** serialized data of assoc */
11:Text data,
/** wormhole comment */
12:Text wormhole_comment
) throws (1:IOError io)
/**
* TAO Assoc Delete operation.
*
* @return the updated count for this assoc
*/
i64 taoAssocDelete(
/** name of table */
1:Text tableName,
/** type assoc */
2:i64 assocType,
/** id1 of assoc */
3:i64 id1,
/** id2 of assoc */
4:i64 id2,
/** visibility flag for this delete */
5:AssocVisibility visibility,
/** whether to keep the count or not */
6:bool update_count,
/** wormhole comment */
7:Text wormhole_comment
) throws (1:IOError io)
/**
* TAO Assoc RangeGet operation.
* Obtain assocs in bewteen start_time and end_time in reverse time order.
* The range check is inclusive: start_time >= time && time >= end_time.
* And yes, start_time >= end_time.
*/
list<TaoAssocGetResult> taoAssocRangeGet(
/** name of table */
1:Text tableName,
/** type of assoc */
2:i64 assocType,
/** id1 of assoc */
3:i64 id1,
/** maximum timestamp of assocs to retrieve */
4:i64 start_time,
/** minimum timestamp of assocs to retrieve */
5:i64 end_time,
/** number of assocs to skip from start */
6:i64 offset,
/** max number of assocs (columns) returned */
7:i64 limit
) throws (1:IOError io)
/**
* TAO Assoc Get operation.
*/
list<TaoAssocGetResult> taoAssocGet(
/** name of table */
1:Text tableName,
/** type of assoc */
2:i64 assocType,
/** id1 of assoc */
3:i64 id1,
/** list of id2 need to be fetch */
4:list<i64> id2s
) throws (1:IOError io)
/**
* TAO Assoc Count Get operation.
* Returns the number of assocs for given id1 and assoc type
*/
i64 taoAssocCount(
/** name of table */
1:Text tableName,
/** type of assoc */
2:i64 assocType,
/** id1 of assoc */
3:i64 id1,
) throws (1:IOError io)
}

@ -142,15 +142,15 @@ class ContextStack {
};
class EventHandlerBase {
private:
int setEventHandlerPos_;
ContextStack* s_;
public:
EventHandlerBase()
: setEventHandlerPos_(-1)
, s_(NULL)
{}
: setEventHandlerPos_(-1) {}
EventHandlerBase(const EventHandlerBase& original)
: handlers_(original.handlers_),
eventHandler_(original.eventHandler_),
setEventHandlerPos_(original.setEventHandlerPos_),
s_() {}
void addEventHandler(
const boost::shared_ptr<TProcessorEventHandler>& handler) {
@ -191,13 +191,18 @@ class EventHandlerBase {
* The generated code should be the ONLY user of s_. All other functions
* should just use the ContextStack parameter.
*/
ContextStack* getContextStack() {
return s_;
void generateClientContextStack(const char* fn_name,
TConnectionContext* connectionContext) {
auto s = getContextStack(fn_name, connectionContext);
s_ = std::move(s);
}
void clearClientContextStack() {
s_.reset();
}
// Context only freed by freer, this is only used across function calls.
void setContextStack(ContextStack* s) {
s_ = s;
ContextStack* getClientContextStack() {
return s_.get();
}
protected:
@ -259,8 +264,14 @@ class EventHandlerBase {
}
}
public:
std::vector<boost::shared_ptr<TProcessorEventHandler>> handlers_;
boost::shared_ptr<TProcessorEventHandler> eventHandler_;
private:
int setEventHandlerPos_;
std::unique_ptr<ContextStack> s_;
};
class TProcessorEventHandlerFactory {

@ -272,6 +272,12 @@ void profile_print_info();
void profile_write_pprof(FILE* gen_calls_f, FILE* virtual_calls_f);
#endif
template <class ThriftContainer>
inline void reallyClear(ThriftContainer& container) {
ThriftContainer emptyContainer;
swap(container, emptyContainer);
}
}} // apache::thrift
#endif // #ifndef THRIFT_THRIFT_H_

@ -372,6 +372,7 @@ class TAsyncSSLSocket : public TAsyncSocket {
void invalidState(HandshakeCallback* callback);
bool willBlock(int ret, int *errorOut) THRIFT_NOEXCEPT;
virtual void checkForImmediateRead() THRIFT_NOEXCEPT;
// TAsyncSocket calls this at the wrong time for SSL
void handleInitialReadWrite() THRIFT_NOEXCEPT {}

@ -435,7 +435,7 @@ class TAsyncServerSocket : public TDelayedDestruction,
/**
* Get the number of connections dropped by the TAsyncServerSocket
*/
double getNumDroppedConnections() const {
uint64_t getNumDroppedConnections() const {
return numDroppedConnections_;
}
@ -502,7 +502,7 @@ class TAsyncServerSocket : public TDelayedDestruction,
double acceptRateAdjustSpeed_; //0 to disable auto adjust
double acceptRate_;
int64_t lastAccepTimestamp_; // milliseconds
int64_t numDroppedConnections_;
uint64_t numDroppedConnections_;
uint32_t callbackIndex_;
BackoffTimeout *backoffTimeout_;
std::vector<CallbackInfo> callbacks_;

@ -360,6 +360,14 @@ class TAsyncSocket : public TAsyncTransport,
*/
int setNoDelay(bool noDelay);
/*
* Set the Flavor of Congestion Control to be used for this Socket
* Please check '/lib/modules/<kernel>/kernel/net/ipv4' for tcp_*.ko
* first to make sure the module is available for plugging in
* Alternatively you can choose from net.ipv4.tcp_allowed_congestion_control
*/
int setCongestionFlavor(const std::string &cname);
/*
* Forces ACKs to be sent immediately
*
@ -486,6 +494,7 @@ class TAsyncSocket : public TAsyncTransport,
// event notification methods
void ioReady(uint16_t events) THRIFT_NOEXCEPT;
virtual void checkForImmediateRead() THRIFT_NOEXCEPT;
virtual void handleInitialReadWrite() THRIFT_NOEXCEPT;
virtual void handleRead() THRIFT_NOEXCEPT;
virtual void handleWrite() THRIFT_NOEXCEPT;

@ -137,6 +137,15 @@ class TAsyncTimeout : private boost::noncopyable {
static void libeventCallback(int fd, short events, void* arg);
struct event event_;
/*
* In debug builds, store a pointer to the TEventBase. We only use this
* for some assert() statements, to make sure that TAsyncTimeout is always
* used from the correct thread.
*/
#ifndef NDEBUG
TEventBase* eventBase_;
#endif
};
}}} // apache::thrift::async

@ -180,6 +180,9 @@ class TAsyncTransport {
* If a ReadCallback is already installed, it is replaced with the new
* callback.
*
* Note that setReadCallback() may invoke the ReadCallback immediately,
* before returning.
*
* @param callback The callback to invoke when data is available.
* This parameter may be NULL to uninstall the current
* read callback.

@ -340,7 +340,7 @@ class TEventServer : public apache::thrift::server::TServer {
*/
template<typename AsyncProcessor>
TEventServer(boost::shared_ptr<AsyncProcessor> processor,
boost::shared_ptr<apache::thrift::server::TProtocolFactory>
boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>
protocolFactory,
int port,
int nWorkers = T_ASYNC_DEFAULT_WORKER_THREADS,
@ -386,9 +386,9 @@ class TEventServer : public apache::thrift::server::TServer {
*/
template<typename AsyncProcessor>
TEventServer(boost::shared_ptr<AsyncProcessor> processor,
boost::shared_ptr<apache::thrift::server::TProtocolFactory>
boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>
inputProtocolFactory,
boost::shared_ptr<apache::thrift::server::TProtocolFactory>
boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>
outputProtocolFactory,
int port,
int nWorkers = T_ASYNC_DEFAULT_WORKER_THREADS,
@ -433,12 +433,13 @@ class TEventServer : public apache::thrift::server::TServer {
@param nWorkers the number of worker threads
*/
template<typename AsyncProcessor>
TEventServer(boost::shared_ptr<AsyncProcessor> processor,
boost::shared_ptr<apache::thrift::server::TDuplexProtocolFactory>
duplexProtocolFactory,
int port,
int nWorkers = T_ASYNC_DEFAULT_WORKER_THREADS,
THRIFT_OVERLOAD_IF(AsyncProcessor, TAsyncProcessor)):
TEventServer(
boost::shared_ptr<AsyncProcessor> processor,
boost::shared_ptr<apache::thrift::protocol::TDuplexProtocolFactory>
duplexProtocolFactory,
int port,
int nWorkers = T_ASYNC_DEFAULT_WORKER_THREADS,
THRIFT_OVERLOAD_IF(AsyncProcessor, TAsyncProcessor)):
apache::thrift::server::TServer(boost::shared_ptr<TProcessor>()),
maxConnectionPoolSize_(T_ASYNC_MAX_CONNECTION_POOL_SIZE),
asyncProcessorFactory_(new TAsyncSingletonProcessorFactory(processor)),
@ -479,8 +480,8 @@ class TEventServer : public apache::thrift::server::TServer {
*/
template<typename Processor>
TEventServer(
boost::shared_ptr<Processor>& processor,
boost::shared_ptr<apache::thrift::server::TProtocolFactory>&
boost::shared_ptr<Processor> processor,
boost::shared_ptr<apache::thrift::protocol::TProtocolFactory>
protocolFactory,
int port,
boost::shared_ptr<concurrency::ThreadManager> const& threadManager =
@ -524,9 +525,9 @@ class TEventServer : public apache::thrift::server::TServer {
*/
template<typename Processor>
TEventServer(
boost::shared_ptr<Processor>& processor,
boost::shared_ptr<apache::thrift::server::TDuplexProtocolFactory>&
duplexProtocolFactory,
boost::shared_ptr<Processor> processor,
boost::shared_ptr<apache::thrift::protocol::TDuplexProtocolFactory>
duplexProtocolFactory,
int port,
boost::shared_ptr<concurrency::ThreadManager> const& threadManager =
boost::shared_ptr<concurrency::ThreadManager>(),
@ -714,7 +715,7 @@ class TEventServer : public apache::thrift::server::TServer {
/**
* Get the number of connections dropped by the TAsyncServerSocket
*/
void getNumDroppedConnections() const;
uint64_t getNumDroppedConnections() const;
/** Reset the maximum number of inactive connection objects to the default.
*/

@ -202,7 +202,10 @@ class THeaderProtocol
uint32_t writeDouble(const double dub);
uint32_t writeString(const std::string& str);
template<typename StrType>
uint32_t writeString(const StrType& str) {
return proto_->writeString(str);
}
uint32_t writeBinary(const std::string& str);
@ -255,7 +258,10 @@ class THeaderProtocol
uint32_t readDouble(double& dub);
uint32_t readString(std::string& str);
template<typename StrType>
uint32_t readString(StrType& str) {
return proto_->readString(str);
}
uint32_t readBinary(std::string& binary);

@ -199,6 +199,9 @@ class TBufferedTransport
: transport_(transport)
, rBufSize_(DEFAULT_BUFFER_SIZE)
, wBufSize_(DEFAULT_BUFFER_SIZE)
, wBufResetSize_(0)
, wBufResetEveryN_(0)
, wBufResetCount_(0)
, rBuf_(new uint8_t[rBufSize_])
, wBuf_(new uint8_t[wBufSize_])
{
@ -210,17 +213,34 @@ class TBufferedTransport
: transport_(transport)
, rBufSize_(sz)
, wBufSize_(sz)
, wBufResetSize_(0)
, wBufResetEveryN_(0)
, wBufResetCount_(0)
, rBuf_(new uint8_t[rBufSize_])
, wBuf_(new uint8_t[wBufSize_])
{
initPointers();
}
/// Use specified read and write buffer sizes.
TBufferedTransport(boost::shared_ptr<TTransport> transport, uint32_t rsz, uint32_t wsz)
/**
* Ctor with initial read and write buffer sizes and write buffer reset
* behaviour settings.
*
* @param transport Underlying transport.
* @param sz Initial buffer size.
* @param reset_sz Buffer size after a reset. See also reset_every_n.
* @param reset_every_n Reset the buffer after every N calls to flush().
* If set to zero (default), no reset is done.
*/
TBufferedTransport(boost::shared_ptr<TTransport> transport, uint32_t rsz,
uint32_t wsz, uint32_t reset_sz = 0,
uint32_t reset_every_n = 0)
: transport_(transport)
, rBufSize_(rsz)
, wBufSize_(wsz)
, wBufResetSize_(reset_sz)
, wBufResetEveryN_(reset_every_n)
, wBufResetCount_(0)
, rBuf_(new uint8_t[rBufSize_])
, wBuf_(new uint8_t[wBufSize_])
{
@ -291,6 +311,9 @@ class TBufferedTransport
uint32_t rBufSize_;
uint32_t wBufSize_;
uint32_t wBufResetSize_;
uint32_t wBufResetEveryN_;
uint32_t wBufResetCount_;
boost::scoped_array<uint8_t> rBuf_;
boost::scoped_array<uint8_t> wBuf_;
};
@ -336,19 +359,36 @@ class TFramedTransport
: transport_(transport)
, rBufSize_(0)
, wBufSize_(DEFAULT_BUFFER_SIZE)
, wBufResetSize_(0)
, wBufResetEveryN_(0)
, wBufResetCount_(0)
, rBuf_()
, wBuf_(new uint8_t[wBufSize_])
{
initPointers();
}
TFramedTransport(boost::shared_ptr<TTransport> transport, uint32_t sz)
/**
* Ctor with initial buffer size and write buffer reset behaviour settings.
*
* @param transport Underlying transport.
* @param sz Initial buffer size.
* @param reset_sz Buffer size after a reset. See also reset_every_n.
* @param reset_every_n Reset the buffer after every N calls to flush().
* If set to zero (default), no reset is done.
*/
TFramedTransport(boost::shared_ptr<TTransport> transport, uint32_t sz,
uint32_t reset_sz = 0, uint32_t reset_every_n = 0)
: transport_(transport)
, rBufSize_(0)
, wBufSize_(sz)
, wBufResetSize_(reset_sz)
, wBufResetEveryN_(reset_every_n)
, wBufResetCount_(0)
, rBuf_()
, wBuf_(new uint8_t[wBufSize_])
{
assert(wBufResetSize_ == 0 || wBufSize_ <= wBufResetSize_);
initPointers();
}
@ -396,6 +436,9 @@ class TFramedTransport
TFramedTransport()
: rBufSize_(0)
, wBufSize_(DEFAULT_BUFFER_SIZE)
, wBufResetSize_(0)
, wBufResetEveryN_(0)
, wBufResetCount_(0)
, rBuf_()
, wBuf_(new uint8_t[wBufSize_])
{
@ -426,6 +469,9 @@ class TFramedTransport
uint32_t rBufSize_;
uint32_t wBufSize_;
uint32_t wBufResetSize_;
uint32_t wBufResetEveryN_;
uint32_t wBufResetCount_;
boost::scoped_array<uint8_t> rBuf_;
boost::scoped_array<uint8_t> wBuf_;
};

@ -34,7 +34,7 @@ namespace apache { namespace thrift { namespace transport {
*/
class THttpTransport : public TVirtualTransport<THttpTransport> {
public:
THttpTransport(boost::shared_ptr<TTransport> transport);
explicit THttpTransport(boost::shared_ptr<TTransport> transport);
virtual ~THttpTransport();
@ -62,6 +62,10 @@ class THttpTransport : public TVirtualTransport<THttpTransport> {
virtual void flush() = 0;
boost::shared_ptr<TTransport> getUnderlyingTransport() {
return transport_;
}
protected:
boost::shared_ptr<TTransport> transport_;

@ -167,6 +167,9 @@ class ServerCreatorBase : public ServerCreator {
*/
virtual boost::shared_ptr<protocol::TProtocolFactory> getProtocolFactory();
virtual boost::shared_ptr<protocol::TDuplexProtocolFactory>
getDuplexProtocolFactory();
bool strictRead_;
bool strictWrite_;
int32_t stringLimit_;

@ -25,6 +25,12 @@
namespace apache { namespace thrift {
class TProcessor;
namespace concurrency {
class ThreadManager;
}
namespace async {
class TAsyncProcessor;
class TEventServer;
@ -36,8 +42,11 @@ class TEventServerCreator : public ServerCreatorBase {
public:
typedef async::TEventServer ServerType;
/// Use 8 worker threads by default.
static const size_t DEFAULT_NUM_THREADS = 8;
/// Use 8 IO worker threads by default.
static const size_t DEFAULT_NUM_IO_THREADS = 8;
/// Use 8 task worker threads by default.
static const size_t DEFAULT_NUM_TASK_THREADS = 8;
/// Default limit on the size of each worker's idle connection pool
static const uint32_t DEFAULT_CONN_POOL_SIZE = 64;
@ -78,17 +87,44 @@ class TEventServerCreator : public ServerCreatorBase {
static const int DEFAULT_RESIZE_EVERY_N = 64;
/**
* Create a new TEventServerCreator.
* Create a new TEventServerCreator to be used for building a native-mode
* TEventServer.
*/
TEventServerCreator(const boost::shared_ptr<async::TAsyncProcessor>& proc,
uint16_t port,
size_t numThreads = DEFAULT_NUM_THREADS);
TEventServerCreator(
const boost::shared_ptr<async::TAsyncProcessor>& asyncProcessor,
uint16_t port,
size_t numIoThreads = DEFAULT_NUM_IO_THREADS);
/**
* Create a new TEventServerCreator to be used for building a queuing-mode
* TEventServer.
*/
TEventServerCreator(
const boost::shared_ptr<TProcessor>& syncProcessor,
uint16_t port,
size_t numIoThreads = DEFAULT_NUM_IO_THREADS,
size_t numTaskThreads = DEFAULT_NUM_TASK_THREADS);
/**
* Set the number of IO threads to use.
*/
void setNumIoThreads(size_t numIoThreads) {
numIoThreads_ = numIoThreads;
}
/**
* Set the number of task threads to use.
*/
void setNumTaskThreads(size_t numTaskThreads) {
numTaskThreads_ = numTaskThreads;
}
/**
* Set the number of threads to use.
* Set the thread manager to use for task queue threads.
*/
void setNumThreads(size_t numThreads) {
numThreads_ = numThreads;
void setTaskQueueThreadManager(
const boost::shared_ptr<concurrency::ThreadManager>& threadManager) {
taskQueueThreadManager_ = threadManager;
}
/**
@ -176,9 +212,12 @@ class TEventServerCreator : public ServerCreatorBase {
boost::shared_ptr<async::TEventServer> createEventServer();
private:
boost::shared_ptr<async::TAsyncProcessor> processor_;
boost::shared_ptr<TProcessor> syncProcessor_;
boost::shared_ptr<async::TAsyncProcessor> asyncProcessor_;
boost::shared_ptr<concurrency::ThreadManager> taskQueueThreadManager_;
uint16_t port_;
size_t numThreads_;
size_t numIoThreads_;
size_t numTaskThreads_;
uint32_t maxConnPoolSize_;
int recvTimeout_;
uint32_t maxFrameSize_;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -60,7 +60,6 @@ struct onehandle {
Text name;
leveldb::DB* onedb; // locate the localleveldb instance
int refcount; // currently not used
int64_t uniqueid; // unique identifier
std::atomic<uint64_t> currentSnapshotId; // valid snapshotids > 0
std::atomic<uint64_t> currentIteratorId; // valid iterators > 0
unordered_map<uint64_t, struct snapshotEntry*> snaplist;
@ -139,7 +138,7 @@ struct onehandle {
class OpenHandles {
public:
OpenHandles() : dbnum_(1) {
OpenHandles() {
}
// Inserts a new database into the list.
@ -150,7 +149,6 @@ class OpenHandles {
if (found == NULL) {
found = new onehandle;
found->name = dbname;
found->uniqueid = dbnum_++;
fprintf(stderr, "openhandle.add: Opening leveldb DB %s\n",
dbname.c_str());
leveldb::Status status = leveldb::DB::Open(options, dbdir, &found->onedb);
@ -166,20 +164,15 @@ class OpenHandles {
head_[dbname] = found;
}
found->refcount++;
return found->uniqueid;
}
leveldb::DB* get(Text dbname, int64_t uniqueid, struct onehandle** f) {
leveldb::DB* get(Text dbname, struct onehandle** f) {
auto p = head_.find(dbname);
if (p == head_.end()) {
fprintf(stderr, "get:No db with name\n");
return NULL;
}
struct onehandle* found = p->second;
if (found->uniqueid != uniqueid) {
fprintf(stderr, "get:Uniqueid does not match\n.");
return NULL;
}
if (found->refcount <= 0) {
fprintf(stderr, "get:bad refcount\n.");
return NULL;
@ -191,17 +184,13 @@ class OpenHandles {
return found->onedb;
}
bool remove(Text dbname, int64_t uniqueid) {
bool remove(Text dbname) {
auto p = head_.find(dbname);
if (p == head_.end()) {
fprintf(stderr, "get:No db with name\n");
return false;
}
struct onehandle* found = p->second;
if (found->uniqueid != uniqueid) {
fprintf(stderr, "remove:Uniqueid does not match\n.");
return false;
}
if (found->refcount == 1) {
delete found->onedb; // close database
int numRemoved = head_.erase(dbname);
@ -214,7 +203,6 @@ class OpenHandles {
private:
unordered_map<std::string, struct onehandle*> head_; // all open databases
std::atomic<uint64_t> dbnum_;
struct onehandle* lookup(Text dbname) {
auto p = head_.find(dbname);

@ -1,11 +0,0 @@
/**
* Options for the Thrift leveldb server.
* @author Dhruba Borthakur (dhruba@gmail.com)
* Copyright 2012 Facebook
**/
#include <DB.h>
#include "server_options.h"
const std::string ServerOptions::DEFAULT_HOST = "hostname";
const std::string ServerOptions::DEFAULT_ROOTDIR = "/tmp/ldb/";

@ -41,24 +41,20 @@ class ServerOptions {
// default port
const static int DEFAULT_PORT = 6666;
// default machine name
const static std::string DEFAULT_HOST;
// default directory where the server stores all its data
const static std::string DEFAULT_ROOTDIR;
public:
ServerOptions() : num_threads_(DEFAULT_threads),
cache_numshardbits_(DEFAULT_cache_numshardbits),
cache_size_(DEFAULT_cache_size),
port_(DEFAULT_PORT),
hostname_(DEFAULT_HOST),
rootdir_(DEFAULT_ROOTDIR + DEFAULT_HOST),
cache_(NULL) {
char buf[100];
if (gethostname(buf, sizeof(buf)) == 0) {
char* buf = new char[HOST_NAME_MAX];
if (gethostname(buf, HOST_NAME_MAX) == 0) {
hostname_ = buf;
} else {
hostname_ = "unknownhost";
delete buf;
}
rootdir_ = "/tmp"; // default rootdir
}
//
@ -121,11 +117,18 @@ public:
}
}
// Returns the server port
// Returns the base server port
int getPort() {
return port_;
}
// Returns the assoc server port. Currently, it is one more than the base
// server port. In fiture, the assoc service would be supported on multiple
// ports, each port serving a distinct range of keys.
int getAssocPort() {
return port_ + 1;
}
// Returns the cache
leveldb::Cache* getCache() {
return cache_;

@ -18,6 +18,7 @@
#include <leveldb_types.h>
#include "openhandles.h"
#include "server_options.h"
#include "assoc.h"
#include "leveldb/db.h"
#include "leveldb/write_batch.h"
@ -34,15 +35,16 @@ using boost::shared_ptr;
extern "C" void startServer(int argc, char** argv);
extern "C" void stopServer(int port);
static boost::shared_ptr<TServer> tServer;
static boost::shared_ptr<TServer> baseServer;
static boost::shared_ptr<TServer> assocServer;
// The global object that stores the default configuration of the server
ServerOptions server_options;
class DBHandler : virtual public DBIf {
public:
DBHandler() {
openHandles = new OpenHandles();
DBHandler(OpenHandles* oh) {
openHandles = oh;
}
void Open(DBHandle& _return, const Text& dbname,
@ -73,19 +75,15 @@ class DBHandler : virtual public DBIf {
} else if (dboptions.compression == kSnappyCompression) {
options.compression = leveldb::kSnappyCompression;
}
int64_t session = openHandles->add(options, dbname, dbdir);
openHandles->add(options, dbname, dbdir);
_return.dbname = dbname;
_return.handleid = session;
}
Code Close(const DBHandle& dbhandle, const Text& dbname) {
/**
* We do not close any handles for now, otherwise we have to do
* some locking that will degrade performance in the normal case.
if (openHandles->remove(dbname, dbhandle.handleid) == false) {
return Code::kIOError;
}
*/
//
// We do not close any handles for now, otherwise we have to do
// some locking that will degrade performance in the normal case.
//
return Code::kNotSupported;
}
@ -98,7 +96,7 @@ class DBHandler : virtual public DBIf {
key.size_ = kv.key.size;
value.data_ = kv.value.data.data();
value.size_ = kv.value.size;
leveldb::DB* db = openHandles->get(dbhandle.dbname, dbhandle.handleid, NULL);
leveldb::DB* db = openHandles->get(dbhandle.dbname, NULL);
if (db == NULL) {
return Code::kNotFound;
}
@ -116,7 +114,7 @@ class DBHandler : virtual public DBIf {
leveldb::Slice key;
key.data_ = kv.data.data();
key.size_ = kv.size;
leveldb::DB* db = openHandles->get(dbhandle.dbname, dbhandle.handleid, NULL);
leveldb::DB* db = openHandles->get(dbhandle.dbname, NULL);
if (db == NULL) {
return Code::kNotFound;
}
@ -141,7 +139,7 @@ class DBHandler : virtual public DBIf {
value.size_ = one.value.size;
lbatch.Put(key, value);
}
leveldb::DB* db = openHandles->get(dbhandle.dbname, dbhandle.handleid, NULL);
leveldb::DB* db = openHandles->get(dbhandle.dbname, NULL);
if (db == NULL) {
return Code::kNotFound;
}
@ -160,8 +158,7 @@ class DBHandler : virtual public DBIf {
leveldb::Slice ikey;
ikey.data_ = inputkey.data.data();
ikey.size_ = inputkey.size;
leveldb::DB* db = openHandles->get(dbhandle.dbname, dbhandle.handleid,
&thishandle);
leveldb::DB* db = openHandles->get(dbhandle.dbname, &thishandle);
if (db == NULL) {
return;
}
@ -192,8 +189,7 @@ class DBHandler : virtual public DBIf {
const Slice& target) {
struct onehandle* thishandle;
_return.status = Code::kNotFound;
leveldb::DB* db = openHandles->get(dbhandle.dbname, dbhandle.handleid,
&thishandle);
leveldb::DB* db = openHandles->get(dbhandle.dbname, &thishandle);
if (db == NULL) {
return;
}
@ -245,8 +241,7 @@ class DBHandler : virtual public DBIf {
Code DeleteIterator(const DBHandle& dbhandle, const Iterator& iterator) {
// find the db
struct onehandle* thishandle;
leveldb::DB* db = openHandles->get(dbhandle.dbname, dbhandle.handleid,
&thishandle);
leveldb::DB* db = openHandles->get(dbhandle.dbname, &thishandle);
if (db == NULL) {
return kNotFound;
}
@ -271,8 +266,7 @@ class DBHandler : virtual public DBIf {
// find the db
struct onehandle* thishandle;
_return.status = Code::kNotFound;
leveldb::DB* db = openHandles->get(dbhandle.dbname, dbhandle.handleid,
&thishandle);
leveldb::DB* db = openHandles->get(dbhandle.dbname, &thishandle);
if (db == NULL) {
return;
}
@ -338,8 +332,7 @@ class DBHandler : virtual public DBIf {
void GetSnapshot(ResultSnapshot& _return, const DBHandle& dbhandle) {
_return.status = kIOError;
struct onehandle* thishandle;
leveldb::DB* db = openHandles->get(dbhandle.dbname, dbhandle.handleid,
&thishandle);
leveldb::DB* db = openHandles->get(dbhandle.dbname, &thishandle);
if (db == NULL) {
return;
}
@ -354,8 +347,7 @@ class DBHandler : virtual public DBIf {
Code ReleaseSnapshot(const DBHandle& dbhandle, const Snapshot& snapshot) {
struct onehandle* thishandle;
leveldb::DB* db = openHandles->get(dbhandle.dbname, dbhandle.handleid,
&thishandle);
leveldb::DB* db = openHandles->get(dbhandle.dbname, &thishandle);
if (db == NULL) {
return kNotFound;
}
@ -369,7 +361,7 @@ class DBHandler : virtual public DBIf {
Code CompactRange(const DBHandle& dbhandle, const Slice& begin,
const Slice& end) {
leveldb::DB* db = openHandles->get(dbhandle.dbname, dbhandle.handleid, NULL);
leveldb::DB* db = openHandles->get(dbhandle.dbname, NULL);
if (db == NULL) {
return Code::kNotFound;
}
@ -395,6 +387,14 @@ class DBHandler : virtual public DBIf {
OpenHandles* openHandles;
};
//
// starts a service
static void* startOneService(void *arg) {
TSimpleServer* t = (TSimpleServer *)arg;
t->serve();
}
// Starts a very simple thrift server
void startServer(int argc, char** argv) {
@ -410,17 +410,43 @@ void startServer(int argc, char** argv) {
// create the server's block cache
server_options.createCache();
int port = server_options.getPort();
shared_ptr<DBHandler> handler(new DBHandler());
shared_ptr<TProcessor> processor(new DBProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
// data structure to record ope databases
OpenHandles* openHandles = new OpenHandles();
shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
TSimpleServer tServer(processor, serverTransport, transportFactory, protocolFactory);
fprintf(stderr, "Server started on port %d\n", port);
// create the service to process the normal get/put to leveldb.
int port = server_options.getPort();
fprintf(stderr, "Server starting on port %d\n", port);
shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
shared_ptr<DBHandler> handler(new DBHandler(openHandles));
shared_ptr<TProcessor> processor(new DBProcessor(handler));
TSimpleServer* baseServer = new TSimpleServer(processor, serverTransport,
transportFactory, protocolFactory);
pthread_t dbServerThread;
int rc = pthread_create(&dbServerThread, NULL, startOneService,
(void *)baseServer);
if (rc != 0) {
fprintf(stderr, "Unable to start DB server on port %d\n.", port);
exit(1);
}
tServer.serve();
// create the service to process the assoc get/put to leveldb.
int assocport = server_options.getAssocPort();
fprintf(stderr, "Server starting on port %d\n", assocport);
shared_ptr<TServerTransport> assocTransport(new TServerSocket(assocport));
shared_ptr<AssocServiceHandler> assocHandler(new AssocServiceHandler(openHandles));
shared_ptr<TProcessor> assocProcessor(new AssocServiceProcessor(assocHandler));
TSimpleServer* assocServer = new TSimpleServer(assocProcessor,
assocTransport, transportFactory, protocolFactory);
pthread_t assocServerThread;
rc = pthread_create(&assocServerThread, NULL, startOneService,
(void *)assocServer);
if (rc != 0) {
fprintf(stderr, "Unable to start assoc server on port %d\n.", port);
exit(1);
}
}
/**
@ -436,5 +462,6 @@ void startEventServer(int port) {
// Stops the thrift server
void stopServer(int port) {
tServer->stop();
baseServer->stop();
assocServer->stop();
}

@ -6,7 +6,9 @@
#include <protocol/TBinaryProtocol.h>
#include <transport/TSocket.h>
#include <transport/TBufferTransports.h>
#include <util/testharness.h>
#include <DB.h>
#include <AssocService.h>
#include <leveldb_types.h>
#include "server_options.h"
@ -22,7 +24,8 @@ extern ServerOptions server_options;
static DBHandle dbhandle;
static DBClient* dbclient;
static const Text dbname = "test";
static AssocServiceClient* aclient;
static const Text dbname = "test-dhruba";
static pthread_t serverThread;
static int ARGC;
static char** ARGV;
@ -51,17 +54,31 @@ static void createDatabase() {
dbclient->Open(dbhandle, dbname, options);
}
static void testClient(int port) {
boost::shared_ptr<TSocket> socket(new TSocket("localhost", port));
boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
WriteOptions writeOptions;
static void initialize(int port) {
boost::shared_ptr<TSocket> socket1(new TSocket("localhost", port));
boost::shared_ptr<TTransport> transport1(new TBufferedTransport(socket1));
boost::shared_ptr<TProtocol> protocol1(new TBinaryProtocol(transport1));
// open database
dbclient = new DBClient(protocol);
transport->open();
dbclient = new DBClient(protocol1);
transport1->open();
boost::shared_ptr<TSocket> socket2(new TSocket("localhost", port+1));
boost::shared_ptr<TTransport> transport2(new TBufferedTransport(socket2));
boost::shared_ptr<TProtocol> protocol2(new TBinaryProtocol(transport2));
aclient = new AssocServiceClient(protocol2);
transport2->open();
createDatabase();
printf("Database created.\n");
}
//
// Run base leveldb thrift server get/put/iter/scan tests
//
static void testClient() {
WriteOptions writeOptions;
printf("Running base leveldb operations .................\n");
// insert record into leveldb
Slice key;
@ -74,23 +91,23 @@ static void testClient(int port) {
keyvalue.key = key;
keyvalue.value = value;
int ret = dbclient->Put(dbhandle, keyvalue, writeOptions);
assert(ret == Code::kOk);
ASSERT_TRUE(ret == Code::kOk);
printf("Put Key1 suceeded.\n");
//read it back
ReadOptions readOptions;
ResultItem rValue;
dbclient->Get(rValue, dbhandle, key, readOptions);
assert(rValue.status == Code::kOk);
assert(value.data.compare(rValue.value.data) == 0);
assert(value.size == rValue.value.size);
ASSERT_TRUE(rValue.status == Code::kOk);
ASSERT_TRUE(value.data.compare(rValue.value.data) == 0);
ASSERT_TRUE(value.size == rValue.value.size);
printf("Get suceeded.\n");
// get a snapshot
ResultSnapshot rsnap;
dbclient->GetSnapshot(rsnap, dbhandle);
assert(rsnap.status == Code::kOk);
assert(rsnap.snapshot.snapshotid > 0);
ASSERT_TRUE(rsnap.status == Code::kOk);
ASSERT_TRUE(rsnap.snapshot.snapshotid > 0);
printf("Snapshot suceeded.\n");
// insert a new record into leveldb
@ -103,29 +120,29 @@ static void testClient(int port) {
keyvalue.key = key2;
keyvalue.value = value2;
ret = dbclient->Put(dbhandle, keyvalue, writeOptions);
assert(ret == Code::kOk);
ASSERT_TRUE(ret == Code::kOk);
printf("Put Key2 suceeded.\n");
// verify that a get done with a previous snapshot does not find Key2
readOptions.snapshot = rsnap.snapshot;
dbclient->Get(rValue, dbhandle, key2, readOptions);
assert(rValue.status == Code::kNotFound);
ASSERT_TRUE(rValue.status == Code::kNotFound);
printf("Get with snapshot succeeded.\n");
// release snapshot
ret = dbclient->ReleaseSnapshot(dbhandle, rsnap.snapshot);
assert(ret == Code::kOk);
ASSERT_TRUE(ret == Code::kOk);
printf("Snapshot released.\n");
// if we try to re-release the same snapshot, it should fail
ret = dbclient->ReleaseSnapshot(dbhandle, rsnap.snapshot);
assert(ret == Code::kNotFound);
ASSERT_TRUE(ret == Code::kNotFound);
// compact whole database
Slice range;
range.size = 0;
ret = dbclient->CompactRange(dbhandle, range, range);
assert(ret == Code::kOk);
ASSERT_TRUE(ret == Code::kOk);
printf("Compaction trigger suceeded.\n");
// create a new iterator to scan all keys from the start
@ -134,7 +151,7 @@ static void testClient(int port) {
readOptions.snapshot.snapshotid = 0;
dbclient->NewIterator(ri, dbhandle, readOptions,
IteratorType::seekToFirst, target);
assert(ri.status == Code::kOk);
ASSERT_TRUE(ri.status == Code::kOk);
int foundPairs = 0;
while (true) {
ResultPair pair;
@ -145,16 +162,16 @@ static void testClient(int port) {
break;
}
}
assert(foundPairs == 2);
ASSERT_TRUE(foundPairs == 2);
ret = dbclient->DeleteIterator(dbhandle, ri.iterator);
assert(ret == Code::kOk);
ASSERT_TRUE(ret == Code::kOk);
printf("Iterator scan-all forward passes.\n");
// create a new iterator, position at end and scan backwards
readOptions.snapshot.snapshotid = 0;
dbclient->NewIterator(ri, dbhandle, readOptions,
IteratorType::seekToLast, target);
assert(ri.status == Code::kOk);
ASSERT_TRUE(ri.status == Code::kOk);
foundPairs = 0;
while (true) {
ResultPair pair;
@ -165,9 +182,9 @@ static void testClient(int port) {
break;
}
}
assert(foundPairs == 2);
ASSERT_TRUE(foundPairs == 2);
ret = dbclient->DeleteIterator(dbhandle, ri.iterator);
assert(ret == Code::kOk);
ASSERT_TRUE(ret == Code::kOk);
printf("Iterator scan-all backward passes.\n");
// create a new iterator, position at middle
@ -175,7 +192,7 @@ static void testClient(int port) {
target = key;
dbclient->NewIterator(ri, dbhandle, readOptions,
IteratorType::seekToKey, target);
assert(ri.status == Code::kOk);
ASSERT_TRUE(ri.status == Code::kOk);
foundPairs = 0;
while (true) {
ResultPair pair;
@ -186,29 +203,78 @@ static void testClient(int port) {
break;
}
}
assert(foundPairs == 1);
ASSERT_TRUE(foundPairs == 1);
ret = dbclient->DeleteIterator(dbhandle, ri.iterator);
assert(ret == Code::kOk);
ASSERT_TRUE(ret == Code::kOk);
printf("Iterator scan-selective backward passes.\n");
// close database
dbclient->Close(dbhandle, dbname);
transport->close();
}
//
// Run assoc tests
//
static void testAssocs() {
WriteOptions writeOptions;
printf("Running assoc leveldb operations ................\n");
static void* startTestServer(void *arg) {
printf("Server test server\n");
startServer(ARGC, ARGV);
// insert record into leveldb
int64_t assocType = 100;
int64_t id1 = 1;
int64_t id2 = 2;
int64_t id1Type = 101;
int64_t id2Type = 102;
int64_t ts =3333;
AssocVisibility vis = AssocVisibility::VISIBLE;
bool update_count = true;
int64_t dataVersion = 5;
const Text data = "data......";
const Text wormhole_comments = "wormhole...";
int64_t count = aclient->taoAssocPut(dbname, assocType,
id1, id2, id1Type, id2Type,
ts, vis, update_count,
dataVersion, data, wormhole_comments);
ASSERT_GE(count, 0);
printf("Put AssocPut suceeded.\n");
// verify assoc counts.
int64_t cnt = aclient->taoAssocCount(dbname, assocType, id1);
ASSERT_EQ(cnt, 1);
printf("AssocCount suceeded.\n");
// verify that we can read back what we inserted earlier
std::vector<int64_t> id2list(1);
id2list[0] = id2;
std::vector<TaoAssocGetResult> readback(1);
aclient->taoAssocGet(readback, dbname,
assocType, id1, id2list);
printf("AssocGet suceeded.\n");
printf("size = %lld\n", readback.size());
ASSERT_EQ(1, readback.size());
ASSERT_EQ(id1Type, readback[0].id1Type);
printf("XXX %lld %lld\n", id1Type, readback[0].id1Type);
ASSERT_EQ(id2Type, readback[0].id2Type);
ASSERT_EQ(ts, readback[0].time);
ASSERT_EQ(dataVersion, readback[0].dataVersion);
ASSERT_EQ(readback[0].data.compare(wormhole_comments), 0);
}
//
// close all resources
//
static void close() {
// close database
dbclient->Close(dbhandle, dbname);
// transport->close();
}
int main(int argc, char **argv) {
ARGC = argc;
ARGV = argv;
// create a server
int rc = pthread_create(&serverThread, NULL, startTestServer, NULL);
startServer(argc, argv);
printf("Server thread created.\n");
// give some time to the server to initialize itself
@ -217,7 +283,14 @@ int main(int argc, char **argv) {
}
// test client
testClient(server_options.getPort());
initialize(server_options.getPort());
// run all tests
testClient();
testAssocs();
// done all tests
close();
return 0;
}

Loading…
Cancel
Save