]> git.mxchange.org Git - core.git/blobdiff - framework/main/classes/index/file/class_BaseFileIndex.php
Continued:
[core.git] / framework / main / classes / index / file / class_BaseFileIndex.php
index 708875057d7c3d64488ee42a6c6fb542a81dbab1..6a9169bc4be1b4d4b91045c5171ed208af476b88 100644 (file)
@@ -3,10 +3,14 @@
 namespace Org\Mxchange\CoreFramework\Index\File;
 
 // Import framework stuff
+use Org\Mxchange\CoreFramework\EntryPoint\ApplicationEntryPoint;
 use Org\Mxchange\CoreFramework\Factory\Object\ObjectFactory;
 use Org\Mxchange\CoreFramework\Filesystem\File\BaseBinaryFile;
+use Org\Mxchange\CoreFramework\Filesystem\File\BinaryFile;
 use Org\Mxchange\CoreFramework\Index\BaseIndex;
-use Org\Mxchange\CoreFramework\Utils\String\StringUtils;
+use Org\Mxchange\CoreFramework\Index\Indexable;
+use Org\Mxchange\CoreFramework\Utils\Arrays\ArrayUtils;
+use Org\Mxchange\CoreFramework\Utils\Strings\StringUtils;
 
 // Import SPL stuff
 use \OutOfBoundsException;
@@ -18,7 +22,7 @@ use \UnexpectedValueException;
  *
  * @author             Roland Haeder <webmaster@ship-simu.org>
  * @version            0.0.0
- * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2020 Core Developer Team
+ * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2021 Core Developer Team
  * @license            GNU GPL 3.0 or any newer version
  * @link               http://www.ship-simu.org
  *
