Skip to content

Commit

Permalink
Refined exception handling and noexcept specifications for public APIs
Browse files Browse the repository at this point in the history
- Reviewed all public APIs to ensure the correct exception specifications.
- Corrected APIs that were missing or incorrectly specifying noexcept.
- Updated documentation to clearly state which exceptions are thrown by each API.
- Fixed several areas where exceptions were not being handled properly, ensuring robust error handling.
  • Loading branch information
umegane committed Sep 25, 2024
1 parent 6a7e4a8 commit 86df100
Show file tree
Hide file tree
Showing 14 changed files with 176 additions and 64 deletions.
67 changes: 67 additions & 0 deletions fcheck.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include <clang/AST/ASTConsumer.h>
#include <clang/AST/RecursiveASTVisitor.h>
#include <clang/Frontend/ASTConsumers.h>
#include <clang/Frontend/FrontendActions.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Tooling.h>
#include <clang/Frontend/CompilerInstance.h>
#include <iostream>

using namespace clang;
using namespace clang::tooling;

class FunctionVisitor : public RecursiveASTVisitor<FunctionVisitor> {
public:
explicit FunctionVisitor(ASTContext *context) : context(context) {}

bool VisitFunctionDecl(FunctionDecl *func) {
// 関数名を取得
std::string funcName = func->getNameInfo().getName().getAsString();

// noexcept が指定されているかどうかを確認
bool isNoexcept = (func->getExceptionSpecType() == EST_BasicNoexcept);

// 結果を出力
std::cout << "Function: " << funcName
<< " - noexcept: " << (isNoexcept ? "true" : "false")
<< std::endl;

return true;
}

private:
ASTContext *context;
};

class FunctionASTConsumer : public ASTConsumer {
public:
explicit FunctionASTConsumer(ASTContext *context) : visitor(context) {}

virtual void HandleTranslationUnit(ASTContext &context) override {
visitor.TraverseDecl(context.getTranslationUnitDecl());
}

private:
FunctionVisitor visitor;
};

class FunctionFrontendAction : public ASTFrontendAction {
public:
virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, StringRef file) override {
return std::make_unique<FunctionASTConsumer>(&CI.getASTContext());
}
};

static llvm::cl::OptionCategory MyToolCategory("my-tool options");

int main(int argc, const char **argv) {
auto optionsParser = CommonOptionsParser::create(argc, argv, MyToolCategory);
if (!optionsParser) {
llvm::errs() << "Error creating CommonOptionsParser\n";
return 1;
}

ClangTool tool(optionsParser->getCompilations(), optionsParser->getSourcePathList());
return tool.run(newFrontendActionFactory<FunctionFrontendAction>().get());
}

20 changes: 10 additions & 10 deletions include/limestone/api/backup_detail.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,46 +57,46 @@ class backup_detail {
* @param is_detached Indicates whether the target file can be moved.
* If true, the command may or may not move this file.
*/
entry(boost::filesystem::path source_path, boost::filesystem::path destination_path, bool is_mutable, bool is_detached)
entry(boost::filesystem::path source_path, boost::filesystem::path destination_path, bool is_mutable, bool is_detached) noexcept
: source_path_(std::move(source_path)), destination_path_(std::move(destination_path)), is_mutable_(is_mutable), is_detached_(is_detached) {}

[[nodiscard]] boost::filesystem::path source_path() const { return source_path_; }
[[nodiscard]] boost::filesystem::path destination_path() const { return destination_path_; }
[[nodiscard]] bool is_mutable() const { return is_mutable_; }
[[nodiscard]] bool is_detached() const { return is_detached_; }
[[nodiscard]] boost::filesystem::path source_path() const noexcept { return source_path_; }
[[nodiscard]] boost::filesystem::path destination_path() const noexcept { return destination_path_; }
[[nodiscard]] bool is_mutable() const noexcept { return is_mutable_; }
[[nodiscard]] bool is_detached() const noexcept { return is_detached_; }
private:
boost::filesystem::path source_path_ {};
boost::filesystem::path destination_path_ {};
bool is_mutable_ {};
bool is_detached_ {};
};

