From cb81ceb31d1a5aba8f1febfafecdcc2106822168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Fri, 12 Jul 2013 10:40:24 +0200 Subject: [PATCH 1/9] add new file above summary if it is the first file in the list --- apps/files/js/filelist.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index cf3ce2e508..c847e2eff8 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -171,6 +171,8 @@ var FileList={ } }else if(type=='dir' && $('tr[data-file]').length>0){ $('tr[data-file]').first().before(element); + } else if(type=='file' && $('tr[data-file]').length>0) { + $('tr[data-file]').last().before(element); }else{ $('#fileList').append(element); } From e15914316521bb6d9d791926434c9c6ce5b0aa91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Tue, 25 Jun 2013 09:39:01 +0200 Subject: [PATCH 2/9] call expire function before writing the new version to make sure to have enough free space --- apps/files_versions/lib/versions.php | 163 ++++++++++++++++----------- 1 file changed, 98 insertions(+), 65 deletions(-) diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index 2f8262475b..6abf278dda 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -113,6 +113,18 @@ class Storage { mkdir($versionsFolderName.'/'.$info['dirname'], 0750, true); } + $versionsSize = self::getVersionsSize($uid); + if ( $versionsSize === false || $versionsSize < 0 ) { + $versionsSize = self::calculateSize($uid); + } + + // assumptgion: we need filesize($filename) for the new version + + // some more free space for the modified file which might be + // 1.5 times as large as the current version -> 2.5 + $neededSpace = $files_view->filesize($filename) * 2.5; + + $versionsSize = self::expire($filename, $versionsSize, $neededSpace); + // disable proxy to prevent multiple fopen calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; @@ -123,11 +135,6 @@ class Storage { // reset proxy state \OC_FileProxy::$enabled = $proxyStatus; - $versionsSize = self::getVersionsSize($uid); - if ( $versionsSize === false || $versionsSize < 0 ) { - $versionsSize = self::calculateSize($uid); - } - $versionsSize += $users_view->filesize('files'.$filename); // expire old revisions if necessary @@ -175,12 +182,12 @@ class Storage { if ($files_view->file_exists($newpath)) { return self::store($new_path); } - + $abs_newpath = $versions_view->getLocalFile($newpath); if ( $files_view->is_dir($oldpath) && $versions_view->is_dir($oldpath) ) { $versions_view->rename($oldpath, $newpath); - } else if ( ($versions = Storage::getVersions($uid, $oldpath)) ) { + } else if ( ($versions = Storage::getVersions($uid, $oldpath)) ) { $info=pathinfo($abs_newpath); if(!file_exists($info['dirname'])) mkdir($info['dirname'], 0750, true); foreach ($versions as $v) { @@ -391,7 +398,7 @@ class Storage { /** * @brief Erase a file's versions which exceed the set quota */ - private static function expire($filename, $versionsSize = null) { + private static function expire($filename, $versionsSize = null, $offset = 0) { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { list($uid, $filename) = self::getUidAndFilename($filename); $versions_fileview = new \OC\Files\View('/'.$uid.'/files_versions'); @@ -424,76 +431,39 @@ class Storage { $rootInfo = $files_view->getFileInfo('/'); $free = $quota-$rootInfo['size']; // remaining free space for user if ( $free > 0 ) { - $availableSpace = ($free * self::DEFAULTMAXSIZE / 100) - $versionsSize; // how much space can be used for versions + $availableSpace = ($free * self::DEFAULTMAXSIZE / 100) - ($versionsSize + $offset); // how much space can be used for versions } else { - $availableSpace = $free-$versionsSize; + $availableSpace = $free - $versionsSize - $offset; } } else { - $availableSpace = $quota; + $availableSpace = $quota - $offset; } // after every 1000s run reduce the number of all versions not only for the current file $random = rand(0, 1000); if ($random == 0) { + $allFiles = true; + } else { + $allFiles = false; + } + + $all_versions = Storage::getVersions($uid, $filename); + $versions_by_file[$filename] = $all_versions; + + $sizeOfDeletedVersions = self::delOldVersions($versions_by_file, $all_versions, $versions_fileview); + $availableSpace = $availableSpace + $sizeOfDeletedVersions; + $versionsSize = $versionsSize - $sizeOfDeletedVersions; + + // if still not enough free space we rearrange the versions from all files + if ($availableSpace < 0 || $allFiles) { $result = Storage::getAllVersions($uid); $versions_by_file = $result['by_file']; $all_versions = $result['all']; - } else { - $all_versions = Storage::getVersions($uid, $filename); - $versions_by_file[$filename] = $all_versions; - } - $time = time(); - - // it is possible to expire versions from more than one file - // iterate through all given files - foreach ($versions_by_file as $filename => $versions) { - $versions = array_reverse($versions); // newest version first - - $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']; - } - - $firstVersion = reset($versions); - $firstKey = key($versions); - $prevTimestamp = $firstVersion['version']; - $nextVersion = $firstVersion['version'] - $step; - $remaining_versions[$firstKey] = $firstVersion; - unset($versions[$firstKey]); - - foreach ($versions as $key => $version) { - $newInterval = true; - while ( $newInterval ) { - if ( $nextInterval == -1 || $version['version'] >= $nextInterval ) { - if ( $version['version'] > $nextVersion ) { - //distance between two version too small, delete version - $versions_fileview->unlink($version['path'].'.v'.$version['version']); - $availableSpace += $version['size']; - $versionsSize -= $version['size']; - unset($all_versions[$key]); // update array with all versions - } else { - $nextVersion = $version['version'] - $step; - } - $newInterval = false; // version checked so we can move to the next one - } else { // time to move on to the next interval - $interval++; - $step = Storage::$max_versions_per_interval[$interval]['step']; - $nextVersion = $prevTimestamp - $step; - if ( Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'] == -1 ) { - $nextInterval = -1; - } else { - $nextInterval = $time - Storage::$max_versions_per_interval[$interval]['intervalEndsAfter']; - } - $newInterval = true; // we changed the interval -> check same version with new interval - } - } - $prevTimestamp = $version['version']; - } + $sizeOfDeletedVersions = self::delOldVersions($versions_by_file, $all_versions, $versions_fileview); + $availableSpace = $availableSpace + $sizeOfDeletedVersions; + $versionsSize = $versionsSize - $sizeOfDeletedVersions; } // Check if enough space is available after versions are rearranged. @@ -513,4 +483,67 @@ class Storage { return false; } + + /** + * @brief delete old version from a given list of versions + * + * @param array $versions_by_file list of versions ordered by files + * @param array $all_versions all versions accross multiple files + * @param $versions_fileview OC\Files\View on data/user/files_versions + * @return size of releted versions + */ + private static function delOldVersions($versions_by_file, &$all_versions, $versions_fileview) { + + $time = time(); + $size = 0; + + // delete old versions for every given file + foreach ($versions_by_file as $versions) { + $versions = array_reverse($versions); // newest version first + + $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']; + } + + $firstVersion = reset($versions); + $firstKey = key($versions); + $prevTimestamp = $firstVersion['version']; + $nextVersion = $firstVersion['version'] - $step; + unset($versions[$firstKey]); + + foreach ($versions as $key => $version) { + $newInterval = true; + while ($newInterval) { + if ($nextInterval == -1 || $version['version'] >= $nextInterval) { + if ($version['version'] > $nextVersion) { + //distance between two version too small, delete version + $versions_fileview->unlink($version['path'] . '.v' . $version['version']); + $size += $version['size']; + unset($all_versions[$key]); // update array with all versions + } else { + $nextVersion = $version['version'] - $step; + } + $newInterval = false; // version checked so we can move to the next one + } else { // time to move on to the next interval + $interval++; + $step = Storage::$max_versions_per_interval[$interval]['step']; + $nextVersion = $prevTimestamp - $step; + if (Storage::$max_versions_per_interval[$interval]['intervalEndsAfter'] == -1) { + $nextInterval = -1; + } else { + $nextInterval = $time - Storage::$max_versions_per_interval[$interval]['intervalEndsAfter']; + } + $newInterval = true; // we changed the interval -> check same version with new interval + } + } + $prevTimestamp = $version['version']; + } + } + return $size; + } + } From d6c1e5490d8f457da5fac12fce3db33802669abe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Wed, 26 Jun 2013 16:24:46 +0200 Subject: [PATCH 3/9] it is enough to call the expire function once --- apps/files_versions/lib/versions.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index 6abf278dda..d9016e4093 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -137,12 +137,7 @@ class Storage { $versionsSize += $users_view->filesize('files'.$filename); - // expire old revisions if necessary - $newSize = self::expire($filename, $versionsSize); - - if ( $newSize != $versionsSize ) { - self::setVersionsSize($uid, $newSize); - } + self::setVersionsSize($uid, $versionsSize); } } From e8760d7284577bb785093e0cbea74b8ca13d643a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Wed, 26 Jun 2013 16:28:23 +0200 Subject: [PATCH 4/9] also expire versions on rename, to update the history more regularly --- apps/files_versions/lib/versions.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index d9016e4093..b9cc40a066 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -178,6 +178,8 @@ class Storage { return self::store($new_path); } + self::expire($newpath); + $abs_newpath = $versions_view->getLocalFile($newpath); if ( $files_view->is_dir($oldpath) && $versions_view->is_dir($oldpath) ) { From e7959d3da07ee8e577713452303cd10f9b587119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Thu, 27 Jun 2013 10:49:13 +0200 Subject: [PATCH 5/9] fix typo in comment --- apps/files_versions/lib/versions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index b9cc40a066..80d7e78a22 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -118,7 +118,7 @@ class Storage { $versionsSize = self::calculateSize($uid); } - // assumptgion: we need filesize($filename) for the new version + + // assumption: we need filesize($filename) for the new version + // some more free space for the modified file which might be // 1.5 times as large as the current version -> 2.5 $neededSpace = $files_view->filesize($filename) * 2.5; From 2f0d88cae4cdb9e4478db3d417ff0045fa72400a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Thu, 27 Jun 2013 14:22:01 +0200 Subject: [PATCH 6/9] adjust comments --- apps/files_versions/lib/versions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index 80d7e78a22..b526c9a18d 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -437,7 +437,7 @@ class Storage { } - // after every 1000s run reduce the number of all versions not only for the current file + // with the probability of 0.1% we reduce the number of all versions not only for the current file $random = rand(0, 1000); if ($random == 0) { $allFiles = true; From fbf34f3bf697bf3c9e15742489d7d6fe4a338251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Fri, 28 Jun 2013 17:06:02 +0200 Subject: [PATCH 7/9] fix some var names according to our style guide --- apps/files_versions/lib/versions.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index b526c9a18d..a66e8279f6 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -484,18 +484,18 @@ class Storage { /** * @brief delete old version from a given list of versions * - * @param array $versions_by_file list of versions ordered by files - * @param array $all_versions all versions accross multiple files - * @param $versions_fileview OC\Files\View on data/user/files_versions + * @param array $versionsByFile list of versions ordered by files + * @param array $allVversions all versions accross multiple files + * @param $versionsFileview OC\Files\View on data/user/files_versions * @return size of releted versions */ - private static function delOldVersions($versions_by_file, &$all_versions, $versions_fileview) { + private static function delOldVersions($versionsByFile, &$allVersions, $versionsFileview) { $time = time(); $size = 0; // delete old versions for every given file - foreach ($versions_by_file as $versions) { + foreach ($versionsByFile as $versions) { $versions = array_reverse($versions); // newest version first $interval = 1; @@ -518,9 +518,9 @@ class Storage { if ($nextInterval == -1 || $version['version'] >= $nextInterval) { if ($version['version'] > $nextVersion) { //distance between two version too small, delete version - $versions_fileview->unlink($version['path'] . '.v' . $version['version']); + $versionsFileview->unlink($version['path'] . '.v' . $version['version']); $size += $version['size']; - unset($all_versions[$key]); // update array with all versions + unset($allVersions[$key]); // update array with all versions } else { $nextVersion = $version['version'] - $step; } From 15f7bb296cd0b1af588e4fbc2f201ef8375f4326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Fri, 28 Jun 2013 17:13:14 +0200 Subject: [PATCH 8/9] continue cleaning-up old versions if availableSpace=0. It's not necessary but gives us some additional free space, especially in the case of a hard quota --- apps/files_versions/lib/versions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index a66e8279f6..a458861d88 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -453,7 +453,7 @@ class Storage { $versionsSize = $versionsSize - $sizeOfDeletedVersions; // if still not enough free space we rearrange the versions from all files - if ($availableSpace < 0 || $allFiles) { + if ($availableSpace <= 0 || $allFiles) { $result = Storage::getAllVersions($uid); $versions_by_file = $result['by_file']; $all_versions = $result['all']; From b16c5a6df75a9b5ce0f3e4e7b661184ba24fe3e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Fri, 28 Jun 2013 20:31:33 +0200 Subject: [PATCH 9/9] fix array access and change variable names according to the coding style --- apps/files_versions/lib/versions.php | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index a458861d88..c083a000c3 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -398,7 +398,7 @@ class Storage { private static function expire($filename, $versionsSize = null, $offset = 0) { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { list($uid, $filename) = self::getUidAndFilename($filename); - $versions_fileview = new \OC\Files\View('/'.$uid.'/files_versions'); + $versionsFileview = new \OC\Files\View('/'.$uid.'/files_versions'); // get available disk space for user $softQuota = true; @@ -445,20 +445,20 @@ class Storage { $allFiles = false; } - $all_versions = Storage::getVersions($uid, $filename); - $versions_by_file[$filename] = $all_versions; + $allVersions = Storage::getVersions($uid, $filename); + $versionsByFile[$filename] = $allVersions; - $sizeOfDeletedVersions = self::delOldVersions($versions_by_file, $all_versions, $versions_fileview); + $sizeOfDeletedVersions = self::delOldVersions($versionsByFile, $allVersions, $versionsFileview); $availableSpace = $availableSpace + $sizeOfDeletedVersions; $versionsSize = $versionsSize - $sizeOfDeletedVersions; // if still not enough free space we rearrange the versions from all files if ($availableSpace <= 0 || $allFiles) { $result = Storage::getAllVersions($uid); - $versions_by_file = $result['by_file']; - $all_versions = $result['all']; + $versionsByFile = $result['by_file']; + $allVersions = $result['all']; - $sizeOfDeletedVersions = self::delOldVersions($versions_by_file, $all_versions, $versions_fileview); + $sizeOfDeletedVersions = self::delOldVersions($versionsByFile, $allVersions, $versionsFileview); $availableSpace = $availableSpace + $sizeOfDeletedVersions; $versionsSize = $versionsSize - $sizeOfDeletedVersions; } @@ -466,12 +466,14 @@ class Storage { // Check if enough space is available after versions are rearranged. // If not we delete the oldest versions until we meet the size limit for versions, // but always keep the two latest versions - $numOfVersions = count($all_versions) -2 ; + $numOfVersions = count($allVersions) -2 ; $i = 0; while ($availableSpace < 0 && $i < $numOfVersions) { - $versions_fileview->unlink($all_versions[$i]['path'].'.v'.$all_versions[$i]['version']); - $versionsSize -= $all_versions[$i]['size']; - $availableSpace += $all_versions[$i]['size']; + $version = current($allVersions); + $versionsFileview->unlink($version['path'].'.v'.$version['version']); + $versionsSize -= $version['size']; + $availableSpace += $version['size']; + next($allVersions); $i++; }