diff options
author | Björn Schießle <schiessle@owncloud.com> | 2013-01-09 17:11:46 +0100 |
---|---|---|
committer | Björn Schießle <schiessle@owncloud.com> | 2013-01-09 17:11:46 +0100 |
commit | d51fba7781a1edabdb531b81d0aaab48e2ff46a0 (patch) | |
tree | 81e6670f2cb86cfb81153d1408efd1eec3ab27aa /apps/files_versions | |
parent | a0b0a1d2947f909ea6f5d1878b91aa63a9c6f9db (diff) | |
download | nextcloud-server-d51fba7781a1edabdb531b81d0aaab48e2ff46a0.tar.gz nextcloud-server-d51fba7781a1edabdb531b81d0aaab48e2ff46a0.zip |
every 1000s run reduce the number of versions for all files, not only for the currently edited file
Diffstat (limited to 'apps/files_versions')
-rw-r--r-- | apps/files_versions/lib/versions.php | 151 |
1 files changed, 104 insertions, 47 deletions
diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index ccbbf3ab2cd..e890715b5a5 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -16,16 +16,6 @@ namespace OCA_Versions; class Storage { - - // config.php configuration: - // - files_versions - // - files_versionsfolder - // - files_versionsmaxfilesize - // - // todo: - // - finish porting to OC_FilesystemView to enable network transparency - // - add transparent compression. first test if it´s worth it. - const DEFAULTENABLED=true; const DEFAULTMAXSIZE=50; // unit: percentage; 50% of available disk space/quota @@ -177,14 +167,14 @@ class Storage { $files_view = new \OC_FilesystemView('/'.$uid.'/files'); $local_file = $files_view->getLocalFile($filename); - $versions_fileview = \OCP\Files::getStorage('files_versions'); foreach( $matches as $ma ) { $i++; $versions[$i]['cur'] = 0; $parts = explode( '.v', $ma ); - $versions[$i]['version'] = ( end( $parts ) );
+ $versions[$i]['version'] = ( end( $parts ) ); + $versions[$i]['path'] = $filename;
$versions[$i]['size'] = $versions_fileview->filesize($filename.'.v'.$versions[$i]['version']); // if file with modified date exists, flag it in array as currently enabled version @@ -226,6 +216,62 @@ class Storage { } } + + /** + * @brief returns all stored file versions from a given user + * @param $uid id to the user + * @return array with contains two arrays 'all' which contains all versions sorted by age and 'by_file' which contains all versions sorted by filename + */ + + private static function getAllVersions($uid) { + if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) {
+ $versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions'); + $versionsRoot = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath(''); + + $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($versionsRoot), \RecursiveIteratorIterator::CHILD_FIRST);
+ + $versions = array(); + + foreach ($iterator as $path) { + if ( preg_match('/^.+\.v(\d+)$/', $path, $match) ) { + $relpath = substr($path, strlen($versionsRoot)-1); + $versions[$match[1].'#'.$relpath] = array('path' => $relpath, 'timestamp' => $match[1]); + } + }
+ + ksort($versions); + + $i = 0; + + $result = array(); + $file_count = array(); + + foreach( $versions as $key => $value ) {
+ $i++; + $size = $versions_fileview->filesize($value['path']); + $filename = substr($value['path'], 0, -strlen($value['timestamp'])-2); +
+ $result['all'][$i]['version'] = $value['timestamp']; + $result['all'][$i]['path'] = $filename;
+ $result['all'][$i]['size'] = $size; + + if ( key_exists($filename, $file_count) ) { + $c = $file_count[$filename] +1; + $file_count[$filename] = $c; + } else { + $file_count[$filename] = 1; + $c = 1; + } + $filename = substr($value['path'], 0, -strlen($value['timestamp'])-2); + $result['by_file'][$filename][$c]['version'] = $value['timestamp']; + $result['by_file'][$filename][$c]['path'] = $filename;
+ $result['by_file'][$filename][$c]['size'] = $size; +
+ } + + return $result; + } + } /** * @brief Erase a file's versions which exceed the set quota @@ -248,56 +294,67 @@ class Storage { $free = $quota-$rootInfo['size']; // remaining free space for user if ( $free > 0 ) { - $availableSpace = 100* self::DEFAULTMAXSIZE / ($quota-$rootInfo['size']); // how much space can be used for versions + $availableSpace = 100* self::DEFAULTMAXSIZE / ($free); // how much space can be used for versions } // otherwise available space negative and we need to reach at least 0 at the end of the expiration process; - - $versions = Storage::getVersions($filename); - $versions = array_reverse($versions); // newest version first + + // after every 1000s run reduce the number of all versions not only for the current file + $random = rand(0, 1000); + if ($random == 0) { + $result = Storage::getAllVersions($uid); + $versions_by_file = $result['by_file']; + $all_versions = $result['all']; + } else { + $all_versions = Storage::getVersions($filename); + $versions_by_file[$filename] = $all_versions; + } $time = time(); - $numOfVersions = count($versions); - $interval = 1; - $step = Storage::$max_versions_per_interval[$interval]['step']; - if (Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'] == -1) { - $nextInterval = -1; - } else { - $nextInterval = $time - Storage::$max_versions_per_interval[$interval]['intervalEndsAfter']; - } + foreach ($versions_by_file as $filename => $versions) { + $versions = array_reverse($versions); // newest version first + + $numOfVersions = count($versions); + $interval = 1; + $step = Storage::$max_versions_per_interval[$interval]['step']; + if (Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'] == -1) { + $nextInterval = -1; + } else { + $nextInterval = $time - Storage::$max_versions_per_interval[$interval]['intervalEndsAfter']; + } - $nextVersion = $versions[0]['version'] - $step; + $nextVersion = $versions[0]['version'] - $step; - for ($i=1; $i<$numOfVersions; $i++) { - if ( $nextInterval == -1 || $versions[$i]['version'] >= $nextInterval ) { - if ( $versions[$i]['version'] > $nextVersion ) { - //distance between two version to small, delete version - $versions_fileview->unlink($filename.'.v'.$versions[$i]['version']); - $availableSpace += $versions[$i]['size']; - } else { + for ($i=1; $i<$numOfVersions; $i++) { + if ( $nextInterval == -1 || $versions[$i]['version'] >= $nextInterval ) { + if ( $versions[$i]['version'] > $nextVersion ) { + //distance between two version to small, delete version + $versions_fileview->unlink($versions[$i]['path'].'.v'.$versions[$i]['version']); + $availableSpace += $versions[$i]['size']; + } else { + $nextVersion = $versions[$i]['version'] - $step; + } + } else { // time to move on to the next interval + $interval++; + $i--; // need to go one version back to check the same version against the new interval. + $step = Storage::$max_versions_per_interval[$interval]['step']; $nextVersion = $versions[$i]['version'] - $step; - } - } else { // time to move on to the next interval - $interval++; - $step = Storage::$max_versions_per_interval[$interval]['step']; - $nextVersion = $versions[$i]['version'] - $step; - if ( Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'] == -1 ) { - $nextInterval = -1; - } else {
- $nextInterval = $time - Storage::$max_versions_per_interval[$interval]['intervalEndsAfter']; + if ( Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'] == -1 ) { + $nextInterval = -1; + } else {
+ $nextInterval = $time - Storage::$max_versions_per_interval[$interval]['intervalEndsAfter']; + } } } } - // check if enough space is available after versions are rearranged - $versions = array_reverse( $versions ); // oldest version first - $numOfVersions = count($versions); + $numOfVersions = count($all_versions); $i = 0; while ($availableSpace < 0) { - $versions_fileview->unlink($filename.'.v'.$versions[$i]['version']); - $availableSpace += $versions[$i]['size']; + $versions_fileview->unlink($all_versions[$i]['path'].'.v'.$all_versions[$i]['version']); + $availableSpace += $all_versions[$i]['size']; $i++; if ($i = $numOfVersions-2) break; // keep at least the last version } } } -}
\ No newline at end of file +} |