source: imaps-frontend/node_modules/@parcel/watcher/src/DirTree.cc@ 0c6b92a

main
Last change on this file since 0c6b92a was 0c6b92a, checked in by stefan toskovski <stefantoska84@…>, 5 weeks ago

Pred finalna verzija

  • Property mode set to 100644
File size: 3.7 KB
Line 
1#include "DirTree.hh"
2#include <inttypes.h>
3
4static std::mutex mDirCacheMutex;
5static std::unordered_map<std::string, std::weak_ptr<DirTree>> dirTreeCache;
6
7struct DirTreeDeleter {
8 void operator()(DirTree *tree) {
9 std::lock_guard<std::mutex> lock(mDirCacheMutex);
10 dirTreeCache.erase(tree->root);
11 delete tree;
12
13 // Free up memory.
14 if (dirTreeCache.size() == 0) {
15 dirTreeCache.rehash(0);
16 }
17 }
18};
19
20std::shared_ptr<DirTree> DirTree::getCached(std::string root) {
21 std::lock_guard<std::mutex> lock(mDirCacheMutex);
22
23 auto found = dirTreeCache.find(root);
24 std::shared_ptr<DirTree> tree;
25
26 // Use cached tree, or create an empty one.
27 if (found != dirTreeCache.end()) {
28 tree = found->second.lock();
29 } else {
30 tree = std::shared_ptr<DirTree>(new DirTree(root), DirTreeDeleter());
31 dirTreeCache.emplace(root, tree);
32 }
33
34 return tree;
35}
36
37DirTree::DirTree(std::string root, FILE *f) : root(root), isComplete(true) {
38 size_t size;
39 if (fscanf(f, "%zu", &size)) {
40 for (size_t i = 0; i < size; i++) {
41 DirEntry entry(f);
42 entries.emplace(entry.path, entry);
43 }
44 }
45}
46
47// Internal find method that has no lock
48DirEntry *DirTree::_find(std::string path) {
49 auto found = entries.find(path);
50 if (found == entries.end()) {
51 return NULL;
52 }
53
54 return &found->second;
55}
56
57DirEntry *DirTree::add(std::string path, uint64_t mtime, bool isDir) {
58 std::lock_guard<std::mutex> lock(mMutex);
59
60 DirEntry entry(path, mtime, isDir);
61 auto it = entries.emplace(entry.path, entry);
62 return &it.first->second;
63}
64
65DirEntry *DirTree::find(std::string path) {
66 std::lock_guard<std::mutex> lock(mMutex);
67 return _find(path);
68}
69
70DirEntry *DirTree::update(std::string path, uint64_t mtime) {
71 std::lock_guard<std::mutex> lock(mMutex);
72
73 DirEntry *found = _find(path);
74 if (found) {
75 found->mtime = mtime;
76 }
77
78 return found;
79}
80
81void DirTree::remove(std::string path) {
82 std::lock_guard<std::mutex> lock(mMutex);
83
84 DirEntry *found = _find(path);
85
86 // Remove all sub-entries if this is a directory
87 if (found && found->isDir) {
88 std::string pathStart = path + DIR_SEP;
89 for (auto it = entries.begin(); it != entries.end();) {
90 if (it->first.rfind(pathStart, 0) == 0) {
91 it = entries.erase(it);
92 } else {
93 it++;
94 }
95 }
96 }
97
98 entries.erase(path);
99}
100
101void DirTree::write(FILE *f) {
102 std::lock_guard<std::mutex> lock(mMutex);
103
104 fprintf(f, "%zu\n", entries.size());
105 for (auto it = entries.begin(); it != entries.end(); it++) {
106 it->second.write(f);
107 }
108}
109
110void DirTree::getChanges(DirTree *snapshot, EventList &events) {
111 std::lock_guard<std::mutex> lock(mMutex);
112 std::lock_guard<std::mutex> snapshotLock(snapshot->mMutex);
113
114 for (auto it = entries.begin(); it != entries.end(); it++) {
115 auto found = snapshot->entries.find(it->first);
116 if (found == snapshot->entries.end()) {
117 events.create(it->second.path);
118 } else if (found->second.mtime != it->second.mtime && !found->second.isDir && !it->second.isDir) {
119 events.update(it->second.path);
120 }
121 }
122
123 for (auto it = snapshot->entries.begin(); it != snapshot->entries.end(); it++) {
124 size_t count = entries.count(it->first);
125 if (count == 0) {
126 events.remove(it->second.path);
127 }
128 }
129}
130
131DirEntry::DirEntry(std::string p, uint64_t t, bool d) {
132 path = p;
133 mtime = t;
134 isDir = d;
135 state = NULL;
136}
137
138DirEntry::DirEntry(FILE *f) {
139 size_t size;
140 if (fscanf(f, "%zu", &size)) {
141 path.resize(size);
142 if (fread(&path[0], sizeof(char), size, f)) {
143 int d = 0;
144 fscanf(f, "%" PRIu64 " %d\n", &mtime, &d);
145 isDir = d == 1;
146 }
147 }
148}
149
150void DirEntry::write(FILE *f) const {
151 fprintf(f, "%zu%s%" PRIu64 " %d\n", path.size(), path.c_str(), mtime, isDir);
152}
Note: See TracBrowser for help on using the repository browser.