]> git.mxchange.org Git - core.git/blobdiff - inc/classes/main/stacker/file/class_BaseFileStack.php
Continued with indexes/stacks:
[core.git] / inc / classes / main / stacker / file / class_BaseFileStack.php
index c768db3ea87acab508164b60bdb8e3e4e7c33dd8..4ff2dfc5179d3afd32462d8ac5c6a4c4e6eb2988 100644 (file)
@@ -77,6 +77,16 @@ class BaseFileStack extends BaseStacker {
         */
        private $header = array();
 
+       /**
+        * Seek positions for gaps ("fragmentation")
+        */
+       private $gaps = array();
+
+       /**
+        * Seek positions for damaged entries (e.g. mismatching hash sum, ...)
+        */
+       private $damagedEntries = array();
+
        /**
         * Protected constructor
         *
@@ -96,6 +106,27 @@ class BaseFileStack extends BaseStacker {
                        self::LENGTH_POSITION +
                        strlen(self::SEPARATOR_HEADER_ENTRIES)
                );
+
+               // Init counters and gaps array
+               $this->initCountersGapsArray();
+       }
+
+       /**
+        * Initializes counter for valid entries, arrays for damaged entries and
+        * an array for gap seek positions. If you call this method on your own,
+        * please re-analyze the file structure. So you are better to call
+        * analyzeStackFile() instead of this method.
+        *
+        * @return      void
+        */
+       private function initCountersGapsArray () {
+               // Init counter and seek position
+               $this->setCounter(0);
+               $this->setSeekPosition(0);
+
+               // Init arrays
+               $this->gaps = array();
+               $this->damagedEntries = array();
        }
 
        /**
@@ -103,7 +134,7 @@ class BaseFileStack extends BaseStacker {
         *
         * @return      $totalEntries   Total entries in this stack
         */
-       private function getCounter () {
+       private final function getCounter () {
                // Get it
                return $this->totalEntries;
        }
@@ -113,7 +144,7 @@ class BaseFileStack extends BaseStacker {
         *
         * @return      void
         */
-       private function incrementCounter () {
+       private final function incrementCounter () {
                // Get it
                $this->totalEntries++;
        }
@@ -123,7 +154,7 @@ class BaseFileStack extends BaseStacker {
         *
         * @return      $seekPosition   Current seek position (stored here in object)
         */
-       private function getSeekPosition () {
+       private final function getSeekPosition () {
                // Get it
                return $this->seekPosition;
        }
@@ -134,7 +165,7 @@ class BaseFileStack extends BaseStacker {
         * @param       $seekPosition   Current seek position (stored here in object)
         * @return      void
         */
-       private function setSeekPosition ($seekPosition) {
+       private final function setSeekPosition ($seekPosition) {
                // And set it
                $this->seekPosition = $seekPosition;
        }
@@ -385,14 +416,37 @@ class BaseFileStack extends BaseStacker {
                //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
        }
 
+       /**
+        * Analyzes entries in stack file. This will count all found (and valid)
+        * entries, mark invalid as damaged and count gaps ("fragmentation"). If
+        * only gaps are found, the file is considered as "virgin" (no entries).
+        *
+        * @return      void
+        */
+       private function analyzeStackFile () {
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+
+               // Make sure the file is initialized
+               assert($this->isFileInitialized());
+
+               // Init counters and gaps array
+               $this->initCountersGapsArray();
+
+               // Output message (as this may take some time)
+               self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Analyzing file structure ... (this may take some time)', __METHOD__, __LINE__));
+
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
+       }
+
        /**
         * Initializes this file-based stack.
         *
         * @param       $fileName       File name of this stack
+        * @param       $type           Type of this stack (e.g. url_source for URL sources)
         * @return      void
         */
-       protected function initFileStack ($fileName) {
-               // Get a file i/o pointer instance
+       protected function initFileStack ($fileName, $type) {
+               // Get a file i/o pointer instance for stack file
                $pointerInstance = ObjectFactory::createObjectByConfiguredName('file_raw_input_output_class', array($fileName));
 
                // Get iterator instance
@@ -416,63 +470,17 @@ class BaseFileStack extends BaseStacker {
                // Load the file header
                $this->readFileHeader();
 
-               // Try to read file stack to speed up its processing.
-       }
-
-       /**
-        * Initializes given stacker
-        *
-        * @param       $stackerName    Name of the stack
-        * @param       $forceReInit    Force re-initialization
-        * @return      void
-        * @throws      AlreadyInitializedStackerException      If the stack is already initialized
-        */
-       public function initStack ($stackerName, $forceReInit = FALSE) {
-               // Is the stack already initialized?
-               if (($forceReInit === FALSE) && ($this->isStackInitialized($stackerName))) {
-                       // Then throw the exception
-                       throw new AlreadyInitializedStackerException(array($this, $stackerName, $forceReInit), self::EXCEPTION_STACKER_ALREADY_INITIALIZED);
-               } // END - if
-
-               // Initialize the given stack
-               $this->partialStub('stackerName=' . $stackerName . ',forceReInit=' . intval($forceReInit));
-       }
+               // Count all entries in file
+               $this->analyzeStackFile();
 
-       /**
-        * Checks whether the given stack is initialized (set in array $stackers)
-        *
-        * @param       $stackerName    Name of the stack
-        * @return      $isInitialized  Whether the stack is initialized
-        */
-       public function isStackInitialized ($stackerName) {
-               // Is is there?
-               $this->partialStub('stackerName=' . $stackerName);
-               $isInitialized = TRUE;
-
-               // Return result
-               return $isInitialized;
-       }
-
-       /**
-        * Getter for size of given stack (array count)
-        *
-        * @param       $stackerName    Name of the stack
-        * @return      $count                  Size of stack (array count)
-        * @throws      NoStackerException      If given stack is missing
-        */
-       public function getStackCount ($stackerName) {
-               // Is the stack not yet initialized?
-               if (!$this->isStackInitialized($stackerName)) {
-                       // Throw an exception
-                       throw new NoStackerException(array($this, $stackerName), self::EXCEPTION_NO_STACKER_FOUND);
-               } // END - if
-
-               // Now, count the array of entries
-               $this->partialStub('stackerName=' . $stackerName);
-               $count = 0;
+               /*
+                * Get stack index instance. This can be used for faster
+                * "defragmentation" and startup.
+                */
+               $indexInstance = FileStackIndexFactory::createFileStackIndexInstance($fileName, $type);
 
-               // Return result
-               return $count;
+               // And set it here
+               $this->setIndexInstance($indexInstance);
        }
 
        /**
@@ -481,17 +489,14 @@ class BaseFileStack extends BaseStacker {
         * @param       $stackerName    Name of the stack
         * @param       $value                  Value to add to this stacker
         * @return      void
-        * @throws      FullStackerException    Thrown if the stack is full
+        * @throws      FullStackerException    If the stack is full
         */
        protected function addValue ($stackerName, $value) {
-               // Is the stack not yet initialized or full?
-               if (!$this->isStackInitialized($stackerName)) {
-                       // Then do it here
-                       $this->initStack($stackerName);
-               } elseif ($this->isStackFull($stackerName)) {
+               // Do some tests
+               if ($this->isStackFull($stackerName)) {
                        // Stacker is full
                        throw new FullStackerException(array($this, $stackerName, $value), self::EXCEPTION_STACKER_IS_FULL);
-               }
+               } // END - if
 
                // Now add the value to the stack
                $this->partialStub('stackerName=' . $stackerName . ',value[]=' . gettype($value));
@@ -502,18 +507,14 @@ class BaseFileStack extends BaseStacker {
         *
         * @param       $stackerName    Name of the stack
         * @return      $value                  Value of last added value
-        * @throws      NoStackerException      If the named stacker was not found
-        * @throws      EmptyStackerException   If the named stacker is empty
+        * @throws      EmptyStackerException   If the stack is empty
         */
        protected function getLastValue ($stackerName) {
                // Is the stack not yet initialized or full?
-               if (!$this->isStackInitialized($stackerName)) {
-                       // Throw an exception
-                       throw new NoStackerException(array($this, $stackerName), self::EXCEPTION_NO_STACKER_FOUND);
-               } elseif ($this->isStackEmpty($stackerName)) {
+               if ($this->isStackEmpty($stackerName)) {
                        // Throw an exception
                        throw new EmptyStackerException(array($this, $stackerName), self::EXCEPTION_STACKER_IS_EMPTY);
-               }
+               } // END - if
 
                // Now get the last value
                $this->partialStub('stackerName=' . $stackerName);
@@ -528,18 +529,14 @@ class BaseFileStack extends BaseStacker {
         *
         * @param       $stackerName    Name of the stack
         * @return      $value                  Value of last added value
-        * @throws      NoStackerException      If the named stacker was not found
-        * @throws      EmptyStackerException   If the named stacker is empty
+        * @throws      EmptyStackerException   If the stack is empty
         */
        protected function getFirstValue ($stackerName) {
                // Is the stack not yet initialized or full?
-               if (!$this->isStackInitialized($stackerName)) {
-                       // Throw an exception
-                       throw new NoStackerException(array($this, $stackerName), self::EXCEPTION_NO_STACKER_FOUND);
-               } elseif ($this->isStackEmpty($stackerName)) {
+               if ($this->isStackEmpty($stackerName)) {
                        // Throw an exception
                        throw new EmptyStackerException(array($this, $stackerName), self::EXCEPTION_STACKER_IS_EMPTY);
-               }
+               } // END - if
 
                // Now get the first value
                $this->partialStub('stackerName=' . $stackerName);
@@ -554,18 +551,14 @@ class BaseFileStack extends BaseStacker {
         *
         * @param       $stackerName    Name of the stack
         * @return      $value                  Value "poped" from array
-        * @throws      NoStackerException      If the named stacker was not found
-        * @throws      EmptyStackerException   If the named stacker is empty
+        * @throws      EmptyStackerException   If the stack is empty
         */
        protected function popLast ($stackerName) {
                // Is the stack not yet initialized or full?
-               if (!$this->isStackInitialized($stackerName)) {
-                       // Throw an exception
-                       throw new NoStackerException(array($this, $stackerName), self::EXCEPTION_NO_STACKER_FOUND);
-               } elseif ($this->isStackEmpty($stackerName)) {
+               if ($this->isStackEmpty($stackerName)) {
                        // Throw an exception
                        throw new EmptyStackerException(array($this, $stackerName), self::EXCEPTION_STACKER_IS_EMPTY);
-               }
+               } // END - if
 
                // Now, remove the last entry, we don't care about the return value here, see elseif() block above
                $this->partialStub('stackerName=' . $stackerName);
@@ -577,23 +570,93 @@ class BaseFileStack extends BaseStacker {
         *
         * @param       $stackerName    Name of the stack
         * @return      $value                  Value "shifted" from array
-        * @throws      NoStackerException      If the named stacker was not found
         * @throws      EmptyStackerException   If the named stacker is empty
         */
        protected function popFirst ($stackerName) {
                // Is the stack not yet initialized or full?
-               if (!$this->isStackInitialized($stackerName)) {
-                       // Throw an exception
-                       throw new NoStackerException(array($this, $stackerName), self::EXCEPTION_NO_STACKER_FOUND);
-               } elseif ($this->isStackEmpty($stackerName)) {
+               if ($this->isStackEmpty($stackerName)) {
                        // Throw an exception
                        throw new EmptyStackerException(array($this, $stackerName), self::EXCEPTION_STACKER_IS_EMPTY);
-               }
+               } // END - if
 
                // Now, remove the last entry, we don't care about the return value here, see elseif() block above
                $this->partialStub('stackerName=' . $stackerName);
                return NULL;
        }
+
+       /**
+        * Checks whether the given stack is full
+        *
+        * @param       $stackerName    Name of the stack
+        * @return      $isFull                 Whether the stack is full
+        */
+       protected function isStackFull ($stackerName) {
+               // File-based stacks will only run full if the disk space is low.
+               // @TODO Please implement this, returning FALSE
+               $isFull = FALSE;
+
+               // Return result
+               return $isFull;
+       }
+
+       /**
+        * Checks whether the given stack is empty
+        *
+        * @param       $stackerName            Name of the stack
+        * @return      $isEmpty                        Whether the stack is empty
+        * @throws      NoStackerException      If given stack is missing
+        */
+       public function isStackEmpty ($stackerName) {
+               // So, is the stack empty?
+               $isEmpty = (($this->getStackCount($stackerName)) == 0);
+
+               // Return result
+               return $isEmpty;
+       }
+
+       /**
+        * Initializes given stacker
+        *
+        * @param       $stackerName    Name of the stack
+        * @param       $forceReInit    Force re-initialization
+        * @return      void
+        * @throws      UnsupportedOperationException   This method is not (and maybe never will be) supported
+        */
+       public function initStack ($stackerName, $forceReInit = FALSE) {
+               throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION);
+       }
+
+       /**
+        * Initializes all stacks
+        *
+        * @return      void
+        * @throws      UnsupportedOperationException   This method is not (and maybe never will be) supported
+        */
+       public function initStacks (array $stacks, $forceReInit = FALSE) {
+               throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION);
+       }
+
+       /**
+        * Checks whether the given stack is initialized (set in array $stackers)
+        *
+        * @param       $stackerName    Name of the stack
+        * @return      $isInitialized  Whether the stack is initialized
+        * @throws      UnsupportedOperationException   This method is not (and maybe never will be) supported
+        */
+       public function isStackInitialized ($stackerName) {
+               throw new UnsupportedOperationException(array($this, __FUNCTION__, $this->getIteratorInstance()->getPointerInstance()), self::EXCEPTION_UNSPPORTED_OPERATION);
+       }
+
+       /**
+        * Getter for size of given stack (array count)
+        *
+        * @param       $stackerName    Name of the stack
+        * @return      $count                  Size of stack (array count)
+        */
+       public function getStackCount ($stackerName) {
+               // Now, simply return the found count value, this must be up-to-date then!
+               return $this->getCounter();
+       }
 }
 
 // [EOF]