/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ORC_READER_IMPL_HH #define ORC_READER_IMPL_HH #include "orc/Int128.hh" #include "orc/OrcFile.hh" #include "orc/Reader.hh" #include "ColumnReader.hh" #include "orc/Exceptions.hh" #include "RLE.hh" #include "TypeImpl.hh" namespace orc { static const uint64_t DIRECTORY_SIZE_GUESS = 16 * 1024; /** * WriterVersion Implementation */ class WriterVersionImpl { private: WriterVersion version; public: // Known Versions with issues resolved // The static method below is to fix global constructors Clang warning static const WriterVersionImpl& VERSION_HIVE_8732(); WriterVersionImpl(WriterVersion ver) : version(ver) {} bool compareGT(const WriterVersion other) const { return version > other; } }; /** * State shared between Reader and Row Reader */ struct FileContents { std::unique_ptr stream; std::unique_ptr postscript; std::unique_ptr footer; std::unique_ptr schema; uint64_t blockSize; CompressionKind compression; MemoryPool *pool; std::ostream *errorStream; }; proto::StripeFooter getStripeFooter(const proto::StripeInformation& info, const FileContents& contents); class ReaderImpl; class ColumnSelector { private: std::map nameIdMap; std::map idTypeMap; const FileContents* contents; std::vector columns; // build map from type name and id, id to Type void buildTypeNameIdMap(const Type* type); std::string toDotColumnPath(); public: // Select a field by name void updateSelectedByName(std::vector& selectedColumns, const std::string& name); // Select a field by id void updateSelectedByFieldId(std::vector& selectedColumns, uint64_t fieldId); // Select a type by id void updateSelectedByTypeId(std::vector& selectedColumns, uint64_t typeId); // Select all of the recursive children of the given type. void selectChildren(std::vector& selectedColumns, const Type& type); // For each child of type, select it if one of its children // is selected. bool selectParents(std::vector& selectedColumns, const Type& type); /** * Constructor that selects columns. * @param contents of the file */ ColumnSelector(const FileContents* contents); // Select the columns from the RowReaderoptions object void updateSelected(std::vector& selectedColumns, const RowReaderOptions& options); // Select the columns from the Readeroptions object void updateSelected(std::vector& selectedColumns, const ReaderOptions& options); }; class RowReaderImpl : public RowReader { private: const Timezone& localTimezone; // contents std::shared_ptr contents; const bool throwOnHive11DecimalOverflow; const int32_t forcedScaleOnHive11Decimal; // inputs std::vector selectedColumns; // footer proto::Footer* footer; DataBuffer firstRowOfStripe; mutable std::unique_ptr selectedSchema; bool skipBloomFilters; // reading state uint64_t previousRow; uint64_t firstStripe; uint64_t currentStripe; uint64_t lastStripe; // the stripe AFTER the last one uint64_t currentRowInStripe; uint64_t rowsInCurrentStripe; proto::StripeInformation currentStripeInfo; proto::StripeFooter currentStripeFooter; std::unique_ptr reader; bool enableEncodedBlock; // internal methods void startNextStripe(); // row index of current stripe with column id as the key std::unordered_map rowIndexes; /** * Seek to the start of a row group in the current stripe * @param rowGroupEntryId the row group id to seek to */ void seekToRowGroup(uint32_t rowGroupEntryId); /** * Check if the file has bad bloom filters. We will skip using them in the * following reads. * @return true if it has. */ bool hasBadBloomFilters(); public: /** * Constructor that lets the user specify additional options. * @param contents of the file * @param options options for reading */ RowReaderImpl(std::shared_ptr contents, const RowReaderOptions& options); // Select the columns from the options object void updateSelected(); const std::vector getSelectedColumns() const override; const Type& getSelectedType() const override; std::unique_ptr createRowBatch(uint64_t size ) const override; bool next(ColumnVectorBatch& data) override; CompressionKind getCompression() const; uint64_t getCompressionSize() const; uint64_t getRowNumber() const override; void seekToRow(uint64_t rowNumber) override; const FileContents& getFileContents() const; bool getThrowOnHive11DecimalOverflow() const; int32_t getForcedScaleOnHive11Decimal() const; }; class ReaderImpl : public Reader { private: // FileContents std::shared_ptr contents; // inputs const ReaderOptions options; const uint64_t fileLength; const uint64_t postscriptLength; // footer proto::Footer* footer; uint64_t numberOfStripes; uint64_t getMemoryUse(int stripeIx, std::vector& selectedColumns); // internal methods void readMetadata() const; void checkOrcVersion(); void getRowIndexStatistics(const proto::StripeInformation& stripeInfo, uint64_t stripeIndex, const proto::StripeFooter& currentStripeFooter, std::vector >* indexStats) const; // metadata mutable std::unique_ptr metadata; mutable bool isMetadataLoaded; public: /** * Constructor that lets the user specify additional options. * @param contents of the file * @param options options for reading * @param fileLength the length of the file in bytes * @param postscriptLength the length of the postscript in bytes */ ReaderImpl(std::shared_ptr contents, const ReaderOptions& options, uint64_t fileLength, uint64_t postscriptLength); const ReaderOptions& getReaderOptions() const; CompressionKind getCompression() const override; FileVersion getFormatVersion() const override; WriterId getWriterId() const override; uint32_t getWriterIdValue() const override; std::string getSoftwareVersion() const override; WriterVersion getWriterVersion() const override; uint64_t getNumberOfRows() const override; uint64_t getRowIndexStride() const override; std::list getMetadataKeys() const override; std::string getMetadataValue(const std::string& key) const override; bool hasMetadataValue(const std::string& key) const override; uint64_t getCompressionSize() const override; uint64_t getNumberOfStripes() const override; std::unique_ptr getStripe(uint64_t ) const override; uint64_t getNumberOfStripeStatistics() const override; const std::string& getStreamName() const override; std::unique_ptr getStripeStatistics(uint64_t stripeIndex) const override; std::unique_ptr createRowReader() const override; std::unique_ptr createRowReader(const RowReaderOptions& options ) const override; uint64_t getContentLength() const override; uint64_t getStripeStatisticsLength() const override; uint64_t getFileFooterLength() const override; uint64_t getFilePostscriptLength() const override; uint64_t getFileLength() const override; std::unique_ptr getStatistics() const override; std::unique_ptr getColumnStatistics(uint32_t columnId ) const override; std::string getSerializedFileTail() const override; const Type& getType() const override; bool hasCorrectStatistics() const override; const proto::PostScript* getPostscript() const {return contents->postscript.get();} uint64_t getBlockSize() const {return contents->blockSize;} const proto::Footer* getFooter() const {return contents->footer.get();} const Type* getSchema() const {return contents->schema.get();} InputStream* getStream() const {return contents->stream.get();} uint64_t getMemoryUse(int stripeIx = -1) override; uint64_t getMemoryUseByFieldId(const std::list& include, int stripeIx=-1) override; uint64_t getMemoryUseByName(const std::list& names, int stripeIx=-1) override; uint64_t getMemoryUseByTypeId(const std::list& include, int stripeIx=-1) override; std::map getBloomFilters(uint32_t stripeIndex, const std::set& included) const override; }; }// namespace #endif