Skip to content

Commit

Permalink
[experiment] Use SQLiteCpp
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcel Lauhoff committed Oct 18, 2023
1 parent 73fafa8 commit 71bf8d6
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 64 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,6 @@
[submodule "src/rgw/driver/sfs/sqlite/sqlite_orm"]
path = src/rgw/driver/sfs/sqlite/sqlite_orm
url = https://github.com/fnc12/sqlite_orm.git
[submodule "src/rgw/driver/sfs/SQLiteCpp"]
path = src/rgw/driver/sfs/SQLiteCpp
url = https://github.com/SRombauts/SQLiteCpp.git
1 change: 1 addition & 0 deletions src/rgw/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ if(WITH_RADOSGW_DBSTORE)
endif()
if(WITH_RADOSGW_SFS)
include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/src/rgw/driver/sfs/sqlite/sqlite_orm/include")
include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/src/rgw/driver/sfs/SQLiteCpp/include")
add_subdirectory(driver/sfs)
list(APPEND librgw_common_srcs rgw_sal_sfs.cc rgw_s3gw_telemetry.cc)
endif()
Expand Down
8 changes: 7 additions & 1 deletion src/rgw/driver/sfs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ find_package(SQLite3 REQUIRED)
set(SQLITE_COMPILE_FLAGS "-DSQLITE_THREADSAFE=1")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SQLITE_COMPILE_FLAGS}")

set(SQLITECPP_RUN_CPPCHECK OFF CACHE BOOL "" FORCE)
set(SQLITECPP_RUN_CPPLINT OFF CACHE BOOL "" FORCE)
set(SQLITECPP_USE_STATIC_RUNTIME OFF CACHE BOOL "" FORCE)
add_subdirectory(SQLiteCpp)

