8 #include <shared_mutex> 11 #include <string_view> 15 #include <unordered_map> 36 template <
typename T >
39 template <
typename T >
45 using IdMap_t = std::unordered_map< ThreadId_t, std::size_t > ;
48 explicit Handle( std::shared_ptr< const details::Entry > entry )
49 : _entry{std::move( entry )},
50 _mapping( std::make_unique< IdMap_t >() ) {}
76 const T& merged()
const ;
84 std::shared_ptr< const details::Entry > _entry{
nullptr} ;
86 std::unique_ptr< IdMap_t > _mapping{} ;
88 std::atomic< std::size_t > _count{0} ;
90 std::shared_mutex _mappingAccess{};
97 template <
typename,
unsigned long long >
107 std::size_t operator()(
const Identifier &
id )
const ;
111 : _path{std::move(path)} {}
114 return _path ==
id._path ;
126 std::shared_ptr< details::Entry >
127 addEntry(
const std::shared_ptr< EntryBase > &entry,
EntryKey key ) ;
135 const std::shared_ptr<details::Entry>
138 return _entries[key.
idx] ;
139 }
catch (
const std::out_of_range& ) {
152 template <
class T,
typename... Args_t >
153 std::shared_ptr< details::Entry > bookSingle(
154 std::filesystem::path path,
166 void ( *MERGE )(
const std::shared_ptr< T > &,
167 const std::shared_ptr< T > & ),
169 std::shared_ptr< details::Entry > bookMultiCopy(
171 std::filesystem::path path,
180 template <
class T,
typename... Args_t >
181 std::shared_ptr<details::Entry> bookMultiShared(
183 std::filesystem::path path,
191 static std::filesystem::path normalizeDirPath(
const std::filesystem::path& path);
199 return *_entries[idx] ;
200 }
catch (
const std::out_of_range & ) {
217 return *_entries[idx] ;
218 }
catch (
const std::out_of_range & ) {
233 : _constructThread(
std::this_thread::get_id() ),
234 _allowMoving{allowMoving} { }
248 book(
const std::filesystem::path& path,
249 const std::string_view& name,
276 void remove(
const EntryKey &key ) ;
283 void remove(
const Selection &selection ) ;
307 template<
typename Itr>
308 void storeList(
StoreWriter& writer, Itr begin, Itr end)
const ;
319 std::vector< std::shared_ptr< details::Entry > > _entries{} ;
321 std::unordered_map< Identifier, std::size_t, Identifier::Hash >
325 const bool _allowMoving{
false} ;
330 template <
class T,
typename... Args_t >
331 std::shared_ptr< details::Entry >
334 EntryKey key{std::type_index(
typeid( T ) )} ;
335 key.
path = std::move( path ) ;
339 auto entry = std::make_shared< EntrySingle< T > >(
Context(
342 return addEntry( entry, key ) ;
348 void ( *MERGE )(
const std::shared_ptr< T > &,
349 const std::shared_ptr< T > & ),
351 std::shared_ptr< details::Entry >
353 std::filesystem::path path,
355 EntryKey key{std::type_index(
typeid( T ) )} ;
356 key.
path = std::move( path ) ;
360 auto entry = std::make_shared< EntryMultiCopy< T > >(
362 n, ctor_p... ) , n) ) ;
364 return addEntry( entry, key ) ;
368 template <
class T,
typename... Args_t >
369 std::shared_ptr< details::Entry >
372 std::filesystem::path path,
374 EntryKey key{std::type_index(
typeid( T ) )} ;
375 key.
path = std::move(path) ;
376 key.mInstances = std::max<std::size_t>(1, n) ;
379 auto entry = std::make_shared< EntryMultiShared< T > >(
Context(
382 return addEntry( entry, key ) ;
390 const std::string_view &name,
392 std::filesystem::path nPath = normalizeDirPath(path);
394 if ( !_allowMoving && std::this_thread::get_id() != _constructThread ) {
396 "from the construction Thread" ) ;
399 auto entry = _idToEntry.find(
Identifier(nPath)) ;
400 if ( entry == _idToEntry.end() ) {
402 data.template book< std::filesystem::path >(
407 + static_cast< std::string >( nPath ) +
"' name:'" 408 + static_cast< std::string >( name )
409 +
"' is already booked!" ) ;
414 template <
typename T >
418 std::shared_lock lock(_mappingAccess);
419 auto itr = _mapping->find(
id ) ;
420 if ( itr != _mapping->end() ) {
425 std::unique_lock lock(_mappingAccess);
426 return _mapping->insert(std::make_pair(
id, _count++ ) ).first->second;
431 template<
typename T >
433 return _entry->handle<T>(0).merged();
438 template <
typename T >
440 : _entry(
nullptr ), _mapping(
nullptr ), _count( hnd._count.load() ) {
441 _entry = hnd._entry ;
442 _mapping = std::move( hnd._mapping ) ;
449 template <
typename T >
452 _entry = hnd._entry ;
453 _mapping = std::move( hnd._mapping ) ;
454 _count = hnd._count.load() ;
462 template <
typename T >
464 std::size_t
id = unmap( std::this_thread::get_id() ) ;
465 return _entry->handle< T >(
id < _entry->key().mInstances ? id : -1) ;
470 template <
typename Itr >
472 static_assert(std::is_same_v<
474 std::remove_cv_t<std::remove_reference_t<decltype(*begin)>>>);
475 decltype(_entries) storeList{};
476 for( Itr itr = begin; itr != end; ++itr) {
477 storeList.push_back(getPtr(*itr));
std::unordered_map< ThreadId_t, std::size_t > IdMap_t
Data selection to identify and manage an Entry.
MemLayout for mutable object instances.
Managed Access and creation of Objects.
Container for data to construct and setup booked object.
bool operator==(const Identifier &id) const
#define MARLIN_BOOK_THROW(message)
std::filesystem::path path
virtual Entry path
std::shared_ptr< details::Entry > bookMultiShared(std::size_t n, std::filesystem::path path, Args_t... ctor_p)
creates an Entry for parallel access.
BookStore(bool allowMoving=false)
const EntryKey & key() const
std::shared_ptr< details::Entry > bookSingle(std::filesystem::path path, Args_t... ctor_p)
creates an Entry for a default Object.
Functor for hashing Identifier.
Handle< Entry< T > > entry(const EntryKey &key) const
get access to entry from key.
static Selection find(T begin, T end, const Condition &cond)
Construct Selection from range of Entries.
constexpr Flag_t MultiShared(1U<< 1U)
create one instance witch concurrent access.
Wrapper for weak pointer to Entry.
std::thread::id ThreadId_t
const std::shared_ptr< details::Entry > & getPtr(const EntryKey &key) const
Handle< Entry< typename T::Object_t > > book(const std::filesystem::path &path, const std::string_view &name, const T &data)
book new object.
Identifier(std::filesystem::path path)
std::thread::id _constructThread
Handle(std::shared_ptr< const details::Entry > entry)
constructor
void storeList(StoreWriter &writer, Itr begin, Itr end) const
stores only Objects which key is listed.
helper to create a Condition.
constexpr Flag_t MultiCopy(1U<< 2U)
create multiple instances of booked object (if possible) to avoid sync points
Contains references to entries.
holds references for identify an entry.
std::shared_ptr< details::Entry > bookMultiCopy(std::size_t n, std::filesystem::path path, Args_t... ctor_p)
creates an Entry for parallel access.
std::size_t idx
unique number for Entry
MemLayout for Single object instance.
Data selection for the Entry to work properly.
class to store and manage objects in BookStore.
std::filesystem::path _path
constexpr Flag_t Single(1U<< 0U)
vanilla object.
wrapper class for an Entry filter function.