mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 06:18:28 +01:00
MDL-41674 backup: Use a trie for grouped path detection.
This commit is contained in:
parent
edbcfbd61f
commit
92996836d0
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@ -43,6 +42,22 @@ abstract class grouped_parser_processor extends simplified_parser_processor {
|
||||
protected $groupedpaths; // Paths we are requesting grouped
|
||||
protected $currentdata; // Where we'll be acummulating data
|
||||
|
||||
// We create a array that stores each of the paths in a tree fashion
|
||||
// like the filesystem. Each element stores all the child elements that are
|
||||
// part of a full path that builds the grouped parent path we are storing.
|
||||
// eg Array keys are stored as follows;
|
||||
// root => a => b
|
||||
// => b
|
||||
// => c => d
|
||||
// => e => f.
|
||||
// Grouped paths here are; /a/b, /b, /c/d, /c/e/f.
|
||||
// There are no nested parent paths, that is an enforced rule so
|
||||
// we store an empty array to designate that the particular XML path element
|
||||
// is in fact a grouped path.
|
||||
// eg; $this->groupedparentprefixtree['a']['b'] = array();
|
||||
/** @var array Search tree storing the grouped paths. */
|
||||
protected $groupedparentprefixtree;
|
||||
|
||||
/**
|
||||
* Keep cache of parent directory paths for XML parsing.
|
||||
* @var array
|
||||
@ -78,6 +93,18 @@ abstract class grouped_parser_processor extends simplified_parser_processor {
|
||||
throw new progressive_parser_exception('xml_grouped_child_found', $a);
|
||||
}
|
||||
$this->groupedpaths[$path] = true;
|
||||
|
||||
// We check earlier in the function if there is a parent that is above the path
|
||||
// to be added so we can be sure no parent exists in the tree.
|
||||
$patharray = explode('/', $path);
|
||||
$currentpos = &$this->groupedparentprefixtree;
|
||||
foreach ($patharray as $item) {
|
||||
if (!isset($currentpos[$item])) {
|
||||
$currentpos[$item] = array();
|
||||
}
|
||||
// Update the current array position using a reference to allow in-place updates to the array.
|
||||
$currentpos = &$currentpos[$item];
|
||||
}
|
||||
}
|
||||
parent::add_path($path);
|
||||
}
|
||||
@ -162,13 +189,29 @@ abstract class grouped_parser_processor extends simplified_parser_processor {
|
||||
* false if not
|
||||
*/
|
||||
protected function grouped_parent_exists($path) {
|
||||
$parentpath = $this->get_parent_path($path);
|
||||
|
||||
while ($parentpath != '/') {
|
||||
if ($this->path_is_grouped($parentpath)) {
|
||||
return $parentpath;
|
||||
// Search the tree structure to find out if one of the paths
|
||||
// above the $path is a grouped path.
|
||||
$patharray = explode('/', $this->get_parent_path($path));
|
||||
$groupedpath = '';
|
||||
$currentpos = &$this->groupedparentprefixtree;
|
||||
foreach ($patharray as $item) {
|
||||
// When the item isn't set in the array we know
|
||||
// there is no parent grouped path.
|
||||
if (!isset($currentpos[$item])) {
|
||||
return false;
|
||||
}
|
||||
$parentpath = $this->get_parent_path($parentpath);
|
||||
|
||||
// When we aren't at the start of the path, continue to build
|
||||
// a string representation of the path that is traversed. We will
|
||||
// return the grouped path to the caller if we find one.
|
||||
if ($item != '') {
|
||||
$groupedpath .= '/'.$item;
|
||||
}
|
||||
|
||||
if ($currentpos[$item] == array()) {
|
||||
return $groupedpath;
|
||||
}
|
||||
$currentpos = &$currentpos[$item];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user