Skip to content

Commit

Permalink
(WIP) [skip ci] decoupling segment storage
Browse files Browse the repository at this point in the history
  • Loading branch information
KIwabuchi committed Nov 30, 2023
1 parent c57f0a6 commit c63ec18
Show file tree
Hide file tree
Showing 12 changed files with 560 additions and 445 deletions.
17 changes: 11 additions & 6 deletions include/metall/basic_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,23 @@
#include <metall/container/scoped_allocator.hpp>
#include <metall/kernel/manager_kernel.hpp>
#include <metall/detail/named_proxy.hpp>
#include "metall/kernel/mmap_data_storage.hpp"

namespace metall {

#if !defined(DOXYGEN_SKIP)
// Forward declaration
template <typename chunk_no_type, std::size_t k_chunk_size>
template <typename data_storage_impl, typename chunk_no_type,
std::size_t k_chunk_size>
class basic_manager;
#endif // DOXYGEN_SKIP

/// \brief A generalized Metall manager class
/// \tparam chunk_no_type
/// \tparam k_chunk_size
template <typename chunk_no_type = uint32_t,
/// \tparam data_storage_impl Data storage implementation.
/// \tparam chunk_no_type Type of chunk number.
/// \tparam k_chunk_size Size of single chunk in byte.
template <typename data_storage_impl = kernel::mmap_data_storage,
typename chunk_no_type = uint32_t,
std::size_t k_chunk_size = (1ULL << 21ULL)>
class basic_manager {
public:
Expand All @@ -36,7 +40,7 @@ class basic_manager {

/// \brief Manager kernel type
using manager_kernel_type =
kernel::manager_kernel<chunk_no_type, k_chunk_size>;
kernel::manager_kernel<data_storage_impl, chunk_no_type, k_chunk_size>;

/// \brief Void pointer type
using void_pointer = typename manager_kernel_type::void_pointer;
Expand Down Expand Up @@ -107,7 +111,8 @@ class basic_manager {
// -------------------- //
using char_ptr_holder_type =
typename manager_kernel_type::char_ptr_holder_type;
using self_type = basic_manager<chunk_no_type, k_chunk_size>;
using self_type =
basic_manager<data_storage_impl, chunk_no_type, k_chunk_size>;

public:
// -------------------- //
Expand Down
145 changes: 145 additions & 0 deletions include/metall/kernel/data_storage.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// Copyright 2023 Lawrence Livermore National Security, LLC and other Metall
// Project Developers. See the top-level COPYRIGHT file for details.
//
// SPDX-License-Identifier: (Apache-2.0 OR MIT)

#ifndef METALL_INCLUDE_METALL_KERNEL_DATA_STORAGE_HPP
#define METALL_INCLUDE_METALL_KERNEL_DATA_STORAGE_HPP

namespace metall::kernel {

/// \brief A class for manage all datastore data (files) on file system.
template <typename data_storage_impl>
class data_storage {
private:
using imp_type = data_storage_impl;

public:
// TODO: Change design
using size_type = typename imp_type::size_type;
using different_type = typename imp_type::different_type;

using path_type = typename imp_type::path_type;

data_storage() = default;

~data_storage() = default;

data_storage(const data_storage &) = delete;
data_storage &operator=(const data_storage &) = delete;

data_storage(data_storage &&other) noexcept = default;
data_storage &operator=(data_storage &&other) noexcept = default;

/// \brief Returns the directory path where segment manager can store files.
inline static path_type get_path(const path_type &base_path) {
return imp_type::get_path(base_path);
}

/// \brief Gets the size of an existing segment.
/// This is a static version of size() method.
/// \param base_path A path to a segment.
inline static size_type get_size(const path_type &base_path) {
return imp_type::get_size(base_path);
}

/// \brief Checks if a segment is openable.
/// \param base_path A path to a segment.
/// \return Return true if success; otherwise, false.
inline static bool openable(const path_type &base_path) {
return imp_type::openable(base_path);
}

/// \brief Copies segment to another location.
/// \param source_path A path to a source segment.
/// \param destination_path A destination path.
/// \param clone If true, uses clone (reflink) for copying files.
/// \param max_num_threads The maximum number of threads to use.
/// If <= 0 is given, the value is automatically determined.
/// \return Return true if success; otherwise, false.
inline static bool copy(const path_type &source_path,
const path_type &destination_path, const bool clone,
const int max_num_threads) {
return imp_type::copy(source_path, destination_path, clone,
max_num_threads);
}

/// \brief Creates a new segment.
/// Calling this function fails if this class already manages an opened
/// segment. \base_path A base directory path to create a segment. \param
/// vm_region_size The size of a reserved VM region. \param vm_region The
/// address of a reserved VM region. \block_size The block size. \return
/// Return true if success; otherwise, false.
inline bool create(const path_type &base_path, const size_type vm_region_size,
void *const vm_region, const size_type block_size) {
return m_impl.create(base_path, vm_region_size, vm_region, block_size);
}

/// \brief Opens an existing segment.
/// Calling this function fails if this class already manages an opened
/// segment. \base_path A base directory path to create a segment. \param
/// vm_region_size The size of a VM region. \param vm_region The address of a
/// VM region. \param read_only If true, this segment is read only. \return
/// Return true if success; otherwise, false.
inline bool open(const path_type &base_path, const size_type vm_region_size,
void *const vm_region, const bool read_only) {
return m_impl.open(base_path, vm_region_size, vm_region, read_only);
}

/// \brief Extends the currently opened segment if necessary.
/// \param request_size A segment size to extend to.
/// \return Returns true if the segment is extended to or already larger than
/// the requested size. Returns false on failure.
inline bool extend(const size_type request_size) {
return m_impl.extend(request_size);
}

/// \brief Destroys the segment --- the data will be lost.
/// To save data to files, sync() must be called beforehand.
inline bool destroy() { return m_impl.destroy(); }

/// \brief Syncs the segment with backing files.
/// \param sync If false is specified, this function returns before finishing
/// the sync operation.
inline bool sync(const bool sync) { return m_impl.sync(sync); }

/// \brief Tries to free the specified region in DRAM and file(s).
/// The actual behavior depends on the running system.
/// \param offset An offset to the region from the beginning of the segment.
/// \param nbytes The size of the region.
inline bool free_region(const different_type offset, const size_type nbytes) {
return m_impl.free_region(offset, nbytes);
}

/// \brief Returns the address of the segment.
/// \return The address of the segment.
inline void *get_segment() const { return m_impl.get_segment(); }

/// \brief Returns the current size.
/// \return The current segment size.
inline size_type size() const { return m_impl.size(); }

/// \brief Returns the page size.
/// \return The page size of the system.
inline size_type page_size() const { return m_impl.page_size(); }

/// \brief Checks if the segment is read only.
/// \return Returns true if the segment is read only; otherwise, returns
/// false.
inline bool read_only() const { return m_impl.read_only(); }

/// \brief Checks if there is a segment already open.
/// \return Returns true if there is a segment already open.
inline bool is_open() const { return m_impl.is_open(); }

/// \brief Checks the sanity.
/// \return Returns true if there is no issue; otherwise, returns false.
/// If false is returned, the instance of this class cannot be used anymore.
inline bool check_sanity() const { return m_impl.check_sanity(); }

private:
imp_type m_impl;
};
} // namespace metall::kernel

#endif // METALL_INCLUDE_METALL_KERNEL_DATA_STORAGE_HPP
Loading

0 comments on commit c63ec18

Please sign in to comment.