netsurf: branch vince/disccache updated. release/3.0-1116-gc940d69

NetSurf Browser Project (Commit Mailer) no-reply at netsurf-browser.org
Thu Feb 13 18:09:43 GMT 2014


Gitweb links:

...log http://git.netsurf-browser.org/netsurf.git/shortlog/c940d69028064b5a3ffa38dfd67302ada9eaaaa2
...commit http://git.netsurf-browser.org/netsurf.git/commit/c940d69028064b5a3ffa38dfd67302ada9eaaaa2
...tree http://git.netsurf-browser.org/netsurf.git/tree/c940d69028064b5a3ffa38dfd67302ada9eaaaa2

The branch, vince/disccache has been updated
       via  c940d69028064b5a3ffa38dfd67302ada9eaaaa2 (commit)
       via  a96db42291cd6cbc806aa20fc063151e8475d5a6 (commit)
       via  839c50a0d012d093d97db5ae28b9d9a114f8404c (commit)
      from  45c3adba5a683a744329c564448140252e1b48d7 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=c940d69028064b5a3ffa38dfd67302ada9eaaaa2
commit c940d69028064b5a3ffa38dfd67302ada9eaaaa2
Author: Vincent Sanders <vince at netsurf-browser.org>
Commit: Vincent Sanders <vince at netsurf-browser.org>

    attempt fetch from persistant storage for new objects before fetching from network

diff --git a/content/llcache.c b/content/llcache.c
index 79650b1..87e1692 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -1035,6 +1035,50 @@ llcache_persist_retrieve(llcache_object *object)
 				       &object->source_len);
 }
 
+static nserror
+llcache_object_persist_fetch(llcache_object *object,
+			     uint32_t flags,
+			     nsurl *referer,
+			     const llcache_post_data *post,
+			     uint32_t redirect_count)
+{
+	nserror error;
+	nsurl *referer_clone = NULL;
+	llcache_post_data *post_clone = NULL;
+
+	/* attempt to retrieve object from the cache */
+	error = guit->llcache->retrieve(object->url,
+				       &object->cache,
+				       &object->source_data,
+				       &object->source_len);
+	if (error != NSERROR_OK)
+		return error;
+
+	/* entry came out of cache - need to setup object state */
+	if (post != NULL) {
+		error = llcache_post_data_clone(post, &post_clone);
+		if (error != NSERROR_OK)
+			return error;
+	}
+
+	if (referer != NULL)
+		referer_clone = nsurl_ref(referer);
+
+	object->fetch.flags = flags;
+	object->fetch.referer = referer_clone;
+	object->fetch.post = post_clone;
+	object->fetch.redirect_count = redirect_count;
+
+	/* fetch is "finished" */
+	object->fetch.state = LLCACHE_FETCH_COMPLETE;
+	object->fetch.fetch = NULL;
+
+	object->store_state = LLCACHE_STORE_DISC;
+	object->source_alloc = object->source_len;
+
+	return NSERROR_OK;
+}
+
 /**
  * Retrieve a potentially cached object
  *
@@ -1059,7 +1103,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
 
 #ifdef LLCACHE_TRACE
 	LOG(("Searching cache for %s (%x %s %p)",
-	     nsurl_access(url), flags, nsurl_access(referer), post));
+	     nsurl_access(url), flags, referer==NULL?"":nsurl_access(referer), post));
 #endif
 
 	/* Search for the most recently fetched matching object */
@@ -1161,24 +1205,28 @@ llcache_object_retrieve_from_cache(nsurl *url,
 		llcache_object_remove_from_list(newest,
 						&llcache->cached_objects);
 		llcache_object_destroy(newest);
+	} else {
+#ifdef LLCACHE_TRACE
+		LOG(("Not found"));
+#endif
 	}
 
 	/* No viable object found in cache; create a new object */
-
 	error = llcache_object_new(url, &obj);
 	if (error != NSERROR_OK)
 		return error;
 
-#ifdef LLCACHE_TRACE
-	LOG(("Not found %p", obj));
-#endif
-
-	/* Attempt to kick-off fetch */
-	error = llcache_object_fetch(obj, flags, referer, post,
-				     redirect_count);
+	/* attempt to "fetch" object from persistant store first */
+	error = llcache_object_persist_fetch(obj, flags, referer, post,
+					     redirect_count);
 	if (error != NSERROR_OK) {
-		llcache_object_destroy(obj);
-		return error;
+		/* Attempt to kick-off fetch */
+		error = llcache_object_fetch(obj, flags, referer, post,
+					     redirect_count);
+		if (error != NSERROR_OK) {
+			llcache_object_destroy(obj);
+			return error;
+		}
 	}
 
 	/* Add new object to cache */
