]> source.dussan.org Git - nextcloud-server.git/commitdiff
keep track of the size of the versions directory
authorBjörn Schießle <schiessle@owncloud.com>
Thu, 10 Jan 2013 17:04:30 +0000 (18:04 +0100)
committerBjörn Schießle <schiessle@owncloud.com>
Thu, 10 Jan 2013 17:04:30 +0000 (18:04 +0100)
apps/files_versions/lib/hooks.php
apps/files_versions/lib/versions.php

index e897a81f7af4588de258115ca8f17003b46bdef5..736d9cd86876e5fcc5a21f2390dd287f791cd270 100644 (file)
@@ -39,15 +39,15 @@ class Hooks {
         * cleanup the versions directory if the actual file gets deleted
         */
        public static function remove_hook($params) {
-               $versions_fileview = \OCP\Files::getStorage('files_versions');
-               $rel_path =  $params['path'];
-               $abs_path = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('').$rel_path.'.v';
-               if(Storage::isversioned($rel_path)) {
-                       $versions = Storage::getVersions($rel_path);
-                       foreach ($versions as $v) {
-                               unlink($abs_path . $v['version']);
-                       }
-               }
+               if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {\r
+               \r
+                       $versions = new Storage( new \OC_FilesystemView('') );\r
+               \r
+                       $path = $params[\OC_Filesystem::signal_param_path];\r
+               \r
+                       if($path<>'') $versions->delete( $path );\r
+               \r
+               }\r
        }
 
        /**
index 58e4a2ce1321a38e7d9fb4514337a2c8ef9d2020..fc8adf646a8565f4ed86958b889fd825efa47d70 100644 (file)
@@ -82,14 +82,39 @@ class Storage {
                        }
 
                        // store a new version of a file
-                       $users_view->copy('files'.$filename, 'files_versions'.$filename.'.v'.$users_view->filemtime('files'.$filename));
-
+                       $result = $users_view->copy('files'.$filename, 'files_versions'.$filename.'.v'.$users_view->filemtime('files'.$filename));
+                       if (  ($versionsSize = \OCP\Config::getAppValue('files_versions', 'size')) === null ) {\r
+                               $versionsSize = self::calculateSize($uid);\r
+                       }
+                       $versionsSize += $users_view->filesize('files'.$filename);
+                       
                        // expire old revisions if necessary
-                       Storage::expire($filename);
+                       self::expire($filename, $versionsSize);
                }
        }
 
 
+       /**
+        * Delete versions of a file
+        */
+       public static function delete($filename) {
+               list($uid, $filename) = self::getUidAndFilename($filename);\r
+               $versions_fileview = new \OC_FilesystemView('/'.$uid .'/files_versions');
+               \r
+               $abs_path = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('').$filename.'.v';\r
+               if(Storage::isversioned($filename)) {\r
+                       $versions = self::getVersions($filename);\r
+                       if (  ($versionsSize = \OCP\Config::getAppValue('files_versions', 'size')) === null ) {\r
+                               $versionsSize = self::calculateSize($uid);\r
+                       }\r
+                       foreach ($versions as $v) {\r
+                               unlink($abs_path . $v['version']);\r
+                               $versionsSize -= $v['size'];\r
+                       }\r
+                       \OCP\Config::setAppValue('files_versions', 'size', $versionsSize);\r
+               }
+       }
+       
        /**
         * rollback to an old version of a file.
         */
@@ -216,13 +241,37 @@ class Storage {
                }
 
        }
+
+       /**\r
+        * @brief get the size of all stored versions from a given user\r
+        * @param $uid id from the user\r
+        * @return size of vesions\r
+        */\r
+       private static function calculateSize($uid) {\r
+               if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) {\r
+                       $versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions');\r
+                       $versionsRoot = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('');\r
+                               \r
+                       $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($versionsRoot), \RecursiveIteratorIterator::CHILD_FIRST);\r
+                               \r
+                       $size = 0;
+                                                       \r
+                       foreach ($iterator as $path) {\r
+                               if ( preg_match('/^.+\.v(\d+)$/', $path, $match) ) {\r
+                                       $relpath = substr($path, strlen($versionsRoot)-1);
+                                       $size += $versions_fileview->filesize($relpath);\r
+                               }\r
+                       }
+                       
+                       return $size;\r
+               }\r
+       }
        
        /**
         * @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' ) {\r
                        $versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions');
@@ -280,7 +329,7 @@ class Storage {
        /**
         * @brief Erase a file's versions which exceed the set quota
         */
-       public static function expire($filename) {
+       public static function expire($filename, $versionsSize = null) {
                if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
                        list($uid, $filename) = self::getUidAndFilename($filename);                     
                        $versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions');
@@ -293,13 +342,20 @@ class Storage {
                        if ( $quota == null ) {
                                $quota = \OC_Filesystem::free_space('/');
                        }
-\r
+                       
+                       if ( $versionsSize === null ) {
+                               if (  ($versionsSize = \OCP\Config::getAppValue('files_versions', 'size')) === null ) {
+                                       $versionsSize = self::calculateSize($uid);
+                               }
+                       }
+                       \r
                        $rootInfo = \OC_FileCache::get('', '/'. $uid . '/files');
                        $free = $quota-$rootInfo['size']; // remaining free space for user
-
                        if ( $free > 0 ) {
-                               $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;
+                               $availableSpace = ($free * self::DEFAULTMAXSIZE / 100) - $versionsSize; // how much space can be used for versions
+                       } else {
+                               $availableSpace = $free-$versionsSize;
+                       } 
 
                        // after every 1000s run reduce the number of all versions not only for the current file 
                        $random = rand(0, 1000);
@@ -334,6 +390,7 @@ class Storage {
                                                        //distance between two version to small, delete version
                                                        $versions_fileview->unlink($versions[$i]['path'].'.v'.$versions[$i]['version']);
                                                        $availableSpace += $versions[$i]['size'];
+                                                       $versionsSize -= $versions[$i]['size'];
                                                } else {
                                                        $nextVersion = $versions[$i]['version'] - $step;
                                                }
@@ -355,10 +412,13 @@ class Storage {
                        $i = 0; 
                        while ($availableSpace < 0) {
                                $versions_fileview->unlink($all_versions[$i]['path'].'.v'.$all_versions[$i]['version']);
+                               $versionsSize -= $all_versions[$i]['size'];
                                $availableSpace += $all_versions[$i]['size'];
                                $i++;
                                if ($i = $numOfVersions-2) break; // keep at least the last version
                        }
+               
+                       \OCP\Config::setAppValue('files_versions', 'size', $versionsSize);
                }
        }
 }