[evince] libdocument: when LOAD_FLAG_NO_CACHE is present, load the cache on demand when needed



commit 8fca313485ea19b8b68b71ec703a36fa014ad837
Author: Carlos Garcia Campos <carlosgc gnome org>
Date:   Sun Mar 26 12:38:08 2017 +0200

    libdocument: when LOAD_FLAG_NO_CACHE is present, load the cache on demand when needed
    
    The cache is an optimization to avoid taking locks required when using
    the backends, but it's also required for some of the features like
    getting max/min page sizes or finding a page by its label. This patch
    moves the n_pages and info out of what we consider the cache, because
    they should always be fast to initialze during the load. The rest of the
    cache information is only loaded when actually required when using the
    no cache load flag.

 libdocument/ev-document.c |   99 ++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 88 insertions(+), 11 deletions(-)
---
diff --git a/libdocument/ev-document.c b/libdocument/ev-document.c
index 18c7a0b..de0e1fc 100644
--- a/libdocument/ev-document.c
+++ b/libdocument/ev-document.c
@@ -41,6 +41,7 @@ struct _EvDocumentPrivate
        gchar          *uri;
        guint64         file_size;
 
+       gboolean        cache_loaded;
        gint            n_pages;
 
        gboolean        uniform;
@@ -199,8 +200,7 @@ ev_document_setup_cache (EvDocument *document)
         /* Cache some info about the document to avoid
          * going to the backends since it requires locks
          */
