File indexing completed on 2024-11-24 04:31:14
0001 /* 0002 SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #ifndef BTCACHEFILE_H 0007 #define BTCACHEFILE_H 0008 0009 #include <QFile> 0010 #include <QMap> 0011 #include <QRecursiveMutex> 0012 #include <QSharedPointer> 0013 #include <util/constants.h> 0014 0015 namespace bt 0016 { 0017 class PreallocationThread; 0018 0019 /** 0020 * Interface which classes must implement to be able to map something from a CacheFile 0021 * It will also be used to notify when things get unmapped or remapped 0022 */ 0023 class MMappeable 0024 { 0025 public: 0026 virtual ~MMappeable() 0027 { 0028 } 0029 0030 /** 0031 * When a CacheFile is closed, this will be called on all existing mappings. 0032 */ 0033 virtual void unmapped() = 0; 0034 }; 0035 0036 /** 0037 @author Joris Guisson <joris.guisson@gmail.com> 0038 0039 Used by Single and MultiFileCache to write to disk. 0040 */ 0041 class CacheFile : public QObject 0042 { 0043 Q_OBJECT 0044 public: 0045 CacheFile(); 0046 ~CacheFile() override; 0047 0048 enum Mode { 0049 READ, 0050 WRITE, 0051 RW, 0052 }; 0053 0054 /** 0055 * Open the file. 0056 * @param path Path of the file 0057 * @param size Max size of the file 0058 * @throw Error when something goes wrong 0059 */ 0060 void open(const QString &path, Uint64 size); 0061 0062 /// Change the path of the file 0063 void changePath(const QString &npath); 0064 0065 /** 0066 * Map a part of the file into memory, will expand the file 0067 * if it is to small, but will not go past the limit set in open. 0068 * @param thing The thing that wishes to map the mmapping 0069 * @param off Offset into the file 0070 * @param size Size of the region to map 0071 * @param mode How the region will be mapped 0072 * @return A ptr to the mmaped region, or 0 if something goes wrong 0073 */ 0074 void *map(MMappeable *thing, Uint64 off, Uint32 size, Mode mode); 0075 0076 /** 0077 * Unmap a previously mapped region. 0078 * @param ptr Ptr to the region 0079 * @param size Size of the region 0080 */ 0081 void unmap(void *ptr, Uint32 size); 0082 0083 /** 0084 * Close the file, everything will be unmapped. 0085 * @param to_be_reopened Indicates if the close is temporarely (i.e. it will be reopened) 0086 */ 0087 void close(); 0088 0089 /** 0090 * Read from the file. 0091 * @param buf Buffer to store data 0092 * @param size Size to read 0093 * @param off Offset to read from in file 0094 */ 0095 void read(Uint8 *buf, Uint32 size, Uint64 off); 0096 0097 /** 0098 * Write to the file. 0099 * @param buf Buffer to write 0100 * @param size Size to read 0101 * @param off Offset to read from in file 0102 */ 0103 void write(const Uint8 *buf, Uint32 size, Uint64 off); 0104 0105 /** 0106 * Preallocate disk space 0107 */ 0108 void preallocate(PreallocationThread *prealloc); 0109 0110 /// Get the number of bytes this cache file is taking up 0111 Uint64 diskUsage(); 0112 0113 typedef QSharedPointer<CacheFile> Ptr; 0114 0115 private: 0116 void growFile(Uint64 to_write); 0117 void closeTemporary(); 0118 void openFile(Mode mode); 0119 void unmapAll(); 0120 bool allocateBytes(bt::Uint64 off, bt::Uint64 size); 0121 0122 private Q_SLOTS: 0123 void aboutToClose(); 0124 0125 private: 0126 QFile *fptr; 0127 bool read_only; 0128 Uint64 max_size, file_size; 0129 QString path; 0130 struct Entry { 0131 MMappeable *thing; 0132 void *ptr; 0133 Uint32 size; 0134 Uint64 offset; 0135 Uint32 diff; 0136 Mode mode; 0137 }; 0138 QMap<void *, Entry> mappings; // mappings where offset wasn't a multiple of 4K 0139 mutable QRecursiveMutex mutex; 0140 bool manual_close; 0141 }; 0142 0143 } 0144 0145 #endif