X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=framework%2Fmain%2Fclasses%2Findex%2Ffile%2Fclass_BaseFileIndex.php;h=6a9169bc4be1b4d4b91045c5171ed208af476b88;hb=6c6bf6fe589285efaf8d66ae29bf2c12a1990365;hp=84cd783432233fd3faa532ed16f23e06ac0f602f;hpb=93c10cd8bbd88a27bdcd0e65956298666218f150;p=core.git diff --git a/framework/main/classes/index/file/class_BaseFileIndex.php b/framework/main/classes/index/file/class_BaseFileIndex.php index 84cd7834..6a9169bc 100644 --- a/framework/main/classes/index/file/class_BaseFileIndex.php +++ b/framework/main/classes/index/file/class_BaseFileIndex.php @@ -6,9 +6,11 @@ namespace Org\Mxchange\CoreFramework\Index\File; 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\Index\Indexable; -use Org\Mxchange\CoreFramework\Utils\String\StringUtils; +use Org\Mxchange\CoreFramework\Utils\Arrays\ArrayUtils; +use Org\Mxchange\CoreFramework\Utils\Strings\StringUtils; // Import SPL stuff use \OutOfBoundsException; @@ -20,7 +22,7 @@ use \UnexpectedValueException; * * @author Roland Haeder * @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 * @@ -65,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) )); } @@ -93,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: @@ -102,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!'); @@ -141,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)); @@ -179,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; @@ -217,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 @@ -238,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)) ); } @@ -256,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; } /** @@ -276,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))); } /** @@ -301,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)); @@ -315,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))); }