summaryrefslogtreecommitdiff
path: root/src/history.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-05-11 12:56:14 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-05-11 12:56:25 +0300
commit9f7a9058d3593d09a8fad9cd42b59f8a15873837 (patch)
tree75efa83e07e2130f45308e9bff627b569086fa3a /src/history.c
parenta13543aa922647ea2f8cc40cb9f3f797df8758df (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.c72
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
35void init_RecentUrl(iRecentUrl *d) { 35void 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
41void deinit_RecentUrl(iRecentUrl *d) { 42void 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)
48iRecentUrl *copy_RecentUrl(const iRecentUrl *d) { 50iRecentUrl *copy_RecentUrl(const iRecentUrl *d) {
49 iRecentUrl *copy = new_RecentUrl(); 51 iRecentUrl *copy = new_RecentUrl();
50 set_String(&copy->url, &d->url); 52 set_String(&copy->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
59size_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
68size_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
58struct Impl_History { 78struct 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
337void 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
304size_t cacheSize_History(const iHistory *d) { 347size_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;