PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
file_storage.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
18#pragma once
19
20#include "storage_interface.h"
21
24
25#include <filesystem>
26#include <mutex>
27#include <shared_mutex>
28#include <string>
29#include <unordered_map>
30
31namespace kcenon::pacs::storage {
32
38enum class naming_scheme {
41
44
46 flat
47};
48
52enum class duplicate_policy {
54 reject,
55
57 replace,
58
60 ignore
61};
62
82
123public:
124 // =========================================================================
125 // Construction
126 // =========================================================================
127
133 explicit file_storage(const file_storage_config& config);
134
138 ~file_storage() override = default;
139
141 file_storage(const file_storage&) = delete;
143
147
148 // =========================================================================
149 // storage_interface Implementation
150 // =========================================================================
151
163 [[nodiscard]] auto store(const core::dicom_dataset& dataset)
164 -> VoidResult override;
165
172 [[nodiscard]] auto retrieve(std::string_view sop_instance_uid)
173 -> Result<core::dicom_dataset> override;
174
181 [[nodiscard]] auto remove(std::string_view sop_instance_uid)
182 -> VoidResult override;
183
190 [[nodiscard]] auto exists(std::string_view sop_instance_uid) const
191 -> bool override;
192
203 [[nodiscard]] auto find(const core::dicom_dataset& query)
205
211 [[nodiscard]] auto get_statistics() const -> storage_statistics override;
212
220 [[nodiscard]] auto verify_integrity() -> VoidResult override;
221
222 // =========================================================================
223 // File-specific Operations
224 // =========================================================================
225
232 [[nodiscard]] auto get_file_path(std::string_view sop_instance_uid) const
233 -> std::filesystem::path;
234
243 [[nodiscard]] auto import_directory(const std::filesystem::path& source)
244 -> VoidResult;
245
251 [[nodiscard]] auto root_path() const -> const std::filesystem::path&;
252
260 [[nodiscard]] auto rebuild_index() -> VoidResult;
261
262private:
263 // =========================================================================
264 // Internal Helper Methods
265 // =========================================================================
266
274 [[nodiscard]] auto build_path(std::string_view study_uid,
275 std::string_view series_uid,
276 std::string_view sop_uid) const
277 -> std::filesystem::path;
278
286 [[nodiscard]] auto build_date_path(std::string_view study_date,
287 std::string_view study_uid,
288 std::string_view sop_uid) const
289 -> std::filesystem::path;
290
296 void update_index(const std::string& sop_uid,
297 const std::filesystem::path& path);
298
303 void remove_from_index(const std::string& sop_uid);
304
311 [[nodiscard]] static auto matches_query(const core::dicom_dataset& dataset,
312 const core::dicom_dataset& query)
313 -> bool;
314
320 [[nodiscard]] static auto sanitize_uid(std::string_view uid) -> std::string;
321
322 // =========================================================================
323 // Member Variables
324 // =========================================================================
325
328
330 std::unordered_map<std::string, std::filesystem::path> index_;
331
333 mutable std::shared_mutex mutex_;
334};
335
336} // namespace kcenon::pacs::storage
auto retrieve(std::string_view sop_instance_uid) -> Result< core::dicom_dataset > override
Retrieve a DICOM dataset by SOP Instance UID.
auto import_directory(const std::filesystem::path &source) -> VoidResult
Import DICOM files from a directory.
auto build_date_path(std::string_view study_date, std::string_view study_uid, std::string_view sop_uid) const -> std::filesystem::path
Build filesystem path using date-based hierarchy.
auto find(const core::dicom_dataset &query) -> Result< std::vector< core::dicom_dataset > > override
Find DICOM datasets matching query criteria.
std::unordered_map< std::string, std::filesystem::path > index_
Mapping from SOP Instance UID to file path.
file_storage & operator=(file_storage &&)=delete
void update_index(const std::string &sop_uid, const std::filesystem::path &path)
Update internal index with new mapping.
file_storage(const file_storage_config &config)
Construct file storage with configuration.
file_storage(const file_storage &)=delete
Non-copyable (contains mutex)
auto get_file_path(std::string_view sop_instance_uid) const -> std::filesystem::path
Get the filesystem path for a SOP Instance UID.
void remove_from_index(const std::string &sop_uid)
Remove entry from internal index.
static auto sanitize_uid(std::string_view uid) -> std::string
Sanitize UID for use in filesystem path.
file_storage & operator=(const file_storage &)=delete
auto rebuild_index() -> VoidResult
Rebuild the internal index from filesystem.
file_storage_config config_
Storage configuration.
std::shared_mutex mutex_
Mutex for thread-safe access.
auto root_path() const -> const std::filesystem::path &
Get the root storage path.
file_storage(file_storage &&)=delete
Non-movable (contains mutex)
auto get_statistics() const -> storage_statistics override
Get storage statistics.
auto exists(std::string_view sop_instance_uid) const -> bool override
Check if a DICOM instance exists.
auto remove(std::string_view sop_instance_uid) -> VoidResult override
Remove a DICOM file by SOP Instance UID.
auto store(const core::dicom_dataset &dataset) -> VoidResult override
Store a DICOM dataset to filesystem.
static auto matches_query(const core::dicom_dataset &dataset, const core::dicom_dataset &query) -> bool
Check if dataset matches query criteria.
~file_storage() override=default
Destructor.
auto verify_integrity() -> VoidResult override
Verify storage integrity.
auto build_path(std::string_view study_uid, std::string_view series_uid, std::string_view sop_uid) const -> std::filesystem::path
Build filesystem path for a dataset.
DICOM Dataset - ordered collection of Data Elements.
DICOM Part 10 file handling for reading/writing DICOM files.
naming_scheme
Naming scheme for DICOM file organization.
@ flat
{SOPUID}.dcm (flat structure)
@ date_hierarchical
YYYY/MM/DD/{StudyUID}/{SOPUID}.dcm.
@ uid_hierarchical
{StudyUID}/{SeriesUID}/{SOPUID}.dcm
duplicate_policy
Policy for handling duplicate SOP Instance UIDs.
@ ignore
Skip silently if instance exists.
@ reject
Return error if instance already exists.
@ replace
Overwrite existing instance.
Abstract storage interface for DICOM persistent storage backends.
Configuration for file_storage.
std::string file_extension
File extension for DICOM files.
bool create_directories
Create directories automatically if they don't exist.
duplicate_policy duplicate
How to handle duplicate instances.
std::filesystem::path root_path
Root directory for storage.
naming_scheme naming
File organization scheme.
std::string_view uid