-       priv->info = _ev_document_get_info (document);
-        priv->n_pages = _ev_document_get_n_pages (document);
+       priv->cache_loaded = TRUE;
 
         for (i = 0; i < priv->n_pages; i++) {
                 EvPage     *page = ev_document_get_page (document, i);
@@ -334,7 +334,9 @@ ev_document_load (EvDocument  *document,
                                             "Internal error in backend");
                }
        } else {
-                ev_document_setup_cache (document);
+               document->priv->info = _ev_document_get_info (document);
+               document->priv->n_pages = _ev_document_get_n_pages (document);
+               ev_document_setup_cache (document);
                document->priv->uri = g_strdup (uri);
                document->priv->file_size = _ev_document_get_size (uri);
                ev_document_initialize_synctex (document, uri);
@@ -382,6 +384,9 @@ ev_document_load_stream (EvDocument         *document,
         if (!klass->load_stream (document, stream, flags, cancellable, error))
                 return FALSE;
 
+       document->priv->info = _ev_document_get_info (document);
+       document->priv->n_pages = _ev_document_get_n_pages (document);
+
         if (!(flags & EV_DOCUMENT_LOAD_FLAG_NO_CACHE))
                 ev_document_setup_cache (document);
 
@@ -427,6 +432,9 @@ ev_document_load_gfile (EvDocument         *document,
         if (!klass->load_gfile (document, file, flags, cancellable, error))
                 return FALSE;
 
+       document->priv->info = _ev_document_get_info (document);
+       document->priv->n_pages = _ev_document_get_n_pages (document);
+
         if (!(flags & EV_DOCUMENT_LOAD_FLAG_NO_CACHE))
                 ev_document_setup_cache (document);
 
@@ -652,17 +660,31 @@ ev_document_get_page_size (EvDocument *document,
                           double     *width,
                           double     *height)
 {
+       EvDocumentPrivate *priv;
+
        g_return_if_fail (EV_IS_DOCUMENT (document));
        g_return_if_fail (page_index >= 0 || page_index < document->priv->n_pages);
 
-       if (width)
-               *width = document->priv->uniform ?
-                       document->priv->uniform_width :
-                       document->priv->page_sizes[page_index].width;
-       if (height)
-               *height = document->priv->uniform ?
-                       document->priv->uniform_height :
-                       document->priv->page_sizes[page_index].height;
+       priv = document->priv;
+
+       if (priv->cache_loaded) {
+               if (width)
+                       *width = priv->uniform ?
+                               priv->uniform_width :
+                               priv->page_sizes[page_index].width;
+               if (height)
+                       *height = priv->uniform ?
+                               priv->uniform_height :
+                               priv->page_sizes[page_index].height;
+       } else {
+               EvPage *page;
+
+               g_mutex_lock (&ev_doc_mutex);
+               page = ev_document_get_page (document, page_index);
+               _ev_document_get_page_size (document, page, width, height);
+               g_object_unref (page);
+               g_mutex_unlock (&ev_doc_mutex);
+       }
 }
 
 static gchar *
@@ -682,6 +704,19 @@ ev_document_get_page_label (EvDocument *document,
        g_return_val_if_fail (EV_IS_DOCUMENT (document), NULL);
        g_return_val_if_fail (page_index >= 0 || page_index < document->priv->n_pages, NULL);
 
+       if (!document->priv->cache_loaded) {
+               EvPage *page;
+               gchar *page_label;
+
+               g_mutex_lock (&ev_doc_mutex);
+               page = ev_document_get_page (document, page_index);
+               page_label = _ev_document_get_page_label (document, page);
+               g_object_unref (page);
+               g_mutex_unlock (&ev_doc_mutex);
+
+               return page_label ? page_label : g_strdup_printf ("%d", page_index + 1);
+       }
+
        return (document->priv->page_labels && document->priv->page_labels[page_index]) ?
                g_strdup (document->priv->page_labels[page_index]) :
                g_strdup_printf ("%d", page_index + 1);
@@ -805,6 +840,12 @@ ev_document_is_page_size_uniform (EvDocument *document)
 {
        g_return_val_if_fail (EV_IS_DOCUMENT (document), TRUE);
 
+       if (!document->priv->cache_loaded) {
+               g_mutex_lock (&ev_doc_mutex);
+               ev_document_setup_cache (document);
+               g_mutex_unlock (&ev_doc_mutex);
+       }
+
        return document->priv->uniform;
 }
 
@@ -815,6 +856,12 @@ ev_document_get_max_page_size (EvDocument *document,
 {
        g_return_if_fail (EV_IS_DOCUMENT (document));
 
+       if (!document->priv->cache_loaded) {
+               g_mutex_lock (&ev_doc_mutex);
+               ev_document_setup_cache (document);
+               g_mutex_unlock (&ev_doc_mutex);
+       }
+
        if (width)
                *width = document->priv->max_width;
        if (height)
@@ -828,6 +875,12 @@ ev_document_get_min_page_size (EvDocument *document,
 {
        g_return_if_fail (EV_IS_DOCUMENT (document));
 
+       if (!document->priv->cache_loaded) {
+               g_mutex_lock (&ev_doc_mutex);
+               ev_document_setup_cache (document);
+               g_mutex_unlock (&ev_doc_mutex);
+       }
+
        if (width)
                *width = document->priv->min_width;
        if (height)
@@ -839,6 +892,12 @@ ev_document_check_dimensions (EvDocument *document)
 {
        g_return_val_if_fail (EV_IS_DOCUMENT (document), FALSE);
 
+       if (!document->priv->cache_loaded) {
+               g_mutex_lock (&ev_doc_mutex);
+               ev_document_setup_cache (document);
+               g_mutex_unlock (&ev_doc_mutex);
+       }
+
        return (document->priv->max_width > 0 && document->priv->max_height > 0);
 }
 
@@ -855,6 +914,12 @@ ev_document_get_max_label_len (EvDocument *document)
 {
        g_return_val_if_fail (EV_IS_DOCUMENT (document), -1);
 
+       if (!document->priv->cache_loaded) {
+               g_mutex_lock (&ev_doc_mutex);
+               ev_document_setup_cache (document);
+               g_mutex_unlock (&ev_doc_mutex);
+       }
+
        return document->priv->max_label;
 }
 
@@ -863,6 +928,12 @@ ev_document_has_text_page_labels (EvDocument *document)
 {
        g_return_val_if_fail (EV_IS_DOCUMENT (document), FALSE);
 
+       if (!document->priv->cache_loaded) {
+               g_mutex_lock (&ev_doc_mutex);
+               ev_document_setup_cache (document);
+               g_mutex_unlock (&ev_doc_mutex);
+       }
+
        return document->priv->page_labels != NULL;
 }
 
@@ -880,6 +951,12 @@ ev_document_find_page_by_label (EvDocument  *document,
        g_return_val_if_fail (page_label != NULL, FALSE);
        g_return_val_if_fail (page_index != NULL, FALSE);
 
+       if (!document->priv->cache_loaded) {
+               g_mutex_lock (&ev_doc_mutex);
+               ev_document_setup_cache (document);
+               g_mutex_unlock (&ev_doc_mutex);
+       }
+
         /* First, look for a literal label match */
        for (i = 0; priv->page_labels && i < priv->n_pages; i ++) {
                if (priv->page_labels[i] != NULL &&


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]