ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
ftree.hpp
Go to the documentation of this file.
1/** ************************************************************************************************
2 * \file
3 * This header file is part of module \alib_files of the \aliblong.
4 *
5 * \emoji :copyright: 2013-2024 A-Worx GmbH, Germany.
6 * Published under \ref mainpage_license "Boost Software License".
7 **************************************************************************************************/
8#ifndef HPP_ALIB_FILES_FTREE
9#define HPP_ALIB_FILES_FTREE 1
10
11#if !defined(HPP_ALIB_FILES_FINFO)
12# include "alib/files/finfo.hpp"
13#endif
14
15#if !defined(HPP_ALIB_MONOMEM_STRINGTREE)
17#endif
18
19#if !defined (HPP_ALIB_CAMP_DIRECTORY)
21#endif
22
23#if !defined (HPP_ALIB_ENUMS_ITERABLE_BITSET)
25#endif
26
27
28namespace alib { namespace files {
29
30/** Local path string buffer helper type fixed to size 512. The flexible nature of \alib local
31 * strings allow dynamic allocation if exceeded.*/
33
34/**
35 * This namespace implements internals of namespace #alib::files.
36 */
37 namespace detail {
38
39/**
40 * Specialized \ref alib_ns_monomem_stringtree_referencedoc "TNodeMaintainer" for class
41 * \alib{files;FTree} which recycles extended information objects of type
42 * \alib{files;FInfo::EIDirectory}, \alib{files;FInfo::EISymLinkFile} and
43 * \alib{files;FInfo::EISymLinkDir} with node deletion.
44 *
45 * In respect to the node name allocation, this type behaves like
46 * default maintainer \alib{monomem;StringTreeNamesDynamic}. In debug compilations, statistics
47 * variables \alib{monomem;DbgStatsStringTreeNames} and \alib{monomem;DbgStatsStringTreeNameOverflows}
48 * are increased, just like the original does.
49 */
51{
52 /** The character type that the \b StringTree uses for child name and path strings. */
54
55 /** The string type of a node's name. Here, a buffered dynamic string */
57
58 /**
59 * Copies the node's name to the local string.
60 *
61 * @param tree The instance of struct \alib{monomem;detail::StringTreeBase} that invokes
62 * this method. Any member may be accessed, including
63 * \alib{monomem::detail::StringTreeBase;nodeTable} which contains the
64 * \alib{monomem;MonoAllocator} that the tree uses for the allocation of nodes.
65 * @param node The node that was just created. Allows access to the key and
66 * custom value data. While the parent and sibling nodes are likewise accessible,
67 * it is strictly forbidden to modify those.
68 * @tparam TTree The type of the templated instantiation of struct
69 * \alib{monomem;detail::StringTreeBase} that this method is invoked by.
70 * (Deduced by the compiler.)
71 */
72 template<typename TTree>
73 static
74 void InitializeNode( TTree& tree, typename TTree::Node& node )
75 {
76 (void) tree;
77
78 String key= node.name.key; // get current pointer
79 new (&node.name.storage) NameStringType(); // placement new to re-establish local string
80 node.name.storage.DbgDisableBufferReplacementWarning();
81 ALIB_DBG( const auto* internalBuffer= node.name.storage.Buffer(); )
82 node.name.storage.Append(key); // copy key to buf
84 if( internalBuffer != node.name.storage.Buffer() )
86 }
87
88 /**
89 * This implementation frees any dynamically allocated memory of the node's name and in
90 * addition recycles any extended information object attached to the \alib{files;FInfo}
91 * object.
92 * @param tree The instance of struct \alib{monomem;detail::StringTreeBase} that invokes
93 * this method. Any member may be accessed, including
94 * \alib{monomem::detail::StringTreeBase;nodeTable} which contains the
95 * \alib{monomem;MonoAllocator} that the tree uses for the allocation of nodes.
96 * @param node The node that is to be removed. Allows access to the key and
97 * custom value data. While the parent and sibling nodes are likewise accessible,
98 * it is strictly forbidden to modify those.
99 * @tparam TTree The type of the templated instantiation of struct
100 * \alib{monomem;detail::StringTreeBase} that this method is invoked by.
101 * (Deduced by the compiler.)
102 */
103 template<typename TTree>
104 static
105 inline
106 void FreeNode( TTree& tree, typename TTree::Node& node );
107}; // struct FTreeNodeMaintainer
108} // namespace alib::files[::detail]
109
110/** ************************************************************************************************
111 * This class is a \alib{monomem;StringTree} containing \alib{files;FInfo} elements.
112 * Usually the tree is filled using function \alib{files;ScanFiles}.
113 *
114 * ### StringTree Interface ###
115 * Public base class \alib{monomem::StringTree} provides all interfaces necessary to create and
116 * delete entries, iterate and recursively walk the file tree. Please consult its documentation
117 * for further information.
118 *
119 * \note As \alib{files;ScanFiles;documented with function ScanFiles}, entities of this
120 * module \alib_files_nl exclusively store entries along their <em>"Real Path"</em>, hence
121 * always resolving symbolic links. A user of this library may deviate from this
122 * "data contract".
123 *
124 * ### Monotonic Behaviour ###
125 * The class fulfills \ref alib_monomem_intro_strictweak "weak monotonic allocation requirements",
126 * which is achieved by recycling not only the nodes (what base type \b StringTree does by default)
127 * but also any extended node information. This is implemented with maintainer type
128 * \alib{files;detail::FTreeNodeMaintainer} on the one hand, and on the other hand
129 * with the implementation of method #AllocateExtendedInfo, which has to be exclusively used
130 * to attach information structs on \b FInfo elements.
131 *
132 * In respect to the file names, hence the key types of base class \b StringTree, class
133 * \alib{files;detail::FTreeNodeMaintainer} uses an internal buffer of size <c>100</c>.
134 * This leads to quite some monotonic allocation overhead when file names are short, but
135 * limits the percentage of exceeding file names quite well. Exceeding filenames have not been
136 * further optimized, but are simply allocated on the heap (and of-course free with the deletion
137 * of an entry).
138 *
139 * In summary, this allows an indefinite sequence of file-scan and result filtering (deletions)
140 * with using more memory than the highest resulting fill state in such sequence requires.
141 *
142 **************************************************************************************************/
143class FTree : public StringTree<FInfo, detail::FTreeNodeMaintainer>
144{
145 public:
146 /** Type alias of this classes' base class. */
148
149 protected:
150 /** The node maintainer is friend, as it needs access to the recyclers of this class. */
152
153 /** Internal struct which embeds extended \b FInfo data at the front, together with a recursive
154 * link used for recycling instances of the extended type. */
156 {
157 FInfo::EIDirectory data; ///< The usable data receivable with the \b FInfo instance.
158 LinkedEIDir* next = nullptr; ///< A recursive link to implement a recyling list.
159 };
160
161 /** Internal struct which embeds extended \b FInfo data at the front, together with a recursive
162 * link used for recycling instances of the extended type. */
164 {
165 FInfo::EISymLinkFile data; ///< The usable data receivable with the \b FInfo instance.
166 LinkedEISL* next = nullptr; ///< A recursive link to implement a recyling list.
167 };
168
169 /** Internal struct which embeds extended \b FInfo data at the front, together with a recursive
170 * link used for recycling instances of the extended type. */
172 {
173 FInfo::EISymLinkDir data; ///< The usable data receivable with the \b FInfo instance.
174 LinkedEISLDir* next = nullptr; ///< A recursive link to implement a recyling list.
175 };
176
177
178 LinkedEIDir * recyclerEIDir = nullptr; ///< Linked list hook for recycling information elements of disposed nodes.
179 LinkedEISL * recyclerEISL = nullptr; ///< Linked list hook for recycling information elements of disposed nodes.
180 LinkedEISLDir* recyclerEISlDir= nullptr; ///< Linked list hook for recycling information elements of disposed nodes.
181
182 public:
183 /**
184 * Constructor.
185 * @param allocator The allocator to use. Passed to the
186 * \alib{monomem::StringTree;StringTree;constructor} of base class
187 * \alib{monomem;StringTree}.
188 */
190 FTree(monomem::MonoAllocator* allocator);
191
192 /** Destructor. */
194
195 /**
196 * Allocates (or recycles) an appropriate information object fitting to the type of this entry.
197 * This method must only be applied to entries of types
198 * - \alib{files::FInfo::Types;DIRECTORY},
199 * - \alib{files::FInfo::Types;SYMBOLIC_LINK} or
200 * - \alib{files::FInfo::Types;SYMBOLIC_LINK_DIR}.
201 * In debug compilations, this is asserted. It is likewise asserted that the sybolic link
202 * information strings are empty in case the type is \alib{files::FInfo::Types;DIRECTORY}.
203 *
204 * \param node The node add extended information to.
205 * \param symLinkDest In case of symbolic link types, the symbolic link target.
206 * \param symLinkRealPath In case of symbolic link types, the symbolic link target as real path.
207 */
209 void AllocateExtendedInfo(Cursor& node, String& symLinkDest, String& symLinkRealPath);
210
211 /**
212 * Returns the number of currently available recycled objects of derived type of
213 * \alib{files::FInfo;ExtendedEntryInfo}.
214 * This method is rather for testing or debugging.
215 * @param type Must be one of the types
216 * \alib{files::FInfo;Types::DIRECTORY},
217 * \alib{files::FInfo;Types::SYMBOLIC_LINK} or
218 * \alib{files::FInfo;Types::SYMBOLIC_LINK_DIR}.
219 * @return The number of
220 */
223
224 /**
225 * Recalculates the sums of the given node. This is \b not done recursively. The fix is needed
226 * when scanning an existent directory with potentially more greedy scan parameters.
227 * @param directoryNode The node to re-calculate the sums for.
228 */
230 static
231 void FixSums( Cursor directoryNode);
232
233}; //class FTree
234
235// --------------------- Implementation of the node mainer's FreeNode() method ---------------------
236#if !defined(ALIB_DOX)
237template<typename TTree>
238inline
239void detail::FTreeNodeMaintainer::FreeNode( TTree& tree, typename TTree::Node& node )
240{
241 // delete local string
242 node.name.storage.~TLocalString();
243
244 // recycle extended info structs
245 FTree& fTree= static_cast<FTree&>(tree);
246 FInfo& value= node.data;
247 auto extendedInfo= value.GetExtendedInfo();
248 if( extendedInfo == nullptr )
249 return;
250
251 if( value.Type() == FInfo::Types::DIRECTORY )
252 {
253 FTree::LinkedEIDir* recycle= reinterpret_cast<FTree::LinkedEIDir*>(extendedInfo );
254 recycle->next= fTree.recyclerEIDir;
255 fTree.recyclerEIDir= recycle;
256 }
257 else if( value.Type() == FInfo::Types::SYMBOLIC_LINK )
258 {
259 FTree::LinkedEISL* recycle= reinterpret_cast<FTree::LinkedEISL*>(extendedInfo );
260 recycle->next= fTree.recyclerEISL;
261 fTree.recyclerEISL= recycle;
262 }
263 else
264 {
266 "CAMP/FILES", "Given node is not a directory or symbolic link but still has extendedInfo set.")
267
268
269 FTree::LinkedEISLDir* recycle= reinterpret_cast<FTree::LinkedEISLDir*>(extendedInfo);
270 recycle->next= fTree.recyclerEISlDir;
271 fTree.recyclerEISlDir= recycle;
272 }
273
274 // clear to be able to check double use in debug mode
275 ALIB_DBG( value.SetExtendedInfo(nullptr) );
276}
277#endif
278
279
280} // namespace alib[::files]
281
282
283/// Type alias in namespace \b alib.
285} // namespace [alib]
286
287//--------------------------------------- Debug Dump ---------------------------------------
288#if ALIB_DEBUG
289namespace alib::files {
290 /**
291 * Dumps the given branch of this object's tree.
292 * @param target The target string buffer.
293 * @param tree The tree to dump.
294 * @param includedTypes Optional filter for types. Defaults to 'all'.
295 * @param startNode The start node. If this is not
296 * \doxlinkproblem{classalib_1_1monomem_1_1StringTree_1_1TCursor.html;ac532c4b500b1a85ea22217f2c65a70ed;a valid node;alib::monomem::StringTree::TCursor::IsValid},
297 * the root node is chosen. Defaults to an invalid cursor.
298 * @param depth The maximum depth of recursion. Defaults to unlimited depth.
299 * @return The given \p{target} to allow concatenated operations.
300 */
303 FTree& tree ,
305 FTree::Cursor startNode = FTree::Cursor(),
306 unsigned int depth = (std::numeric_limits<unsigned int>::max)() );
307
308
309
310} // namespace [alib::files]
311#endif
312
313
314
315#endif // HPP_ALIB_FILES_FTREE
@ DIRECTORY
Directory/folder.
constexpr ExtendedEntryInfo * GetExtendedInfo() const
Definition finfo.hpp:438
constexpr Types Type() const noexcept
Definition finfo.hpp:407
ALIB_API void AllocateExtendedInfo(Cursor &node, String &symLinkDest, String &symLinkRealPath)
Definition ftree.cpp:61
static ALIB_API void FixSums(Cursor directoryNode)
Definition ftree.cpp:42
LinkedEISLDir * recyclerEISlDir
Linked list hook for recycling information elements of disposed nodes.
Definition ftree.hpp:180
LinkedEIDir * recyclerEIDir
Linked list hook for recycling information elements of disposed nodes.
Definition ftree.hpp:178
ALIB_API integer CountRecyclables(FInfo::Types type)
Definition ftree.cpp:130
LinkedEISL * recyclerEISL
Linked list hook for recycling information elements of disposed nodes.
Definition ftree.hpp:179
#define ALIB_API
Definition alib.hpp:538
#define ALIB_ASSERT_ERROR(cond,...)
Definition alib.hpp:984
#define ALIB_DBG(...)
Definition alib.hpp:457
alib::strings::TLocalString< character, 512 > PathString
Definition finfo.hpp:36
ALIB_API AString & DbgDump(AString &target, FTree &tree, EnumBitSet< FInfo::Types > includedTypes=EnumBitSet< FInfo::Types >(true), FTree::Cursor startNode=FTree::Cursor(), unsigned int depth=(std::numeric_limits< unsigned int >::max)())
ALIB_API uinteger DbgStatsStringTreeNameOverflows
ALIB_API uinteger DbgStatsStringTreeNames
Definition alib.cpp:57
characters::character character
Type alias in namespace alib.
files::FTree FTree
Type alias in namespace alib.
Definition ftree.hpp:284
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:286
FInfo::EIDirectory data
The usable data receivable with the FInfo instance.
Definition ftree.hpp:157
LinkedEIDir * next
A recursive link to implement a recyling list.
Definition ftree.hpp:158
LinkedEISLDir * next
A recursive link to implement a recyling list.
Definition ftree.hpp:174
FInfo::EISymLinkDir data
The usable data receivable with the FInfo instance.
Definition ftree.hpp:173
FInfo::EISymLinkFile data
The usable data receivable with the FInfo instance.
Definition ftree.hpp:165
LinkedEISL * next
A recursive link to implement a recyling list.
Definition ftree.hpp:166
static void InitializeNode(TTree &tree, typename TTree::Node &node)
Definition ftree.hpp:74
strings::TLocalString< character, 100 > NameStringType
Definition ftree.hpp:56
static void FreeNode(TTree &tree, typename TTree::Node &node)