diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-05-11 12:56:14 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-05-11 12:56:25 +0300 |
commit | 9f7a9058d3593d09a8fad9cd42b59f8a15873837 (patch) | |
tree | 75efa83e07e2130f45308e9bff627b569086fa3a /src/history.c | |
parent | a13543aa922647ea2f8cc40cb9f3f797df8758df (diff) |
Cache GmDocuments in memory
Navigation history keeps final GmDocuments in memory for quicker restore when navigating; no need to redo layout.
Changed the color escape to Vertical Tab so Carriage Returns can be left in the source, reducing need to normalize spaces.
Diffstat (limited to 'src/history.c')
-rw-r--r-- | src/history.c | 72 |
1 files changed, 57 insertions, 15 deletions
diff --git a/src/history.c b/src/history.c index 9f4e415b..58ffa5c4 100644 --- a/src/history.c +++ b/src/history.c | |||
@@ -34,11 +34,13 @@ static const size_t maxStack_History_ = 50; /* back/forward navigable items */ | |||
34 | 34 | ||
35 | void init_RecentUrl(iRecentUrl *d) { | 35 | void init_RecentUrl(iRecentUrl *d) { |
36 | init_String(&d->url); | 36 | init_String(&d->url); |
37 | d->normScrollY = 0; | 37 | d->normScrollY = 0; |
38 | d->cachedResponse = NULL; | 38 | d->cachedResponse = NULL; |
39 | d->cachedDoc = NULL; | ||
39 | } | 40 | } |
40 | 41 | ||
41 | void deinit_RecentUrl(iRecentUrl *d) { | 42 | void deinit_RecentUrl(iRecentUrl *d) { |
43 | iRelease(d->cachedDoc); | ||
42 | deinit_String(&d->url); | 44 | deinit_String(&d->url); |
43 | delete_GmResponse(d->cachedResponse); | 45 | delete_GmResponse(d->cachedResponse); |
44 | } | 46 | } |
@@ -48,11 +50,29 @@ iDefineTypeConstruction(RecentUrl) | |||
48 | iRecentUrl *copy_RecentUrl(const iRecentUrl *d) { | 50 | iRecentUrl *copy_RecentUrl(const iRecentUrl *d) { |
49 | iRecentUrl *copy = new_RecentUrl(); | 51 | iRecentUrl *copy = new_RecentUrl(); |
50 | set_String(©->url, &d->url); | 52 | set_String(©->url, &d->url); |
51 | copy->normScrollY = d->normScrollY; | 53 | copy->normScrollY = d->normScrollY; |
52 | copy->cachedResponse = d->cachedResponse ? copy_GmResponse(d->cachedResponse) : NULL; | 54 | copy->cachedResponse = d->cachedResponse ? copy_GmResponse(d->cachedResponse) : NULL; |
55 | copy->cachedDoc = ref_Object(d->cachedDoc); | ||
53 | return copy; | 56 | return copy; |
54 | } | 57 | } |
55 | 58 | ||
59 | size_t cacheSize_RecentUrl(const iRecentUrl *d) { | ||
60 | size_t size = 0; | ||
61 | if (d->cachedResponse) { | ||
62 | size += size_String(&d->cachedResponse->meta); | ||
63 | size += size_Block(&d->cachedResponse->body); | ||
64 | } | ||
65 | return size; | ||
66 | } | ||
67 | |||
68 | size_t memorySize_RecentUrl(const iRecentUrl *d) { | ||
69 | size_t size = cacheSize_RecentUrl(d); | ||
70 | if (d->cachedDoc) { | ||
71 | size += memorySize_GmDocument(d->cachedDoc); | ||
72 | } | ||
73 | return size; | ||
74 | } | ||
75 | |||
56 | /*----------------------------------------------------------------------------------------------*/ | 76 | /*----------------------------------------------------------------------------------------------*/ |
57 | 77 | ||
58 | struct Impl_History { | 78 | struct Impl_History { |
@@ -92,20 +112,31 @@ iString *debugInfo_History(const iHistory *d) { | |||
92 | iString *str = new_String(); | 112 | iString *str = new_String(); |
93 | format_String(str, | 113 | format_String(str, |
94 | "```\n" | 114 | "```\n" |
95 | "Idx | Size | SP%% | URL\n" | 115 | "Idx | Cache | Memory | SP%% | URL\n" |
96 | "----+---------+-----+-----\n"); | 116 | "----+---------+----------+-----+-----\n"); |
97 | size_t totalSize = 0; | 117 | size_t totalCache = 0; |
118 | size_t totalMemory = 0; | ||
98 | iConstForEach(Array, i, &d->recent) { | 119 | iConstForEach(Array, i, &d->recent) { |
99 | const iRecentUrl *item = i.value; | 120 | const iRecentUrl *item = i.value; |
100 | appendFormat_String( | 121 | appendFormat_String( |
101 | str, " %2zu | ", size_Array(&d->recent) - index_ArrayConstIterator(&i) - 1); | 122 | str, " %2zu | ", size_Array(&d->recent) - index_ArrayConstIterator(&i) - 1); |
102 | if (item->cachedResponse) { | 123 | const size_t cacheSize = cacheSize_RecentUrl(item); |
103 | appendFormat_String(str, "%7zu", size_Block(&item->cachedResponse->body)); | 124 | const size_t memSize = memorySize_RecentUrl(item); |
104 | totalSize += size_Block(&item->cachedResponse->body); | 125 | if (cacheSize) { |
126 | appendFormat_String(str, "%7zu", cacheSize); | ||
127 | totalCache += cacheSize; | ||
105 | } | 128 | } |
106 | else { | 129 | else { |
107 | appendFormat_String(str, " --"); | 130 | appendFormat_String(str, " --"); |
108 | } | 131 | } |
132 | appendCStr_String(str, " | "); | ||
133 | if (memSize) { | ||
134 | appendFormat_String(str, "%8zu", memSize); | ||
135 | totalMemory += memSize; | ||
136 | } | ||
137 | else { | ||
138 | appendFormat_String(str, " --"); | ||
139 | } | ||
109 | appendFormat_String(str, | 140 | appendFormat_String(str, |
110 | " | %3d | %s\n", | 141 | " | %3d | %s\n", |
111 | iRound(100.0f * item->normScrollY), | 142 | iRound(100.0f * item->normScrollY), |
@@ -114,8 +145,10 @@ iString *debugInfo_History(const iHistory *d) { | |||
114 | appendFormat_String(str, "\n```\n"); | 145 | appendFormat_String(str, "\n```\n"); |
115 | appendFormat_String(str, | 146 | appendFormat_String(str, |
116 | "Total cached data: %.3f MB\n" | 147 | "Total cached data: %.3f MB\n" |
148 | "Total memory usage: %.3f MB\n" | ||
117 | "Navigation position: %zu\n\n", | 149 | "Navigation position: %zu\n\n", |
118 | totalSize / 1.0e6f, | 150 | totalCache / 1.0e6f, |
151 | totalMemory / 1.0e6f, | ||
119 | d->recentPos); | 152 | d->recentPos); |
120 | return str; | 153 | return str; |
121 | } | 154 | } |
@@ -301,14 +334,22 @@ void setCachedResponse_History(iHistory *d, const iGmResponse *response) { | |||
301 | unlock_Mutex(d->mtx); | 334 | unlock_Mutex(d->mtx); |
302 | } | 335 | } |
303 | 336 | ||
337 | void setCachedDocument_History(iHistory *d, iGmDocument *doc) { | ||
338 | lock_Mutex(d->mtx); | ||
339 | iRecentUrl *item = mostRecentUrl_History(d); | ||
340 | if (item && item->cachedDoc != doc) { | ||
341 | iRelease(item->cachedDoc); | ||
342 | item->cachedDoc = ref_Object(doc); | ||
343 | } | ||
344 | unlock_Mutex(d->mtx); | ||
345 | } | ||
346 | |||
304 | size_t cacheSize_History(const iHistory *d) { | 347 | size_t cacheSize_History(const iHistory *d) { |
305 | size_t cached = 0; | 348 | size_t cached = 0; |
306 | lock_Mutex(d->mtx); | 349 | lock_Mutex(d->mtx); |
307 | iConstForEach(Array, i, &d->recent) { | 350 | iConstForEach(Array, i, &d->recent) { |
308 | const iRecentUrl *url = i.value; | 351 | const iRecentUrl *url = i.value; |
309 | if (url->cachedResponse) { | 352 | cached += cacheSize_RecentUrl(url); |
310 | cached += size_Block(&url->cachedResponse->body); | ||
311 | } | ||
312 | } | 353 | } |
313 | unlock_Mutex(d->mtx); | 354 | unlock_Mutex(d->mtx); |
314 | return cached; | 355 | return cached; |
@@ -335,9 +376,9 @@ size_t pruneLeastImportant_History(iHistory *d) { | |||
335 | lock_Mutex(d->mtx); | 376 | lock_Mutex(d->mtx); |
336 | iConstForEach(Array, i, &d->recent) { | 377 | iConstForEach(Array, i, &d->recent) { |
337 | const iRecentUrl *url = i.value; | 378 | const iRecentUrl *url = i.value; |
338 | if (url->cachedResponse) { | 379 | if (url->cachedResponse || url->cachedDoc) { |
339 | const double urlScore = | 380 | const double urlScore = |
340 | size_Block(&url->cachedResponse->body) * | 381 | cacheSize_RecentUrl(url) * |
341 | pow(secondsSince_Time(&now, &url->cachedResponse->when) / 60.0, 1.25); | 382 | pow(secondsSince_Time(&now, &url->cachedResponse->when) / 60.0, 1.25); |
342 | if (urlScore > score) { | 383 | if (urlScore > score) { |
343 | chosen = index_ArrayConstIterator(&i); | 384 | chosen = index_ArrayConstIterator(&i); |
@@ -347,9 +388,10 @@ size_t pruneLeastImportant_History(iHistory *d) { | |||
347 | } | 388 | } |
348 | if (chosen != iInvalidPos) { | 389 | if (chosen != iInvalidPos) { |
349 | iRecentUrl *url = at_Array(&d->recent, chosen); | 390 | iRecentUrl *url = at_Array(&d->recent, chosen); |
350 | delta = size_Block(&url->cachedResponse->body); | 391 | delta = cacheSize_RecentUrl(url); |
351 | delete_GmResponse(url->cachedResponse); | 392 | delete_GmResponse(url->cachedResponse); |
352 | url->cachedResponse = NULL; | 393 | url->cachedResponse = NULL; |
394 | iReleasePtr(&url->cachedDoc); | ||
353 | } | 395 | } |
354 | unlock_Mutex(d->mtx); | 396 | unlock_Mutex(d->mtx); |
355 | return delta; | 397 | return delta; |