@@ -1210,7 +1258,7 @@ static nserror llcache_object_retrieve(nsurl *url, uint32_t flags,
 	nsurl *defragmented_url;
 
 #ifdef LLCACHE_TRACE
-	LOG(("Retrieve %s (%x, %s, %p)", url, flags, referer, post));
+	LOG(("Retrieve %s (%x, %s, %p)", nsurl_access(url), flags, referer==NULL?"":nsurl_access(referer), post));
 #endif
 
 	/**
diff --git a/gtk/llcache.c b/gtk/llcache.c
index 3587c0d..e6bf7aa 100644
--- a/gtk/llcache.c
+++ b/gtk/llcache.c
@@ -16,6 +16,10 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+/** \file
+ * Low-level resource cache persistant storage implementation.
+ */
+
 #include "utils/nsurl.h"
 #include "utils/log.h"
 #include "desktop/gui.h"


commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=a96db42291cd6cbc806aa20fc063151e8475d5a6
commit a96db42291cd6cbc806aa20fc063151e8475d5a6
Author: Vincent Sanders <vince at netsurf-browser.org>
Commit: Vincent Sanders <vince at netsurf-browser.org>

    improve frontend operation interface

diff --git a/content/llcache.c b/content/llcache.c
index 7aa02ab..79650b1 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -34,7 +34,7 @@
 #include "desktop/gui_factory.h"
 
 #include "content/fetch.h"
-#include "content/llcache.h"
+#include "content/llcache_private.h"
 #include "content/urldb.h"
 
 /** Define to enable tracing of llcache operations. */
@@ -93,27 +93,6 @@ typedef struct {
 	bool outstanding_query;		/**< Waiting for a query response */
 } llcache_fetch_ctx;
 
-typedef enum {
-	LLCACHE_VALIDATE_FRESH,		/**< Only revalidate if not fresh */
-	LLCACHE_VALIDATE_ALWAYS,	/**< Always revalidate */
-	LLCACHE_VALIDATE_ONCE		/**< Revalidate once only */
-} llcache_validate;
-
-/** Cache control data */
-typedef struct {
-	time_t req_time;	/**< Time of request */
-	time_t res_time;	/**< Time of response */
-	time_t fin_time;	/**< Time of request completion */
-	time_t date;		/**< Date: response header */
-	time_t expires;		/**< Expires: response header */
-#define INVALID_AGE -1
-	int age;		/**< Age: response header */
-	int max_age;		/**< Max-Age Cache-control parameter */
-	llcache_validate no_cache;	/**< No-Cache Cache-control parameter */
-	char *etag;		/**< Etag: response header */
-	time_t last_modified;	/**< Last-Modified: response header */
-} llcache_cache_control;
-
 /** Representation of a fetch header */
 typedef struct {
 	char *name;		/**< Header name */
@@ -1051,7 +1030,7 @@ llcache_persist_retrieve(llcache_object *object)
 
 	/* Source data for the object may be in the persiatant store */
 	return guit->llcache->retrieve(object->url,
-				       NULL,
+				       &object->cache,
 				       &object->source_data,
 				       &object->source_len);
 }
@@ -1781,7 +1760,7 @@ static void llcache_persist(void *p)
 		    (remaining_lifetime > LLCACHE_MIN_DISC_LIFETIME)) {
 			/* ok found an object to write */
 			ret = guit->llcache->persist(object->url,
-						 remaining_lifetime,
+						 &object->cache,
 						 object->source_data,
 						 object->source_len);
 			if (ret != NSERROR_OK) {
diff --git a/content/llcache.h b/content/llcache.h
index 1faba81..3d8232c 100644
--- a/content/llcache.h
+++ b/content/llcache.h
@@ -131,12 +131,6 @@ typedef struct {
 	} data;
 } llcache_query;
 
-/** operation table */
-struct gui_llcache_table {
-	nserror (*persist)(struct nsurl *url, int remaining, const uint8_t *data, const size_t datalen);
-	nserror (*retrieve)(struct nsurl *url, int *remaining_out, uint8_t **data_out, size_t *datalen_out);
-};
-
 /**
  * Response handler for fetch-related queries
  *
diff --git a/content/llcache_private.h b/content/llcache_private.h
new file mode 100644
index 0000000..926773b
--- /dev/null
+++ b/content/llcache_private.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2014 Vincent Sanders <vince at netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** \file
+ * Low-level resource cache private interface
+ */
+
+#ifndef NETSURF_CONTENT_LLCACHE_PRIVATE_H_
+#define NETSURF_CONTENT_LLCACHE_PRIVATE_H_
+
+#include "content/llcache.h"
+
+/** validation control */
+typedef enum {
+	LLCACHE_VALIDATE_FRESH,		/**< Only revalidate if not fresh */
+	LLCACHE_VALIDATE_ALWAYS,	/**< Always revalidate */
+	LLCACHE_VALIDATE_ONCE		/**< Revalidate once only */
+} llcache_validate;
+
+/** cache control value for invalid age */
+#define INVALID_AGE -1
+
+/** Cache control data */
+typedef struct {
+	time_t req_time;	/**< Time of request */
+	time_t res_time;	/**< Time of response */
+	time_t fin_time;	/**< Time of request completion */
+	time_t date;		/**< Date: response header */
+	time_t expires;		/**< Expires: response header */
+	int age;		/**< Age: response header */
+	int max_age;		/**< Max-Age Cache-control parameter */
+	llcache_validate no_cache;	/**< No-Cache Cache-control parameter */
+	char *etag;		/**< Etag: response header */
+	time_t last_modified;	/**< Last-Modified: response header */
+} llcache_cache_control;
+
+/** operation table */
+struct gui_llcache_table {
+	nserror (*persist)(struct nsurl *url, llcache_cache_control *cache_control, const uint8_t *data, const size_t datalen);
+	nserror (*retrieve)(struct nsurl *url, llcache_cache_control *cache_control, uint8_t **data, size_t *datalen);
+};
+
+#endif
diff --git a/desktop/gui_factory.c b/desktop/gui_factory.c
index e7d2994..37fee39 100644
--- a/desktop/gui_factory.c
+++ b/desktop/gui_factory.c
@@ -17,6 +17,8 @@
  */
 
 #include "content/hlcache.h"
+#include "content/llcache_private.h"
+
 #include "desktop/download.h"
 #include "desktop/gui_factory.h"
 
@@ -343,12 +345,12 @@ static nserror verify_utf8_register(struct gui_utf8_table *gut)
 	return NSERROR_OK;
 }
 
