Turi Create  4.0
file_handle_pool.hpp
1 /* Copyright © 2017 Apple Inc. All rights reserved.
2  *
3  * Use of this source code is governed by a BSD-3-clause license that can
4  * be found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause
5  */
6 #ifndef TURI_FILEIO_FILE_HANDLE_POOL_HPP
7 #define TURI_FILEIO_FILE_HANDLE_POOL_HPP
8 #include <map>
9 #include <string>
10 #include <atomic>
11 #include <core/parallel/mutex.hpp>
12 #include <core/storage/fileio/file_ownership_handle.hpp>
13 namespace turi {
14 namespace fileio {
15 /**
16  * \ingroup fileio
17  * A global file lifespan manager that manages life time for non temporary files
18  * that are currently in use by any SArray(including the array index file and the
19  * segment files).
20  *
21  * Permanent files used by SArray can be removed when user saves a SArray to a
22  * directory where there is already a SArray saved there. In case there is some
23  * SArray actively referencing the files in the directory, we will delay deletion
24  * of those files until nobody is referencing those files. new files will be
25  * created under the directory to save the new SArray and the directory index
26  * will correctly point to the new files.
27  *
28  * A file_handle object is created for each file that is in use by SArray. All
29  * SArrays referencing those files keep a shared pointer to the file handle object.
30  * On reading from a directory, SAray registers the files with global file_handle_pool,
31  * When SArray is out of scope, the corresponding ref to the file_handle is removed.
32  * Once all ref of a given file_handle goes away, the files may or may not be deleted
33  * depend on whether or not the files are overwritten.
34  *
35  * The pool itself keeps a weak pointer to the file_handle object so the files can
36  * be deleted when all SArrays referencing the file are gone.
37  */
39 public:
40  /**
41  * Singleton retriever
42  **/
44 
45  /**
46  * Register with file pool that a file is in use.
47  * Returns a file_ownership_handle to the caller that can do auto deletion
48  * of the file if it goes out of scope.
49  *
50  * \param file_name The name of the file to be registered
51  *
52  * Returns a shared pointer to the newly created file_ownership_handle
53  **/
54  std::shared_ptr<file_ownership_handle> register_file(const std::string& file_name);
55 
56  /**
57  * Try to mark the file for deletion, returns success if the mark is
58  * done successfuly, other wise, the global file pool doesn't know
59  * about the file, caller is responsible for deleting the files
60  * The marked files will be deleted when all users are out of scope
61  *
62  * \param file_name The name of the file to be marked for deletion
63  **/
64  bool mark_file_for_delete(std::string file_name);
65 
66  /**
67  * Unmarks a previously marked file for deletion. Returns true if the file
68  * was previously marked for deletion. False otherwise.
69  */
70  bool unmark_file_for_delete(std::string file_name);
71 private:
72  file_handle_pool() {};
73  file_handle_pool(file_handle_pool const&) = delete;
74  file_handle_pool& operator=(file_handle_pool const&) = delete;
75 
76  std::shared_ptr<file_ownership_handle> get_file_handle(const std::string& file_name);
77 
78 private:
79  turi::mutex m_mutex;
80 
81  // We need to periodically clear out the map below in order to avoid
82  // a memory leak. Here we clear out all the expired weak pointers
83  // every 16K times we register a new file.
84  size_t num_file_registers = 0;
85  std::map<std::string, std::weak_ptr<file_ownership_handle>> m_file_handles;
86 };
87 
88 } // namespace fileio
89 } // namespace turi
90 #endif
bool mark_file_for_delete(std::string file_name)
bool unmark_file_for_delete(std::string file_name)
static file_handle_pool & get_instance()
std::shared_ptr< file_ownership_handle > register_file(const std::string &file_name)