@@ -36,14 +40,20 @@ use \UnexpectedValueException;
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 abstract class BaseFileIndex extends BaseIndex implements FileIndexer {
+       /**
+        * Minimum block length
+        */
+       private static $minimumBlockLength = 0;
+
        /**
         * Protected constructor
         *
+        * @param       $className      Name of class
         * @return      void
         */
-       protected function __construct () {
+       protected function __construct (string $className) {
                // Call parent constructor
-               parent::__construct(__CLASS__);
+               parent::__construct($className);
        }
 
        /**
@@ -57,27 +67,31 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer {
                /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: CALLED!');
                $this->getIteratorInstance()->rewind();
 
+               // Get header size
+               $headerSize = $this->getIteratorInstance()->getBinaryFileInstance()->getHeaderSize();
+
                // Then read it (see constructor for calculation)
-               $data = $this->getIteratorInstance()->read($this->getIteratorInstance()->getHeaderSize());
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: headerSize=%d', $headerSize));
+               $data = $this->getIteratorInstance()->getBinaryFileInstance()->read($headerSize);
 
                // Have all requested bytes been read?
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: Read %d bytes (%d wanted).', strlen($data), $this->getIteratorInstance()->getHeaderSize()));
-               if (strlen($data) != $this->getIteratorInstance()->getHeaderSize()) {
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: Read %d bytes (%d wanted).', strlen($data), $this->getIteratorInstance()->getBinaryFileInstance()->getHeaderSize()));
+               if (strlen($data) != $this->getIteratorInstance()->getBinaryFileInstance()->getHeaderSize()) {
                        // Invalid header length
                        throw new UnexpectedValueException(sprintf('data(%d)=%s is not expected length %d',
                                strlen($data),
                                $data,
-                               $this->getIteratorInstance()->getHeaderSize()
+                               $this->getIteratorInstance()->getBinaryFileInstance()->getHeaderSize()
                        ));
                } elseif (empty(trim($data, chr(0)))) {
                        // Empty file header
                        /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: File header is empty - EXIT!');
                        return;
-               } elseif (substr($data, -1, 1) != chr(BaseBinaryFile::SEPARATOR_HEADER_ENTRIES)) {
+               } elseif (substr($data, -1, 1) != chr(BinaryFile::SEPARATOR_HEADER_ENTRIES)) {
                        // Bad last character
                        throw new UnexpectedValueException(sprintf('data=%s does not end with "%s"',
                                $data,
-                               chr(BaseBinaryFile::SEPARATOR_HEADER_ENTRIES)
+                               chr(BinaryFile::SEPARATOR_HEADER_ENTRIES)
                        ));
                }
 
@@ -85,8 +99,8 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer {
                $data = substr($data, 0, -1);
 
                // And update seek position
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->updateSeekPosition() ...');
-               $this->getIteratorInstance()->updateSeekPosition();
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->binaryFileInstance->updateSeekPosition() ...');
+               $this->getIteratorInstance()->getBinaryFileInstance()->updateSeekPosition();
 
                /*
                 * Now split it:
@@ -94,27 +108,34 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer {
                 * 0 => magic
                 * 1 => total entries
                 */
-               $header = explode(chr(BaseBinaryFile::SEPARATOR_HEADER_DATA), $data);
+               $header = explode(chr(BinaryFile::SEPARATOR_HEADER_DATA), $data);
 
-               // Check if the array has only 3 elements
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: header()=%d', count($header)));
+               // Map numeric entries to associative (alpha-numeric) elements
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: Calling ArrayUtils::mapNumericKeysToAssociative(%d) ...', count($header)));
                //* PRINTR-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: header(%d)=%s', count($header), print_r($header, true)));
-               if (count($header) != 2) {
+               $header = ArrayUtils::mapNumericKeysToAssociative($header, [
+                       BinaryFile::HEADER_NAME_MAGIC,
+                       BinaryFile::HEADER_NAME_TOTAL_ENTRIES,
+               ]);
+
+               // Check if the array has only 2 elements
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: HEADER_INDEX_ELEMENT_COUNT=%d,header()=%d', BinaryFile::HEADER_INDEX_ELEMENT_COUNT, count($header)));
+               if (count($header) != BinaryFile::HEADER_INDEX_ELEMENT_COUNT) {
                        // Bad header
-                       throw new UnexpectedValueException(sprintf('header()=%d is not expected value 2', count($header)));
-               } elseif ($header[0] !== Indexable::INDEX_MAGIC) {
+                       throw new UnexpectedValueException(sprintf('header()=%d is not expected value %d', count($header), BinaryFile::HEADER_INDEX_ELEMENT_COUNT));
+               } elseif ($header[BinaryFile::HEADER_NAME_MAGIC] !== Indexable::INDEX_MAGIC) {
                        // Magic must be in first element
-                       throw new UnexpectedValueException(sprintf('header[0]=%s is not the expected magic (%s)', $header[0], Indexable::INDEX_MAGIC));
-               } elseif (strlen($header[1]) != BaseBinaryFile::LENGTH_COUNT) {
+                       throw new UnexpectedValueException(sprintf('header[%s]=%s is not the expected magic (%s)', BinaryFile::HEADER_NAME_MAGIC, $header[BinaryFile::HEADER_NAME_MAGIC], Indexable::INDEX_MAGIC));
+               } elseif (strlen($header[BinaryFile::HEADER_NAME_TOTAL_ENTRIES]) != BinaryFile::LENGTH_COUNT) {
                        // Length of total entries not matching
-                       throw new UnexpectedValueException(sprintf('header[1](%d)=%s does not have expected length %d', strlen($header[1]), $header[1], BaseBinaryFile::LENGTH_COUNT));
+                       throw new UnexpectedValueException(sprintf('header[%s](%d)=%s does not have expected length %d', BinaryFile::HEADER_NAME_TOTAL_ENTRIES, strlen($header[BinaryFile::HEADER_NAME_TOTAL_ENTRIES]), $header[BinaryFile::HEADER_NAME_TOTAL_ENTRIES], BinaryFile::LENGTH_COUNT));
                }
 
                // Decode count
-               $header[1] = hex2bin($header[1]);
+               $header[BinaryFile::HEADER_NAME_TOTAL_ENTRIES] = hex2bin($header[BinaryFile::HEADER_NAME_TOTAL_ENTRIES]);
 
                // Set it here
-               $this->getIteratorInstance()->setHeader($header);
+               $this->getIteratorInstance()->getBinaryFileInstance()->setHeader($header);
 
                // Trace message
                /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: EXIT!');
@@ -133,31 +154,31 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer {
                        Indexable::INDEX_MAGIC,
 
                        // Separator header data
-                       chr(BaseBinaryFile::SEPARATOR_HEADER_DATA),
+                       chr(BinaryFile::SEPARATOR_HEADER_DATA),
 
                        // Total entries
-                       str_pad(StringUtils::dec2hex($this->getIteratorInstance()->getCounter()), BaseBinaryFile::LENGTH_COUNT, '0', STR_PAD_LEFT),
+                       str_pad(StringUtils::dec2hex($this->getIteratorInstance()->getBinaryFileInstance()->getCounter()), BinaryFile::LENGTH_COUNT, '0', STR_PAD_LEFT),
 
                        // Separator header<->entries
-                       chr(BaseBinaryFile::SEPARATOR_HEADER_ENTRIES)
+                       chr(BinaryFile::SEPARATOR_HEADER_ENTRIES)
                );
 
                // Write it to disk (header is always at seek position 0)
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: Calling this->iteratorInstance->writeAtPosition(0, header=%s) ...', $header));
-               $this->getIteratorInstance()->writeAtPosition(0, $header);
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: Calling this->iteratorInstance->binaryFileInstance->writeAtPosition(0, header=%s) ...', $header));
+               $this->getIteratorInstance()->getBinaryFileInstance()->writeAtPosition(0, $header);
 
                // Trace message
                /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: EXIT!');
        }
 
        /**
-        * Initializes this index
+        * Initializes this file-based index
         *
         * @param       $fileInfoInstance       An instance of a SplFileInfo class
         * @return      void
         * @todo        Currently the index file is not cached, please implement a memory-handling class and if enough RAM is found, cache the whole index file.
         */
-       protected function initIndex (SplFileInfo $fileInfoInstance) {
+       protected function initFileIndex (SplFileInfo $fileInfoInstance) {
                // Get a file i/o pointer instance for index file
                /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: fileInfoInstance[%s]=%s - CALLED!', get_class($fileInfoInstance), $fileInfoInstance));
                $fileInstance = ObjectFactory::createObjectByConfiguredName('index_file_class', array($fileInfoInstance, $this));
@@ -171,31 +192,31 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer {
                // Calculate header size
                $headerSize = (
                        strlen(Indexable::INDEX_MAGIC) +
-                       strlen(chr(BaseBinaryFile::SEPARATOR_HEADER_DATA)) +
-                       BaseBinaryFile::LENGTH_COUNT +
-                       strlen(chr(BaseBinaryFile::SEPARATOR_HEADER_ENTRIES))
+                       strlen(chr(BinaryFile::SEPARATOR_HEADER_DATA)) +
+                       BinaryFile::LENGTH_COUNT +
+                       strlen(chr(BinaryFile::SEPARATOR_HEADER_ENTRIES))
                );
 
                // Set it
                /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: Setting headerSize=%d ...', $headerSize));
-               $this->getIteratorInstance()->setHeaderSize($headerSize);
+               $this->getIteratorInstance()->getBinaryFileInstance()->setHeaderSize($headerSize);
 
                // Init counters and gaps array
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->initCountersGapsArray() ...');
-               $this->getIteratorInstance()->initCountersGapsArray();
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->binaryFileInstance->initCountersGapsArray() ...');
+               $this->getIteratorInstance()->getBinaryFileInstance()->initCountersGapsArray();
 
                // Default is not created
                $created = false;
 
                // Is the file's header initialized?
-               if (!$this->getIteratorInstance()->isFileHeaderInitialized()) {
+               if (!$this->getIteratorInstance()->getBinaryFileInstance()->isFileHeaderInitialized()) {
                        // First pre-allocate a bit
-                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->preAllocateFile(index) ...');
-                       $this->getIteratorInstance()->preAllocateFile('index');
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->binaryFileInstance->preAllocateFile(index) ...');
+                       $this->getIteratorInstance()->getBinaryFileInstance()->preAllocateFile('index');
 
                        // Then write file header
-                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->createFileHeader() ...');
-                       $this->getIteratorInstance()->createFileHeader();
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->binaryFileInstance->createFileHeader() ...');
+                       $this->getIteratorInstance()->getBinaryFileInstance()->createFileHeader();
 
                        // Mark as freshly created
                        $created = true;
@@ -209,8 +230,8 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer {
                /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: created=%d', intval($created)));
                if (!$created) {
                        // Analyze file structure
-                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->analyzeFileStructure() ...');
-                       $this->getIteratorInstance()->analyzeFileStructure();
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->binaryFileInstance->analyzeFileStructure() ...');
+                       $this->getIteratorInstance()->getBinaryFileInstance()->analyzeFileStructure();
                }
 
                // Trace message
@@ -230,9 +251,9 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer {
                        //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calculating ...');
                        self::$minimumBlockLength = (
                                // Type
-                               BaseBinaryFile::LENGTH_TYPE + strlen(chr(BaseBinaryFile::SEPARATOR_TYPE_POSITION)) +
+                               BinaryFile::LENGTH_TYPE + strlen(chr(BinaryFile::SEPARATOR_TYPE_POSITION)) +
                                // Position
-                               BaseBinaryFile::LENGTH_POSITION + strlen(chr(BaseBinaryFile::SEPARATOR_ENTRIES))
+                               BinaryFile::LENGTH_POSITION + strlen(chr(BinaryFile::SEPARATOR_ENTRIES))
                        );
                }
 
@@ -248,7 +269,12 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer {
         */
        public function getFileSize () {
                // Call iterator's method
-               return $this->getIteratorInstance()->getFileSize();
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: CALLED!');
+               $fileSize = $this->getIteratorInstance()->getBinaryFileInstance()->getFileSize();
+
+               // Return it
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: fileSize=%d - EXIT!', $fileSize));
+               return $fileSize;
        }
 
        /**
@@ -268,8 +294,8 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer {
                        throw new InvalidArgumentException(sprintf('length=%d is not valid', $length));
                }
 
-               // Partial stub!
-               $this->partialStub('length=' . $length);
+               // Debug message
+               /* DEBUG-DIE: */ ApplicationEntryPoint::exitApplication(sprintf('[%s:%d]: length=%d,this=%s', __METHOD__, __LINE__, $length, print_r($this, true)));
        }
 
        /**
@@ -293,8 +319,8 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer {
                }
 
                // Call iterated object's method
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: Calling this->iteratorInstance->writeAtPosition(%d, %s) ...', $seekPosition, $dataStream));
-               $status = $this->getIteratorInstance()->writeAtPosition($seekPosition, $dataStream);
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: Calling this->iteratorInstance->binaryFileInstance->writeAtPosition(%d, %s) ...', $seekPosition, $dataStream));
+               $status = $this->getIteratorInstance()->getBinaryFileInstance()->writeAtPosition($seekPosition, $dataStream);
 
                // Return status
                /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BASE-FILE-INDEX: status[%s]=%d - EXIT!', gettype($status), $status));
@@ -307,8 +333,15 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer {
         * @return      $isLoaded       Whether this index has been loaded
         */
        public function isIndexLoaded () {
-               // Trace message
+               // Is the file gaps-only?
                /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: CALLED!');
+               if ($this->getIteratorInstance()->getBinaryFileInstance()->isFileGapsOnly()) {
+                       // Then skip below code as this implies the file has been fully analyzed and "loaded"
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Underlaying file is gaps-only: Returning TRUE ... - EXIT!');
+                       return TRUE;
+               }
+
+               // Debug message
                /* DEBUG-DIE: */ ApplicationEntryPoint::exitApplication(sprintf('[%s:%d]: this=%s', __METHOD__, __LINE__, print_r($this, true)));
        }