-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Begin transitioning to a simpler layout for the on-disk representatio…
…n. (#13) This eliminates the need to consult the schema and/or a dedicated metadata file. Now, we just have an OBJECT file that specifies the object type, and that allows us to dispatch to all the various validators for each type. Each representation now uses hard-coded file and directory names, which avoids the need to check user-defined file names in the metadata. Also, because each object's representation is fully defined by its directory contents, we can greatly simplify the takane API by avoiding the need for loads of arguments. For the time being, I've only simplified the basic object classes (defined in S4Vectors); the other classes will eventually transition to this new scheme.
- Loading branch information
Showing
30 changed files
with
3,054 additions
and
2,007 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ | |
build/ | ||
docs/html | ||
docs/latex | ||
TEST_* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,23 @@ | ||
include(FetchContent) | ||
|
||
FetchContent_Declare( | ||
uzuki2 | ||
GIT_REPOSITORY https://github.com/ArtifactDB/uzuki2 | ||
GIT_TAG master | ||
) | ||
|
||
FetchContent_Declare( | ||
ritsuko | ||
GIT_REPOSITORY https://github.com/ArtifactDB/ritsuko | ||
GIT_TAG master | ||
) | ||
|
||
FetchContent_MakeAvailable(ritsuko) | ||
|
||
FetchContent_Declare( | ||
comservatory | ||
GIT_REPOSITORY https://github.com/ArtifactDB/comservatory | ||
GIT_TAG master | ||
) | ||
|
||
FetchContent_MakeAvailable(uzuki2) | ||
FetchContent_MakeAvailable(ritsuko) | ||
FetchContent_MakeAvailable(comservatory) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
#ifndef TAKANE_HEIGHT_HPP | ||
#define TAKANE_HEIGHT_HPP | ||
|
||
#include <functional> | ||
#include <string> | ||
#include <stdexcept> | ||
#include <filesystem> | ||
|
||
#include "utils_public.hpp" | ||
#include "atomic_vector.hpp" | ||
#include "string_factor.hpp" | ||
#include "simple_list.hpp" | ||
#include "data_frame.hpp" | ||
#include "data_frame_factor.hpp" | ||
|
||
/** | ||
* @file _height.hpp | ||
* @brief Dispatch to functions for the object's height. | ||
*/ | ||
|
||
namespace takane { | ||
|
||
/** | ||
* @cond | ||
*/ | ||
namespace internal_height { | ||
|
||
inline auto default_registry() { | ||
std::unordered_map<std::string, std::function<size_t(const std::filesystem::path&, const Options&)> > registry; | ||
registry["atomic_vector"] = [](const std::filesystem::path& p, const Options& o) -> size_t { return atomic_vector::height(p, o); }; | ||
registry["string_factor"] = [](const std::filesystem::path& p, const Options& o) -> size_t { return string_factor::height(p, o); }; | ||
registry["simple_list"] = [](const std::filesystem::path& p, const Options& o) -> size_t { return simple_list::height(p, o); }; | ||
registry["data_frame"] = [](const std::filesystem::path& p, const Options& o) -> size_t { return data_frame::height(p, o); }; | ||
registry["data_frame_factor"] = [](const std::filesystem::path& p, const Options& o) -> size_t { return data_frame_factor::height(p, o); }; | ||
return registry; | ||
} | ||
|
||
} | ||
/** | ||
* @endcond | ||
*/ | ||
|
||
/** | ||
* Registry of functions to be used by `height()`. | ||
*/ | ||
inline std::unordered_map<std::string, std::function<size_t(const std::filesystem::path&, const Options&)> > height_registry = internal_height::default_registry(); | ||
|
||
/** | ||
* Override for application-defined height functions, to be used by `height()`. | ||
* | ||
* Any supplied function should accept the directory path, a string containing the object type, and additional `Options`. | ||
* It should then return a pair indicating whether a height function for this object type was identified, and if so, the height itself. | ||
* | ||
* If no overriding function is found for the object type (or if `height_override` was not set at all), | ||
* `height()` will instead search `height_registry` for an appropriate function. | ||
*/ | ||
inline std::function<std::pair<bool, size_t>(const std::filesystem::path&, const std::string&, const Options&)> height_override; | ||
|
||
/** | ||
* Get the height of an object in a subdirectory, based on the supplied object type. | ||
* This is used to check the shape of objects stored in vertical containers, e.g., columns of a `data_frame`. | ||
* For vectors or other 1-dimensional objects, the height is usually just the length; | ||
* for higher dimensional objects, the height is usually the extent of the first dimension. | ||
* | ||
* @param path Path to a directory representing an object. | ||
* @param type Type of the object, typically determined from its `OBJECT` file. | ||
* @param options Validation options, mostly for input performance. | ||
* | ||
* @return The object's height. | ||
*/ | ||
inline size_t height(const std::filesystem::path& path, const std::string& type, const Options& options) { | ||
if (!std::filesystem::exists(path) || std::filesystem::status(path).type() != std::filesystem::file_type::directory) { | ||
throw std::runtime_error("expected '" + path.string() + "' to be a directory"); | ||
} | ||
|
||
if (height_override) { | ||
auto found = height_override(path, type, options); | ||
if (found.first) { | ||
return found.second; | ||
} | ||
} | ||
|
||
auto vrIt = height_registry.find(type); | ||
if (vrIt == height_registry.end()) { | ||
throw std::runtime_error("no registered height function for object type '" + type + "' at '" + path.string() + "'"); | ||
} | ||
|
||
return (vrIt->second)(path, options); | ||
} | ||
|
||
/** | ||
* Get the height of an object in a subdirectory, using its `OBJECT` file to automatically determine the type. | ||
* | ||
* @param path Path to a directory containing an object. | ||
* @param options Validation options, mostly for input performance. | ||
* @return The object's height. | ||
*/ | ||
inline size_t height(const std::filesystem::path& path, const Options& options) { | ||
return height(path, read_object_type(path), options); | ||
} | ||
|
||
/** | ||
* Overload of `height()` with default options. | ||
* | ||
* @param path Path to a directory containing an object. | ||
* @return The object's height. | ||
*/ | ||
inline size_t height(const std::filesystem::path& path) { | ||
return height(path, Options()); | ||
} | ||
|
||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
#ifndef TAKANE_VALIDATE_HPP | ||
#define TAKANE_VALIDATE_HPP | ||
|
||
#include <functional> | ||
#include <string> | ||
#include <stdexcept> | ||
#include <filesystem> | ||
|
||
#include "utils_public.hpp" | ||
#include "atomic_vector.hpp" | ||
#include "string_factor.hpp" | ||
#include "simple_list.hpp" | ||
#include "data_frame.hpp" | ||
#include "data_frame_factor.hpp" | ||
|
||
/** | ||
* @file _validate.hpp | ||
* @brief Validation dispatch function. | ||
*/ | ||
|
||
namespace takane { | ||
|
||
/** | ||
* @cond | ||
*/ | ||
namespace internal_validate { | ||
|
||
inline auto default_registry() { | ||
std::unordered_map<std::string, std::function<void(const std::filesystem::path&, const Options&)> > registry; | ||
registry["atomic_vector"] = [](const std::filesystem::path& p, const Options& o) { atomic_vector::validate(p, o); }; | ||
registry["string_factor"] = [](const std::filesystem::path& p, const Options& o) { string_factor::validate(p, o); }; | ||
registry["simple_list"] = [](const std::filesystem::path& p, const Options& o) { simple_list::validate(p, o); }; | ||
registry["data_frame"] = [](const std::filesystem::path& p, const Options& o) { data_frame::validate(p, o); }; | ||
registry["data_frame_factor"] = [](const std::filesystem::path& p, const Options& o) { data_frame_factor::validate(p, o); }; | ||
return registry; | ||
} | ||
|
||
} | ||
/** | ||
* @endcond | ||
*/ | ||
|
||
/** | ||
* Registry of functions to be used by `validate()`. | ||
*/ | ||
inline std::unordered_map<std::string, std::function<void(const std::filesystem::path&, const Options& )> > validate_registry = internal_validate::default_registry(); | ||
|
||
/** | ||
* Override for application-defined validation functions, to be used by `validate()`. | ||
* | ||
* Any supplied function should accept the directory path, a string containing the object type, and additional `Options`. | ||
* It should then return a boolean indicating whether a validation function for this object type was identified. | ||
* | ||
* If no overriding validator is found for the object type (or if `validate_override` was not set at all), | ||
* `validate()` will instead search `validate_registry` for an appropriate function. | ||
*/ | ||
inline std::function<bool(const std::filesystem::path&, const std::string&, const Options&)> validate_override; | ||
|
||
/** | ||
* Validate an object in a subdirectory, based on the supplied object type. | ||
* | ||
* @param path Path to a directory representing an object. | ||
* @param type Type of the object, typically determined from its `OBJECT` file. | ||
* @param options Validation options, mostly for input performance. | ||
*/ | ||
inline void validate(const std::filesystem::path& path, const std::string& type, const Options& options) { | ||
if (!std::filesystem::exists(path) || std::filesystem::status(path).type() != std::filesystem::file_type::directory) { | ||
throw std::runtime_error("expected '" + path.string() + "' to be a directory"); | ||
} | ||
|
||
if (validate_override) { | ||
if (validate_override(path, type, options)) { | ||
return; | ||
} | ||
} | ||
|
||
auto vrIt = validate_registry.find(type); | ||
if (vrIt == validate_registry.end()) { | ||
throw std::runtime_error("no registered validation function for object type '" + type + "' at '" + path.string() + "'"); | ||
} | ||
|
||
(vrIt->second)(path, options); | ||
} | ||
|
||
/** | ||
* Validate an object in a subdirectory, using its `OBJECT` file to automatically determine the type. | ||
* | ||
* @param path Path to a directory containing an object. | ||
* @param options Validation options, mostly for input performance. | ||
*/ | ||
inline void validate(const std::filesystem::path& path, const Options& options) { | ||
validate(path, read_object_type(path), options); | ||
} | ||
|
||
/** | ||
* Overload of `validate()` with default options. | ||
* | ||
* @param path Path to a directory containing an object. | ||
*/ | ||
inline void validate(const std::filesystem::path& path) { | ||
validate(path, Options()); | ||
} | ||
|
||
} | ||
|
||
#endif |
Oops, something went wrong.