Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 11:56:18

0001 #ifndef GENERS_BINARYARCHIVEBASE_HH_
0002 #define GENERS_BINARYARCHIVEBASE_HH_
0003 
0004 #include <fstream>
0005 #include <sstream>
0006 
0007 #include "Alignment/Geners/interface/AbsArchive.hh"
0008 #include "Alignment/Geners/interface/AbsCatalog.hh"
0009 #include "Alignment/Geners/interface/CStringStream.hh"
0010 
0011 namespace gs {
0012   class BinaryArchiveBase : public AbsArchive {
0013   public:
0014     // The "mode" argument is a string which can have one or more
0015     // sections, separated by ":". The first section has the same
0016     // meaning as in the "fopen" call (see "man 3 fopen"). Additional
0017     // sections can specify other aspects of the archive behavior
0018     // using the format "option=value" if the default settings are
0019     // not suitable. The available options are:
0020     //
0021     // "z"   -- compression type. Possible option values are
0022     //           "n" -- no compression (default)
0023     //           "z" -- compress with zlib
0024     //           "b" -- compress with bzlib2
0025     //
0026     // "cl"  -- compression level (an integer between -1 and 9,
0027     //           -1 is default. Meanigful for zlib compression
0028     //           only. See zlib documentation for details.
0029     //
0030     // "cb"  -- compression buffer size in bytes (unsigned integer).
0031     //           Default is 1 MB.
0032     //
0033     // "cm"  -- minimum object size in bytes to compress (unsigned
0034     //           integer). Objects whose serialized size is below
0035     //           this limit are not compressed. Default is 1 KB.
0036     //
0037     // "cat" -- if the value is set to "i" (which means "internal"
0038     //           or "injected"), the catalog data will be injected
0039     //           into the data stream in addition to having it in
0040     //           a separate catalog file. This allows for catalog
0041     //           recovery from the data stream in cases of program
0042     //           failure but also increases the data file size.
0043     //           The default value of this option is "s" which means
0044     //           that the catalog data will be stored separately.
0045     //           This option is meaningful for new archives only,
0046     //           for existing archives the value of this option is
0047     //           taken from the archive header record.
0048     //
0049     // Example: "w+:z=z:cl=9:cm=2048:cat=s". This will compress
0050     // objects with 2 KB or larger size using level 9 zlib compression
0051     // (the best compression ratio possible in zlib which is also
0052     // the slowest). The archive will be open for reading and writing.
0053     // If an archive with the same name already exists, it will be
0054     // overwritten. The catalog will be stored in a separate file
0055     // created when the archive is closed, catalog recovery from the
0056     // data file(s) in case of a catastrophic program failure will not
0057     // be possible.
0058     //
0059     BinaryArchiveBase(const char *name, const char *mode);
0060 
0061     ~BinaryArchiveBase() override;
0062 
0063     inline bool isOpen() const override { return modeIsValid_ && catalog_; }
0064 
0065     inline bool isReadable() const override { return modeIsValid_ && catalog_ && (mode_ & std::ios_base::in); }
0066 
0067     inline bool isWritable() const override { return modeIsValid_ && catalog_ && (mode_ & std::ios_base::out); }
0068 
0069     // Error message produced in case the archive could not be opened
0070     inline std::string error() const override { return errorStream_ ? errorStream_->str() : std::string(""); }
0071 
0072     // Check whether the constructor "mode" argument was valid.
0073     // If it was not, derived classes should behave as if the
0074     // archive could not be opened.
0075     inline bool modeValid() const { return modeIsValid_; }
0076 
0077     inline unsigned long long size() const override { return catalog_ ? catalog_->size() : 0ULL; }
0078 
0079     inline unsigned long long smallestId() const override { return catalog_ ? catalog_->smallestId() : 0ULL; }
0080 
0081     inline unsigned long long largestId() const override { return catalog_ ? catalog_->largestId() : 0ULL; }
0082 
0083     inline bool idsAreContiguous() const override { return catalog_ ? catalog_->isContiguous() : false; }
0084 
0085     inline bool itemExists(const unsigned long long id) const override {
0086       return catalog_ ? catalog_->itemExists(id) : false;
0087     }
0088 
0089     void itemSearch(const SearchSpecifier &namePattern,
0090                     const SearchSpecifier &categoryPattern,
0091                     std::vector<unsigned long long> *idsFound) const override;
0092 
0093     inline std::shared_ptr<const CatalogEntry> catalogEntry(const unsigned long long id) override {
0094       return catalog_ ? catalog_->retrieveEntry(id)
0095                       : std::shared_ptr<const CatalogEntry>((const CatalogEntry *)nullptr);
0096     }
0097 
0098     // Inspection methods for compression options
0099     inline CStringStream::CompressionMode compressionMode() const { return cStream_->compressionMode(); }
0100 
0101     inline std::size_t compressionBufferSize() const { return cStream_->bufferSize(); }
0102 
0103     inline int compressionLevel() const { return cStream_->compressionLevel(); }
0104 
0105     inline unsigned minSizeToCompress() const { return cStream_->minSizeToCompress(); }
0106 
0107     // Inject metadata into the data stream when writing? If this
0108     // method returns "true", we either had "cat=i" in the opening
0109     // mode for a new archive or a corresponding flag was set in
0110     // the header of an existing archive data file.
0111     inline bool injectMetadata() const { return addCatalogToData_; }
0112 
0113     // The following method moves the "get pointer" of the stream
0114     // to the end of file as a side effect
0115     static bool isEmptyFile(std::fstream &s);
0116 
0117     // The following method converts the first section of the "mode"
0118     // argument into std::ios_base::openmode
0119     static std::ios_base::openmode parseMode(const char *mode);
0120 
0121   protected:
0122     inline AbsCatalog *catalog() const { return catalog_; }
0123 
0124     // Non-null catalog must be set exactly once. This object will
0125     // assume the catalog ownership. Null catalog can be set after
0126     // non-null in case some essential operation on the catalog has
0127     // failed (such as writing it to file) in order to indicate
0128     // failure to open the archive.
0129     void setCatalog(AbsCatalog *c);
0130 
0131     // Set compression mode (can be used when the catalog is read).
0132     // The argment must be consistent with one of the modes defined
0133     // in the CStringStream.hh header.
0134     inline void setCompressionMode(const unsigned cMode) {
0135       cStream_->setCompressionMode(static_cast<CStringStream::CompressionMode>(cMode));
0136     }
0137 
0138     // Stream for error messages. To be used from constructors
0139     // of derived classes in case of problems, to indicate the
0140     // reason why the archive could not be opened.
0141     inline std::ostringstream &errorStream() {
0142       if (!errorStream_)
0143         errorStream_ = new std::ostringstream();
0144       return *errorStream_;
0145     }
0146 
0147     // The following method opens a binary archive. It makes sure
0148     // that a proper header is written out in case an empty file
0149     // is open or in case the file is truncated, and that the header
0150     // is there when a non-empty file is open without truncation.
0151     // If the argument fstream is open when this method is invoked,
0152     // it is closed first. After invocation of this method, the
0153     // "injectMetadata()" flag will be properly set up for the
0154     // data file open last. If the method is not successful, it
0155     // closes the stream and throws an exception inherited from
0156     // "IOException".
0157     //
0158     void openDataFile(std::fstream &stream, const char *filename);
0159 
0160     // Stream mode used to open the archive data file(s)
0161     inline std::ios_base::openmode openmode() const { return mode_; }
0162 
0163     // Info needed for catalog recovery. These methods will return
0164     // null pointers if item metadata is not in the data stream.
0165     const ClassId *catalogEntryClassId() const { return storedEntryId_; }
0166     const ClassId *itemLocationClassId() const { return storedLocationId_; }
0167 
0168   public:
0169     BinaryArchiveBase() = delete;
0170     BinaryArchiveBase(const BinaryArchiveBase &) = delete;
0171     BinaryArchiveBase &operator=(const BinaryArchiveBase &) = delete;
0172 
0173   private:
0174     static bool parseArchiveOptions(std::ostringstream &errmes,
0175                                     const char *mode,
0176                                     CStringStream::CompressionMode *m,
0177                                     int *compressionLevel,
0178                                     unsigned *minSizeToCompress,
0179                                     unsigned *bufSize,
0180                                     bool *multiplexCatalog);
0181 
0182     void writeHeader(std::ostream &os);
0183 
0184     // The following method returns "true" if a correctly
0185     // formatted header was found
0186     bool readHeader(std::istream &is);
0187 
0188     void search(AbsReference &reference) override;
0189 
0190     // The derived classes must override the following two methods
0191     virtual std::ostream &plainOutputStream() = 0;
0192     virtual std::istream &plainInputStream(unsigned long long id,
0193                                            unsigned *compressionCode,
0194                                            unsigned long long *length) = 0;
0195 
0196     std::istream &inputStream(unsigned long long id, long long *sz) override;
0197     std::ostream &outputStream() override;
0198     std::ostream &compressedStream(std::ostream &uncompressed) override;
0199     unsigned flushCompressedRecord(std::ostream &compressed) override;
0200     void releaseClassIds();
0201 
0202     const std::ios_base::openmode mode_;
0203     std::ostringstream *errorStream_;
0204     CStringStream *cStream_;
0205     AbsCatalog *catalog_;
0206     ClassId *storedEntryId_;
0207     ClassId *storedLocationId_;
0208     bool catalogIsSet_;
0209     bool modeIsValid_;
0210     bool addCatalogToData_;
0211   };
0212 }  // namespace gs
0213 
0214 #endif  // GENERS_BINARYARCHIVEBASE_HH_