Added isFileOnlyGaps() and getFileSize(), both are "basicly finished".
authorRoland Haeder <roland@mxchange.org>
Wed, 4 Jun 2014 21:20:56 +0000 (23:20 +0200)
committerRoland Haeder <roland@mxchange.org>
Wed, 4 Jun 2014 21:20:56 +0000 (23:20 +0200)
Signed-off-by: Roland H├Ąder <roland@mxchange.org>
inc/classes/interfaces/block/class_Block.php
inc/classes/main/file_directories/class_BaseFile.php
inc/classes/main/file_directories/io/class_FrameworkFileInputOutputPointer.php

index f00e973..5f68b81 100644 (file)
@@ -113,6 +113,13 @@ interface Block extends FrameworkInterface {
         * @return      $totalEntries   Total entries in this file
         */
        function getCounter ();
+
+       /**
+        * "Getter" for file size
+        *
+        * @return      $fileSize       Size of currently loaded file
+        */
+       function getFileSize ();
 }
 
 // [EOF]
index cfefe49..d7a7337 100644 (file)
@@ -151,6 +151,38 @@ y   * @return      void
                parent::__destruct();
        }
 
+       /**
+        * Checks whether the abstracted file only contains gaps by counting all
+        * gaps' bytes together and compare it to total length.
+        *
+        * @return      $isGapsOnly             Whether the abstracted file only contains gaps
+        */
+       private function isFileOnlyGaps () {
+               // First/last gap found?
+               /* Only for debugging
+               if (isset($this->gaps[0])) {
+                       // Output first and last gap
+                       self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] this->gaps[0]=%s,this->gaps[%s]=%s', __METHOD__, __LINE__, print_r($this->gaps[0], TRUE), (count($this->gaps) - 1), print_r($this->gaps[count($this->gaps) - 1], TRUE)));
+               } // END - if
+               */
+
+               // Now count every gap
+               $gapsSize = 0;
+               foreach ($this->gaps as $gap) {
+                       // Calculate size of found gap: end-start including both
+                       $gapsSize += ($gap[self::GAPS_INDEX_END] - $gap[self::GAPS_INDEX_START]);
+               } // END - if
+
+               // Debug output
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] gapsSize=%s,this->headerSize=%s', __METHOD__, __LINE__, $gapsSize, $this->getHeaderSize()));
+
+               // Total gap size + header size must be same as file size
+               $isGapsOnly = (($this->getHeaderSize() + $gapsSize) == $this->getFileSize());
+
+               // Return status
+               return $isGapsOnly;
+       }
+
        /**
         * Initializes counter for valid entries, arrays for damaged entries and
         * an array for gap seek positions. If you call this method on your own,
@@ -169,6 +201,16 @@ y   * @return      void
                $this->damagedEntries = array();
        }
 
+       /**
+        * "Getter" for abstracted file size
+        *
+        * @return      $fileSize       Size of abstracted file
+        */
+       public function getFileSize () {
+               // Call block instanze
+               return $this->getBlockInstance()->getFileSize();
+       }
+
        /**
         * Getter for total entries
         *
@@ -735,10 +777,41 @@ y  * @return      void
                        // Get current entry
                        $current = $this->getCurrentBlock();
 
+                       /*
+                        * If the block is empty, maybe the whole file is? This could mean
+                        * that the file has been pre-allocated.
+                        */
+                       if (empty($current)) {
+                               // Then skip this part
+                               continue;
+                       } // END - if
+
                        // Debug message
                        /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] current()=%s', __METHOD__, __LINE__, strlen($current)));
                } // END - while
 
+               // If the last read block is empty, check gaps
+               if (empty($current)) {
+                       // Output message
+                       self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Found a total of %s gaps.', __METHOD__, __LINE__, count($this->gaps)));
+
+                       // Check gaps, if the whole file is empty.
+                       if ($this->isFileOnlyGaps()) {
+                               // Only gaps, so don't continue here.
+                               return;
+                       } // END - if
+
+                       /*
+                        * The above call has calculated a total size of all gaps. If the
+                        * percentage of gaps passes a "soft" limit and last
+                        * defragmentation is to far in the past, or if a "hard" limit has
+                        * reached, run defragmentation.
+                        */
+                       if ($this->isDefragmentationNeeded()) {
+                               // Run "defragmentation"
+                               $this->doRunDefragmentation();
+                       } // END - if
+               } // END - if
                //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
        }
 
@@ -754,11 +827,15 @@ y  * @return      void
                        return;
                } // END - if
 
+               // Debug message
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d] key()=%s', __FUNCTION__, __LINE__, $this->key()));
+
                // Make sure the block instance is set
                assert($this->getBlockInstance() instanceof CalculatableBlock);
 
                // First calculate minimum block length
                $length = $this->getBlockInstance()->calculateMinimumBlockLength();
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d] length=%s', __FUNCTION__, __LINE__, $length));
 
                // Short be more than zero!
                assert($length > 0);
@@ -775,10 +852,13 @@ y  * @return      void
                        // Then read the next possible block
                        $block = $this->read($length);
 
+                       // Debug message
+                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d] block()=%s,length=%s', __FUNCTION__, __LINE__, strlen($block), $length));
+
                        // Is it all empty?
                        if (strlen(trim($block)) == 0) {
                                // Mark this block as empty
-                               $this->markCurrentBlockAsEmpty($length);
+                               $this->markCurrentBlockAsEmpty(strlen($block));
 
                                // Skip to next block
                                continue;
@@ -789,7 +869,7 @@ y    * @return      void
 
                        // A debug message
                        //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d] data()=%s', __FUNCTION__, __LINE__, strlen($data)));
-               } // END - if
+               } // END - while
 
                // EOF reached?
                if ($this->isEndOfFileReached()) {
index b703f09..39aa4ef 100644 (file)
@@ -214,6 +214,25 @@ class FrameworkFileInputOutputPointer extends BaseFileIo implements InputOutputP
        public function key () {
                throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
        }
+
+       /**
+        * "Getter" for file size
+        *
+        * @return      $fileSize       Size of currently loaded file
+        */
+       public function getFileSize () {
+               // Check if the pointer is still valid
+               $this->validateFilePointer();
+
+               // Get file's data
+               $fileData = fstat($this->getPointer())
+
+               // Make sure the required array key is there
+               assert(isset($fileData['size']));
+
+               // Return size
+               return $fileData['size'];
+       }
 }
 
 // [EOF]