summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Müller <thomas.mueller@tmit.eu>2013-07-12 15:30:01 +0200
committerThomas Müller <thomas.mueller@tmit.eu>2013-07-12 15:30:01 +0200
commitd1c05647115e6d904fb643478b6b24d48e9e60a1 (patch)
tree653e9065fa896029e2e73f34b9c658477a458fd7
parentca16c08ba175ca2a8c6709103c87c2d1a4161a0c (diff)
parent8ae2066b203e5420fa48d6717192db7e96343a2a (diff)
downloadnextcloud-server-d1c05647115e6d904fb643478b6b24d48e9e60a1.tar.gz
nextcloud-server-d1c05647115e6d904fb643478b6b24d48e9e60a1.zip
Merge branch 'master' into ext-fs-irods-master
-rw-r--r--apps/files/js/filelist.js2
-rw-r--r--apps/files_versions/lib/versions.php182
2 files changed, 109 insertions, 75 deletions
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index cf3ce2e5089..c847e2eff8b 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);
}
diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php
index 2f8262475b4..c083a000c37 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);
+ }
+
+ // 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;
+
+ $versionsSize = self::expire($filename, $versionsSize, $neededSpace);
+
// disable proxy to prevent multiple fopen calls
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
@@ -123,19 +135,9 @@ 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
- $newSize = self::expire($filename, $versionsSize);
-
- if ( $newSize != $versionsSize ) {
- self::setVersionsSize($uid, $newSize);
- }
+ self::setVersionsSize($uid, $versionsSize);
}
}
@@ -175,12 +177,14 @@ class Storage {
if ($files_view->file_exists($newpath)) {
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) ) {
$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,10 +395,10 @@ 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');
+ $versionsFileview = new \OC\Files\View('/'.$uid.'/files_versions');
// get available disk space for user
$softQuota = true;
@@ -424,87 +428,52 @@ 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
+ // 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) {
- $result = Storage::getAllVersions($uid);
- $versions_by_file = $result['by_file'];
- $all_versions = $result['all'];
+ $allFiles = true;
} else {
- $all_versions = Storage::getVersions($uid, $filename);
- $versions_by_file[$filename] = $all_versions;
+ $allFiles = false;
}
- $time = time();
+ $allVersions = Storage::getVersions($uid, $filename);
+ $versionsByFile[$filename] = $allVersions;
- // 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
+ $sizeOfDeletedVersions = self::delOldVersions($versionsByFile, $allVersions, $versionsFileview);
+ $availableSpace = $availableSpace + $sizeOfDeletedVersions;
+ $versionsSize = $versionsSize - $sizeOfDeletedVersions;
- $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'];
- }
+ // if still not enough free space we rearrange the versions from all files
+ if ($availableSpace <= 0 || $allFiles) {
+ $result = Storage::getAllVersions($uid);
+ $versionsByFile = $result['by_file'];
+ $allVersions = $result['all'];
- $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($versionsByFile, $allVersions, $versionsFileview);
+ $availableSpace = $availableSpace + $sizeOfDeletedVersions;
+ $versionsSize = $versionsSize - $sizeOfDeletedVersions;
}
// 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++;
}
@@ -513,4 +482,67 @@ class Storage {
return false;
}
+
+ /**
+ * @brief delete old version from a given list of 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($versionsByFile, &$allVersions, $versionsFileview) {
+
+ $time = time();
+ $size = 0;
+
+ // delete old versions for every given file
+ foreach ($versionsByFile 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
+ $versionsFileview->unlink($version['path'] . '.v' . $version['version']);
+ $size += $version['size'];
+ unset($allVersions[$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;
+ }
+
}