-static nserror gui_default_persist(nsurl *url, int remaining, const uint8_t *data, const size_t datalen)
+static nserror gui_default_persist(nsurl *url, llcache_cache_control *cache_control, const uint8_t *data, const size_t datalen)
 {
 	return NSERROR_SAVE_FAILED;
 }
 
-static nserror gui_default_retrieve(nsurl *url, int *remaining_out, uint8_t **data_out, size_t *datalen_out)
+static nserror gui_default_retrieve(nsurl *url, llcache_cache_control *cache_control, uint8_t **data_out, size_t *datalen_out)
 {
 	return NSERROR_NOT_FOUND;
 }
diff --git a/gtk/llcache.c b/gtk/llcache.c
index ef00641..3587c0d 100644
--- a/gtk/llcache.c
+++ b/gtk/llcache.c
@@ -19,19 +19,19 @@
 #include "utils/nsurl.h"
 #include "utils/log.h"
 #include "desktop/gui.h"
-#include "content/llcache.h"
+#include "content/llcache_private.h"
 
 #include "gtk/llcache.h"
 
 static nserror
-persist(nsurl *url, int remaining, const uint8_t *data, const size_t datalen)
+persist(nsurl *url, llcache_cache_control *cache_control, const uint8_t *data, const size_t datalen)
 {
 	LOG(("Writing cache file for url:%s", nsurl_access(url)));
 	return NSERROR_OK;
 }
 
 static nserror
-retrieve(nsurl *url, int *remaining_out, uint8_t **data_out, size_t *datalen_out)
+retrieve(nsurl *url, llcache_cache_control *cache_control, uint8_t **data_out, size_t *datalen_out)
 {
 	return NSERROR_NOT_FOUND;
 }


commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=839c50a0d012d093d97db5ae28b9d9a114f8404c
commit 839c50a0d012d093d97db5ae28b9d9a114f8404c
Author: Vincent Sanders <vince at netsurf-browser.org>
Commit: Vincent Sanders <vince at netsurf-browser.org>

    may teh object retrival from persistant storage much more obvious

diff --git a/content/llcache.c b/content/llcache.c
index 49a8ccd..7aa02ab 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -1028,6 +1028,35 @@ static nserror llcache_object_remove_from_list(llcache_object *object,
 }
 
 /**
+ * Retrieve source data for an object from persistant store if necessary.
+ *
+ * If an objects source data has been placed in the persistant store
+ * and the in memory copy freed this will attempt to retrive the
+ * source data.
+ *
+ * @param object the object to operate on.
+ *
+ */
+static nserror
+llcache_persist_retrieve(llcache_object *object)
+{
+	/* ensure the source data is present if necessary */
+	if ((object->source_data != NULL) ||
+	    (object->store_state != LLCACHE_STORE_DISC)) {
+		/* source data does not require retriving from
+		 * persistant store.
+		 */
+		return NSERROR_OK;
+	}
+
+	/* Source data for the object may be in the persiatant store */
+	return guit->llcache->retrieve(object->url,
+				       NULL,
+				       &object->source_data,
+				       &object->source_len);
+}
+
+/**
  * Retrieve a potentially cached object
  *
  * \param url		  URL of object to retrieve
@@ -1050,127 +1079,132 @@ llcache_object_retrieve_from_cache(nsurl *url,
 	llcache_object *obj, *newest = NULL;
 
 #ifdef LLCACHE_TRACE
-	LOG(("Searching cache for %s (%x %s %p)", url, flags, referer, post));
+	LOG(("Searching cache for %s (%x %s %p)",
+	     nsurl_access(url), flags, nsurl_access(referer), post));
 #endif
 
 	/* Search for the most recently fetched matching object */
 	for (obj = llcache->cached_objects; obj != NULL; obj = obj->next) {
 
 		if ((newest == NULL ||
-				obj->cache.req_time > newest->cache.req_time) &&
-				nsurl_compare(obj->url, url,
-						NSURL_COMPLETE) == true) {
+		     obj->cache.req_time > newest->cache.req_time) &&
+		    nsurl_compare(obj->url, url,
+				  NSURL_COMPLETE) == true) {
 			newest = obj;
 		}
 	}
 
