LLFIO v2.00
Loading...
Searching...
No Matches
llfio_v2_xxx::algorithm::cached_parent_handle_adapter< T > Class Template Reference

Adapts any construct()-able implementation to cache its parent directory handle in a process wide cache. More...

#include "cached_parent.hpp"

Inheritance diagram for llfio_v2_xxx::algorithm::cached_parent_handle_adapter< T >:

Public Types

using adapted_handle_type = T
 The handle type being adapted.
 
using path_type = typename T::path_type
 
using path_view_type = typename T::path_view_type
 

Public Member Functions

 cached_parent_handle_adapter (const cached_parent_handle_adapter &)=default
 
 cached_parent_handle_adapter (cached_parent_handle_adapter &&)=default
 
cached_parent_handle_adapteroperator= (const cached_parent_handle_adapter &)=default
 
cached_parent_handle_adapteroperator= (cached_parent_handle_adapter &&o) noexcept
 
 cached_parent_handle_adapter (adapted_handle_type &&o, const path_handle &base, path_view path)
 
virtual result< path_type > current_path () const noexcept override
 
virtual result< void > close () noexcept override
 
virtual native_handle_type release () noexcept override
 
virtual result< path_handleparent_path_handle (deadline=std::chrono::seconds(30)) const noexcept override
 
virtual result< void > relink (const path_handle &base, path_view_type newpath, bool atomic_replace=true, deadline d=std::chrono::seconds(30)) noexcept override
 
virtual result< void > unlink (deadline d=std::chrono::seconds(30)) noexcept override
 

Protected Attributes

detail::cached_path_handle_ptr _sph
 
filesystem::path _leafname
 

Detailed Description

template<class T>
class llfio_v2_xxx::algorithm::cached_parent_handle_adapter< T >

Adapts any construct()-able implementation to cache its parent directory handle in a process wide cache.

For some use cases where one is calling parent_path_handle() or code which calls that function very frequently e.g. calling relink() or unlink() a lot on many files with the same parent directory, having to constantly fetch the current path, open the parent directory and verify inodes becomes unhelpfully inefficient. This adapter keeps a process-wide hash table of directory handles shared between all instances of this adapter, thus making calling parent_path_handle() almost zero cost.

This adapter is of especial use on platforms which do not reliably implement per-fd path tracking for regular files (Apple MacOS, FreeBSD) as current_path() is reimplemented to use the current path of the shared parent directory instead. One loses race freedom within the contained directory, but that is the case on POSIX anyway.

This adapter is also of use on platforms which do not implement path tracking for open handles at all (e.g. Linux without /proc mounted) as the process-wide cache of directory handles retains the path of the directory handle at the time of creation. Third party changes to the part of the filesystem you are working upon will result in the inability to do race free unlinking etc, but if no third party changes are encountered it ought to work well.

Todo:
I have been lazy and used public inheritance from that base i/o handle. I should use protected inheritance to prevent slicing, and expose all the public functions by hand.

Constructor & Destructor Documentation

◆ cached_parent_handle_adapter()

template<class T >
llfio_v2_xxx::algorithm::cached_parent_handle_adapter< T >::cached_parent_handle_adapter ( adapted_handle_type &&  o,
const path_handle base,
path_view  path 
)
inline
109 : adapted_handle_type(std::move(o))
110 {
111 auto r = detail::get_cached_path_handle(base, path);
112 _sph = std::move(r.first);
113 _leafname = std::move(r.second);
114 }
T adapted_handle_type
The handle type being adapted.
Definition cached_parent.hpp:85
result< path_handle > path(const path_handle &base, path_handle::path_view_type path) noexcept
Definition path_handle.hpp:171

◆ ~cached_parent_handle_adapter()

template<class T >
virtual llfio_v2_xxx::algorithm::cached_parent_handle_adapter< T >::~cached_parent_handle_adapter ( )
inlineoverridevirtual
116 {
117 if(this->_v)
118 {
119 (void) cached_parent_handle_adapter::close();
120 }
121 }

Member Function Documentation

◆ close()

template<class T >
virtual result< void > llfio_v2_xxx::algorithm::cached_parent_handle_adapter< T >::close ( )
inlineoverridevirtualnoexcept
128 {
129 LLFIO_LOG_FUNCTION_CALL(this);
130 OUTCOME_TRYV(adapted_handle_type::close());
131 _sph.reset();
132 _leafname.clear();
133 return success();
134 }

◆ current_path()

template<class T >
virtual result< path_type > llfio_v2_xxx::algorithm::cached_parent_handle_adapter< T >::current_path ( ) const
inlineoverridevirtualnoexcept
123 {
124 LLFIO_LOG_FUNCTION_CALL(this);
125 return (_sph != nullptr) ? _sph->current_path(_leafname) : path_type();
126 }

◆ operator=()

99 {
100 if(this == &o)
101 {
102 return *this;
103 }
104 this->~cached_parent_handle_adapter();
105 new(this) cached_parent_handle_adapter(std::move(o));
106 return *this;
107 }

◆ parent_path_handle()

template<class T >
virtual result< path_handle > llfio_v2_xxx::algorithm::cached_parent_handle_adapter< T >::parent_path_handle ( deadline  = std::chrono::seconds(30)) const
inlineoverridevirtualnoexcept
143 {
144 LLFIO_LOG_FUNCTION_CALL(this);
145 OUTCOME_TRY(auto &&ret, _sph->h.clone_to_path_handle());
146 return {std::move(ret)};
147 }

◆ release()

template<class T >
virtual native_handle_type llfio_v2_xxx::algorithm::cached_parent_handle_adapter< T >::release ( )
inlineoverridevirtualnoexcept
136 {
137 LLFIO_LOG_FUNCTION_CALL(this);
138 _sph.reset();
139 _leafname.clear();
140 return adapted_handle_type::release();
141 }

◆ relink()

template<class T >
virtual result< void > llfio_v2_xxx::algorithm::cached_parent_handle_adapter< T >::relink ( const path_handle base,
path_view_type  newpath,
bool  atomic_replace = true,
deadline  d = std::chrono::seconds(30) 
)
inlineoverridevirtualnoexcept
150 {
151 LLFIO_LOG_FUNCTION_CALL(this);
152 OUTCOME_TRYV(adapted_handle_type::relink(base, newpath, atomic_replace, d));
153 _sph.reset();
154 _leafname.clear();
155 LLFIO_EXCEPTION_TRY
156 {
157 auto r = detail::get_cached_path_handle(base, newpath);
158 _sph = std::move(r.first);
159 _leafname = std::move(r.second);
160 return success();
161 }
162 LLFIO_EXCEPTION_CATCH_ALL
163 {
164 return error_from_exception();
165 }
166 abort();
167 }

◆ unlink()

template<class T >
virtual result< void > llfio_v2_xxx::algorithm::cached_parent_handle_adapter< T >::unlink ( deadline  d = std::chrono::seconds(30))
inlineoverridevirtualnoexcept
170 {
171 LLFIO_LOG_FUNCTION_CALL(this);
172 OUTCOME_TRYV(adapted_handle_type::unlink(d));
173 _sph.reset();
174 _leafname.clear();
175 return success();
176 }

The documentation for this class was generated from the following file: