diff options
author | Adrian Lang <mail@adrianlang.de> | 2011-05-08 20:55:40 +0200 |
---|---|---|
committer | Adrian Lang <mail@adrianlang.de> | 2011-05-08 20:55:40 +0200 |
commit | 9199737c351d653a1d384cb50ed0d185f6512826 (patch) | |
tree | 2da4dbc0b92a72c767712549b6d90f53b0a3605e /inc/parserutils.php | |
parent | e68653d8ef3df043761e4042c563d65731f9b9c6 (diff) | |
parent | 2b537ba8dc1863d603770c208ae4f91d4d0877b9 (diff) | |
download | rpg-9199737c351d653a1d384cb50ed0d185f6512826.tar.gz rpg-9199737c351d653a1d384cb50ed0d185f6512826.tar.bz2 |
Merge branch 'master' into stable
Conflicts:
doku.php
Diffstat (limited to 'inc/parserutils.php')
-rw-r--r-- | inc/parserutils.php | 124 |
1 files changed, 77 insertions, 47 deletions
diff --git a/inc/parserutils.php b/inc/parserutils.php index 9b2d99328..abba89b5a 100644 --- a/inc/parserutils.php +++ b/inc/parserutils.php @@ -10,11 +10,43 @@ if(!defined('DOKU_INC')) die('meh.'); /** - * For how many different pages shall the first heading be loaded from the - * metadata? When this limit is reached the title index is loaded and used for - * all following requests. + * How many pages shall be rendered for getting metadata during one request + * at maximum? Note that this limit isn't respected when METADATA_RENDER_UNLIMITED + * is passed as render parameter to p_get_metadata. */ -if (!defined('P_GET_FIRST_HEADING_METADATA_LIMIT')) define('P_GET_FIRST_HEADING_METADATA_LIMIT', 10); +if (!defined('P_GET_METADATA_RENDER_LIMIT')) define('P_GET_METADATA_RENDER_LIMIT', 5); + +/** Don't render metadata even if it is outdated or doesn't exist */ +define('METADATA_DONT_RENDER', 0); +/** + * Render metadata when the page is really newer or the metadata doesn't exist. + * Uses just a simple check, but should work pretty well for loading simple + * metadata values like the page title and avoids rendering a lot of pages in + * one request. The P_GET_METADATA_RENDER_LIMIT is used in this mode. + * Use this if it is unlikely that the metadata value you are requesting + * does depend e.g. on pages that are included in the current page using + * the include plugin (this is very likely the case for the page title, but + * not for relation references). + */ +define('METADATA_RENDER_USING_SIMPLE_CACHE', 1); +/** + * Render metadata using the metadata cache logic. The P_GET_METADATA_RENDER_LIMIT + * is used in this mode. Use this mode when you are requesting more complex + * metadata. Although this will cause rendering more often it might actually have + * the effect that less current metadata is returned as it is more likely than in + * the simple cache mode that metadata needs to be rendered for all pages at once + * which means that when the metadata for the page is requested that actually needs + * to be updated the limit might have been reached already. + */ +define('METADATA_RENDER_USING_CACHE', 2); +/** + * Render metadata without limiting the number of pages for which metadata is + * rendered. Use this mode with care, normally it should only be used in places + * like the indexer or in cli scripts where the execution time normally isn't + * limited. This can be combined with the simple cache using + * METADATA_RENDER_USING_CACHE | METADATA_RENDER_UNLIMITED. + */ +define('METADATA_RENDER_UNLIMITED', 4); /** * Returns the parsed Wikitext in XHTML for the given id and revision. @@ -229,14 +261,21 @@ function p_get_instructions($text){ * * @param string $id The id of the page the metadata should be returned from * @param string $key The key of the metdata value that shall be read (by default everything) - separate hierarchies by " " like "date created" - * @param boolean $render If the page should be rendererd when the cache can't be used - default true + * @param int $render If the page should be rendererd - possible values: + * METADATA_DONT_RENDER, METADATA_RENDER_USING_SIMPLE_CACHE, METADATA_RENDER_USING_CACHE + * METADATA_RENDER_UNLIMITED (also combined with the previous two options), + * default: METADATA_RENDER_USING_CACHE * @return mixed The requested metadata fields * * @author Esther Brunner <esther@kaffeehaus.ch> * @author Michael Hamann <michael@content-space.de> */ -function p_get_metadata($id, $key='', $render=true){ +function p_get_metadata($id, $key='', $render=METADATA_RENDER_USING_CACHE){ global $ID; + static $render_count = 0; + // track pages that have already been rendered in order to avoid rendering the same page + // again + static $rendered_pages = array(); // cache the current page // Benchmarking shows the current page's metadata is generally the only page metadata @@ -244,14 +283,36 @@ function p_get_metadata($id, $key='', $render=true){ $cache = ($ID == $id); $meta = p_read_metadata($id, $cache); + if (!is_numeric($render)) { + if ($render) { + $render = METADATA_RENDER_USING_SIMPLE_CACHE; + } else { + $render = METADATA_DONT_RENDER; + } + } + // prevent recursive calls in the cache static $recursion = false; - if (!$recursion && $render){ + if (!$recursion && $render != METADATA_DONT_RENDER && !isset($rendered_pages[$id])&& page_exists($id)){ $recursion = true; $cachefile = new cache_renderer($id, wikiFN($id), 'metadata'); - if (page_exists($id) && !$cachefile->useCache()){ + $do_render = false; + if ($render & METADATA_RENDER_UNLIMITED || $render_count < P_GET_METADATA_RENDER_LIMIT) { + if ($render & METADATA_RENDER_USING_SIMPLE_CACHE) { + $pagefn = wikiFN($id); + $metafn = metaFN($id, '.meta'); + if (!@file_exists($metafn) || @filemtime($pagefn) > @filemtime($cachefile->cache)) { + $do_render = true; + } + } elseif (!$cachefile->useCache()){ + $do_render = true; + } + } + if ($do_render) { + ++$render_count; + $rendered_pages[$id] = true; $old_meta = $meta; $meta = p_render_metadata($id, $meta); // only update the file when the metadata has been changed @@ -648,49 +709,18 @@ function & p_get_renderer($mode) { * Gets the first heading from a file * * @param string $id dokuwiki page id - * @param bool $render rerender if first heading not known - * default: true -- must be set to false for calls from the metadata renderer to - * protects against loops and excessive resource usage when pages - * for which only a first heading is required will attempt to - * render metadata for all the pages for which they require first - * headings ... and so on. + * @param int $render rerender if first heading not known + * default: METADATA_RENDER_USING_SIMPLE_CACHE + * Possible values: METADATA_DONT_RENDER, + * METADATA_RENDER_USING_SIMPLE_CACHE, + * METADATA_RENDER_USING_CACHE, + * METADATA_RENDER_UNLIMITED * * @author Andreas Gohr <andi@splitbrain.org> * @author Michael Hamann <michael@content-space.de> */ -function p_get_first_heading($id, $render=true){ - // counter how many titles have been requested using p_get_metadata - static $count = 1; - // the index of all titles, only loaded when many titles are requested - static $title_index = null; - // cache for titles requested using p_get_metadata - static $title_cache = array(); - - $id = cleanID($id); - - // check if this title has already been requested - if (isset($title_cache[$id])) - return $title_cache[$id]; - - // check if already too many titles have been requested and probably - // using the title index is better - if ($count > P_GET_FIRST_HEADING_METADATA_LIMIT) { - if (is_null($title_index)) { - $pages = array_map('rtrim', idx_getIndex('page', '')); - $titles = array_map('rtrim', idx_getIndex('title', '')); - // check for corrupt title index #FS2076 - if(count($pages) != count($titles)){ - $titles = array_fill(0,count($pages),''); - @unlink($conf['indexdir'].'/title.idx'); // will be rebuilt in inc/init.php - } - $title_index = array_combine($pages, $titles); - } - return $title_index[$id]; - } - - ++$count; - $title_cache[$id] = p_get_metadata($id,'title',$render); - return $title_cache[$id]; +function p_get_first_heading($id, $render=METADATA_RENDER_USING_SIMPLE_CACHE){ + return p_get_metadata(cleanID($id),'title',$render); } /** |