Refactor Tenant class in fdb_api header to match conventions of existing classes and move tenant creation into populate function
This commit is contained in:
parent
cdca68e26a
commit
b92b3b21b0
|
@ -112,7 +112,7 @@ if(NOT WIN32)
|
|||
test/unit/fdb_api.hpp)
|
||||
|
||||
add_library(fdb_cpp INTERFACE)
|
||||
target_sources(fdb_cpp INTERFACE test/fdb_api.hpp test/fdb_api.cpp)
|
||||
target_sources(fdb_cpp INTERFACE test/fdb_api.hpp)
|
||||
target_include_directories(fdb_cpp INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/test)
|
||||
target_link_libraries(fdb_cpp INTERFACE fmt::fmt)
|
||||
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* fdb_api.cpp
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2022 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "fdb_api.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace fdb {
|
||||
|
||||
const std::string Tenant::tenantManagementMapPrefix = "\xff\xff/management/tenant_map/";
|
||||
|
||||
} // namespace fdb
|
|
@ -23,7 +23,7 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef FDB_API_VERSION
|
||||
#define FDB_API_VERSION 710
|
||||
#define FDB_API_VERSION 720
|
||||
#endif
|
||||
|
||||
#include <cassert>
|
||||
|
@ -560,55 +560,42 @@ public:
|
|||
};
|
||||
|
||||
class Tenant final {
|
||||
static const std::string tenantManagementMapPrefix;
|
||||
static const std::string tenantMapPrefix;
|
||||
std::shared_ptr<native::FDBTenant> tenant;
|
||||
static constexpr CharsRef tenantManagementMapPrefix = "\xff\xff/management/tenant_map/";
|
||||
|
||||
public:
|
||||
static TypedFuture<future_var::None> createTenant(Transaction tr, std::string name) {
|
||||
Tenant(const Tenant&) noexcept = default;
|
||||
Tenant& operator=(const Tenant&) noexcept = default;
|
||||
Tenant(fdb::Database* db, BytesRef name, int name_length) : tenant(nullptr) {
|
||||
auto tenant_raw = static_cast<native::FDBTenant*>(nullptr);
|
||||
if (auto err = Error(native::fdb_database_open_tenant(db->db.get(), name.data(), name_length, &tenant_raw))) {
|
||||
throwError(fmt::format("Failed to create tenant with name '{}': ", name), err);
|
||||
}
|
||||
tenant = std::shared_ptr<native::FDBTenant>(tenant_raw, &native::fdb_tenant_destroy);
|
||||
}
|
||||
Tenant() noexcept : tenant(nullptr) {}
|
||||
|
||||
static void createTenant(Transaction tr, BytesRef name) {
|
||||
tr.setOption(FDBTransactionOption::FDB_TR_OPTION_SPECIAL_KEY_SPACE_ENABLE_WRITES, 1);
|
||||
tr.setOption(FDBTransactionOption::FDB_TR_OPTION_LOCK_AWARE, 1);
|
||||
KeyRef tenantManagementKey = toBytesRef(tenantManagementMapPrefix + name);
|
||||
tr.set(tenantManagementKey, toBytesRef(std::string("")));
|
||||
return tr.commit();
|
||||
tr.set(toBytesRef(fmt::format("{}{}", tenantManagementMapPrefix, toCharsRef(name))),
|
||||
toBytesRef(std::string("")));
|
||||
}
|
||||
|
||||
static TypedFuture<future_var::None> deleteTenant(Transaction tr, std::string name) {
|
||||
static void deleteTenant(Transaction tr, BytesRef name) {
|
||||
tr.setOption(FDBTransactionOption::FDB_TR_OPTION_RAW_ACCESS, 1);
|
||||
tr.setOption(FDBTransactionOption::FDB_TR_OPTION_LOCK_AWARE, 1);
|
||||
KeyRef tenantManagementKey = toBytesRef(tenantManagementMapPrefix + name);
|
||||
tr.clear(tenantManagementKey);
|
||||
return tr.commit();
|
||||
}
|
||||
|
||||
Tenant(fdb::Database* db, const uint8_t* name, int name_length) {
|
||||
if (native::fdb_error_t err = fdb_database_open_tenant(db->db.get(), name, name_length, &tenant)) {
|
||||
std::cerr << native::fdb_get_error(err) << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
|
||||
~Tenant() {
|
||||
if (tenant != nullptr) {
|
||||
fdb_tenant_destroy(tenant);
|
||||
}
|
||||
tr.clear(toBytesRef(fmt::format("{}{}", tenantManagementMapPrefix, toCharsRef(name))));
|
||||
}
|
||||
|
||||
Transaction createTransaction() {
|
||||
auto tx_native = static_cast<native::FDBTransaction*>(nullptr);
|
||||
auto err = Error(native::fdb_tenant_create_transaction(tenant, &tx_native));
|
||||
auto err = Error(native::fdb_tenant_create_transaction(tenant.get(), &tx_native));
|
||||
if (err)
|
||||
throwError("Failed to create transaction: ", err);
|
||||
return Transaction(tx_native);
|
||||
}
|
||||
|
||||
Tenant(const Tenant&) = delete;
|
||||
Tenant& operator=(const Tenant&) = delete;
|
||||
Tenant(Tenant&&) = delete;
|
||||
Tenant& operator=(Tenant&&) = delete;
|
||||
|
||||
private:
|
||||
friend class Transaction;
|
||||
native::FDBTenant* tenant;
|
||||
};
|
||||
|
||||
} // namespace fdb
|
||||
|
|
|
@ -78,15 +78,15 @@ using namespace mako;
|
|||
|
||||
thread_local Logger logr = Logger(MainProcess{}, VERBOSE_DEFAULT);
|
||||
|
||||
Transaction createNewTransaction(Database* db, Arguments const& args, int id = -1) {
|
||||
Transaction createNewTransaction(Database db, Arguments const& args, int id = -1) {
|
||||
// No tenants specified
|
||||
if (args.tenants <= 0) {
|
||||
return db->createTransaction();
|
||||
return db.createTransaction();
|
||||
}
|
||||
// Create Tenant Transaction
|
||||
int tenant_id = (id == -1) ? urand(1, args.tenants) : id;
|
||||
std::string tenant_name = "tenant" + std::to_string(tenant_id);
|
||||
Tenant t(db, reinterpret_cast<const uint8_t*>(tenant_name.c_str()), tenant_name.length());
|
||||
BytesRef tenant_name = toBytesRef("tenant" + std::to_string(tenant_id));
|
||||
Tenant t(&db, tenant_name, tenant_name.length());
|
||||
return t.createTransaction();
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ int cleanup(Database db, Arguments const& args) {
|
|||
// If args.tenants is zero, this will use a non-tenant txn and perform a single range clear.
|
||||
// If 1, it will use a tenant txn and do a single range clear instead.
|
||||
// If > 1, it will perform a range clear with a different tenant txn per iteration.
|
||||
Transaction tx = createNewTransaction(&db, args, i);
|
||||
Transaction tx = createNewTransaction(db, args, i);
|
||||
while (true) {
|
||||
tx.clearRange(beginstr, endstr);
|
||||
auto future_commit = tx.commit();
|
||||
|
@ -132,19 +132,16 @@ int cleanup(Database db, Arguments const& args) {
|
|||
|
||||
// If tenants are specified, also delete the tenant after clearing out its keyspace
|
||||
if (args.tenants > 0) {
|
||||
std::string tenant_name = "tenant" + std::to_string(i);
|
||||
while (true) {
|
||||
Transaction systemTx = db.createTransaction();
|
||||
auto future_commit = Tenant::deleteTenant(systemTx, tenant_name);
|
||||
Tenant::deleteTenant(systemTx, toBytesRef("tenant" + std::to_string(i)));
|
||||
auto future_commit = systemTx.commit();
|
||||
const auto rc = waitAndHandleError(systemTx, future_commit, "DELETE_TENANT");
|
||||
if (rc == FutureRC::OK) {
|
||||
break;
|
||||
} else if (rc == FutureRC::RETRY || rc == FutureRC::CONFLICT) {
|
||||
// tx already reset
|
||||
continue;
|
||||
} else {
|
||||
// try with new transaction object
|
||||
systemTx = db.createTransaction();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +175,23 @@ int populate(Database db,
|
|||
auto watch_trace = Stopwatch(watch_total.getStart());
|
||||
auto key_checkpoint = key_begin; // in case of commit failure, restart from this key
|
||||
|
||||
Transaction tx = createNewTransaction(&db, args);
|
||||
Transaction systemTx = db.createTransaction();
|
||||
for (int i = 1; i <= args.tenants; ++i) {
|
||||
std::string tenant_name = "tenant" + std::to_string(i);
|
||||
Tenant::createTenant(systemTx, toBytesRef(tenant_name));
|
||||
while (i % 10 == 0 || i == args.tenants) {
|
||||
// create {batchSize} # of tenants
|
||||
// commit every batch
|
||||
auto future_commit = systemTx.commit();
|
||||
const auto rc = waitAndHandleError(systemTx, future_commit, "CREATE_TENANT");
|
||||
if (rc == FutureRC::OK) {
|
||||
systemTx.reset();
|
||||
break;
|
||||
}
|
||||
// look up tenant range limit 1. If found, break, else retry
|
||||
}
|
||||
}
|
||||
Transaction tx = createNewTransaction(db, args);
|
||||
for (auto i = key_begin; i <= key_end; i++) {
|
||||
/* sequential keys */
|
||||
genKey(keystr.data(), KEY_PREFIX, args, i);
|
||||
|
@ -224,7 +237,7 @@ int populate(Database db,
|
|||
auto tx_restarter = ExitGuard([&watch_tx]() { watch_tx.startFromStop(); });
|
||||
if (rc == FutureRC::OK) {
|
||||
key_checkpoint = i + 1; // restart on failures from next key
|
||||
tx = createNewTransaction(&db, args);
|
||||
tx = createNewTransaction(db, args);
|
||||
} else if (rc == FutureRC::ABORT) {
|
||||
return -1;
|
||||
} else {
|
||||
|
@ -410,7 +423,7 @@ int runWorkload(Database db,
|
|||
|
||||
/* main transaction loop */
|
||||
while (1) {
|
||||
Transaction tx = createNewTransaction(&db, args);
|
||||
Transaction tx = createNewTransaction(db, args);
|
||||
while ((thread_tps > 0) && (xacts >= current_tps)) {
|
||||
/* throttle on */
|
||||
const auto time_now = steady_clock::now();
|
||||
|
@ -615,29 +628,6 @@ void workerThread(ThreadArgs& thread_args) {
|
|||
? -1
|
||||
: computeThreadIters(args.iteration, worker_id, thread_id, args.num_processes, args.num_threads);
|
||||
|
||||
/* create my own transaction object */
|
||||
Transaction tx;
|
||||
tx = database.createTransaction();
|
||||
|
||||
if (tenant_main && tenants > 0) {
|
||||
for (int i = 1; i <= tenants; ++i) {
|
||||
std::string tenant_name = "tenant" + std::to_string(i);
|
||||
while (true) {
|
||||
auto future_commit = Tenant::createTenant(tx, tenant_name);
|
||||
const auto rc = waitAndHandleError(tx, future_commit, "CREATE_TENANT");
|
||||
if (rc == FutureRC::OK) {
|
||||
break;
|
||||
} else if (rc == FutureRC::RETRY || rc == FutureRC::CONFLICT) {
|
||||
// tx already reset
|
||||
continue;
|
||||
} else {
|
||||
// try with new transaction object
|
||||
tx = database.createTransaction();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* i'm ready */
|
||||
readycount.fetch_add(1);
|
||||
auto stopcount_guard = ExitGuard([&stopcount]() { stopcount.fetch_add(1); });
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#define MAKO_HPP
|
||||
|
||||
#ifndef FDB_API_VERSION
|
||||
#define FDB_API_VERSION 710
|
||||
#define FDB_API_VERSION 720
|
||||
#endif
|
||||
|
||||
#include <array>
|
||||
|
|
Loading…
Reference in New Issue