-	if (newest != NULL && llcache_object_is_fresh(newest)) {
-		/* Found a suitable object, and it's still fresh, so use it */
-		obj = newest;
+	if ((newest != NULL) && (llcache_object_is_fresh(newest))) {
+		/* Found a suitable object, and it's still fresh */
 
 #ifdef LLCACHE_TRACE
-		LOG(("Found fresh %p", obj));
+		LOG(("Found fresh %p", newest));
 #endif
 
 		/* The client needs to catch up with the object's state.
 		 * This will occur the next time that llcache_poll is called.
 		 */
 
-		/* the objects source data may be in the persiatant store */
-		if ((obj->store_state == LLCACHE_STORE_DISC) &&
-		    (obj->source_data == NULL)) {
-			int remaining;
-			error = guit->llcache->retrieve(obj->url,
-							&remaining,
-							&obj->source_data,
-							&obj->source_len);
-			if (error != NSERROR_OK) {
-				/* persistant store failed, destroy
-				 * cache object and re-retch
-				 */
-#ifdef LLCACHE_TRACE
-				LOG(("Persistant retrival failed for %p", obj));
-#endif
+		/* ensure the source data is present */
+		error = llcache_persist_retrieve(newest);
+		if (error == NSERROR_OK) {
+			/* source data was sucessfully retrived from
+			 * persistant store
+			 */
+			*result = newest;
 
-				llcache_object_remove_from_list(obj,
-						&llcache->cached_objects);
-				llcache_object_destroy(obj);
+			return NSERROR_OK;
+		}
 
-				/* Create new object */
-				error = llcache_object_new(url, &obj);
-				if (error != NSERROR_OK)
-					return error;
+		/* retrival of source data from persistant store
+		 * failed, destroy cache object and fall though to
+		 * cache miss to re-retch
+		 */
+#ifdef LLCACHE_TRACE
+		LOG(("Persistant retrival failed for %p", newest));
+#endif
 
-				/* Attempt to kick-off fetch */
-				error = llcache_object_fetch(obj, flags,
-							     referer, post,
-							     redirect_count);
-				if (error != NSERROR_OK) {
-					llcache_object_destroy(obj);
-					return error;
-				}
+		llcache_object_remove_from_list(newest,	&llcache->cached_objects);
+		llcache_object_destroy(newest);
 
-				/* Add new object to cache */
-				llcache_object_add_to_list(obj, &llcache->cached_objects);
-			}
-		}
 	} else if (newest != NULL) {
 		/* Found a candidate object but it needs freshness validation */
 
-		/* Create a new object */
-		error = llcache_object_new(url, &obj);
-		if (error != NSERROR_OK)
-			return error;
+		/* ensure the source data is present */
+		error = llcache_persist_retrieve(newest);
+		if (error == NSERROR_OK) {
+
+			/* Create a new object */
+			error = llcache_object_new(url, &obj);
+			if (error != NSERROR_OK)
+				return error;
 
 #ifdef LLCACHE_TRACE
-		LOG(("Found candidate %p (%p)", obj, newest));
+			LOG(("Found candidate %p (%p)", obj, newest));
 #endif
 
-		/* Clone candidate's cache data */
-		error = llcache_object_clone_cache_data(newest, obj, true);
-		if (error != NSERROR_OK) {
-			llcache_object_destroy(obj);
-			return error;
-		}
+			/* Clone candidate's cache data */
+			error = llcache_object_clone_cache_data(newest, obj, true);
+			if (error != NSERROR_OK) {
+				llcache_object_destroy(obj);
+				return error;
+			}
 
-		/* Record candidate, so we can fall back if it is still fresh */
-		newest->candidate_count++;
-		obj->candidate = newest;
+			/* Record candidate, so we can fall back if it is still fresh */
+			newest->candidate_count++;
+			obj->candidate = newest;
 
-		/* Attempt to kick-off fetch */
-		error = llcache_object_fetch(obj, flags, referer, post,
-				redirect_count);
-		if (error != NSERROR_OK) {
-			newest->candidate_count--;
-			llcache_object_destroy(obj);
-			return error;
-		}
+			/* Attempt to kick-off fetch */
+			error = llcache_object_fetch(obj, flags, referer, post,
+						     redirect_count);
+			if (error != NSERROR_OK) {
+				newest->candidate_count--;
+				llcache_object_destroy(obj);
+				return error;
+			}
 
-		/* Add new object to cache */
-		llcache_object_add_to_list(obj, &llcache->cached_objects);
-	} else {
-		/* No object found; create a new one */
-		/* Create new object */
-		error = llcache_object_new(url, &obj);
-		if (error != NSERROR_OK)
-			return error;
+			/* Add new object to cache */
+			llcache_object_add_to_list(obj, &llcache->cached_objects);
+
+			*result = obj;
+
+			return NSERROR_OK;
+		}
 
+		/* retrival of source data from persistant store
+		 * failed, destroy cache object and fall though to
+		 * cache miss to re-retch
+		 */
 #ifdef LLCACHE_TRACE
-		LOG(("Not found %p", obj));
+		LOG(("Persistant retrival failed for %p", newest));
 #endif
 
-		/* Attempt to kick-off fetch */
-		error = llcache_object_fetch(obj, flags, referer, post,
-				redirect_count);
-		if (error != NSERROR_OK) {
-			llcache_object_destroy(obj);
-			return error;
-		}
+		llcache_object_remove_from_list(newest,
+						&llcache->cached_objects);
+		llcache_object_destroy(newest);
+	}
 
-		/* Add new object to cache */
-		llcache_object_add_to_list(obj, &llcache->cached_objects);
+	/* No viable object found in cache; create a new object */
+
+	error = llcache_object_new(url, &obj);
+	if (error != NSERROR_OK)
+		return error;
+
+#ifdef LLCACHE_TRACE
+	LOG(("Not found %p", obj));
+#endif
+
+	/* Attempt to kick-off fetch */
+	error = llcache_object_fetch(obj, flags, referer, post,
+				     redirect_count);
+	if (error != NSERROR_OK) {
+		llcache_object_destroy(obj);
+		return error;
 	}
 
+	/* Add new object to cache */
+	llcache_object_add_to_list(obj, &llcache->cached_objects);
+
 	*result = obj;
 
 	return NSERROR_OK;


-----------------------------------------------------------------------

Summary of changes:
 content/llcache.c         |  261 ++++++++++++++++++++++++++++-----------------
 content/llcache.h         |    6 -
 content/llcache_private.h |   58 ++++++++++
 desktop/gui_factory.c     |    6 +-
 gtk/llcache.c             |   10 ++-
 5 files changed, 230 insertions(+), 111 deletions(-)
 create mode 100644 content/llcache_private.h

diff --git a/content/llcache.c b/content/llcache.c
index 49a8ccd..87e1692 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -34,7 +34,7 @@
 #include "desktop/gui_factory.h"
 
 #include "content/fetch.h"
-#include "content/llcache.h"
+#include "content/llcache_private.h"
 #include "content/urldb.h"
 
 /** Define to enable tracing of llcache operations. */
@@ -93,27 +93,6 @@ typedef struct {
 	bool outstanding_query;		/**< Waiting for a query response */
 } llcache_fetch_ctx;
 
-typedef enum {
-	LLCACHE_VALIDATE_FRESH,		/**< Only revalidate if not fresh */
-	LLCACHE_VALIDATE_ALWAYS,	/**< Always revalidate */
-	LLCACHE_VALIDATE_ONCE		/**< Revalidate once only */
-} llcache_validate;
-
-/** Cache control data */
-typedef struct {
-	time_t req_time;	/**< Time of request */
-	time_t res_time;	/**< Time of response */
-	time_t fin_time;	/**< Time of request completion */
-	time_t date;		/**< Date: response header */
-	time_t expires;		/**< Expires: response header */
-#define INVALID_AGE -1
-	int age;		/**< Age: response header */
-	int max_age;		/**< Max-Age Cache-control parameter */
-	llcache_validate no_cache;	/**< No-Cache Cache-control parameter */
-	char *etag;		/**< Etag: response header */
-	time_t last_modified;	/**< Last-Modified: response header */
-} llcache_cache_control;
-
 /** Representation of a fetch header */
 typedef struct {
 	char *name;		/**< Header name */
@@ -1028,6 +1007,79 @@ static nserror llcache_object_remove_from_list(llcache_object *object,
 }
 
 /**
+ * Retrieve source data for an object from persistant store if necessary.
+ *
+ * If an objects source data has been placed in the persistant store
+ * and the in memory copy freed this will attempt to retrive the
+ * source data.
+ *
+ * @param object the object to operate on.
+ *
+ */
+static nserror
+llcache_persist_retrieve(llcache_object *object)
+{
+	/* ensure the source data is present if necessary */
+	if ((object->source_data != NULL) ||
+	    (object->store_state != LLCACHE_STORE_DISC)) {
+		/* source data does not require retriving from
+		 * persistant store.
+		 */
+		return NSERROR_OK;
+	}
+
+	/* Source data for the object may be in the persiatant store */
+	return guit->llcache->retrieve(object->url,
+				       &object->cache,
+				       &object->source_data,
+				       &object->source_len);
+}
+
+static nserror
+llcache_object_persist_fetch(llcache_object *object,
+			     uint32_t flags,
+			     nsurl *referer,
+			     const llcache_post_data *post,
+			     uint32_t redirect_count)
+{
+	nserror error;
+	nsurl *referer_clone = NULL;
+	llcache_post_data *post_clone = NULL;
+
+	/* attempt to retrieve object from the cache */
+	error = guit->llcache->retrieve(object->url,
+				       &object->cache,
+				       &object->source_data,
+				       &object->source_len);
+	if (error != NSERROR_OK)
+		return error;
+
+	/* entry came out of cache - need to setup object state */
+	if (post != NULL) {
+		error = llcache_post_data_clone(post, &post_clone);
+		if (error != NSERROR_OK)
+			return error;
+	}
+
+	if (referer != NULL)
+		referer_clone = nsurl_ref(referer);
+
+	object->fetch.flags = flags;
+	object->fetch.referer = referer_clone;
+	object->fetch.post = post_clone;
+	object->fetch.redirect_count = redirect_count;
+
+	/* fetch is "finished" */
+	object->fetch.state = LLCACHE_FETCH_COMPLETE;
+	object->fetch.fetch = NULL;
+
+	object->store_state = LLCACHE_STORE_DISC;
+	object->source_alloc = object->source_len;
+
+	return NSERROR_OK;
+}
+
+/**
  * Retrieve a potentially cached object
  *
  * \param url		  URL of object to retrieve
@@ -1050,127 +1102,136 @@ llcache_object_retrieve_from_cache(nsurl *url,
 	llcache_object *obj, *newest = NULL;
 
 #ifdef LLCACHE_TRACE
-	LOG(("Searching cache for %s (%x %s %p)", url, flags, referer, post));
+	LOG(("Searching cache for %s (%x %s %p)",
+	     nsurl_access(url), flags, referer==NULL?"":nsurl_access(referer), post));
 #endif
 
 	/* Search for the most recently fetched matching object */
 	for (obj = llcache->cached_objects; obj != NULL; obj = obj->next) {
 
 		if ((newest == NULL ||
-				obj->cache.req_time > newest->cache.req_time) &&
-				nsurl_compare(obj->url, url,
-						NSURL_COMPLETE) == true) {
+		     obj->cache.req_time > newest->cache.req_time) &&
+		    nsurl_compare(obj->url, url,
+				  NSURL_COMPLETE) == true) {
 			newest = obj;
 		}
 	}
 
-	if (newest != NULL && llcache_object_is_fresh(newest)) {
-		/* Found a suitable object, and it's still fresh, so use it */
-		obj = newest;
+	if ((newest != NULL) && (llcache_object_is_fresh(newest))) {
+		/* Found a suitable object, and it's still fresh */
 
 #ifdef LLCACHE_TRACE
-		LOG(("Found fresh %p", obj));
+		LOG(("Found fresh %p", newest));
 #endif
 
 		/* The client needs to catch up with the object's state.
 		 * This will occur the next time that llcache_poll is called.
 		 */
 
-		/* the objects source data may be in the persiatant store */
-		if ((obj->store_state == LLCACHE_STORE_DISC) &&
-		    (obj->source_data == NULL)) {
-			int remaining;
-			error = guit->llcache->retrieve(obj->url,
-							&remaining,
-							&obj->source_data,
-							&obj->source_len);
-			if (error != NSERROR_OK) {
-				/* persistant store failed, destroy
-				 * cache object and re-retch
-				 */
-#ifdef LLCACHE_TRACE
-				LOG(("Persistant retrival failed for %p", obj));
-#endif
+		/* ensure the source data is present */
+		error = llcache_persist_retrieve(newest);
+		if (error == NSERROR_OK) {
+			/* source data was sucessfully retrived from
+			 * persistant store
+			 */
+			*result = newest;
 
-				llcache_object_remove_from_list(obj,
-						&llcache->cached_objects);
-				llcache_object_destroy(obj);
+			return NSERROR_OK;
+		}
 
-				/* Create new object */
-				error = llcache_object_new(url, &obj);
-				if (error != NSERROR_OK)
-					return error;
+		/* retrival of source data from persistant store
+		 * failed, destroy cache object and fall though to
+		 * cache miss to re-retch
+		 */
+#ifdef LLCACHE_TRACE
+		LOG(("Persistant retrival failed for %p", newest));
+#endif
 
-				/* Attempt to kick-off fetch */
-				error = llcache_object_fetch(obj, flags,
-							     referer, post,
-							     redirect_count);
-				if (error != NSERROR_OK) {
-					llcache_object_destroy(obj);
-					return error;
-				}
+		llcache_object_remove_from_list(newest,	&llcache->cached_objects);
+		llcache_object_destroy(newest);
 
-				/* Add new object to cache */
-				llcache_object_add_to_list(obj, &llcache->cached_objects);
-			}
-		}
 	} else if (newest != NULL) {
 		/* Found a candidate object but it needs freshness validation */
 
-		/* Create a new object */
-		error = llcache_object_new(url, &obj);
-		if (error != NSERROR_OK)
-			return error;
+		/* ensure the source data is present */
+		error = llcache_persist_retrieve(newest);
+		if (error == NSERROR_OK) {
+
+			/* Create a new object */
+			error = llcache_object_new(url, &obj);
+			if (error != NSERROR_OK)
+				return error;
 
 #ifdef LLCACHE_TRACE
-		LOG(("Found candidate %p (%p)", obj, newest));
+			LOG(("Found candidate %p (%p)", obj, newest));
 #endif
 
-		/* Clone candidate's cache data */
-		error = llcache_object_clone_cache_data(newest, obj, true);
-		if (error != NSERROR_OK) {
-			llcache_object_destroy(obj);
-			return error;
-		}
+			/* Clone candidate's cache data */
+			error = llcache_object_clone_cache_data(newest, obj, true);
+			if (error != NSERROR_OK) {
+				llcache_object_destroy(obj);
+				return error;
+			}
 
-		/* Record candidate, so we can fall back if it is still fresh */
-		newest->candidate_count++;
-		obj->candidate = newest;
+			/* Record candidate, so we can fall back if it is still fresh */
+			newest->candidate_count++;
+			obj->candidate = newest;
 
-		/* Attempt to kick-off fetch */
-		error = llcache_object_fetch(obj, flags, referer, post,
-				redirect_count);
-		if (error != NSERROR_OK) {
-			newest->candidate_count--;
-			llcache_object_destroy(obj);
-			return error;
+			/* Attempt to kick-off fetch */
+			error = llcache_object_fetch(obj, flags, referer, post,
+						     redirect_count);
+			if (error != NSERROR_OK) {
+				newest->candidate_count--;
+				llcache_object_destroy(obj);
+				return error;
+			}
+
+			/* Add new object to cache */
+			llcache_object_add_to_list(obj, &llcache->cached_objects);
+
+			*result = obj;
+
+			return NSERROR_OK;
 		}
 
-		/* Add new object to cache */
-		llcache_object_add_to_list(obj, &llcache->cached_objects);
-	} else {
-		/* No object found; create a new one */
-		/* Create new object */
-		error = llcache_object_new(url, &obj);
-		if (error != NSERROR_OK)
-			return error;
+		/* retrival of source data from persistant store
+		 * failed, destroy cache object and fall though to
+		 * cache miss to re-retch
+		 */
+#ifdef LLCACHE_TRACE
+		LOG(("Persistant retrival failed for %p", newest));
+#endif
 
+		llcache_object_remove_from_list(newest,
+						&llcache->cached_objects);
+		llcache_object_destroy(newest);
+	} else {
 #ifdef LLCACHE_TRACE
-		LOG(("Not found %p", obj));
+		LOG(("Not found"));
 #endif
+	}
 
+	/* No viable object found in cache; create a new object */
+	error = llcache_object_new(url, &obj);
+	if (error != NSERROR_OK)
+		return error;
+
+	/* attempt to "fetch" object from persistant store first */
+	error = llcache_object_persist_fetch(obj, flags, referer, post,
+					     redirect_count);
+	if (error != NSERROR_OK) {
 		/* Attempt to kick-off fetch */
 		error = llcache_object_fetch(obj, flags, referer, post,
-				redirect_count);
+					     redirect_count);
 		if (error != NSERROR_OK) {
 			llcache_object_destroy(obj);
 			return error;
 		}
-
-		/* Add new object to cache */
-		llcache_object_add_to_list(obj, &llcache->cached_objects);
 	}
 
+	/* Add new object to cache */
+	llcache_object_add_to_list(obj, &llcache->cached_objects);
+
 	*result = obj;
 
 	return NSERROR_OK;
@@ -1197,7 +1258,7 @@ static nserror llcache_object_retrieve(nsurl *url, uint32_t flags,
 	nsurl *defragmented_url;
 
 #ifdef LLCACHE_TRACE
-	LOG(("Retrieve %s (%x, %s, %p)", url, flags, referer, post));
+	LOG(("Retrieve %s (%x, %s, %p)", nsurl_access(url), flags, referer==NULL?"":nsurl_access(referer), post));
 #endif
 
 	/**
@@ -1747,7 +1808,7 @@ static void llcache_persist(void *p)
 		    (remaining_lifetime > LLCACHE_MIN_DISC_LIFETIME)) {
 			/* ok found an object to write */
 			ret = guit->llcache->persist(object->url,
-						 remaining_lifetime,
+						 &object->cache,
 						 object->source_data,
 						 object->source_len);
 			if (ret != NSERROR_OK) {
diff --git a/content/llcache.h b/content/llcache.h
index 1faba81..3d8232c 100644
--- a/content/llcache.h
+++ b/content/llcache.h
@@ -131,12 +131,6 @@ typedef struct {
 	} data;
 } llcache_query;
 
-/** operation table */
-struct gui_llcache_table {
-	nserror (*persist)(struct nsurl *url, int remaining, const uint8_t *data, const size_t datalen);
-	nserror (*retrieve)(struct nsurl *url, int *remaining_out, uint8_t **data_out, size_t *datalen_out);
-};
-
 /**
  * Response handler for fetch-related queries
  *
diff --git a/content/llcache_private.h b/content/llcache_private.h
new file mode 100644
index 0000000..926773b
--- /dev/null
+++ b/content/llcache_private.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2014 Vincent Sanders <vince at netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** \file
+ * Low-level resource cache private interface
+ */
+
+#ifndef NETSURF_CONTENT_LLCACHE_PRIVATE_H_
+#define NETSURF_CONTENT_LLCACHE_PRIVATE_H_
+
+#include "content/llcache.h"
+
+/** validation control */
+typedef enum {
+	LLCACHE_VALIDATE_FRESH,		/**< Only revalidate if not fresh */
+	LLCACHE_VALIDATE_ALWAYS,	/**< Always revalidate */
+	LLCACHE_VALIDATE_ONCE		/**< Revalidate once only */
+} llcache_validate;
+
+/** cache control value for invalid age */
+#define INVALID_AGE -1
+
+/** Cache control data */
+typedef struct {
+	time_t req_time;	/**< Time of request */
+	time_t res_time;	/**< Time of response */
+	time_t fin_time;	/**< Time of request completion */
+	time_t date;		/**< Date: response header */
+	time_t expires;		/**< Expires: response header */
+	int age;		/**< Age: response header */
+	int max_age;		/**< Max-Age Cache-control parameter */
+	llcache_validate no_cache;	/**< No-Cache Cache-control parameter */
+	char *etag;		/**< Etag: response header */
+	time_t last_modified;	/**< Last-Modified: response header */
+} llcache_cache_control;
+
+/** operation table */
+struct gui_llcache_table {
+	nserror (*persist)(struct nsurl *url, llcache_cache_control *cache_control, const uint8_t *data, const size_t datalen);
+	nserror (*retrieve)(struct nsurl *url, llcache_cache_control *cache_control, uint8_t **data, size_t *datalen);
+};
+
+#endif
diff --git a/desktop/gui_factory.c b/desktop/gui_factory.c
index e7d2994..37fee39 100644
--- a/desktop/gui_factory.c
+++ b/desktop/gui_factory.c
@@ -17,6 +17,8 @@
  */
 
 #include "content/hlcache.h"
+#include "content/llcache_private.h"
+
 #include "desktop/download.h"
 #include "desktop/gui_factory.h"
 
@@ -343,12 +345,12 @@ static nserror verify_utf8_register(struct gui_utf8_table *gut)
 	return NSERROR_OK;
 }
 
-static nserror gui_default_persist(nsurl *url, int remaining, const uint8_t *data, const size_t datalen)
+static nserror gui_default_persist(nsurl *url, llcache_cache_control *cache_control, const uint8_t *data, const size_t datalen)
 {
 	return NSERROR_SAVE_FAILED;
 }
 
-static nserror gui_default_retrieve(nsurl *url, int *remaining_out, uint8_t **data_out, size_t *datalen_out)
+static nserror gui_default_retrieve(nsurl *url, llcache_cache_control *cache_control, uint8_t **data_out, size_t *datalen_out)
 {
 	return NSERROR_NOT_FOUND;
 }
diff --git a/gtk/llcache.c b/gtk/llcache.c
index ef00641..e6bf7aa 100644
--- a/gtk/llcache.c
+++ b/gtk/llcache.c
@@ -16,22 +16,26 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+/** \file
+ * Low-level resource cache persistant storage implementation.
+ */
+
 #include "utils/nsurl.h"
 #include "utils/log.h"
 #include "desktop/gui.h"
-#include "content/llcache.h"
+#include "content/llcache_private.h"
 
 #include "gtk/llcache.h"
 
 static nserror
-persist(nsurl *url, int remaining, const uint8_t *data, const size_t datalen)
+persist(nsurl *url, llcache_cache_control *cache_control, const uint8_t *data, const size_t datalen)
 {
 	LOG(("Writing cache file for url:%s", nsurl_access(url)));
 	return NSERROR_OK;
 }
 
 static nserror
-retrieve(nsurl *url, int *remaining_out, uint8_t **data_out, size_t *datalen_out)
+retrieve(nsurl *url, llcache_cache_control *cache_control, uint8_t **data_out, size_t *datalen_out)
 {
 	return NSERROR_NOT_FOUND;
 }


-- 
NetSurf Browser



More information about the netsurf-commits mailing list