Fixed typo.
[core.git] / inc / classes / main / stacker / file / class_BaseFileStack.php
index 8491479d9a41ae7efc474d374b68a688218a1434..6f55182793b19a9c459f96bbc9a013381d5a7635 100644 (file)
@@ -42,6 +42,11 @@ class BaseFileStack extends BaseStacker {
         */
        const SEPARATOR_HASH_NAME = 0x05;
 
+       /**
+        * Length of name
+        */
+       const COUNT_NAME = 10;
+
        /**
         * Length of count
         */
@@ -52,6 +57,16 @@ class BaseFileStack extends BaseStacker {
         */
        const COUNT_POSITION = 20;
 
+       /**
+        * Counter for total entries
+        */
+       private $totalEntries = 0;
+
+       /**
+        * Current seek position
+        */
+       private $seekPosition = 0;
+
        /**
         * Protected constructor
         *
@@ -63,25 +78,93 @@ class BaseFileStack extends BaseStacker {
                parent::__construct($className);
        }
 
+       /**
+        * Getter for total entries
+        *
+        * @return      $totalEntries   Total entries in this stack
+        */
+       private function getCounter () {
+               // Get it
+               return $this->totalEntries;
+       }
+
+       /**
+        * Increment counter
+        *
+        * @return      void
+        */
+       private function incrementCounter () {
+               // Get it
+               $this->totalEntries++;
+       }
+
+       /**
+        * Getter for seek position
+        *
+        * @return      $seekPosition   Current seek position (stored here in object)
+        */
+       private function getSeekPosition () {
+               // Get it
+               return $this->seekPosition;
+       }
+
+       /**
+        * Setter for seek position
+        *
+        * @param       $seekPosition   Current seek position (stored here in object)
+        * @return      void
+        */
+       private function setSeekPosition ($seekPosition) {
+               // And set it
+               $this->seekPosition = $seekPosition;
+       }
+
+       /**
+        * Updates seekPosition attribute from file to avoid to much access on file.
+        *
+        * @return      void
+        */
+       private function updateSeekPosition () {
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+
+               // Get key (= seek position)
+               $seekPosition = $this->getIteratorInstance()->key();
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Setting seekPosition=%s', __METHOD__, __LINE__, $seekPosition));
+
+               // And set it here
+               $this->setSeekPosition($seekPosition);
+
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
+       }
+
        /**
         * Checks whether the file header is initialized
         *
         * @return      $isInitialized  Whether the file header is initialized
         */
        private function isFileHeaderInitialized () {
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
                // Default is not initialized
                $isInitialized = FALSE;
 
                // Is the file initialized?
                if ($this->isFileInitialized()) {
                        // Some bytes has been written, so rewind to start of it.
-                       $this->getIteratorInstance()->rewind();
+                       $rewindStatus = $this->getIteratorInstance()->rewind();
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] rewindStatus=%s', __METHOD__, __LINE__, $rewindStatus));
+
+                       // Is the rewind() call successfull?
+                       if ($rewindStatus != 1) {
+                               // Something bad happened
+                               self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Could not rewind().', __METHOD__, __LINE__));
+                       } // END - if
 
                        // Read file header
                        $this->readFileHeader();
                } // END - if
 
                // Return result
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] isInitialized=%d - EXIT!', __METHOD__, __LINE__, intval($isInitialized)));
                return $isInitialized;
        }
 
@@ -91,11 +174,11 @@ class BaseFileStack extends BaseStacker {
         * @return      $isInitialized          Whether the file's size is zero
         */
        private function isFileInitialized () {
-               // Default is not initialized
-               $isInitialized = FALSE;
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
 
                // Get it from iterator which holds the pointer instance. If FALSE is returned
                $fileSize = $this->getIteratorInstance()->size();
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] fileSize=%s', __METHOD__, __LINE__, $fileSize));
 
                /*
                 * The returned file size should not be FALSE or NULL as this means
@@ -104,12 +187,10 @@ class BaseFileStack extends BaseStacker {
                assert(is_int($fileSize));
 
                // Is more than 0 returned?
-               if ($fileSize > 0) {
-                       // So is the header written?
-                       $isInitialized = $this->getIteratorInstance()->isHeaderInitialized();
-               } // END - if
+               $isInitialized = ($fileSize > 0);
 
                // Return result
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] isInitialized=%d - EXIT!', __METHOD__, __LINE__, intval($isInitialized)));
                return $isInitialized;
        }
 
@@ -119,14 +200,14 @@ class BaseFileStack extends BaseStacker {
         * @return      void
         */
        private function createFileHeader () {
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
                // The file's header should not be initialized here
                assert(!$this->isFileHeaderInitialized());
 
-               // Init  counter
-               $this->getIteratorInstance()->initCounter();
-
                // Flush file header
                $this->flushFileHeader();
+
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!!', __METHOD__, __LINE__));
        }
 
        /**
@@ -135,6 +216,8 @@ class BaseFileStack extends BaseStacker {
         * @return      void
         */
        private function flushFileHeader () {
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+
                // Put all informations together
                $header = sprintf('%s%s%s%s%s',
                        // Magic
@@ -144,7 +227,7 @@ class BaseFileStack extends BaseStacker {
                        chr(self::SEPARATOR_MAGIC_COUNT),
 
                        // Total entries (will be zero) and pad it to 20 chars
-                       str_pad($this->dec2hex($this->getIteratorInstance()->getCount()), self::COUNT_LENGTH, '0', STR_PAD_LEFT),
+                       str_pad($this->dec2hex($this->getCounter()), self::COUNT_LENGTH, '0', STR_PAD_LEFT),
 
                        // Position (will be zero)
                        str_pad($this->dec2hex(0, 2), self::COUNT_POSITION, '0', STR_PAD_LEFT),
@@ -153,8 +236,50 @@ class BaseFileStack extends BaseStacker {
                        chr(self::SEPARATOR_SEEK_POS_ENTRIES)
                );
 
-               // Write it to disk
+               // Write it to disk (header is always at seek position 0)
                $this->getIteratorInstance()->writeAtPosition(0, $header);
+
+               // Update seek position
+               $this->updateSeekPosition();
+
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
+       }
+
+       /**
+        * Pre-allocates file (if enabled) with some space for later faster write access.
+        *
+        * @return      void
+        */
+       private function preAllocateFile () {
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+
+               // Is it enabled?
+               if ($this->getConfigInstance()->getConfigEntry('file_stack_pre_allocate_enabled') != 'Y') {
+                       // Not enabled
+                       self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Not pre-allocating stack file.', __METHOD__, __LINE__));
+
+                       // Don't continue here.
+                       return;
+               } // END - if
+
+               // Message to user
+               self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Pre-allocating stack file ...', __METHOD__, __LINE__));
+
+               /*
+                * Calculate minimum length for one entry:
+                * minimum length = hash length + separator + name + minimum entry size = ?? + 1 + 10 + 1 = ??
+                */
+               $minLengthEntry = self::getHashLength() + strlen(self::SEPARATOR_HASH_NAME) + self::COUNT_NAME + 1;
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] minLengthEntry=%s', __METHOD__, __LINE__, $minLengthEntry));
+
+               // Calulcate seek position
+               $seekPosition = $minLengthEntry * $this->getConfigInstance()->getConfigEntry('file_stack_pre_allocate_count');
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] seekPosition=%s', __METHOD__, __LINE__, $seekPosition));
+
+               // Now seek to the position
+               $this->getIteratorInstance()->seek($seekPosition);
+
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
        }
 
        /**