inLimbo
TUI Music Player that keeps you in Limbo.
 
Loading...
Searching...
No Matches
inode_mapper.hpp
Go to the documentation of this file.
1#ifndef INODE_MAPPER_HPP
2#define INODE_MAPPER_HPP
3
4#include "rbtree.hpp"
5#include <cstring>
6#include <dirent.h>
7#include <fcntl.h>
8#include <fstream>
9#include <iostream>
10#include <sys/mman.h>
11#include <sys/stat.h>
12#include <unistd.h>
13#include <unordered_map>
14
15using namespace std;
16
17#define LIB_SYNC_NAME "lib.sync"
18#define LIB_BIN_NAME "lib.bin"
19
21{
22private:
23 unordered_map<ino_t, string> inodeToPath;
24 ofstream syncFile;
25
26public:
27 InodeFileMapper(const string& syncFileName, string useCacheFile)
28 {
29 if (useCacheFile == "true")
30 {
31 syncFile.open(syncFileName, std::ios::app);
32 }
33 else
34 {
35 syncFile.open(syncFileName);
36 }
37
38 if (!syncFile.is_open())
39 {
40 cerr << "Error: Could not open file " << syncFileName << endl;
41 exit(EXIT_FAILURE);
42 }
43 }
44
46 {
47 if (syncFile.is_open())
48 {
49 syncFile.close();
50 }
51 }
52
53 void addMapping(ino_t inode, const string& filePath, bool writeSyncFile)
54 {
55 if (inodeToPath.find(inode) == inodeToPath.end())
56 {
57 inodeToPath[inode] = filePath;
58 if (writeSyncFile && syncFile.is_open())
59 {
60 syncFile << inode << endl;
61 syncFile << filePath << endl;
62 }
63 }
64 }
65
66 void printMappings() const
67 {
68 for (const auto& pair : inodeToPath)
69 {
70 cout << "Inode: " << pair.first << " -> " << pair.second << endl;
71 }
72 }
73};
74
75void processDirectory(const string& dirPath, RedBlackTree& rbt, InodeFileMapper& mapper)
76{
77 DIR* dir = opendir(dirPath.c_str());
78 if (!dir)
79 {
80 cerr << "Error: Could not open directory " << dirPath << endl;
81 exit(EXIT_FAILURE);
82 }
83
84 struct dirent* entry;
85 while ((entry = readdir(dir)) != nullptr)
86 {
87 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
88 {
89 continue;
90 }
91
92 string fullPath = dirPath + "/" + entry->d_name;
93 struct stat fileStat;
94 if (stat(fullPath.c_str(), &fileStat) == 0)
95 {
96 rbt.insert(fileStat.st_ino);
97 mapper.addMapping(fileStat.st_ino, fullPath, true);
98 }
99 else
100 {
101 cerr << "Warning: Could not stat file " << fullPath << endl;
102 }
103 }
104
105 closedir(dir);
106}
107
108void processCacheFile(const std::string& cacheFilePath, RedBlackTree& rbt, InodeFileMapper& mapper)
109{
110 // Open file
111 int fd = open(cacheFilePath.c_str(), O_RDONLY);
112 if (fd == -1)
113 {
114 throw std::runtime_error("Could not open cache file " + cacheFilePath);
115 }
116
117 // Get file size
118 struct stat sb;
119 if (fstat(fd, &sb) == -1)
120 {
121 close(fd);
122 throw std::runtime_error("Could not get file size");
123 }
124
125 // Memory map the file
126 const char* data =
127 static_cast<const char*>(mmap(nullptr, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0));
128
129 if (data == MAP_FAILED)
130 {
131 close(fd);
132 throw std::runtime_error("Could not memory map file");
133 }
134
135 const char* current = data;
136 const char* end = data + sb.st_size;
137
138 while (current < end)
139 {
140 // Find end of inode line
141 const char* lineEnd = static_cast<const char*>(memchr(current, '\n', end - current));
142 if (!lineEnd)
143 break;
144
145 // Parse inode
146 ino_t inode = 0;
147 const char* inodeStart = current;
148 while (current < lineEnd && *current >= '0' && *current <= '9')
149 {
150 inode = inode * 10 + (*current - '0');
151 current++;
152 }
153
154 // Skip newline
155 current = lineEnd + 1;
156 if (current >= end)
157 break;
158
159 // Find end of filepath line
160 lineEnd = static_cast<const char*>(memchr(current, '\n', end - current));
161 if (!lineEnd)
162 lineEnd = end;
163
164 // Get filepath
165 std::string filePath(current, lineEnd - current);
166
167 if (inode > 0 && !filePath.empty())
168 {
169 rbt.insert(inode);
170 mapper.addMapping(inode, std::move(filePath), false);
171 }
172
173 current = lineEnd + 1;
174 }
175
176 // Cleanup
177 munmap(const_cast<char*>(data), sb.st_size);
178 close(fd);
179}
180
181#endif // INODE_MAPPER_HPP
Definition inode_mapper.hpp:21
void addMapping(ino_t inode, const string &filePath, bool writeSyncFile)
Definition inode_mapper.hpp:53
~InodeFileMapper()
Definition inode_mapper.hpp:45
InodeFileMapper(const string &syncFileName, string useCacheFile)
Definition inode_mapper.hpp:27
void printMappings() const
Definition inode_mapper.hpp:66
Definition rbtree.hpp:38
void insert(ino_t data)
Definition rbtree.hpp:178
void processDirectory(const string &dirPath, RedBlackTree &rbt, InodeFileMapper &mapper)
Definition inode_mapper.hpp:75
void processCacheFile(const std::string &cacheFilePath, RedBlackTree &rbt, InodeFileMapper &mapper)
Definition inode_mapper.hpp:108