Skip to content
This repository has been archived by the owner on Apr 8, 2022. It is now read-only.

Commit

Permalink
MDL-41674 backup: Use a trie for grouped path detection.
Browse files Browse the repository at this point in the history
  • Loading branch information
mr-russ authored and Russell Smith committed Jan 11, 2015
1 parent edbcfbd commit 9299683
Showing 1 changed file with 49 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -78,6 +93,18 @@ public function add_path($path, $grouped = false) {
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);
}
Expand Down Expand Up @@ -162,13 +189,29 @@ protected function path_is_grouped($path) {
* false if not
*/
protected function grouped_parent_exists($path) {
$parentpath = $this->get_parent_path($path);
// 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;
}

// 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;
}

while ($parentpath != '/') {
if ($this->path_is_grouped($parentpath)) {
return $parentpath;
if ($currentpos[$item] == array()) {
return $groupedpath;
}
$parentpath = $this->get_parent_path($parentpath);
$currentpos = &$currentpos[$item];
}
return false;
}
Expand Down

0 comments on commit 9299683

Please sign in to comment.