aboutsummaryrefslogtreecommitdiff
path: root/page_cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'page_cache.c')
-rw-r--r--page_cache.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/page_cache.c b/page_cache.c
index 89bb1ec3a0..aa681923c6 100644
--- a/page_cache.c
+++ b/page_cache.c
@@ -33,6 +33,9 @@
do { } while (0)
#endif
+/* the page in cache will not be replaced in two cycles */
+#define CACHED_PAGE_LIFETIME 2
+
typedef struct CacheItem CacheItem;
struct CacheItem {
@@ -122,7 +125,8 @@ static size_t cache_get_cache_pos(const PageCache *cache,
return pos;
}
-bool cache_is_cached(const PageCache *cache, uint64_t addr)
+bool cache_is_cached(const PageCache *cache, uint64_t addr,
+ uint64_t current_age)
{
size_t pos;
@@ -131,7 +135,12 @@ bool cache_is_cached(const PageCache *cache, uint64_t addr)
pos = cache_get_cache_pos(cache, addr);
- return (cache->page_cache[pos].it_addr == addr);
+ if (cache->page_cache[pos].it_addr == addr) {
+ /* update the it_age when the cache hit */
+ cache->page_cache[pos].it_age = current_age;
+ return true;
+ }
+ return false;
}
static CacheItem *cache_get_by_addr(const PageCache *cache, uint64_t addr)
@@ -151,7 +160,8 @@ uint8_t *get_cached_data(const PageCache *cache, uint64_t addr)
return cache_get_by_addr(cache, addr)->it_data;
}
-int cache_insert(PageCache *cache, uint64_t addr, const uint8_t *pdata)
+int cache_insert(PageCache *cache, uint64_t addr, const uint8_t *pdata,
+ uint64_t current_age)
{
CacheItem *it = NULL;
@@ -162,6 +172,11 @@ int cache_insert(PageCache *cache, uint64_t addr, const uint8_t *pdata)
/* actual update of entry */
it = cache_get_by_addr(cache, addr);
+ if (it->it_data && it->it_addr != addr &&
+ it->it_age + CACHED_PAGE_LIFETIME > current_age) {
+ /* the cache page is fresh, don't replace it */
+ return -1;
+ }
/* allocate page */
if (!it->it_data) {
it->it_data = g_try_malloc(cache->page_size);
@@ -174,7 +189,7 @@ int cache_insert(PageCache *cache, uint64_t addr, const uint8_t *pdata)
memcpy(it->it_data, pdata, cache->page_size);
- it->it_age = ++cache->max_item_age;
+ it->it_age = current_age;
it->it_addr = addr;
return 0;