Rebuild more things now that it is more performant to do so

Fix #122
This commit is contained in:
Vincent Prouillet 2018-10-06 13:37:06 +02:00
parent cdcebaea26
commit 6843ec5c9c
6 changed files with 49 additions and 91 deletions

View file

@ -244,17 +244,6 @@ impl Section {
self.file.components.is_empty() self.file.components.is_empty()
} }
/// Returns all the paths of the pages belonging to that section
pub fn all_pages_path(&self) -> Vec<PathBuf> {
let paths = vec![];
paths
}
/// Whether the page given belongs to that section
pub fn is_child_page(&self, path: &PathBuf) -> bool {
false
}
/// Creates a vectors of asset URLs. /// Creates a vectors of asset URLs.
fn serialize_assets(&self) -> Vec<String> { fn serialize_assets(&self) -> Vec<String> {
self.assets.iter() self.assets.iter()

View file

@ -101,7 +101,8 @@ impl Library {
self.sections.get_mut(*section_key).unwrap().pages.push(key); self.sections.get_mut(*section_key).unwrap().pages.push(key);
} }
} }
self.sort_sections_pages(None);
self.sort_sections_pages();
let sections = self.paths_to_sections.clone(); let sections = self.paths_to_sections.clone();
let mut sections_weight = HashMap::new(); let mut sections_weight = HashMap::new();
@ -120,17 +121,10 @@ impl Library {
} }
} }
/// Sort all sections pages unless `only` is set. /// Sort all sections pages
/// If `only` is set, only the pages of the section at that specific Path will be rendered. pub fn sort_sections_pages(&mut self) {
pub fn sort_sections_pages(&mut self, only: Option<&Path>) {
let mut updates = HashMap::new(); let mut updates = HashMap::new();
for (key, section) in &self.sections { for (key, section) in &self.sections {
if let Some(p) = only {
if p != section.file.path {
continue;
}
}
let (sorted_pages, cannot_be_sorted_pages) = match section.meta.sort_by { let (sorted_pages, cannot_be_sorted_pages) = match section.meta.sort_by {
SortBy::None => continue, SortBy::None => continue,
SortBy::Date => { SortBy::Date => {
@ -214,6 +208,17 @@ impl Library {
.collect() .collect()
} }
pub fn find_parent_section(&self, path: &Path) -> Option<&Section> {
let page_key = self.paths_to_pages[path];
for s in self.sections.values() {
if s.pages.contains(&page_key) {
return Some(s)
}
}
None
}
pub fn get_section(&self, path: &PathBuf) -> Option<&Section> { pub fn get_section(&self, path: &PathBuf) -> Option<&Section> {
self.sections.get(self.paths_to_sections.get(path).cloned().unwrap_or_default()) self.sections.get(self.paths_to_sections.get(path).cloned().unwrap_or_default())
} }

View file

@ -34,6 +34,7 @@ impl<'a> SerializedTaxonomyItem<'a> {
slug: &item.slug, slug: &item.slug,
permalink: &item.permalink, permalink: &item.permalink,
pages, pages,
} }
} }
} }

View file

@ -12,19 +12,6 @@ use library::{Page, Section};
use front_matter::{PageFrontMatter, SectionFrontMatter}; use front_matter::{PageFrontMatter, SectionFrontMatter};
/// Finds the section that contains the page given if there is one
pub fn find_parent_section<'a>(site: &'a Site, page: &Page) -> Option<&'a Section> {
for section in site.library.sections_values() {
// TODO: remove that, it's wrong now it should check the page key
if section.is_child_page(&page.file.path) {
return Some(section);
}
}
None
}
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum PageChangesNeeded { pub enum PageChangesNeeded {
/// Editing `taxonomies` /// Editing `taxonomies`
@ -106,7 +93,6 @@ fn delete_element(site: &mut Site, path: &Path, is_section: bool) -> Result<()>
if is_section { if is_section {
if let Some(s) = site.library.remove_section(&path.to_path_buf()) { if let Some(s) = site.library.remove_section(&path.to_path_buf()) {
site.permalinks.remove(&s.file.relative); site.permalinks.remove(&s.file.relative);
site.populate_sections();
} }
} else if let Some(p) = site.library.remove_page(&path.to_path_buf()) { } else if let Some(p) = site.library.remove_page(&path.to_path_buf()) {
site.permalinks.remove(&p.file.relative); site.permalinks.remove(&p.file.relative);
@ -114,15 +100,11 @@ fn delete_element(site: &mut Site, path: &Path, is_section: bool) -> Result<()>
if !p.meta.taxonomies.is_empty() { if !p.meta.taxonomies.is_empty() {
site.populate_taxonomies()?; site.populate_taxonomies()?;
} }
}
// if there is a parent section, we will need to re-render it
// most likely
if find_parent_section(site, &p).is_some() {
site.populate_sections(); site.populate_sections();
}
}
// Ensure we have our fn updated so it doesn't contain the permalink(s)/section/page deleted // Ensure we have our fn updated so it doesn't contain the permalink(s)/section/page deleted
site.register_early_global_fns();
site.register_tera_global_fns(); site.register_tera_global_fns();
// Deletion is something that doesn't happen all the time so we // Deletion is something that doesn't happen all the time so we
// don't need to optimise it too much // don't need to optimise it too much
@ -137,9 +119,12 @@ fn handle_section_editing(site: &mut Site, path: &Path) -> Result<()> {
// Updating a section // Updating a section
Some(prev) => { Some(prev) => {
// Copy the section data so we don't end up with an almost empty object // Copy the section data so we don't end up with an almost empty object
site.library.get_section_mut(&pathbuf).unwrap().pages = prev.pages; {
site.library.get_section_mut(&pathbuf).unwrap().ignored_pages = prev.ignored_pages; let s = site.library.get_section_mut(&pathbuf).unwrap();
site.library.get_section_mut(&pathbuf).unwrap().subsections = prev.subsections; s.pages = prev.pages;
s.ignored_pages = prev.ignored_pages;
s.subsections = prev.subsections;
}
if site.library.get_section(&pathbuf).unwrap().meta == prev.meta { if site.library.get_section(&pathbuf).unwrap().meta == prev.meta {
// Front matter didn't change, only content did // Front matter didn't change, only content did
@ -152,7 +137,6 @@ fn handle_section_editing(site: &mut Site, path: &Path) -> Result<()> {
// Sort always comes first if present so the rendering will be fine // Sort always comes first if present so the rendering will be fine
match changes { match changes {
SectionChangesNeeded::Sort => { SectionChangesNeeded::Sort => {
site.sort_sections_pages(Some(path));
site.register_tera_global_fns(); site.register_tera_global_fns();
} }
SectionChangesNeeded::Render => site.render_section(&site.library.get_section(&pathbuf).unwrap(), false)?, SectionChangesNeeded::Render => site.render_section(&site.library.get_section(&pathbuf).unwrap(), false)?,
@ -177,7 +161,7 @@ fn handle_section_editing(site: &mut Site, path: &Path) -> Result<()> {
macro_rules! render_parent_section { macro_rules! render_parent_section {
($site: expr, $path: expr) => { ($site: expr, $path: expr) => {
if let Some(s) = find_parent_section($site, &$site.library.get_page(&$path.to_path_buf()).unwrap()) { if let Some(s) = $site.library.find_parent_section($path) {
$site.render_section(s, false)?; $site.render_section(s, false)?;
}; };
} }
@ -190,6 +174,8 @@ fn handle_page_editing(site: &mut Site, path: &Path) -> Result<()> {
match site.add_page(page, true)? { match site.add_page(page, true)? {
// Updating a page // Updating a page
Some(prev) => { Some(prev) => {
site.populate_sections();
// Front matter didn't change, only content did // Front matter didn't change, only content did
if site.library.get_page(&pathbuf).unwrap().meta == prev.meta { if site.library.get_page(&pathbuf).unwrap().meta == prev.meta {
// Other than the page itself, the summary might be seen // Other than the page itself, the summary might be seen
@ -197,42 +183,24 @@ fn handle_page_editing(site: &mut Site, path: &Path) -> Result<()> {
if site.library.get_page(&pathbuf).unwrap().summary.is_some() { if site.library.get_page(&pathbuf).unwrap().summary.is_some() {
render_parent_section!(site, path); render_parent_section!(site, path);
} }
// TODO: register_tera_global_fns is expensive as it involves lots of cloning site.register_tera_global_fns();
// I can't think of a valid usecase where you would need the content
// of a page through a global fn so it's commented out for now
// site.register_tera_global_fns();
return site.render_page(&site.library.get_page(&pathbuf).unwrap()); return site.render_page(&site.library.get_page(&pathbuf).unwrap());
} }
// Front matter changed // Front matter changed
let mut sections_populated = false;
for changes in find_page_front_matter_changes(&site.library.get_page(&pathbuf).unwrap().meta, &prev.meta) { for changes in find_page_front_matter_changes(&site.library.get_page(&pathbuf).unwrap().meta, &prev.meta) {
site.register_tera_global_fns();
// Sort always comes first if present so the rendering will be fine // Sort always comes first if present so the rendering will be fine
match changes { match changes {
PageChangesNeeded::Taxonomies => { PageChangesNeeded::Taxonomies => {
site.populate_taxonomies()?; site.populate_taxonomies()?;
site.register_tera_global_fns();
site.render_taxonomies()?; site.render_taxonomies()?;
} }
PageChangesNeeded::Sort => { PageChangesNeeded::Sort => {
let section_path = match find_parent_section(site, &site.library.get_page(&pathbuf).unwrap()) {
Some(s) => s.file.path.clone(),
None => continue // Do nothing if it's an orphan page
};
if !sections_populated {
site.populate_sections();
sections_populated = true;
}
site.sort_sections_pages(Some(&section_path));
site.register_tera_global_fns();
site.render_index()?; site.render_index()?;
} }
PageChangesNeeded::Render => { PageChangesNeeded::Render => {
if !sections_populated {
site.populate_sections();
sections_populated = true;
}
site.register_tera_global_fns();
render_parent_section!(site, path); render_parent_section!(site, path);
site.render_page(&site.library.get_page(&path.to_path_buf()).unwrap())?; site.render_page(&site.library.get_page(&path.to_path_buf()).unwrap())?;
} }
@ -244,6 +212,7 @@ fn handle_page_editing(site: &mut Site, path: &Path) -> Result<()> {
None => { None => {
site.populate_sections(); site.populate_sections();
site.populate_taxonomies()?; site.populate_taxonomies()?;
site.register_early_global_fns();
site.register_tera_global_fns(); site.register_tera_global_fns();
// No need to optimise that yet, we can revisit if it becomes an issue // No need to optimise that yet, we can revisit if it becomes an issue
site.build() site.build()

View file

@ -357,12 +357,6 @@ impl Site {
self.library.populate_sections(); self.library.populate_sections();
} }
/// Sorts the pages of the section at the given path
/// By default will sort all sections but can be made to only sort a single one by providing a path
pub fn sort_sections_pages(&mut self, only: Option<&Path>) {
self.library.sort_sections_pages(only);
}
/// Find all the tags and categories if it's asked in the config /// Find all the tags and categories if it's asked in the config
pub fn populate_taxonomies(&mut self) -> Result<()> { pub fn populate_taxonomies(&mut self) -> Result<()> {
if self.config.taxonomies.is_empty() { if self.config.taxonomies.is_empty() {