std::string_view configuration_id() {
std::string_view configuration_id() noexcept {
return configuration_id_;
}

/**
* @brief returns minimum epoch of log files
* @note for LOG-0, always returns 0
*/
[[nodiscard]] epoch_id_type log_start() const {
[[nodiscard]] epoch_id_type log_start() const noexcept{
return 0;
}

/**
* @brief returns maximum epoch of log files
*/
[[nodiscard]] epoch_id_type log_finish() const;
[[nodiscard]] epoch_id_type log_finish() const noexcept;

/**
* @brief returns maximum epoch that is included in dataabase image
* @note for LOG-0, always returns nullopt of std::optional
*/
[[nodiscard]] std::optional<epoch_id_type> image_finish() const {
[[nodiscard]] std::optional<epoch_id_type> image_finish() const noexcept{
return std::nullopt;
}

const std::vector<backup_detail::entry>& entries() {
const std::vector<backup_detail::entry>& entries() noexcept {
return entries_;
}

Expand Down
4 changes: 2 additions & 2 deletions include/limestone/api/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class configuration {
/**
* @brief create empty object
*/
configuration();
configuration() noexcept;

/**
* @brief create a object
Expand All @@ -56,7 +56,7 @@ class configuration {
* @brief setter for recover_max_parallelism
* @param recover_max_parallelism the number of recover_max_parallelism
*/
void set_recover_max_parallelism(int recover_max_parallelism) {
void set_recover_max_parallelism(int recover_max_parallelism) noexcept{
recover_max_parallelism_ = recover_max_parallelism;
}

Expand Down
3 changes: 2 additions & 1 deletion include/limestone/api/cursor.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class cursor {
/**
* @brief change the current cursor to point to the next entry
* @attention this function is not thread-safe.
* @exception limestone_exception if an error occurs while reading the log entry
* @return true if the next entry exists, false otherwise
*/
bool next();
Expand Down Expand Up @@ -80,7 +81,7 @@ class cursor {
std::unique_ptr<log_entry> log_entry_;
std::vector<large_object_view> large_objects_{};

explicit cursor(const boost::filesystem::path& file) noexcept;
explicit cursor(const boost::filesystem::path& file);

friend class snapshot;
};
Expand Down
16 changes: 13 additions & 3 deletions include/limestone/api/datastore.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class datastore {
/**
* @brief create an object with the given configuration
* @param conf a reference to a configuration object used in the object construction
* @exception limestone_exception if an I/O error occurs during construction
*/
explicit datastore(configuration const& conf);

Expand Down Expand Up @@ -99,7 +100,7 @@ class datastore {
status restore(std::string_view from, bool keep_backup) const noexcept;

// restore (prusik era)
status restore(std::string_view from, std::vector<file_set_entry>& entries);
status restore(std::string_view from, std::vector<file_set_entry>& entries) noexcept;

/**
* @brief returns the status of the restore process that is currently in progress or that has finished immediately before
Expand All @@ -111,6 +112,7 @@ class datastore {
/**
* @brief transition this object to an operational state
* @details after this method is called, create_channel() can be invoked.
* @exception limestone_io_exception Thrown if an I/O error occurs.
* @attention this function is not thread-safe, and the from directory must not contain any files other than log files.
*/
void ready();
Expand All @@ -136,7 +138,7 @@ class datastore {
* @return the reference of the log_channel
* @attention this function should be called before the ready() is called.
*/
log_channel& create_channel(const boost::filesystem::path& location);
log_channel& create_channel(const boost::filesystem::path& location) noexcept;

/**
* @brief provide the largest epoch ID
Expand All @@ -149,6 +151,7 @@ class datastore {
/**
* @brief change the current epoch ID
* @param new epoch id which must be greater than current epoch ID.
* @exception limestone_io_exception Thrown if an I/O error occurs.
* @attention this function should be called after the ready() is called.
*/
void switch_epoch(epoch_id_type epoch_id);
Expand Down Expand Up @@ -189,6 +192,7 @@ class datastore {
/**
* @brief start backup operation
* @detail a backup object is created, which contains a list of log files.
* @exception limestone_io_exception Thrown if an I/O error occurs.
* @return a reference to the backup object.
*/
backup& begin_backup();
Expand All @@ -197,6 +201,7 @@ class datastore {
/**
* @brief start backup operation
* @detail a backup_detail object is created, which contains a list of log entry.
* @exception limestone_io_exception Thrown if an I/O error occurs.
* @return a reference to the backup_detail object.
*/
std::unique_ptr<backup_detail> begin_backup(backup_type btype);
Expand All @@ -216,7 +221,12 @@ class datastore {
void recover(const epoch_tag&) const noexcept;

/**
* Performs online compaction of the datastore.
* @brief Performs online log file compaction.
*
* This function compacts log files that have been rotated and are no longer subject to new entries.
*
* @exception limestone_exception Thrown if an I/O error occurs during the compaction process.
* @attention this function should be called before the ready() is called.
*/
void compact_with_online();

Expand Down
6 changes: 3 additions & 3 deletions include/limestone/api/file_set_entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ class file_set_entry {
file_set_entry(boost::filesystem::path source_path, boost::filesystem::path destination_path, bool is_detached)
: source_path_(std::move(source_path)), destination_path_(std::move(destination_path)), is_detached_(is_detached) {}

[[nodiscard]] boost::filesystem::path source_path() const { return source_path_; }
[[nodiscard]] boost::filesystem::path destination_path() const { return destination_path_; }
[[nodiscard]] bool is_detached() const { return is_detached_; }
[[nodiscard]] boost::filesystem::path source_path() const noexcept { return source_path_; }
[[nodiscard]] boost::filesystem::path destination_path() const noexcept { return destination_path_; }
[[nodiscard]] bool is_detached() const noexcept { return is_detached_; }

private:
boost::filesystem::path source_path_ {};
Expand Down
12 changes: 6 additions & 6 deletions include/limestone/api/limestone_exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ namespace limestone::api {

class limestone_exception : public std::runtime_error {
public:
explicit limestone_exception(const std::string& message)
explicit limestone_exception(const std::string& message) noexcept
: std::runtime_error(message) {}

explicit limestone_exception(const std::string& message, int error_code)
explicit limestone_exception(const std::string& message, int error_code) noexcept
: std::runtime_error(message), error_code_(error_code) {}

[[nodiscard]] int error_code() const noexcept { return error_code_; }
Expand All @@ -42,23 +42,23 @@ class limestone_exception : public std::runtime_error {
class limestone_io_exception : public limestone_exception {
public:
// Constructor that takes an error message and errno as arguments (int)
explicit limestone_io_exception(const std::string& message, int error_code)
explicit limestone_io_exception(const std::string& message, int error_code) noexcept
: limestone_exception(message, error_code) {}

// Constructor that takes an error message and boost::system::error_code as arguments
explicit limestone_io_exception(const std::string& message, const boost::system::error_code& error_code)
explicit limestone_io_exception(const std::string& message, const boost::system::error_code& error_code) noexcept
: limestone_exception(message, error_code.value()) {}

// Helper function to format the error message for int error_code
static std::string format_message(const std::string& message, int error_code) {
static std::string format_message(const std::string& message, int error_code) noexcept{
// Retrieve the system error message corresponding to errno
std::string errno_str = std::strerror(error_code);
// Format the complete error message
return "I/O Error (" + errno_str + "): " + message + " (errno = " + std::to_string(error_code) + ")";
}

// Helper function to format the error message for boost::system::error_code
static std::string format_message(const std::string& message, const boost::system::error_code& error_code) {
static std::string format_message(const std::string& message, const boost::system::error_code& error_code) noexcept {
return format_message(message, error_code.value());
}
};
Expand Down
10 changes: 9 additions & 1 deletion include/limestone/api/log_channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,15 @@ class log_channel {
/**
* @brief join a persistence session for the current epoch in this channel
* @attention this function is not thread-safe.
* @exception limestone_exception if I/O error occurs
* @note the current epoch is the last epoch specified by datastore::switch_epoch()
*/
void begin_session();

/**
* @brief notifies the completion of an operation in this channel for the current persistent session the channel is participating in
* @attention this function is not thread-safe.
* @exception limestone_exception if I/O error occurs
* @note when all channels that have participated in the current persistent session call end_session() and the current epoch is
* greater than the session's epoch, the persistent session itself is complete
*/
Expand All @@ -71,6 +73,7 @@ class log_channel {
* @param key the key byte string for the entry to be added
* @param value the value byte string for the entry to be added
* @param write_version (optional) the write version of the entry to be added. If omitted, the default value is used
* @exception limestone_exception if I/O error occurs
* @attention this function is not thread-safe.
*/
void add_entry(storage_id_type storage_id, std::string_view key, std::string_view value, write_version_type write_version);
Expand All @@ -82,6 +85,7 @@ class log_channel {
* @param value the value byte string for the entry to be added
* @param write_version (optional) the write version of the entry to be added. If omitted, the default value is used
* @param large_objects (optional) the list of large objects associated with the entry to be added
* @exception limestone_exception if I/O error occurs
* @attention this function is not thread-safe.
*/
void add_entry(storage_id_type storage_id, std::string_view key, std::string_view value, write_version_type write_version, const std::vector<large_object_input>& large_objects);
Expand All @@ -91,6 +95,7 @@ class log_channel {
* @param storage_id the storage ID of the entry to be deleted
* @param key the key byte string for the entry to be deleted
* @param write_version the write version of the entry to be removed
* @exception limestone_exception if I/O error occurs
* @attention this function is not thread-safe.
* @note no deletion operation is performed on the entry that has been added to the current persistent session, instead,
* the entries to be deleted are treated as if they do not exist in a recover() operation from a log stored in the current persistent session
Expand All @@ -101,6 +106,7 @@ class log_channel {
* @brief add an entry indicating the addition of the specified storage
* @param storage_id the storage ID of the entry to be added
* @param write_version the write version of the entry to be added
* @exception limestone_exception if I/O error occurs
* @attention this function is not thread-safe.
* @impl this operation may be ignored.
*/
Expand All @@ -110,6 +116,7 @@ class log_channel {
* @brief add an entry indicating the deletion of the specified storage and all entries for that storage
* @param storage_id the storage ID of the entry to be removed
* @param write_version the write version of the entry to be removed
* @exception limestone_exception if I/O error occurs
* @attention this function is not thread-safe.
* @note no deletion operation is performed on the entry that has been added to the current persistent session, instead,
* the target entries are treated as if they do not exist in the recover() operation from the log stored in the current persistent session.
Expand All @@ -120,6 +127,7 @@ class log_channel {
* @brief add an entry indicating the deletion of all entries contained in the specified storage
* @param storage_id the storage ID of the entry to be removed
* @param write_version the write version of the entry to be removed
* @exception limestone_exception if I/O error occurs
* @attention this function is not thread-safe.
* @note no deletion operation is performed on the entry that has been added to the current persistent session, instead,
* the target entries are treated as if they do not exist in the recover() operation from the log stored in the current persistent session.
Expand All @@ -131,13 +139,13 @@ class log_channel {
*/
[[nodiscard]] boost::filesystem::path file_path() const noexcept;

private:
/**
* @brief Waits until the specified epoch's session is completed and the epoch ID is removed from waiting_epoch_ids_.
* @param epoch The epoch ID associated with the session to wait for.
*/
void wait_for_end_session(epoch_id_type epoch);

private:
datastore& envelope_;

boost::filesystem::path location_;
Expand Down
1 change: 1 addition & 0 deletions include/limestone/api/snapshot.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class snapshot {
* @brief create a cursor to read the entire contents of the snapshot and returns it
* @details the returned cursor points to the first element by calling cursor::next().
* @attention this function is thread-safe.
* @exception limestone_exception if the file stream of the cursor is not good.
* @return unique pointer of the cursor
*/
[[nodiscard]] std::unique_ptr<cursor> get_cursor() const;
Expand Down
4 changes: 2 additions & 2 deletions src/limestone/backup_detail.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
namespace limestone::api {

// for LOG-0
epoch_id_type backup_detail::log_finish() const {
return log_finish_;
epoch_id_type backup_detail::log_finish() const noexcept {
return log_finish_;
}

// restriction of current implementation:
Expand Down
2 changes: 1 addition & 1 deletion src/limestone/configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

namespace limestone::api {

configuration::configuration() = default;
configuration::configuration() noexcept = default;

configuration::configuration(const std::vector<boost::filesystem::path>& data_locations, boost::filesystem::path metadata_location) noexcept
: metadata_location_(std::move(metadata_location)) {
Expand Down
Loading

0 comments on commit 86df100

Please sign in to comment.