summaryrefslogtreecommitdiff
path: root/desktop/cache.c
blob: 012683ebee1c5e9d65fecb433a3efbfba0beab34 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/**
 * $Id: cache.c,v 1.1 2002/11/02 22:28:05 bursa Exp $
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "netsurf/desktop/cache.h"
#include "netsurf/render/utils.h"
#include "netsurf/utils/log.h"
#include "curl/curl.h"
#include "ubiqx/ubi_Cache.h"

/**
 * internal structures and declarations
 */

ubi_cacheRoot memcache;

struct memcache_entry {
	ubi_cacheEntry Node;
	char * url;
	struct content * content;
};

static int memcache_compare(ubi_trItemPtr item, ubi_trNode * node);
void memcache_free(ubi_trNode * node);


/**
 * cache_init -- initialise the cache manager
 */

void cache_init(void)
{
	/* memory cache */
	ubi_cacheInit(&memcache, memcache_compare, memcache_free, 40, 100*1024);
}


/**
 * cache_quit -- terminate the cache manager
 */

void cache_quit(void)
{
	ubi_cacheClear(&memcache);
}


/**
 * cache_get -- retrieve url from memory cache or disc cache
 */

struct content * cache_get(char * const url)
{
	struct memcache_entry * entry;

	entry = (struct memcache_entry *) ubi_cacheGet(&memcache, url);
	if (entry != 0) {
		LOG(("url %s in cache, node %p", url, entry));
		entry->content->ref_count++;
		return entry->content;
	}

	LOG(("url %s not cached", url));

	/* TODO: check disc cache */

	return 0;
}


/**
 * cache_put -- place content in the memory cache
 */

void cache_put(char * const url, struct content * content, unsigned long size)
{
	struct memcache_entry * entry;
	
	entry = xcalloc(1, sizeof(struct memcache_entry));
	entry->url = xstrdup(url);
	entry->content = content;
	content->ref_count = 2;  /* cache, caller */
	ubi_cachePut(&memcache, size,
			(ubi_cacheEntry *) entry, entry->url);
}


/**
 * cache_free -- free a cache object if it is no longer used
 */

void cache_free(struct content * content)
{
	LOG(("content %p, ref_count %u", content, content->ref_count));
	if (--content->ref_count == 0) {
		LOG(("ref count 0, freeing"));
		content_destroy(content);
	}
}


/**
 * memory cache
 */

static int memcache_compare(ubi_trItemPtr item, ubi_trNode * node)
{
	return strcmp((char *) item, ((struct memcache_entry *) node)->url);
}


void memcache_free(ubi_trNode * node)
{
	struct memcache_entry * entry = (struct memcache_entry *) node;

	LOG(("node %p, node->url %s", node, entry->url));

	cache_free(entry->content);
	free(entry->url);
	free(entry);

	/* TODO: place the object in a disc cache */
}