set(sfs_srcs
sqlite/sqlite_users.cc
sqlite/sqlite_buckets.cc
Expand Down Expand Up @@ -56,6 +61,7 @@ target_compile_options(sfs PRIVATE
# Mark ceph includes system to not see "our" warnings there
target_include_directories(sfs
SYSTEM PRIVATE "${CMAKE_SOURCE_DIR}/src/fmt/include"
SYSTEM PRIVATE "${CMAKE_SOURCE_DIR}/src/rgw/driver/sfs/SQLiteCpp/include"
SYSTEM PRIVATE "${CMAKE_SOURCE_DIR}/src/rgw"
SYSTEM PRIVATE "${CMAKE_SOURCE_DIR}/src"
SYSTEM PRIVATE "${CMAKE_SOURCE_DIR}/src/include")
Expand All @@ -65,5 +71,5 @@ if(WITH_JAEGER)
list(APPEND link_targets jaeger_base)
endif()

set(CMAKE_LINK_LIBRARIES ${CMAKE_LINK_LIBRARIES} ${link_targets} rgw_common sqlite3 pthread)
set(CMAKE_LINK_LIBRARIES ${CMAKE_LINK_LIBRARIES} ${link_targets} rgw_common sqlite3 pthread SQLiteCpp)
target_link_libraries(sfs PRIVATE ${CMAKE_LINK_LIBRARIES})
1 change: 1 addition & 0 deletions src/rgw/driver/sfs/SQLiteCpp
Submodule SQLiteCpp added at bcb4c7
3 changes: 3 additions & 0 deletions src/rgw/driver/sfs/sqlite/dbconn.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "sqlite_orm.h"
#include "users/users_definitions.h"
#include "versioned_object/versioned_object_definitions.h"
#include "SQLiteCpp/SQLiteCpp.h"

namespace rgw::sal::sfs::sqlite {

Expand Down Expand Up @@ -272,6 +273,8 @@ class DBConn {

inline auto get_storage() const { return storage; }

auto get_sqlitecpp() const { return SQLite::Database(get_storage().filename()); }

static std::string getDBPath(CephContext* cct) {
auto rgw_sfs_path = cct->_conf.get_val<std::string>("rgw_sfs_data_path");
auto db_path =
Expand Down
121 changes: 58 additions & 63 deletions src/rgw/driver/sfs/sqlite/sqlite_list.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

#include <limits>

#include "SQLiteCpp/Database.h"
#include "SQLiteCpp/Statement.h"
#include "rgw/driver/sfs/sqlite/conversion_utils.h"
#include "rgw/driver/sfs/sqlite/objects/object_definitions.h"
#include "rgw/driver/sfs/sqlite/versioned_object/versioned_object_definitions.h"
Expand Down Expand Up @@ -101,76 +103,69 @@ bool SQLiteList::versions(
// more available logic: request one more than max. if we get that
// much set out_more_available, but return only up to max
ceph_assert(max < std::numeric_limits<size_t>::max());
const size_t query_limit = max + 1;
const uint32_t query_limit = max + 1;

auto storage = conn->get_storage();
auto rows = storage.select(
columns(
&DBObject::name, &DBVersionedObject::version_id,
&DBVersionedObject::mtime, &DBVersionedObject::etag,
&DBVersionedObject::size, &DBVersionedObject::version_type,
is_equal(
// IsLatest logic
// - Use the id as secondary condition if multiple version
// with same max(commit_time) exists
sqlite_orm::select(
&DBVersionedObject::id, from<DBVersionedObject>(),
where(
is_equal(
&DBObject::uuid, &DBVersionedObject::object_id
) and
is_equal(
&DBVersionedObject::object_state,
ObjectState::COMMITTED
)
),
multi_order_by(
order_by(&DBVersionedObject::commit_time).desc(),
order_by(&DBVersionedObject::id).desc()
),
limit(1)
),
&DBVersionedObject::id
)
),
inner_join<DBVersionedObject>(
on(is_equal(&DBObject::uuid, &DBVersionedObject::object_id))
),
where(
is_equal(&DBVersionedObject::object_state, ObjectState::COMMITTED) and
is_equal(&DBObject::bucket_id, bucket_id) and
greater_than(&DBObject::name, start_after_object_name) and
prefix_to_like(&DBObject::name, prefix)
),
// Sort:
// names a-Z
// first delete markers, then versions - (See: LC CurrentExpiration)
// newest to oldest version
multi_order_by(
order_by(&DBObject::name).asc(),
order_by(&DBVersionedObject::commit_time).desc(),
order_by(&DBVersionedObject::id).desc()
),
limit(query_limit)
);
SQLite::Database db = conn->get_sqlitecpp();
SQLite::Statement query{
db, R"sql(
SELECT
o.name, vo.version_id, vo.mtime, vo.etag, vo.size, vo.version_type,
(vo.id = ( SELECT id FROM versioned_objects
WHERE object_id = o.uuid
AND object_state = ?
ORDER BY commit_time desc, id desc
LIMIT 1
)) AS is_latest
FROM objects as o
INNER JOIN versioned_objects as vo
ON (o.uuid = vo.object_id)
WHERE vo.object_state = ?
AND o.bucket_id = ?
AND o.name > ?
AND o.name LIKE ? ESCAPE '\'
ORDER BY o.name ASC,
vo.commit_time DESC,
vo.id DESC
LIMIT ?)sql"};

ceph_assert(rows.size() <= static_cast<size_t>(query_limit));
const size_t return_limit = std::min(max, rows.size());
out.reserve(return_limit);
for (size_t i = 0; i < return_limit; i++) {
const auto& row = rows[i];
query.bind(1, static_cast<int>(ObjectState::COMMITTED));
query.bind(2, static_cast<int>(ObjectState::COMMITTED));
query.bind(3, bucket_id);
query.bind(4, start_after_object_name);
query.bind(6, query_limit);
std::string like_expr;
like_expr.reserve(prefix.length() + 10);
for (const char c : prefix) {
switch (c) {
case '%':
case '_':
like_expr.push_back('\\');
default:
like_expr.push_back(c);
}
}
like_expr.push_back('%');
query.bind(5, like_expr);

out.reserve(max);
while (query.executeStep() && out.size() < max) {
rgw_bucket_dir_entry e;
e.key.name = std::get<0>(row);
e.key.instance = std::get<1>(row);
e.meta.mtime = std::get<2>(row);
e.meta.etag = std::get<3>(row);
e.meta.size = std::get<4>(row);
e.key.name = query.getColumn(0).getString();
e.key.instance = query.getColumn(1).getString();
e.meta.mtime =
ceph::real_time(std::chrono::nanoseconds(query.getColumn(2).getInt64())
);
e.meta.etag = query.getColumn(3).getString();
e.meta.size = query.getColumn(4).getInt64();
e.meta.accounted_size = e.meta.size;
e.flags = to_dentry_flag(std::get<5>(row), std::get<6>(row));
e.flags = to_dentry_flag(
static_cast<VersionType>(query.getColumn(5).getInt()),
query.getColumn(6).getInt()
);
out.emplace_back(e);
}
if (out_more_available) {
*out_more_available = rows.size() == query_limit;
*out_more_available = !query.isDone();
}
return true;
}
Expand Down
1 change: 1 addition & 0 deletions src/test/rgw/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ endif()

if(WITH_RADOSGW_SFS)
include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/src/rgw/driver/sfs/sqlite/sqlite_orm/include")
include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/src/rgw/driver/sfs/SQLiteCpp/include")
endif()

if(WITH_JAEGER)
Expand Down
2 changes: 2 additions & 0 deletions src/test/rgw/sfs/test_rgw_sfs_sqlite_list.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class TestSFSList : public ::testing::Test {
database_directory(create_database_directory()) {
cct->_conf.set_val("rgw_sfs_data_path", database_directory);
cct->_conf.set_val("rgw_sfs_sqlite_profile", "1");
cct->_conf.set_val("rgw_sfs_sqlite_profile_slowlog_time", "0");
cct->_log->set_stderr_level(5, 5);
cct->_log->start();
rgw_perf_start(cct.get());
}
Expand Down

0 comments on commit 71bf8d6

Please sign in to comment.