X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=inline;f=framework%2Fmain%2Fclasses%2Findex%2Ffile%2Fclass_BaseFileIndex.php;h=2b536cc4caa0784cfe29c5b1faf2b2afdf7f752c;hb=c837cb3fc838a6a303ed38b51ca7f4e9fc278fbd;hp=708875057d7c3d64488ee42a6c6fb542a81dbab1;hpb=79e6029823f993ec7503a399aa2fdbb95aadb2d1;p=core.git diff --git a/framework/main/classes/index/file/class_BaseFileIndex.php b/framework/main/classes/index/file/class_BaseFileIndex.php index 70887505..2b536cc4 100644 --- a/framework/main/classes/index/file/class_BaseFileIndex.php +++ b/framework/main/classes/index/file/class_BaseFileIndex.php @@ -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 * @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 . */ 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) )); } @@ -86,7 +100,7 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer { // And update seek position /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->updateSeekPosition() ...'); - $this->getIteratorInstance()->updateSeekPosition(); + $this->getIteratorInstance()->getBinaryFileInstance()->updateSeekPosition(); /* * Now split it: @@ -94,27 +108,33 @@ 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: HEADER_INDEX_ELEMENT_COUNT=%d,header()=%d', BinaryFile::HEADER_INDEX_ELEMENT_COUNT, 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 + 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 +153,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); + $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 +191,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(); + $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'); + $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(); + $this->getIteratorInstance()->getBinaryFileInstance()->createFileHeader(); // Mark as freshly created $created = true; @@ -210,7 +230,7 @@ abstract class BaseFileIndex extends BaseIndex implements FileIndexer { if (!$created) { // Analyze file structure /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BASE-FILE-INDEX: Calling this->iteratorInstance->analyzeFileStructure() ...'); - $this->getIteratorInstance()->analyzeFileStructure(); + $this->getIteratorInstance()->getBinaryFileInstance()->analyzeFileStructure(); } // Trace message @@ -230,9 +250,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 +268,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 +293,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))); } /** @@ -294,7 +319,7 @@ 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); + $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 +332,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))); }