diff options
Diffstat (limited to 'src/visited.c')
-rw-r--r-- | src/visited.c | 50 |
1 files changed, 38 insertions, 12 deletions
diff --git a/src/visited.c b/src/visited.c index 912a6318..b0b12beb 100644 --- a/src/visited.c +++ b/src/visited.c | |||
@@ -24,6 +24,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
24 | #include "app.h" | 24 | #include "app.h" |
25 | 25 | ||
26 | #include <the_Foundation/file.h> | 26 | #include <the_Foundation/file.h> |
27 | #include <the_Foundation/mutex.h> | ||
27 | #include <the_Foundation/path.h> | 28 | #include <the_Foundation/path.h> |
28 | #include <the_Foundation/ptrarray.h> | 29 | #include <the_Foundation/ptrarray.h> |
29 | #include <the_Foundation/sortedarray.h> | 30 | #include <the_Foundation/sortedarray.h> |
@@ -51,24 +52,30 @@ static int cmpNewer_VisitedUrl_(const void *insert, const void *existing) { | |||
51 | /*----------------------------------------------------------------------------------------------*/ | 52 | /*----------------------------------------------------------------------------------------------*/ |
52 | 53 | ||
53 | struct Impl_Visited { | 54 | struct Impl_Visited { |
55 | iMutex *mtx; | ||
54 | iSortedArray visited; | 56 | iSortedArray visited; |
55 | }; | 57 | }; |
56 | 58 | ||
57 | iDefineTypeConstruction(Visited) | 59 | iDefineTypeConstruction(Visited) |
58 | 60 | ||
59 | void init_Visited(iVisited *d) { | 61 | void init_Visited(iVisited *d) { |
62 | d->mtx = new_Mutex(); | ||
60 | init_SortedArray(&d->visited, sizeof(iVisitedUrl), cmpUrl_VisitedUrl_); | 63 | init_SortedArray(&d->visited, sizeof(iVisitedUrl), cmpUrl_VisitedUrl_); |
61 | } | 64 | } |
62 | 65 | ||
63 | void deinit_Visited(iVisited *d) { | 66 | void deinit_Visited(iVisited *d) { |
64 | clear_Visited(d); | 67 | iGuardMutex(d->mtx, { |
65 | deinit_SortedArray(&d->visited); | 68 | clear_Visited(d); |
69 | deinit_SortedArray(&d->visited); | ||
70 | }); | ||
71 | delete_Mutex(d->mtx); | ||
66 | } | 72 | } |
67 | 73 | ||
68 | void save_Visited(const iVisited *d, const char *dirPath) { | 74 | void save_Visited(const iVisited *d, const char *dirPath) { |
69 | iString *line = new_String(); | 75 | iString *line = new_String(); |
70 | iFile *f = newCStr_File(concatPath_CStr(dirPath, "visited.txt")); | 76 | iFile *f = newCStr_File(concatPath_CStr(dirPath, "visited.txt")); |
71 | if (open_File(f, writeOnly_FileMode | text_FileMode)) { | 77 | if (open_File(f, writeOnly_FileMode | text_FileMode)) { |
78 | lock_Mutex(d->mtx); | ||
72 | iConstForEach(Array, i, &d->visited.values) { | 79 | iConstForEach(Array, i, &d->visited.values) { |
73 | const iVisitedUrl *item = i.value; | 80 | const iVisitedUrl *item = i.value; |
74 | iDate date; | 81 | iDate date; |
@@ -84,6 +91,7 @@ void save_Visited(const iVisited *d, const char *dirPath) { | |||
84 | cstr_String(&item->url)); | 91 | cstr_String(&item->url)); |
85 | writeData_File(f, cstr_String(line), size_String(line)); | 92 | writeData_File(f, cstr_String(line), size_String(line)); |
86 | } | 93 | } |
94 | unlock_Mutex(d->mtx); | ||
87 | } | 95 | } |
88 | iRelease(f); | 96 | iRelease(f); |
89 | delete_String(line); | 97 | delete_String(line); |
@@ -92,6 +100,7 @@ void save_Visited(const iVisited *d, const char *dirPath) { | |||
92 | void load_Visited(iVisited *d, const char *dirPath) { | 100 | void load_Visited(iVisited *d, const char *dirPath) { |
93 | iFile *f = newCStr_File(concatPath_CStr(dirPath, "visited.txt")); | 101 | iFile *f = newCStr_File(concatPath_CStr(dirPath, "visited.txt")); |
94 | if (open_File(f, readOnly_FileMode | text_FileMode)) { | 102 | if (open_File(f, readOnly_FileMode | text_FileMode)) { |
103 | lock_Mutex(d->mtx); | ||
95 | const iRangecc src = range_Block(collect_Block(readAll_File(f))); | 104 | const iRangecc src = range_Block(collect_Block(readAll_File(f))); |
96 | iRangecc line = iNullRange; | 105 | iRangecc line = iNullRange; |
97 | iTime now; | 106 | iTime now; |
@@ -111,15 +120,18 @@ void load_Visited(iVisited *d, const char *dirPath) { | |||
111 | initRange_String(&item.url, (iRangecc){ line.start + 20, line.end }); | 120 | initRange_String(&item.url, (iRangecc){ line.start + 20, line.end }); |
112 | insert_SortedArray(&d->visited, &item); | 121 | insert_SortedArray(&d->visited, &item); |
113 | } | 122 | } |
123 | unlock_Mutex(d->mtx); | ||
114 | } | 124 | } |
115 | iRelease(f); | 125 | iRelease(f); |
116 | } | 126 | } |
117 | 127 | ||
118 | void clear_Visited(iVisited *d) { | 128 | void clear_Visited(iVisited *d) { |
129 | lock_Mutex(d->mtx); | ||
119 | iForEach(Array, v, &d->visited.values) { | 130 | iForEach(Array, v, &d->visited.values) { |
120 | deinit_VisitedUrl(v.value); | 131 | deinit_VisitedUrl(v.value); |
121 | } | 132 | } |
122 | clear_SortedArray(&d->visited); | 133 | clear_SortedArray(&d->visited); |
134 | unlock_Mutex(d->mtx); | ||
123 | } | 135 | } |
124 | 136 | ||
125 | static size_t find_Visited_(const iVisited *d, const iString *url) { | 137 | static size_t find_Visited_(const iVisited *d, const iString *url) { |
@@ -127,8 +139,10 @@ static size_t find_Visited_(const iVisited *d, const iString *url) { | |||
127 | init_VisitedUrl(&visit); | 139 | init_VisitedUrl(&visit); |
128 | set_String(&visit.url, url); | 140 | set_String(&visit.url, url); |
129 | size_t pos = iInvalidPos; | 141 | size_t pos = iInvalidPos; |
130 | locate_SortedArray(&d->visited, &visit, &pos); | 142 | iGuardMutex(d->mtx, { |
131 | deinit_VisitedUrl(&visit); | 143 | locate_SortedArray(&d->visited, &visit, &pos); |
144 | deinit_VisitedUrl(&visit); | ||
145 | }); | ||
132 | return pos; | 146 | return pos; |
133 | } | 147 | } |
134 | 148 | ||
@@ -137,23 +151,28 @@ void visitUrl_Visited(iVisited *d, const iString *url) { | |||
137 | init_VisitedUrl(&visit); | 151 | init_VisitedUrl(&visit); |
138 | set_String(&visit.url, url); | 152 | set_String(&visit.url, url); |
139 | size_t pos; | 153 | size_t pos; |
154 | lock_Mutex(d->mtx); | ||
140 | if (locate_SortedArray(&d->visited, &visit, &pos)) { | 155 | if (locate_SortedArray(&d->visited, &visit, &pos)) { |
141 | iVisitedUrl *old = at_SortedArray(&d->visited, pos); | 156 | iVisitedUrl *old = at_SortedArray(&d->visited, pos); |
142 | if (cmpNewer_VisitedUrl_(&visit, old)) { | 157 | if (cmpNewer_VisitedUrl_(&visit, old)) { |
143 | old->when = visit.when; | 158 | old->when = visit.when; |
159 | unlock_Mutex(d->mtx); | ||
144 | deinit_VisitedUrl(&visit); | 160 | deinit_VisitedUrl(&visit); |
145 | return; | 161 | return; |
146 | } | 162 | } |
147 | } | 163 | } |
148 | insert_SortedArray(&d->visited, &visit); | 164 | insert_SortedArray(&d->visited, &visit); |
165 | unlock_Mutex(d->mtx); | ||
149 | } | 166 | } |
150 | 167 | ||
151 | void removeUrl_Visited(iVisited *d, const iString *url) { | 168 | void removeUrl_Visited(iVisited *d, const iString *url) { |
152 | size_t pos = find_Visited_(d, url); | 169 | iGuardMutex(d->mtx, { |
153 | if (pos != iInvalidPos) { | 170 | size_t pos = find_Visited_(d, url); |
154 | deinit_VisitedUrl(at_SortedArray(&d->visited, pos)); | 171 | if (pos != iInvalidPos) { |
155 | remove_Array(&d->visited.values, pos); | 172 | deinit_VisitedUrl(at_SortedArray(&d->visited, pos)); |
156 | } | 173 | remove_Array(&d->visited.values, pos); |
174 | } | ||
175 | }); | ||
157 | } | 176 | } |
158 | 177 | ||
159 | iTime urlVisitTime_Visited(const iVisited *d, const iString *url) { | 178 | iTime urlVisitTime_Visited(const iVisited *d, const iString *url) { |
@@ -161,9 +180,11 @@ iTime urlVisitTime_Visited(const iVisited *d, const iString *url) { | |||
161 | size_t pos; | 180 | size_t pos; |
162 | iZap(item); | 181 | iZap(item); |
163 | initCopy_String(&item.url, url); | 182 | initCopy_String(&item.url, url); |
183 | lock_Mutex(d->mtx); | ||
164 | if (locate_SortedArray(&d->visited, &item, &pos)) { | 184 | if (locate_SortedArray(&d->visited, &item, &pos)) { |
165 | item.when = ((const iVisitedUrl *) constAt_SortedArray(&d->visited, pos))->when; | 185 | item.when = ((const iVisitedUrl *) constAt_SortedArray(&d->visited, pos))->when; |
166 | } | 186 | } |
187 | unlock_Mutex(d->mtx); | ||
167 | deinit_String(&item.url); | 188 | deinit_String(&item.url); |
168 | return item.when; | 189 | return item.when; |
169 | } | 190 | } |
@@ -175,9 +196,14 @@ static int cmpWhenDescending_VisitedUrlPtr_(const void *a, const void *b) { | |||
175 | 196 | ||
176 | const iArray *list_Visited(const iVisited *d, size_t count) { | 197 | const iArray *list_Visited(const iVisited *d, size_t count) { |
177 | iPtrArray *urls = collectNew_PtrArray(); | 198 | iPtrArray *urls = collectNew_PtrArray(); |
178 | iConstForEach(Array, i, &d->visited.values) { | 199 | iGuardMutex(d->mtx, { |
179 | pushBack_PtrArray(urls, i.value); | 200 | iConstForEach(Array, i, &d->visited.values) { |
180 | } | 201 | pushBack_PtrArray(urls, i.value); |
202 | } | ||
203 | }); | ||
181 | sort_Array(urls, cmpWhenDescending_VisitedUrlPtr_); | 204 | sort_Array(urls, cmpWhenDescending_VisitedUrlPtr_); |
205 | if (count > 0 && size_Array(urls) > count) { | ||
206 | resize_Array(urls, count); | ||
207 | } | ||
182 | return urls; | 208 | return urls; |
183 | } | 209 | } |