You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ch...@apache.org on 2012/12/19 21:34:58 UTC
svn commit: r1424091 [6/9] - in /qpid/trunk/qpid/cpp/src: ./
qpid/legacystore/ qpid/legacystore/jrnl/
Added: qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jdir.hpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jdir.hpp?rev=1424091&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jdir.hpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jdir.hpp Wed Dec 19 20:34:56 2012
@@ -0,0 +1,382 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file jdir.hpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * File containing code for class mrg::journal::jdir (%journal data
+ * directory), used for controlling and manipulating %journal data
+ * directories and files. See class documentation for details.
+ *
+ * \author Kim van der Riet
+ *
+ * Copyright (c) 2007, 2008 Red Hat, Inc.
+ *
+ */
+
+#ifndef mrg_journal_jdir_hpp
+#define mrg_journal_jdir_hpp
+
+namespace mrg
+{
+namespace journal
+{
+class jdir;
+}
+}
+
+#include "jrnl/jinf.hpp"
+#include <dirent.h>
+
+namespace mrg
+{
+namespace journal
+{
+
+ /**
+ * \class jdir
+ * \brief Class to manage the %journal directory
+ */
+ class jdir
+ {
+ private:
+ std::string _dirname;
+ std::string _base_filename;
+
+ public:
+
+ /**
+ * \brief Sole constructor
+ *
+ * \param dirname Name of directory to be managed.
+ * \param base_filename Filename root used in the creation of %journal files
+ * and sub-directories.
+ */
+ jdir(const std::string& dirname, const std::string& base_filename);
+
+ virtual ~jdir();
+
+
+ /**
+ * \brief Create %journal directory as set in the dirname parameter of the constructor.
+ * Recursive creation is supported.
+ *
+ * \exception jerrno::JERR_JDIR_MKDIR The creation of dirname failed.
+ */
+ void create_dir();
+
+ /**
+ * \brief Static function to create a directory. Recursive creation is supported.
+ *
+ * \param dirname C-string containing name of directory.
+ *
+ * \exception jerrno::JERR_JDIR_MKDIR The creation of dirname failed.
+ */
+ static void create_dir(const char* dirname);
+
+ /**
+ * \brief Static function to create a directory. Recursive creation is supported.
+ *
+ * \param dirname String containing name of directory.
+ *
+ * \exception jerrno::JERR_JDIR_MKDIR The creation of dirname failed.
+ */
+ static void create_dir(const std::string& dirname);
+
+
+ /**
+ * \brief Clear the %journal directory of files matching the base filename
+ * by moving them into a subdirectory. This fn uses the dirname and base_filename
+ * that were set on construction.
+ *
+ * \param create_flag If set, create dirname if it is non-existent, otherwise throw
+ * exception.
+ *
+ * \exception jerrno::JERR_JDIR_OPENDIR The %journal directory could not be opened.
+ * \exception jerrno::JERR_JDIR_FMOVE Moving the files from the %journal directory to the created backup
+ * directory failed.
+ * \exception jerrno::JERR_JDIR_CLOSEDIR The directory handle could not be closed.
+ */
+ void clear_dir(const bool create_flag = true);
+
+ /**
+ * \brief Clear the directory dirname of %journal files matching base_filename
+ * by moving them into a subdirectory.
+ *
+ * \param dirname C-string containing name of %journal directory.
+ * \param base_filename C-string containing base filename of %journal files to be matched
+ * for moving into subdirectory.
+ * \param create_flag If set, create dirname if it is non-existent, otherwise throw
+ * exception
+ *
+ * \exception jerrno::JERR_JDIR_OPENDIR The %journal directory could not be opened.
+ * \exception jerrno::JERR_JDIR_FMOVE Moving the files from the %journal directory to the created backup
+ * directory failed.
+ * \exception jerrno::JERR_JDIR_CLOSEDIR The directory handle could not be closed.
+ */
+ static void clear_dir(const char* dirname, const char* base_filename,
+ const bool create_flag = true);
+
+ /**
+ * \brief Clear the directory dirname of %journal files matching base_filename
+ * by moving them into a subdirectory.
+ *
+ * \param dirname String containing name of %journal directory.
+ * \param base_filename String containing base filename of %journal files to be matched
+ * for moving into subdirectory.
+ * \param create_flag If set, create dirname if it is non-existent, otherwise throw
+ * exception
+ *
+ * \exception jerrno::JERR_JDIR_OPENDIR The %journal directory could not be opened.
+ * \exception jerrno::JERR_JDIR_FMOVE Moving the files from the %journal directory to the created backup
+ * directory failed.
+ * \exception jerrno::JERR_JDIR_CLOSEDIR The directory handle could not be closed.
+ */
+ static void clear_dir(const std::string& dirname, const std::string& base_filename,
+ const bool create_flag = true);
+
+
+
+ /**
+ * \brief Move (push down) the directory target_dir located in directory dirname into a backup directory
+ * named _bak_dir_base.XXXX (note prepended underscore), where XXXX is an increasing hex serial number
+ * starting at 0000.
+ *
+ * \param dirname Full path to directory containing directory to be pushed down.
+ * \param target_dir Name of directory in dirname to be pushed down.
+ * \param bak_dir_base Base name for backup directory to be created in dirname, into which target_dir will be moved.
+ * \return Name of backup dir into which target_dir was pushed.
+ */
+ static std::string push_down(const std::string& dirname, const std::string& target_dir, const std::string& bak_dir_base);
+
+
+ /**
+ * \brief Verify that dirname is a valid %journal directory.
+ *
+ * The validation reads the .%jinf file, and using this information verifies that all the expected %journal
+ * (.jdat) files are present.
+ *
+ * \exception jerrno::JERR_JDIR_NOTDIR dirname is not a directory
+ * \exception jerrno::JERR_JDIR_STAT Could not stat dirname
+ * \exception jerrno::JERR__FILEIO Error reading %jinf file
+ * \exception jerrno::JERR_JINF_CVALIDFAIL Error validating %jinf file
+ * \exception jerrno::JERR_JDIR_NOSUCHFILE Expected jdat file is missing
+ */
+ void verify_dir();
+
+ /**
+ * \brief Verify that dirname is a valid %journal directory.
+ *
+ * The validation reads the .%jinf file, and using this information verifies that all the expected %journal
+ * (.jdat) files are present.
+ *
+ * \param dirname C-string containing name of %journal directory.
+ * \param base_filename C-string containing base filename of %journal files to be matched for moving into sub-directory.
+ *
+ * \exception jerrno::JERR_JDIR_NOTDIR dirname is not a directory
+ * \exception jerrno::JERR_JDIR_STAT Could not stat dirname
+ * \exception jerrno::JERR__FILEIO Error reading %jinf file
+ * \exception jerrno::JERR_JINF_CVALIDFAIL Error validating %jinf file
+ * \exception jerrno::JERR_JDIR_NOSUCHFILE Expected jdat file is missing
+ */
+ static void verify_dir(const char* dirname, const char* base_filename);
+
+ /**
+ * \brief Verify that dirname is a valid %journal directory.
+ *
+ * The validation reads the .%jinf file, and using this information verifies that all the expected %journal
+ * (.jdat) files are present.
+ *
+ * \param dirname String containing name of %journal directory.
+ * \param base_filename String containing base filename of %journal files to be matched for moving into sub-directory.
+ *
+ * \exception jerrno::JERR_JDIR_NOTDIR dirname is not a directory
+ * \exception jerrno::JERR_JDIR_STAT Could not stat dirname
+ * \exception jerrno::JERR__FILEIO Error reading %jinf file
+ * \exception jerrno::JERR_JINF_CVALIDFAIL Error validating %jinf file
+ * \exception jerrno::JERR_JDIR_NOSUCHFILE Expected jdat file is missing
+ */
+ static void verify_dir(const std::string& dirname, const std::string& base_filename);
+
+ /**
+ * \brief Delete the %journal directory and all files and sub--directories that it may
+ * contain. This is equivilent of rm -rf.
+ *
+ * FIXME: links are not handled correctly.
+ *
+ * \param children_only If true, delete only children of dirname, but leave dirname itself.
+ *
+ * \exception jerrno::JERR_JDIR_OPENDIR The %journal directory could not be opened.
+ * \exception jerrno::JERR_JDIR_STAT Could not stat dirname.
+ * \exception jerrno::JERR_JDIR_UNLINK A file could not be deleted.
+ * \exception jerrno::JERR_JDIR_BADFTYPE A dir entry is neiter a file nor a dir.
+ * \exception jerrno::JERR_JDIR_CLOSEDIR The directory handle could not be closed.
+ * \exception jerrno::JERR_JDIR_RMDIR A directory could not be deleted.
+ */
+ void delete_dir(bool children_only = false );
+
+ /**
+ * \brief Delete the %journal directory and all files and sub--directories that it may
+ * contain. This is equivilent of rm -rf.
+ *
+ * FIXME: links are not handled correctly.
+ *
+ * \param dirname C-string containing name of directory to be deleted.
+ * \param children_only If true, delete only children of dirname, but leave dirname itself.
+ *
+ * \exception jerrno::JERR_JDIR_OPENDIR The %journal directory could not be opened.
+ * \exception jerrno::JERR_JDIR_STAT Could not stat dirname.
+ * \exception jerrno::JERR_JDIR_UNLINK A file could not be deleted.
+ * \exception jerrno::JERR_JDIR_BADFTYPE A dir entry is neiter a file nor a dir.
+ * \exception jerrno::JERR_JDIR_CLOSEDIR The directory handle could not be closed.
+ * \exception jerrno::JERR_JDIR_RMDIR A directory could not be deleted.
+ */
+ static void delete_dir(const char* dirname, bool children_only = false);
+
+ /**
+ * \brief Delete the %journal directory and all files and sub--directories that it may
+ * contain. This is equivilent of rm -rf.
+ *
+ * FIXME: links are not handled correctly.
+ *
+ * \param dirname String containing name of directory to be deleted.
+ * \param children_only If true, delete only children of dirname, but leave dirname itself.
+ *
+ * \exception jerrno::JERR_JDIR_OPENDIR The %journal directory could not be opened.
+ * \exception jerrno::JERR_JDIR_STAT Could not stat dirname.
+ * \exception jerrno::JERR_JDIR_UNLINK A file could not be deleted.
+ * \exception jerrno::JERR_JDIR_BADFTYPE A dir entry is neiter a file nor a dir.
+ * \exception jerrno::JERR_JDIR_CLOSEDIR The directory handle could not be closed.
+ * \exception jerrno::JERR_JDIR_RMDIR A directory could not be deleted.
+ */
+ static void delete_dir(const std::string& dirname, bool children_only = false);
+
+ /**
+ * \brief Create bakup directory that is next in sequence and move all %journal files
+ * matching base_filename into it.
+ *
+ * In directory dirname, search for existing backup directory using pattern
+ * "_basename.bak.XXXX" where XXXX is a hexadecimal sequence, and create next directory
+ * based on highest number found. Move all %journal files which match the base_fileaname
+ * parameter into this new backup directory.
+ *
+ * \param dirname String containing name of %journal directory.
+ * \param base_filename String containing base filename of %journal files to be matched
+ * for moving into subdirectory.
+ *
+ * \exception jerrno::JERR_JDIR_OPENDIR The %journal directory could not be opened.
+ * \exception jerrno::JERR_JDIR_CLOSEDIR The directory handle could not be closed.
+ * \exception jerrno::JERR_JDIR_MKDIR The backup directory could not be deleted.
+ */
+ static std::string create_bak_dir(const std::string& dirname,
+ const std::string& base_filename);
+
+ /**
+ * \brief Return the directory name as a string.
+ */
+ inline const std::string& dirname() const { return _dirname; }
+
+ /**
+ * \brief Return the %journal base filename name as a string.
+ */
+ inline const std::string& base_filename() const { return _base_filename; }
+
+ /**
+ * \brief Test whether the named file is a directory.
+ *
+ * \param name Name of file to be tested.
+ * \return <b><i>true</i></b> if the named file is a directory; <b><i>false</i></b>
+ * otherwise.
+ * \exception jerrno::JERR_JDIR_STAT Could not stat name.
+ */
+ static bool is_dir(const char* name);
+
+ /**
+ * \brief Test whether the named file is a directory.
+ *
+ * \param name Name of file to be tested.
+ * \return <b><i>true</i></b> if the named file is a directory; <b><i>false</i></b>
+ * otherwise.
+ * \exception jerrno::JERR_JDIR_STAT Could not stat name.
+ */
+ static bool is_dir(const std::string& name);
+
+
+ /**
+ * \brief Test whether the named entity exists on the filesystem.
+ *
+ * If stat() fails with error ENOENT, then this will return <b><i>false</i></b>. If
+ * stat() succeeds, then <b><i>true</i></b> is returned, irrespective of the file type.
+ * If stat() fails with any other error, an exception is thrown.
+ *
+ * \param name Name of entity to be tested.
+ * \return <b><i>true</i></b> if the named entity exists; <b><i>false</i></b>
+ * otherwise.
+ * \exception jerrno::JERR_JDIR_STAT Could not stat name.
+ */
+ static bool exists(const char* name);
+
+ /**
+ * \brief Test whether the named entity exists on the filesystem.
+ *
+ * If stat() fails with error ENOENT, then this will return <b><i>false</i></b>. If
+ * stat() succeeds, then <b><i>true</i></b> is returned, irrespective of the file type.
+ * If stat() fails with any other error, an exception is thrown.
+ *
+ * \param name Name of entity to be tested.
+ * \return <b><i>true</i></b> if the named entity exists; <b><i>false</i></b>
+ * otherwise.
+ * \exception jerrno::JERR_JDIR_STAT Could not stat name.
+ */
+ static bool exists(const std::string& name);
+
+ /**
+ * \brief Stream operator
+ */
+ friend std::ostream& operator<<(std::ostream& os, const jdir& jdir);
+
+ /**
+ * \brief Stream operator
+ */
+ friend std::ostream& operator<<(std::ostream& os, const jdir* jdirPtr);
+
+ private:
+ /**
+ * \brief Check for error, if non-zero close DIR handle and throw JERR_JDIR_READDIR
+ *
+ * \exception jerrno::JERR_JDIR_READDIR Error while reading contents of dir.
+ */
+ static void check_err(const int err_num, DIR* dir, const std::string& dir_name, const std::string& fn_name);
+
+ /**
+ * \brief Close a DIR handle, throw JERR_JDIR_CLOSEDIR if error occurs during close
+ *
+ * \exception jerrno::JERR_JDIR_CLOSEDIR The directory handle could not be closed.
+ */
+ static void close_dir(DIR* dir, const std::string& dir_name, const std::string& fn_name);
+ };
+
+} // namespace journal
+} // namespace mrg
+
+#endif // ifndef mrg_journal_jdir_hpp
Added: qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jerrno.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jerrno.cpp?rev=1424091&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jerrno.cpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jerrno.cpp Wed Dec 19 20:34:56 2012
@@ -0,0 +1,256 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file jerrno.cpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * File containing code for class mrg::journal::jerrno (journal error
+ * codes). See comments in file jerrno.hpp for details.
+ *
+ * See file jerrno.hpp for class details.
+ *
+ * \author Kim van der Riet
+ *
+ * Copyright (c) 2007, 2008, 2009 Red Hat, Inc.
+ *
+ */
+
+#include "jrnl/jerrno.hpp"
+
+namespace mrg
+{
+namespace journal
+{
+
+std::map<u_int32_t, const char*> jerrno::_err_map;
+std::map<u_int32_t, const char*>::iterator jerrno::_err_map_itr;
+bool jerrno::_initialized = jerrno::__init();
+
+// generic errors
+const u_int32_t jerrno::JERR__MALLOC = 0x0100;
+const u_int32_t jerrno::JERR__UNDERFLOW = 0x0101;
+const u_int32_t jerrno::JERR__NINIT = 0x0102;
+const u_int32_t jerrno::JERR__AIO = 0x0103;
+const u_int32_t jerrno::JERR__FILEIO = 0x0104;
+const u_int32_t jerrno::JERR__RTCLOCK = 0x0105;
+const u_int32_t jerrno::JERR__PTHREAD = 0x0106;
+const u_int32_t jerrno::JERR__TIMEOUT = 0x0107;
+const u_int32_t jerrno::JERR__UNEXPRESPONSE = 0x0108;
+const u_int32_t jerrno::JERR__RECNFOUND = 0x0109;
+const u_int32_t jerrno::JERR__NOTIMPL = 0x010a;
+
+// class jcntl
+const u_int32_t jerrno::JERR_JCNTL_STOPPED = 0x0200;
+const u_int32_t jerrno::JERR_JCNTL_READONLY = 0x0201;
+const u_int32_t jerrno::JERR_JCNTL_AIOCMPLWAIT = 0x0202;
+const u_int32_t jerrno::JERR_JCNTL_UNKNOWNMAGIC = 0x0203;
+const u_int32_t jerrno::JERR_JCNTL_NOTRECOVERED = 0x0204;
+const u_int32_t jerrno::JERR_JCNTL_RECOVERJFULL = 0x0205;
+const u_int32_t jerrno::JERR_JCNTL_OWIMISMATCH = 0x0206;
+
+// class jdir
+const u_int32_t jerrno::JERR_JDIR_NOTDIR = 0x0300;
+const u_int32_t jerrno::JERR_JDIR_MKDIR = 0x0301;
+const u_int32_t jerrno::JERR_JDIR_OPENDIR = 0x0302;
+const u_int32_t jerrno::JERR_JDIR_READDIR = 0x0303;
+const u_int32_t jerrno::JERR_JDIR_CLOSEDIR = 0x0304;
+const u_int32_t jerrno::JERR_JDIR_RMDIR = 0x0305;
+const u_int32_t jerrno::JERR_JDIR_NOSUCHFILE = 0x0306;
+const u_int32_t jerrno::JERR_JDIR_FMOVE = 0x0307;
+const u_int32_t jerrno::JERR_JDIR_STAT = 0x0308;
+const u_int32_t jerrno::JERR_JDIR_UNLINK = 0x0309;
+const u_int32_t jerrno::JERR_JDIR_BADFTYPE = 0x030a;
+
+// class fcntl
+const u_int32_t jerrno::JERR_FCNTL_OPENWR = 0x0400;
+const u_int32_t jerrno::JERR_FCNTL_WRITE = 0x0401;
+const u_int32_t jerrno::JERR_FCNTL_CLOSE = 0x0402;
+const u_int32_t jerrno::JERR_FCNTL_FILEOFFSOVFL = 0x0403;
+const u_int32_t jerrno::JERR_FCNTL_CMPLOFFSOVFL = 0x0404;
+const u_int32_t jerrno::JERR_FCNTL_RDOFFSOVFL = 0x0405;
+
+// class lfmgr
+const u_int32_t jerrno::JERR_LFMGR_BADAEFNUMLIM = 0x0500;
+const u_int32_t jerrno::JERR_LFMGR_AEFNUMLIMIT = 0x0501;
+const u_int32_t jerrno::JERR_LFMGR_AEDISABLED = 0x0502;
+
+// class rrfc
+const u_int32_t jerrno::JERR_RRFC_OPENRD = 0x0600;
+
+// class jrec, enq_rec, deq_rec, txn_rec
+const u_int32_t jerrno::JERR_JREC_BADRECHDR = 0x0700;
+const u_int32_t jerrno::JERR_JREC_BADRECTAIL = 0x0701;
+
+// class wmgr
+const u_int32_t jerrno::JERR_WMGR_BADPGSTATE = 0x0801;
+const u_int32_t jerrno::JERR_WMGR_BADDTOKSTATE = 0x0802;
+const u_int32_t jerrno::JERR_WMGR_ENQDISCONT = 0x0803;
+const u_int32_t jerrno::JERR_WMGR_DEQDISCONT = 0x0804;
+const u_int32_t jerrno::JERR_WMGR_DEQRIDNOTENQ = 0x0805;
+
+// class rmgr
+const u_int32_t jerrno::JERR_RMGR_UNKNOWNMAGIC = 0x0900;
+const u_int32_t jerrno::JERR_RMGR_RIDMISMATCH = 0x0901;
+//const u_int32_t jerrno::JERR_RMGR_FIDMISMATCH = 0x0902;
+const u_int32_t jerrno::JERR_RMGR_ENQSTATE = 0x0903;
+const u_int32_t jerrno::JERR_RMGR_BADRECTYPE = 0x0904;
+
+// class data_tok
+const u_int32_t jerrno::JERR_DTOK_ILLEGALSTATE = 0x0a00;
+// const u_int32_t jerrno::JERR_DTOK_RIDNOTSET = 0x0a01;
+
+// class enq_map, txn_map
+const u_int32_t jerrno::JERR_MAP_DUPLICATE = 0x0b00;
+const u_int32_t jerrno::JERR_MAP_NOTFOUND = 0x0b01;
+const u_int32_t jerrno::JERR_MAP_LOCKED = 0x0b02;
+
+// class jinf
+const u_int32_t jerrno::JERR_JINF_CVALIDFAIL = 0x0c00;
+const u_int32_t jerrno::JERR_JINF_NOVALUESTR = 0x0c01;
+const u_int32_t jerrno::JERR_JINF_BADVALUESTR = 0x0c02;
+const u_int32_t jerrno::JERR_JINF_JDATEMPTY = 0x0c03;
+const u_int32_t jerrno::JERR_JINF_TOOMANYFILES = 0x0c04;
+const u_int32_t jerrno::JERR_JINF_INVALIDFHDR = 0x0c05;
+const u_int32_t jerrno::JERR_JINF_STAT = 0x0c06;
+const u_int32_t jerrno::JERR_JINF_NOTREGFILE = 0x0c07;
+const u_int32_t jerrno::JERR_JINF_BADFILESIZE = 0x0c08;
+const u_int32_t jerrno::JERR_JINF_OWIBAD = 0x0c09;
+const u_int32_t jerrno::JERR_JINF_ZEROLENFILE = 0x0c0a;
+
+// Negative returns for some functions
+const int32_t jerrno::AIO_TIMEOUT = -1;
+const int32_t jerrno::LOCK_TAKEN = -2;
+
+
+// static initialization fn
+
+bool
+jerrno::__init()
+{
+ // generic errors
+ _err_map[JERR__MALLOC] = "JERR__MALLOC: Buffer memory allocation failed.";
+ _err_map[JERR__UNDERFLOW] = "JERR__UNDERFLOW: Underflow error";
+ _err_map[JERR__NINIT] = "JERR__NINIT: Operation on uninitialized class.";
+ _err_map[JERR__AIO] = "JERR__AIO: AIO error.";
+ _err_map[JERR__FILEIO] = "JERR__FILEIO: File read or write failure.";
+ _err_map[JERR__RTCLOCK] = "JERR__RTCLOCK: Reading real-time clock failed.";
+ _err_map[JERR__PTHREAD] = "JERR__PTHREAD: pthread failure.";
+ _err_map[JERR__TIMEOUT] = "JERR__TIMEOUT: Timeout waiting for event.";
+ _err_map[JERR__UNEXPRESPONSE] = "JERR__UNEXPRESPONSE: Unexpected response to call or event.";
+ _err_map[JERR__RECNFOUND] = "JERR__RECNFOUND: Record not found.";
+ _err_map[JERR__NOTIMPL] = "JERR__NOTIMPL: Not implemented";
+
+ // class jcntl
+ _err_map[JERR_JCNTL_STOPPED] = "JERR_JCNTL_STOPPED: Operation on stopped journal.";
+ _err_map[JERR_JCNTL_READONLY] = "JERR_JCNTL_READONLY: Write operation on read-only journal (during recovery).";
+ _err_map[JERR_JCNTL_AIOCMPLWAIT] = "JERR_JCNTL_AIOCMPLWAIT: Timeout waiting for AIOs to complete.";
+ _err_map[JERR_JCNTL_UNKNOWNMAGIC] = "JERR_JCNTL_UNKNOWNMAGIC: Found record with unknown magic.";
+ _err_map[JERR_JCNTL_NOTRECOVERED] = "JERR_JCNTL_NOTRECOVERED: Operation requires recover() to be run first.";
+ _err_map[JERR_JCNTL_RECOVERJFULL] = "JERR_JCNTL_RECOVERJFULL: Journal data files full, cannot write.";
+ _err_map[JERR_JCNTL_OWIMISMATCH] = "JERR_JCNTL_OWIMISMATCH: Overwrite Indicator (OWI) change found in unexpected location.";
+
+ // class jdir
+ _err_map[JERR_JDIR_NOTDIR] = "JERR_JDIR_NOTDIR: Directory name exists but is not a directory.";
+ _err_map[JERR_JDIR_MKDIR] = "JERR_JDIR_MKDIR: Directory creation failed.";
+ _err_map[JERR_JDIR_OPENDIR] = "JERR_JDIR_OPENDIR: Directory open failed.";
+ _err_map[JERR_JDIR_READDIR] = "JERR_JDIR_READDIR: Directory read failed.";
+ _err_map[JERR_JDIR_CLOSEDIR] = "JERR_JDIR_CLOSEDIR: Directory close failed.";
+ _err_map[JERR_JDIR_RMDIR] = "JERR_JDIR_RMDIR: Directory delete failed.";
+ _err_map[JERR_JDIR_NOSUCHFILE] = "JERR_JDIR_NOSUCHFILE: File does not exist.";
+ _err_map[JERR_JDIR_FMOVE] = "JERR_JDIR_FMOVE: File move failed.";
+ _err_map[JERR_JDIR_STAT] = "JERR_JDIR_STAT: File stat failed.";
+ _err_map[JERR_JDIR_UNLINK] = "JERR_JDIR_UNLINK: File delete failed.";
+ _err_map[JERR_JDIR_BADFTYPE] = "JERR_JDIR_BADFTYPE: Bad or unknown file type (stat mode).";
+
+ // class fcntl
+ _err_map[JERR_FCNTL_OPENWR] = "JERR_FCNTL_OPENWR: Unable to open file for write.";
+ _err_map[JERR_FCNTL_WRITE] = "JERR_FCNTL_WRITE: Unable to write to file.";
+ _err_map[JERR_FCNTL_CLOSE] = "JERR_FCNTL_CLOSE: File close failed.";
+ _err_map[JERR_FCNTL_FILEOFFSOVFL] = "JERR_FCNTL_FILEOFFSOVFL: Attempted increase file offset past file size.";
+ _err_map[JERR_FCNTL_CMPLOFFSOVFL] = "JERR_FCNTL_CMPLOFFSOVFL: Attempted increase completed file offset past submitted offset.";
+ _err_map[JERR_FCNTL_RDOFFSOVFL] = "JERR_FCNTL_RDOFFSOVFL: Attempted increase read offset past write offset.";
+
+ // class lfmgr
+ _err_map[JERR_LFMGR_BADAEFNUMLIM] = "JERR_LFMGR_BADAEFNUMLIM: Auto-expand file number limit lower than initial number of journal files.";
+ _err_map[JERR_LFMGR_AEFNUMLIMIT] = "JERR_LFMGR_AEFNUMLIMIT: Exceeded auto-expand file number limit.";
+ _err_map[JERR_LFMGR_AEDISABLED] = "JERR_LFMGR_AEDISABLED: Attempted to expand with auto-expand disabled.";
+
+ // class rrfc
+ _err_map[JERR_RRFC_OPENRD] = "JERR_RRFC_OPENRD: Unable to open file for read.";
+
+ // class jrec, enq_rec, deq_rec, txn_rec
+ _err_map[JERR_JREC_BADRECHDR] = "JERR_JREC_BADRECHDR: Invalid data record header.";
+ _err_map[JERR_JREC_BADRECTAIL] = "JERR_JREC_BADRECTAIL: Invalid data record tail.";
+
+ // class wmgr
+ _err_map[JERR_WMGR_BADPGSTATE] = "JERR_WMGR_BADPGSTATE: Page buffer in illegal state for operation.";
+ _err_map[JERR_WMGR_BADDTOKSTATE] = "JERR_WMGR_BADDTOKSTATE: Data token in illegal state for operation.";
+ _err_map[JERR_WMGR_ENQDISCONT] = "JERR_WMGR_ENQDISCONT: Enqueued new dtok when previous enqueue returned partly completed (state ENQ_PART).";
+ _err_map[JERR_WMGR_DEQDISCONT] = "JERR_WMGR_DEQDISCONT: Dequeued new dtok when previous dequeue returned partly completed (state DEQ_PART).";
+ _err_map[JERR_WMGR_DEQRIDNOTENQ] = "JERR_WMGR_DEQRIDNOTENQ: Dequeue rid is not enqueued.";
+
+ // class rmgr
+ _err_map[JERR_RMGR_UNKNOWNMAGIC] = "JERR_RMGR_UNKNOWNMAGIC: Found record with unknown magic.";
+ _err_map[JERR_RMGR_RIDMISMATCH] = "JERR_RMGR_RIDMISMATCH: RID mismatch between current record and dtok RID";
+ //_err_map[JERR_RMGR_FIDMISMATCH] = "JERR_RMGR_FIDMISMATCH: FID mismatch between emap and rrfc";
+ _err_map[JERR_RMGR_ENQSTATE] = "JERR_RMGR_ENQSTATE: Attempted read when data token wstate was not ENQ";
+ _err_map[JERR_RMGR_BADRECTYPE] = "JERR_RMGR_BADRECTYPE: Attempted operation on inappropriate record type";
+
+ // class data_tok
+ _err_map[JERR_DTOK_ILLEGALSTATE] = "JERR_MTOK_ILLEGALSTATE: Attempted to change to illegal state.";
+ //_err_map[JERR_DTOK_RIDNOTSET] = "JERR_DTOK_RIDNOTSET: Record ID not set.";
+
+ // class enq_map, txn_map
+ _err_map[JERR_MAP_DUPLICATE] = "JERR_MAP_DUPLICATE: Attempted to insert record into map using duplicate key.";
+ _err_map[JERR_MAP_NOTFOUND] = "JERR_MAP_NOTFOUND: Key not found in map.";
+ _err_map[JERR_MAP_LOCKED] = "JERR_MAP_LOCKED: Record ID locked by a pending transaction.";
+
+ // class jinf
+ _err_map[JERR_JINF_CVALIDFAIL] = "JERR_JINF_CVALIDFAIL: Journal compatibility validation failure.";
+ _err_map[JERR_JINF_NOVALUESTR] = "JERR_JINF_NOVALUESTR: No value attribute found in jinf file.";
+ _err_map[JERR_JINF_BADVALUESTR] = "JERR_JINF_BADVALUESTR: Bad format for value attribute in jinf file";
+ _err_map[JERR_JINF_JDATEMPTY] = "JERR_JINF_JDATEMPTY: Journal data files empty.";
+ _err_map[JERR_JINF_TOOMANYFILES] = "JERR_JINF_TOOMANYFILES: Too many journal data files.";
+ _err_map[JERR_JINF_INVALIDFHDR] = "JERR_JINF_INVALIDFHDR: Invalid journal data file header";
+ _err_map[JERR_JINF_STAT] = "JERR_JINF_STAT: Error while trying to stat a journal data file";
+ _err_map[JERR_JINF_NOTREGFILE] = "JERR_JINF_NOTREGFILE: Target journal data file is not a regular file";
+ _err_map[JERR_JINF_BADFILESIZE] = "JERR_JINF_BADFILESIZE: Journal data file is of incorrect or unexpected size";
+ _err_map[JERR_JINF_OWIBAD] = "JERR_JINF_OWIBAD: Journal data files have inconsistent OWI flags; >1 transition found in non-auto-expand or min-size journal";
+ _err_map[JERR_JINF_ZEROLENFILE] = "JERR_JINF_ZEROLENFILE: Journal info file zero length";
+
+ //_err_map[] = "";
+
+ return true;
+}
+
+const char*
+jerrno::err_msg(const u_int32_t err_no) throw ()
+{
+ _err_map_itr = _err_map.find(err_no);
+ if (_err_map_itr == _err_map.end())
+ return "<Unknown error code>";
+ return _err_map_itr->second;
+}
+
+} // namespace journal
+} // namespace mrg
Added: qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jerrno.hpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jerrno.hpp?rev=1424091&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jerrno.hpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jerrno.hpp Wed Dec 19 20:34:56 2012
@@ -0,0 +1,176 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file jerrno.hpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * File containing code for class mrg::journal::jerrno (journal error
+ * codes). See class documentation for details.
+ *
+ * \author Kim van der Riet
+ *
+ * Copyright (c) 2007, 2008, 2009 Red Hat, Inc.
+ *
+ */
+
+#ifndef mrg_journal_jerrno_hpp
+#define mrg_journal_jerrno_hpp
+
+namespace mrg
+{
+namespace journal
+{
+class jerrno;
+}
+}
+
+#include <map>
+#include <string>
+#include <sys/types.h>
+
+namespace mrg
+{
+namespace journal
+{
+
+ /**
+ * \class jerrno
+ * \brief Class containing static error definitions and static map for error messages.
+ */
+ class jerrno
+ {
+ static std::map<u_int32_t, const char*> _err_map; ///< Map of error messages
+ static std::map<u_int32_t, const char*>::iterator _err_map_itr; ///< Iterator
+ static bool _initialized; ///< Dummy flag, used to initialise map.
+
+ public:
+ // generic errors
+ static const u_int32_t JERR__MALLOC; ///< Buffer memory allocation failed
+ static const u_int32_t JERR__UNDERFLOW; ///< Underflow error
+ static const u_int32_t JERR__NINIT; ///< Operation on uninitialized class
+ static const u_int32_t JERR__AIO; ///< AIO failure
+ static const u_int32_t JERR__FILEIO; ///< File read or write failure
+ static const u_int32_t JERR__RTCLOCK; ///< Reading real-time clock failed
+ static const u_int32_t JERR__PTHREAD; ///< pthread failure
+ static const u_int32_t JERR__TIMEOUT; ///< Timeout waiting for an event
+ static const u_int32_t JERR__UNEXPRESPONSE; ///< Unexpected response to call or event
+ static const u_int32_t JERR__RECNFOUND; ///< Record not found
+ static const u_int32_t JERR__NOTIMPL; ///< Not implemented
+
+ // class jcntl
+ static const u_int32_t JERR_JCNTL_STOPPED; ///< Operation on stopped journal
+ static const u_int32_t JERR_JCNTL_READONLY; ///< Write operation on read-only journal
+ static const u_int32_t JERR_JCNTL_AIOCMPLWAIT; ///< Timeout waiting for AIOs to complete
+ static const u_int32_t JERR_JCNTL_UNKNOWNMAGIC; ///< Found record with unknown magic
+ static const u_int32_t JERR_JCNTL_NOTRECOVERED; ///< Req' recover() to be called first
+ static const u_int32_t JERR_JCNTL_RECOVERJFULL; ///< Journal data files full, cannot write
+ static const u_int32_t JERR_JCNTL_OWIMISMATCH; ///< OWI change found in unexpected location
+
+ // class jdir
+ static const u_int32_t JERR_JDIR_NOTDIR; ///< Exists but is not a directory
+ static const u_int32_t JERR_JDIR_MKDIR; ///< Directory creation failed
+ static const u_int32_t JERR_JDIR_OPENDIR; ///< Directory open failed
+ static const u_int32_t JERR_JDIR_READDIR; ///< Directory read failed
+ static const u_int32_t JERR_JDIR_CLOSEDIR; ///< Directory close failed
+ static const u_int32_t JERR_JDIR_RMDIR; ///< Directory delete failed
+ static const u_int32_t JERR_JDIR_NOSUCHFILE; ///< File does not exist
+ static const u_int32_t JERR_JDIR_FMOVE; ///< File move failed
+ static const u_int32_t JERR_JDIR_STAT; ///< File stat failed
+ static const u_int32_t JERR_JDIR_UNLINK; ///< File delete failed
+ static const u_int32_t JERR_JDIR_BADFTYPE; ///< Bad or unknown file type (stat mode)
+
+ // class fcntl
+ static const u_int32_t JERR_FCNTL_OPENWR; ///< Unable to open file for write
+ static const u_int32_t JERR_FCNTL_WRITE; ///< Unable to write to file
+ static const u_int32_t JERR_FCNTL_CLOSE; ///< File close failed
+ static const u_int32_t JERR_FCNTL_FILEOFFSOVFL; ///< Increased offset past file size
+ static const u_int32_t JERR_FCNTL_CMPLOFFSOVFL; ///< Increased cmpl offs past subm offs
+ static const u_int32_t JERR_FCNTL_RDOFFSOVFL; ///< Increased read offs past write offs
+
+ // class lfmgr
+ static const u_int32_t JERR_LFMGR_BADAEFNUMLIM; ///< Bad auto-expand file number limit
+ static const u_int32_t JERR_LFMGR_AEFNUMLIMIT; ///< Exceeded auto-expand file number limit
+ static const u_int32_t JERR_LFMGR_AEDISABLED; ///< Attempted to expand with auto-expand disabled
+
+ // class rrfc
+ static const u_int32_t JERR_RRFC_OPENRD; ///< Unable to open file for read
+
+ // class jrec, enq_rec, deq_rec, txn_rec
+ static const u_int32_t JERR_JREC_BADRECHDR; ///< Invalid data record header
+ static const u_int32_t JERR_JREC_BADRECTAIL; ///< Invalid data record tail
+
+ // class wmgr
+ static const u_int32_t JERR_WMGR_BADPGSTATE; ///< Page buffer in illegal state.
+ static const u_int32_t JERR_WMGR_BADDTOKSTATE; ///< Data token in illegal state.
+ static const u_int32_t JERR_WMGR_ENQDISCONT; ///< Enq. new dtok when previous part compl.
+ static const u_int32_t JERR_WMGR_DEQDISCONT; ///< Deq. new dtok when previous part compl.
+ static const u_int32_t JERR_WMGR_DEQRIDNOTENQ; ///< Deq. rid not enqueued
+
+ // class rmgr
+ static const u_int32_t JERR_RMGR_UNKNOWNMAGIC; ///< Found record with unknown magic
+ static const u_int32_t JERR_RMGR_RIDMISMATCH; ///< RID mismatch between rec and dtok
+ //static const u_int32_t JERR_RMGR_FIDMISMATCH; ///< FID mismatch between emap and rrfc
+ static const u_int32_t JERR_RMGR_ENQSTATE; ///< Attempted read when wstate not ENQ
+ static const u_int32_t JERR_RMGR_BADRECTYPE; ///< Attempted op on incorrect rec type
+
+ // class data_tok
+ static const u_int32_t JERR_DTOK_ILLEGALSTATE; ///< Attempted to change to illegal state
+// static const u_int32_t JERR_DTOK_RIDNOTSET; ///< Record ID not set
+
+ // class enq_map, txn_map
+ static const u_int32_t JERR_MAP_DUPLICATE; ///< Attempted to insert using duplicate key
+ static const u_int32_t JERR_MAP_NOTFOUND; ///< Key not found in map
+ static const u_int32_t JERR_MAP_LOCKED; ///< rid locked by pending txn
+
+ // class jinf
+ static const u_int32_t JERR_JINF_CVALIDFAIL; ///< Compatibility validation failure
+ static const u_int32_t JERR_JINF_NOVALUESTR; ///< No value attr found in jinf file
+ static const u_int32_t JERR_JINF_BADVALUESTR; ///< Bad format for value attr in jinf file
+ static const u_int32_t JERR_JINF_JDATEMPTY; ///< Journal data files empty
+ static const u_int32_t JERR_JINF_TOOMANYFILES; ///< Too many journal data files
+ static const u_int32_t JERR_JINF_INVALIDFHDR; ///< Invalid file header
+ static const u_int32_t JERR_JINF_STAT; ///< Error while trying to stat a file
+ static const u_int32_t JERR_JINF_NOTREGFILE; ///< Target file is not a regular file
+ static const u_int32_t JERR_JINF_BADFILESIZE; ///< File is of incorrect or unexpected size
+ static const u_int32_t JERR_JINF_OWIBAD; ///< OWI inconsistent (>1 transition in non-ae journal)
+ static const u_int32_t JERR_JINF_ZEROLENFILE; ///< Journal info file is zero length (empty).
+
+ // Negative returns for some functions
+ static const int32_t AIO_TIMEOUT; ///< Timeout waiting for AIO return
+ static const int32_t LOCK_TAKEN; ///< Attempted to take lock, but it was taken by another thread
+ /**
+ * \brief Method to access error message from known error number.
+ */
+ static const char* err_msg(const u_int32_t err_no) throw ();
+
+ private:
+ /**
+ * \brief Static function to initialize map.
+ */
+ static bool __init();
+ };
+
+} // namespace journal
+} // namespace mrg
+
+#endif // ifndef mrg_journal_jerrno_hpp
Added: qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jexception.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jexception.cpp?rev=1424091&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jexception.cpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jexception.cpp Wed Dec 19 20:34:56 2012
@@ -0,0 +1,186 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file jexception.cpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * Generic journal exception class mrg::journal::jexception. See comments
+ * in file jexception.hpp for details.
+ *
+ * \author Kim van der Riet
+ *
+ * Copyright (c) 2007, 2008 Red Hat, Inc.
+ *
+ */
+
+#include "jrnl/jexception.hpp"
+
+#include <iomanip>
+#include <sstream>
+#include "jrnl/jerrno.hpp"
+
+#define CATLEN(p) MAX_MSG_SIZE - std::strlen(p) - 1
+
+namespace mrg
+{
+namespace journal
+{
+
+jexception::jexception() throw ():
+ std::exception(),
+ _err_code(0)
+{
+ format();
+}
+
+jexception::jexception(const u_int32_t err_code) throw ():
+ std::exception(),
+ _err_code(err_code)
+{
+ format();
+}
+
+jexception::jexception(const char* additional_info) throw ():
+ std::exception(),
+ _err_code(0),
+ _additional_info(additional_info)
+{
+ format();
+}
+
+jexception::jexception(const std::string& additional_info) throw ():
+ std::exception(),
+ _err_code(0),
+ _additional_info(additional_info)
+{
+ format();
+}
+
+jexception::jexception(const u_int32_t err_code, const char* additional_info) throw ():
+ std::exception(),
+ _err_code(err_code),
+ _additional_info(additional_info)
+{
+ format();
+}
+
+jexception::jexception(const u_int32_t err_code, const std::string& additional_info) throw ():
+ std::exception(),
+ _err_code(err_code),
+ _additional_info(additional_info)
+{
+ format();
+}
+
+jexception::jexception(const u_int32_t err_code, const char* throwing_class,
+ const char* throwing_fn) throw ():
+ std::exception(),
+ _err_code(err_code),
+ _throwing_class(throwing_class),
+ _throwing_fn(throwing_fn)
+{
+ format();
+}
+
+jexception::jexception(const u_int32_t err_code, const std::string& throwing_class,
+ const std::string& throwing_fn) throw ():
+ std::exception(),
+ _err_code(err_code),
+ _throwing_class(throwing_class),
+ _throwing_fn(throwing_fn)
+{
+ format();
+}
+
+jexception::jexception(const u_int32_t err_code, const char* additional_info,
+ const char* throwing_class, const char* throwing_fn) throw ():
+ std::exception(),
+ _err_code(err_code),
+ _additional_info(additional_info),
+ _throwing_class(throwing_class),
+ _throwing_fn(throwing_fn)
+{
+ format();
+}
+
+jexception::jexception(const u_int32_t err_code, const std::string& additional_info,
+ const std::string& throwing_class, const std::string& throwing_fn) throw ():
+ std::exception(),
+ _err_code(err_code),
+ _additional_info(additional_info),
+ _throwing_class(throwing_class),
+ _throwing_fn(throwing_fn)
+{
+ format();
+}
+
+jexception::~jexception() throw ()
+{}
+
+void
+jexception::format()
+{
+ const bool ai = !_additional_info.empty();
+ const bool tc = !_throwing_class.empty();
+ const bool tf = !_throwing_fn.empty();
+ std::ostringstream oss;
+ oss << "jexception 0x" << std::hex << std::setfill('0') << std::setw(4) << _err_code << " ";
+ if (tc)
+ {
+ oss << _throwing_class;
+ if (tf)
+ oss << "::";
+ else
+ oss << " ";
+ }
+ if (tf)
+ oss << _throwing_fn << "() ";
+ if (tc || tf)
+ oss << "threw " << jerrno::err_msg(_err_code);
+ if (ai)
+ oss << " (" << _additional_info << ")";
+ _what.assign(oss.str());
+}
+
+const char*
+jexception::what() const throw ()
+{
+ return _what.c_str();
+}
+
+std::ostream&
+operator<<(std::ostream& os, const jexception& je)
+{
+ os << je.what();
+ return os;
+}
+
+std::ostream&
+operator<<(std::ostream& os, const jexception* jePtr)
+{
+ os << jePtr->what();
+ return os;
+}
+
+} // namespace journal
+} // namespace mrg
Added: qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jexception.hpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jexception.hpp?rev=1424091&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jexception.hpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jexception.hpp Wed Dec 19 20:34:56 2012
@@ -0,0 +1,145 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file jexception.hpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * Generic journal exception class mrg::journal::jexception (derived
+ * from class std::exception). Intended to serve as a common exception
+ * class for all more speicalized exceptions in the message journal. See
+ * class documentation for details.
+ *
+ * \author Kim van der Riet
+ *
+ * Copyright (c) 2007, 2008 Red Hat, Inc.
+ *
+ */
+
+#ifndef mrg_journal_jrnl_exception_hpp
+#define mrg_journal_jrnl_exception_hpp
+
+namespace mrg
+{
+namespace journal
+{
+class jexception;
+}
+}
+
+#include <cerrno>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <exception>
+#include "jrnl/jerrno.hpp"
+#include <sstream>
+#include <string>
+#include <sys/types.h>
+
+// Macro for formatting commom system errors
+#define FORMAT_SYSERR(errno) " errno=" << errno << " (" << std::strerror(errno) << ")"
+
+#define MALLOC_CHK(ptr, var, cls, fn) if(ptr == 0) { \
+ clean(); \
+ std::ostringstream oss; \
+ oss << var << ": malloc() failed: " << FORMAT_SYSERR(errno); \
+ throw jexception(jerrno::JERR__MALLOC, oss.str(), cls, fn); \
+ }
+
+// TODO: The following is a temporary bug-tracking aid which forces a core.
+// Replace with the commented out version below when BZ484048 is resolved.
+#define PTHREAD_CHK(err, pfn, cls, fn) if(err != 0) { \
+ std::ostringstream oss; \
+ oss << cls << "::" << fn << "(): " << pfn; \
+ errno = err; \
+ ::perror(oss.str().c_str()); \
+ ::abort(); \
+ }
+/*
+#define PTHREAD_CHK(err, pfn, cls, fn) if(err != 0) { \
+ std::ostringstream oss; \
+ oss << pfn << " failed: " << FORMAT_SYSERR(err); \
+ throw jexception(jerrno::JERR__PTHREAD, oss.str(), cls, fn); \
+ }
+*/
+
+#define ASSERT(cond, msg) if(cond == 0) { \
+ std::cerr << msg << std::endl; \
+ ::abort(); \
+ }
+
+namespace mrg
+{
+namespace journal
+{
+ /**
+ * \class jexception
+ * \brief Generic journal exception class
+ */
+ class jexception : public std::exception
+ {
+ private:
+ u_int32_t _err_code;
+ std::string _additional_info;
+ std::string _throwing_class;
+ std::string _throwing_fn;
+ std::string _what;
+ void format();
+
+ public:
+ jexception() throw ();
+
+ jexception(const u_int32_t err_code) throw ();
+
+ jexception(const char* additional_info) throw ();
+ jexception(const std::string& additional_info) throw ();
+
+ jexception(const u_int32_t err_code, const char* additional_info) throw ();
+ jexception(const u_int32_t err_code, const std::string& additional_info) throw ();
+
+ jexception(const u_int32_t err_code, const char* throwing_class, const char* throwing_fn)
+ throw ();
+ jexception(const u_int32_t err_code, const std::string& throwing_class,
+ const std::string& throwing_fn) throw ();
+
+ jexception(const u_int32_t err_code, const char* additional_info,
+ const char* throwing_class, const char* throwing_fn) throw ();
+ jexception(const u_int32_t err_code, const std::string& additional_info,
+ const std::string& throwing_class, const std::string& throwing_fn) throw ();
+
+ virtual ~jexception() throw ();
+ virtual const char* what() const throw (); // override std::exception::what()
+
+ inline u_int32_t err_code() const throw () { return _err_code; }
+ inline const std::string additional_info() const throw () { return _additional_info; }
+ inline const std::string throwing_class() const throw () { return _throwing_class; }
+ inline const std::string throwing_fn() const throw () { return _throwing_fn; }
+
+ friend std::ostream& operator<<(std::ostream& os, const jexception& je);
+ friend std::ostream& operator<<(std::ostream& os, const jexception* jePtr);
+ }; // class jexception
+
+} // namespace journal
+} // namespace mrg
+
+#endif // ifndef mrg_journal_jrnl_exception_hpp
Added: qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jinf.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jinf.cpp?rev=1424091&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jinf.cpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jinf.cpp Wed Dec 19 20:34:56 2012
@@ -0,0 +1,543 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file jinf.cpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * This file contains the code for the mrg::journal::jinf class.
+ *
+ * See jinf.hpp comments for details of this class.
+ *
+ * \author Kim van der Riet
+ *
+ * Copyright (c) 2007, 2008, 2009 Red Hat, Inc.
+ *
+ */
+
+#include "jrnl/jinf.hpp"
+
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <fstream>
+#include "jrnl/file_hdr.hpp"
+#include "jrnl/jcntl.hpp"
+#include "jrnl/jerrno.hpp"
+#include "jrnl/lp_map.hpp"
+#include <sstream>
+#include <sys/stat.h>
+
+namespace mrg
+{
+namespace journal
+{
+
+jinf::jinf(const std::string& jinf_filename, bool validate_flag):
+ _jver(0),
+ _filename(jinf_filename),
+ _num_jfiles(0),
+ _ae(false),
+ _ae_max_jfiles(0),
+ _jfsize_sblks(0),
+ _sblk_size_dblks(0),
+ _dblk_size(0),
+ _wcache_pgsize_sblks(0),
+ _wcache_num_pages(0),
+ _rcache_pgsize_sblks(0),
+ _rcache_num_pages(0),
+ _tm_ptr(0),
+ _valid_flag(false),
+ _analyzed_flag(false),
+ _initial_owi(false),
+ _frot(false)
+{
+ read(_filename);
+ if (validate_flag)
+ validate();
+}
+
+jinf::jinf(const std::string& jid, const std::string& jdir, const std::string& base_filename, const u_int16_t num_jfiles,
+ const bool auto_expand, const u_int16_t ae_max_jfiles, const u_int32_t jfsize_sblks,
+ const u_int32_t wcache_pgsize_sblks, const u_int16_t wcache_num_pages, const timespec& ts):
+ _jver(RHM_JDAT_VERSION),
+ _jid(jid),
+ _jdir(jdir),
+ _base_filename(base_filename),
+ _ts(ts),
+ _num_jfiles(num_jfiles),
+ _ae(auto_expand),
+ _ae_max_jfiles(ae_max_jfiles),
+ _jfsize_sblks(jfsize_sblks),
+ _sblk_size_dblks(JRNL_SBLK_SIZE),
+ _dblk_size(JRNL_DBLK_SIZE),
+ _wcache_pgsize_sblks(wcache_pgsize_sblks),
+ _wcache_num_pages(wcache_num_pages),
+ _rcache_pgsize_sblks(JRNL_RMGR_PAGE_SIZE),
+ _rcache_num_pages(JRNL_RMGR_PAGES),
+ _tm_ptr(std::localtime(&ts.tv_sec)),
+ _valid_flag(false),
+ _analyzed_flag(false),
+ _initial_owi(false)
+{
+ set_filename();
+}
+
+jinf::~jinf()
+{}
+
+void
+jinf::validate()
+{
+ bool err = false;
+ std::ostringstream oss;
+ if (_jver != RHM_JDAT_VERSION)
+ {
+ oss << "File \"" << _filename << "\": ";
+ oss << "RHM_JDAT_VERSION mismatch: found=" << (int)_jver;
+ oss << "; required=" << RHM_JDAT_VERSION << std::endl;
+ err = true;
+ }
+ if (_num_jfiles < JRNL_MIN_NUM_FILES)
+ {
+ oss << "File \"" << _filename << "\": ";
+ oss << "Number of journal files too small: found=" << _num_jfiles;
+ oss << "; minimum=" << JRNL_MIN_NUM_FILES << std::endl;
+ err = true;
+ }
+ if (_num_jfiles > JRNL_MAX_NUM_FILES)
+ {
+ oss << "File \"" << _filename << "\": ";
+ oss << "Number of journal files too large: found=" << _num_jfiles;
+ oss << "; maximum=" << JRNL_MAX_NUM_FILES << std::endl;
+ err = true;
+ }
+ if (_ae)
+ {
+ if (_ae_max_jfiles < _num_jfiles)
+ {
+ oss << "File \"" << _filename << "\": ";
+ oss << "Number of journal files exceeds auto-expansion limit: found=" << _num_jfiles;
+ oss << "; maximum=" << _ae_max_jfiles;
+ err = true;
+ }
+ if (_ae_max_jfiles > JRNL_MAX_NUM_FILES)
+ {
+ oss << "File \"" << _filename << "\": ";
+ oss << "Auto-expansion file limit too large: found=" << _ae_max_jfiles;
+ oss << "; maximum=" << JRNL_MAX_NUM_FILES;
+ err = true;
+ }
+ }
+ if (_jfsize_sblks < JRNL_MIN_FILE_SIZE)
+ {
+ oss << "File \"" << _filename << "\": ";
+ oss << "Journal file size too small: found=" << _jfsize_sblks;
+ oss << "; minimum=" << JRNL_MIN_FILE_SIZE << " (sblks)" << std::endl;
+ err = true;
+ }
+ if (_sblk_size_dblks != JRNL_SBLK_SIZE)
+ {
+ oss << "File \"" << _filename << "\": ";
+ oss << "JRNL_SBLK_SIZE mismatch: found=" << _sblk_size_dblks;
+ oss << "; required=" << JRNL_SBLK_SIZE << std::endl;
+ err = true;
+ }
+ if (_dblk_size != JRNL_DBLK_SIZE)
+ {
+ oss << "File \"" << _filename << "\": ";
+ oss << "JRNL_DBLK_SIZE mismatch: found=" << _dblk_size;
+ oss << "; required=" << JRNL_DBLK_SIZE << std::endl;
+ err = true;
+ }
+ if (err)
+ throw jexception(jerrno::JERR_JINF_CVALIDFAIL, oss.str(), "jinf", "validate");
+ _valid_flag = true;
+}
+
+void
+jinf::analyze()
+{
+ lp_map early_map; // map for all owi flags same as pfid 0
+ lp_map late_map; // map for all owi flags opposite to pfid 0
+ bool late_latch = false; // latch for owi switchover
+
+ if (!_valid_flag)
+ validate();
+ bool done = false;
+ for (u_int16_t pfid=0; pfid<_num_jfiles && !done; pfid++)
+ {
+ std::ostringstream oss;
+ if (_jdir.at(_jdir.size() - 1) == '/')
+ oss << _jdir << _base_filename << ".";
+ else
+ oss << _jdir << "/" << _base_filename << ".";
+ oss << std::setw(4) << std::setfill('0') << std::hex << pfid;
+ oss << "." << JRNL_DATA_EXTENSION;
+
+ // Check size of each file is consistent and expected
+ u_int32_t fsize = get_filesize(oss.str());
+ if (fsize != (_jfsize_sblks + 1) * _sblk_size_dblks * _dblk_size)
+ {
+ std::ostringstream oss1;
+ oss1 << "File \"" << oss.str() << "\": size=" << fsize << "; expected=" << ((_jfsize_sblks + 1) * _sblk_size_dblks * _dblk_size);
+ throw jexception(jerrno::JERR_JINF_BADFILESIZE, oss1.str(), "jinf", "analyze");
+ }
+
+ std::ifstream jifs(oss.str().c_str());
+ if (!jifs.good())
+ throw jexception(jerrno::JERR__FILEIO, oss.str(), "jinf", "analyze");
+ file_hdr fhdr;
+ jifs.read((char*)&fhdr, sizeof(fhdr));
+ if (fhdr._magic != RHM_JDAT_FILE_MAGIC) // No file header
+ {
+ if (fhdr._magic != 0)
+ throw jexception(jerrno::JERR_JINF_INVALIDFHDR, oss.str(), "jinf", "analyze");
+ if (!pfid) // pfid 0 == lid 0 cannot be empty
+ throw jexception(jerrno::JERR_JINF_JDATEMPTY, oss.str(), "jinf", "analyze");
+ _frot = true;
+ done = true;
+ }
+ else
+ {
+ assert(pfid == fhdr._pfid);
+ if (pfid == 0)
+ {
+ _initial_owi = fhdr.get_owi();
+ early_map.insert(fhdr._lfid, pfid);
+ }
+ else
+ {
+ if (_initial_owi == fhdr.get_owi())
+ {
+ early_map.insert(fhdr._lfid, pfid);
+ if (late_latch && (!_ae || _num_jfiles == JRNL_MIN_NUM_FILES))
+ throw jexception(jerrno::JERR_JINF_OWIBAD, oss.str(), "jinf", "analyze");
+ }
+ else
+ {
+ late_map.insert(fhdr._lfid, pfid);
+ late_latch = true;
+ }
+ }
+ }
+ jifs.close();
+ } // for (pfid)
+
+ // If this is not the first rotation, all files should be in either early or late maps
+ if (!_frot) assert(early_map.size() + late_map.size() == _num_jfiles);
+
+ _pfid_list.clear();
+ late_map.get_pfid_list(_pfid_list);
+ early_map.get_pfid_list(_pfid_list);
+
+ // Check OWI consistency
+// for (u_int16_t lfid=0; lfid<_num_jfiles && !done; lfid++)
+// {
+// throw jexception(jerrno::JERR_JINF_OWIBAD, oss.str(), "jinf", "analyze");
+// }
+
+ _analyzed_flag = true;
+}
+
+void
+jinf::write()
+{
+ std::ostringstream oss;
+ oss << _jdir << "/" << _base_filename << "." << JRNL_INFO_EXTENSION;
+ std::ofstream of(oss.str().c_str(), std::ofstream::out | std::ofstream::trunc);
+ if (!of.good())
+ throw jexception(jerrno::JERR__FILEIO, oss.str(), "jinf", "write");
+ of << xml_str();
+ of.close();
+}
+
+u_int16_t
+jinf::incr_num_jfiles()
+{
+ if (_num_jfiles >= JRNL_MAX_NUM_FILES)
+ throw jexception(jerrno::JERR_JINF_TOOMANYFILES, "jinf", "incr_num_jfiles");
+ return ++_num_jfiles;
+}
+
+u_int16_t
+jinf::get_first_pfid()
+{
+ if (!_analyzed_flag)
+ analyze();
+ return *_pfid_list.begin();
+}
+
+u_int16_t
+jinf::get_last_pfid()
+{
+ if (!_analyzed_flag)
+ analyze();
+ return *_pfid_list.rbegin();
+}
+
+jinf::pfid_list&
+jinf::get_pfid_list()
+{
+ if (!_analyzed_flag)
+ analyze();
+ return _pfid_list;
+}
+
+void
+jinf::get_normalized_pfid_list(pfid_list& pfid_list)
+{
+ if (!_analyzed_flag)
+ analyze();
+ pfid_list.clear();
+ u_int16_t s = _pfid_list.size();
+ u_int16_t iz = 0; // index of 0 value
+ while (_pfid_list[iz] && iz < s)
+ iz++;
+ assert(_pfid_list[iz] == 0);
+ for (u_int16_t i = iz; i < iz + s; i++)
+ pfid_list.push_back(_pfid_list[i % s]);
+ assert(pfid_list[0] == 0);
+ assert(pfid_list.size() == s);
+}
+
+bool
+jinf::get_initial_owi()
+{
+ if (!_analyzed_flag)
+ analyze();
+ return _initial_owi;
+}
+
+bool
+jinf::get_frot()
+{
+ if (!_analyzed_flag)
+ analyze();
+ return _frot;
+}
+
+std::string
+jinf::to_string() const
+{
+ std::ostringstream oss;
+ oss << std::setfill('0');
+ oss << "Journal ID \"" << _jid << "\" initialized " << (_tm_ptr->tm_year + 1900) << "/";
+ oss << std::setw(2) << (_tm_ptr->tm_mon + 1) << "/" << std::setw(2) << _tm_ptr->tm_mday << " ";
+ oss << std::setw(2) << _tm_ptr->tm_hour << ":" << std::setw(2) << _tm_ptr->tm_min << ":";
+ oss << std::setw(2) << _tm_ptr->tm_sec << "." << std::setw(9) << _ts.tv_nsec << ":" << std::endl;
+ oss << " Journal directory: \"" << _jdir << "\"" << std::endl;
+ oss << " Journal base filename: \"" << _base_filename << "\"" << std::endl;
+ oss << " Journal version: " << (unsigned)_jver << std::endl;
+ oss << " Number of journal files: " << _num_jfiles << std::endl;
+// TODO: Uncomment these lines when auto-expand is enabled.
+// oss << " Auto-expand mode: " << (_ae ? "enabled" : "disabled") << std::endl;
+// if (_ae) oss << " Max. number of journal files (in auto-expand mode): " << _ae_max_jfiles << std::endl;
+ oss << " Journal file size: " << _jfsize_sblks << " sblks" << std::endl;
+ oss << " Softblock size (JRNL_SBLK_SIZE): " << _sblk_size_dblks << " dblks" << std::endl;
+ oss << " Datablock size (JRNL_DBLK_SIZE): " << _dblk_size << " bytes" << std::endl;
+ oss << " Write page size: " << _wcache_pgsize_sblks << " sblks" << std::endl;
+ oss << " Number of write pages: " << _wcache_num_pages << std::endl;
+ oss << " Read page size (JRNL_RMGR_PAGE_SIZE): " << _rcache_pgsize_sblks << " sblks" << std::endl;
+ oss << " Number of read pages (JRNL_RMGR_PAGES): " << _rcache_num_pages << std::endl;
+ return oss.str();
+}
+
+std::string
+jinf::xml_str() const
+{
+ // TODO: This is *not* an XML writer, rather for simplicity, it uses literals. I'm sure a more elegant way can be
+ // found to do this using the real thing...
+
+ std::ostringstream oss;
+ oss << std::setfill('0');
+ oss << "<?xml version=\"1.0\" ?>" << std::endl;
+ oss << "<jrnl>" << std::endl;
+ oss << " <journal_version value=\"" << (unsigned)_jver << "\" />" << std::endl;
+ oss << " <journal_id>" << std::endl;
+ oss << " <id_string value=\"" << _jid << "\" />" << std::endl;
+ oss << " <directory value=\"" << _jdir << "\" />" << std::endl;
+ oss << " <base_filename value=\"" << _base_filename << "\" />" << std::endl;
+ oss << " </journal_id>" << std::endl;
+ oss << " <creation_time>" << std::endl;
+ oss << " <seconds value=\"" << _ts.tv_sec << "\" />" << std::endl;
+ oss << " <nanoseconds value=\"" << _ts.tv_nsec << "\" />" << std::endl;
+ oss << " <string value=\"" << (_tm_ptr->tm_year + 1900) << "/";
+ oss << std::setw(2) << (_tm_ptr->tm_mon + 1) << "/" << std::setw(2) << _tm_ptr->tm_mday << " ";
+ oss << std::setw(2) << _tm_ptr->tm_hour << ":" << std::setw(2) << _tm_ptr->tm_min << ":";
+ oss << std::setw(2) << _tm_ptr->tm_sec << "." << std::setw(9) << _ts.tv_nsec;
+ oss << "\" />" << std::endl;
+ oss << " </creation_time>" << std::endl;
+ oss << " <journal_file_geometry>" << std::endl;
+ oss << " <number_jrnl_files value=\"" << _num_jfiles << "\" />" << std::endl;
+ oss << " <auto_expand value=\"" << (_ae ? "true" : "false") << "\" />" << std::endl;
+ if (_ae) oss << " <auto_expand_max_jrnl_files value=\"" << _ae_max_jfiles << "\" />" << std::endl;
+ oss << " <jrnl_file_size_sblks value=\"" << _jfsize_sblks << "\" />" << std::endl;
+ oss << " <JRNL_SBLK_SIZE value=\"" << _sblk_size_dblks << "\" />" << std::endl;
+ oss << " <JRNL_DBLK_SIZE value=\"" << _dblk_size << "\" />" << std::endl;
+ oss << " </journal_file_geometry>" << std::endl;
+ oss << " <cache_geometry>" << std::endl;
+ oss << " <wcache_pgsize_sblks value=\"" << _wcache_pgsize_sblks << "\" />" << std::endl;
+ oss << " <wcache_num_pages value=\"" << _wcache_num_pages << "\" />" << std::endl;
+ oss << " <JRNL_RMGR_PAGE_SIZE value=\"" << _rcache_pgsize_sblks << "\" />" << std::endl;
+ oss << " <JRNL_RMGR_PAGES value=\"" << _rcache_num_pages << "\" />" << std::endl;
+ oss << " </cache_geometry>" << std::endl;
+ oss << "</jrnl>" << std::endl;
+ return oss.str();
+}
+
+void
+jinf::set_filename()
+{
+ std::ostringstream oss;
+ oss << _jdir << "/" << _base_filename << "." << JRNL_INFO_EXTENSION;
+ _filename = oss.str().c_str();
+}
+
+void
+jinf::read(const std::string& jinf_filename)
+{
+ // TODO: This is *not* an XML reader, rather for simplicity, it is a brute-force line reader which relies on string
+ // recognition. It relies on the format of xml_str() above; it will not handle a XML restructuring.
+ // *** Can it be replaced cheaply by a real XML reader? Should it be, or is this sufficient? ***
+
+ char buff[1024]; // limit of line input length
+ std::ifstream jinfs(jinf_filename.c_str());
+ if (!jinfs.good())
+ throw jexception(jerrno::JERR__FILEIO, jinf_filename.c_str(), "jinf", "read");
+ u_int32_t charcnt = 0;
+ while (jinfs.good())
+ {
+ jinfs.getline(buff, 1023);
+ charcnt += std::strlen(buff);
+ if (std::strstr(buff, "journal_version"))
+ _jver = u_int16_value(buff);
+ else if(std::strstr(buff, "id_string"))
+ string_value(_jid, buff);
+ else if(std::strstr(buff, "directory"))
+ string_value(_jdir, buff);
+ else if(std::strstr(buff, "base_filename"))
+ string_value(_base_filename, buff);
+ else if(std::strstr(buff, "number_jrnl_files"))
+ _num_jfiles = u_int16_value(buff);
+ else if(std::strstr(buff, "auto_expand_max_jrnl_files"))
+ _ae_max_jfiles = u_int16_value(buff);
+ else if(std::strstr(buff, "auto_expand"))
+ _ae = bool_value(buff);
+ else if(std::strstr(buff, "jrnl_file_size_sblks"))
+ _jfsize_sblks = u_int32_value(buff);
+ else if(std::strstr(buff, "JRNL_SBLK_SIZE"))
+ _sblk_size_dblks = u_int16_value(buff);
+ else if(std::strstr(buff, "JRNL_DBLK_SIZE"))
+ _dblk_size = u_int32_value(buff);
+ else if(std::strstr(buff, "wcache_pgsize_sblks"))
+ _wcache_pgsize_sblks = u_int32_value(buff);
+ else if(std::strstr(buff, "wcache_num_pages"))
+ _wcache_num_pages = u_int32_value(buff);
+ else if(std::strstr(buff, "JRNL_RMGR_PAGE_SIZE"))
+ _rcache_pgsize_sblks = u_int32_value(buff);
+ else if(std::strstr(buff, "JRNL_RMGR_PAGES"))
+ _rcache_num_pages = u_int32_value(buff);
+ else if(std::strstr(buff, "nanoseconds"))
+ _ts.tv_nsec = u_int32_value(buff);
+ else if(std::strstr(buff, "seconds"))
+ {
+ _ts.tv_sec = u_int32_value(buff);
+ _tm_ptr = std::localtime(&_ts.tv_sec);
+ }
+ }
+ jinfs.close();
+ if (charcnt == 0)
+ throw jexception(jerrno::JERR_JINF_ZEROLENFILE, jinf_filename.c_str(), "jinf", "read");
+}
+
+bool
+jinf::bool_value(char* line) const
+{
+ return std::strcmp(find_value(line), "true") == 0;
+}
+
+u_int16_t
+jinf::u_int16_value(char* line) const
+{
+ return std::atoi(find_value(line));
+}
+
+u_int32_t
+jinf::u_int32_value(char* line) const
+{
+ return std::atol(find_value(line));
+}
+
+std::string&
+jinf::string_value(std::string& str, char* line) const
+{
+ str.assign(find_value(line));
+ return str;
+}
+
+char*
+jinf::find_value(char* line) const
+{
+ const char* target1_str = "value=\"";
+ int target2_char = '\"';
+ char* t1 = std::strstr(line, target1_str);
+ if (t1 == 0)
+ {
+ std::ostringstream oss;
+ oss << "File \"" << _filename << "\": line=" << line;
+ throw jexception(jerrno::JERR_JINF_NOVALUESTR, oss.str(), "jinf", "find_value");
+ }
+ t1 += std::strlen(target1_str);
+
+ char* t2 = std::strchr(t1, target2_char);
+ if (t2 == 0)
+ {
+ std::ostringstream oss;
+ oss << "File \"" << _filename << "\": line=" << line;
+ throw jexception(jerrno::JERR_JINF_BADVALUESTR, oss.str(), "jinf", "find_value");
+ }
+ *t2 = '\0';
+ return t1;
+}
+
+u_int32_t
+jinf::get_filesize(const std::string& file_name) const
+{
+ struct stat s;
+ if (::stat(file_name.c_str(), &s))
+ {
+ std::ostringstream oss;
+ oss << "stat: file=\"" << file_name << "\"" << FORMAT_SYSERR(errno);
+ throw jexception(jerrno::JERR_JINF_STAT, oss.str(), "jinf", "get_filesize");
+ }
+ if (!S_ISREG(s.st_mode)) // not a regular file,
+ {
+ std::ostringstream oss;
+ oss << "File \"" << file_name << "\" is not a regular file: mode=0x" << std::hex << s.st_mode;
+ throw jexception(jerrno::JERR_JINF_NOTREGFILE, oss.str(), "jinf", "get_filesize");
+ }
+ return u_int32_t(s.st_size);
+}
+
+} // namespace journal
+} // namespace mrg
Added: qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jinf.hpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jinf.hpp?rev=1424091&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jinf.hpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jinf.hpp Wed Dec 19 20:34:56 2012
@@ -0,0 +1,136 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file jinf.hpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * This file contains the code for the mrg::journal::jinf class.
+ *
+ * \author Kim van der Riet
+ *
+ * Copyright (c) 2007, 2008, 2009 Red Hat, Inc.
+ *
+ */
+
+#ifndef mrg_journal_jinf_hpp
+#define mrg_journal_jinf_hpp
+
+#include <ctime>
+#include <string>
+#include <sys/types.h>
+#include <vector>
+
+namespace mrg
+{
+namespace journal
+{
+ /**
+ * \class jinf
+ * \brief Class to handle the journal information file <basename>.jinf.
+ */
+ class jinf
+ {
+ public:
+ typedef std::vector<u_int16_t> pfid_list; // pfids
+ typedef pfid_list::const_iterator pfidl_citr;
+
+ private:
+ u_int8_t _jver;
+ std::string _jid;
+ std::string _jdir;
+ std::string _base_filename;
+ std::string _filename;
+ timespec _ts;
+ u_int16_t _num_jfiles;
+ bool _ae;
+ u_int32_t _ae_max_jfiles;
+ u_int32_t _jfsize_sblks;
+ u_int16_t _sblk_size_dblks;
+ u_int32_t _dblk_size;
+ u_int32_t _wcache_pgsize_sblks;
+ u_int16_t _wcache_num_pages;
+ u_int32_t _rcache_pgsize_sblks;
+ u_int16_t _rcache_num_pages;
+ std::tm* _tm_ptr;
+ bool _valid_flag;
+ bool _analyzed_flag;
+ pfid_list _pfid_list;
+ bool _initial_owi;
+ bool _frot;
+
+ public:
+ // constructor for reading existing jinf file
+ jinf(const std::string& jinf_filename, bool validate_flag);
+ // constructor for writing jinf file
+ jinf(const std::string& jid, const std::string& jdir, const std::string& base_filename,
+ const u_int16_t num_jfiles, const bool auto_expand, const u_int16_t ae_max_jfiles,
+ const u_int32_t jfsize_sblks, const u_int32_t wcache_pgsize_sblks, const u_int16_t wcache_num_pages,
+ const timespec& ts);
+ virtual ~jinf();
+
+ void validate();
+ void analyze();
+ void write();
+
+ inline u_int8_t jver() const { return _jver; }
+ inline const std::string& jid() const { return _jid; }
+ inline const std::string& jdir() const { return _jdir; }
+ inline void set_jdir(const std::string& jdir) { _jdir = jdir; }
+ inline const std::string& base_filename() const { return _base_filename; }
+ inline const timespec& ts() const { return _ts; }
+ inline u_int16_t num_jfiles() const { return _num_jfiles; }
+ u_int16_t incr_num_jfiles();
+ inline bool is_ae() const { return _ae; }
+ inline u_int16_t ae_max_jfiles() const { return _ae_max_jfiles; }
+ inline u_int32_t jfsize_sblks() const { return _jfsize_sblks; }
+ inline u_int16_t sblk_size_dblks() const { return _sblk_size_dblks; }
+ inline u_int32_t dblk_size() const { return _dblk_size; }
+ inline u_int32_t wcache_pgsize_sblks() const { return _wcache_pgsize_sblks; }
+ inline u_int16_t wcache_num_pages() const { return _wcache_num_pages; }
+ inline u_int32_t rcache_pgsize_sblks() const { return _rcache_pgsize_sblks; }
+ inline u_int16_t rcache_num_pages() const { return _rcache_num_pages; }
+ u_int16_t get_first_pfid();
+ u_int16_t get_last_pfid();
+ pfid_list& get_pfid_list();
+ void get_normalized_pfid_list(pfid_list& pfid_list);
+ bool get_initial_owi();
+ bool get_frot();
+
+ std::string to_string() const;
+ std::string xml_str() const;
+
+ private:
+ void set_filename();
+ void read(const std::string& jinf_filename);
+ bool bool_value(char* line) const;
+ u_int16_t u_int16_value(char* line) const;
+ u_int32_t u_int32_value(char* line) const;
+ std::string& string_value(std::string& str, char* line) const;
+ char* find_value(char* line) const;
+ u_int32_t get_filesize(const std::string& file_name) const;
+ };
+
+} // namespace journal
+} // namespace mrg
+
+#endif // ifndef mrg_journal_jinf_hpp
Added: qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jrec.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jrec.cpp?rev=1424091&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jrec.cpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jrec.cpp Wed Dec 19 20:34:56 2012
@@ -0,0 +1,122 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file jrec.cpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * File containing source code for class mrg::journal::jrec (abstract journal
+ * jrecord). See comments in file jrec.hpp for details.
+ *
+ * \author Kim van der Riet
+ *
+ * Copyright (c) 2007, 2008 Red Hat, Inc.
+ *
+ */
+
+#include "jrnl/jrec.hpp"
+
+#include <iomanip>
+#include "jrnl/jerrno.hpp"
+#include "jrnl/jexception.hpp"
+#include <sstream>
+
+namespace mrg
+{
+namespace journal
+{
+
+jrec::jrec() {}
+jrec::~jrec() {}
+
+void
+jrec::chk_hdr(const rec_hdr& hdr)
+{
+ if (hdr._magic == 0)
+ {
+ std::ostringstream oss;
+ oss << std::hex << std::setfill('0');
+ oss << "enq magic NULL: rid=0x" << hdr._rid;
+ throw jexception(jerrno::JERR_JREC_BADRECHDR, oss.str(), "jrec", "chk_hdr");
+ }
+ if (hdr._version != RHM_JDAT_VERSION)
+ {
+ std::ostringstream oss;
+ oss << std::hex << std::setfill('0');
+ oss << "version: rid=0x" << hdr._rid;
+ oss << ": expected=0x" << std::setw(2) << (int)RHM_JDAT_VERSION;
+ oss << " read=0x" << std::setw(2) << (int)hdr._version;
+ throw jexception(jerrno::JERR_JREC_BADRECHDR, oss.str(), "jrec", "chk_hdr");
+ }
+#if defined (JRNL_LITTLE_ENDIAN)
+ u_int8_t endian_flag = RHM_LENDIAN_FLAG;
+#else
+ u_int8_t endian_flag = RHM_BENDIAN_FLAG;
+#endif
+ if (hdr._eflag != endian_flag)
+ {
+ std::ostringstream oss;
+ oss << std::hex << std::setfill('0');
+ oss << "endian_flag: rid=" << hdr._rid;
+ oss << ": expected=0x" << std::setw(2) << (int)endian_flag;
+ oss << " read=0x" << std::setw(2) << (int)hdr._eflag;
+ throw jexception(jerrno::JERR_JREC_BADRECHDR, oss.str(), "jrec", "chk_hdr");
+ }
+}
+
+void
+jrec::chk_rid(const rec_hdr& hdr, const u_int64_t rid)
+{
+ if (hdr._rid != rid)
+ {
+ std::ostringstream oss;
+ oss << std::hex << std::setfill('0');
+ oss << "rid mismatch: expected=0x" << rid;
+ oss << " read=0x" << hdr._rid;
+ throw jexception(jerrno::JERR_JREC_BADRECHDR, oss.str(), "jrec", "chk_hdr");
+ }
+}
+
+void
+jrec::chk_tail(const rec_tail& tail, const rec_hdr& hdr)
+{
+ if (tail._xmagic != ~hdr._magic)
+ {
+ std::ostringstream oss;
+ oss << std::hex << std::setfill('0');
+ oss << "magic: rid=0x" << hdr._rid;
+ oss << ": expected=0x" << ~hdr._magic;
+ oss << " read=0x" << tail._xmagic;
+ throw jexception(jerrno::JERR_JREC_BADRECTAIL, oss.str(), "jrec", "chk_tail");
+ }
+ if (tail._rid != hdr._rid)
+ {
+ std::ostringstream oss;
+ oss << std::hex << std::setfill('0');
+ oss << "rid: rid=0x" << hdr._rid;
+ oss << ": read=0x" << tail._rid;
+ throw jexception(jerrno::JERR_JREC_BADRECTAIL, oss.str(), "jrec", "chk_tail");
+ }
+}
+
+} // namespace journal
+} // namespace mrg
Added: qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jrec.hpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jrec.hpp?rev=1424091&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jrec.hpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/legacystore/jrnl/jrec.hpp Wed Dec 19 20:34:56 2012
@@ -0,0 +1,186 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/**
+ * \file jrec.hpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * File containing source code for class mrg::journal::jrec (abstract journal
+ * jrecord). See class documentation for details.
+ *
+ * \author Kim van der Riet
+ *
+ * Copyright (c) 2007, 2008 Red Hat, Inc.
+ *
+ */
+
+#ifndef mrg_journal_jrec_hpp
+#define mrg_journal_jrec_hpp
+
+namespace mrg
+{
+namespace journal
+{
+class jrec;
+}
+}
+
+#include <cstddef>
+#include <fstream>
+#include "jrnl/rec_hdr.hpp"
+#include "jrnl/rec_tail.hpp"
+#include <string>
+#include <sys/types.h>
+
+namespace mrg
+{
+namespace journal
+{
+
+ /**
+ * \class jrec
+ * \brief Abstract class for all file jrecords, both data and log. This class establishes
+ * the common data format and structure for these jrecords.
+ */
+ class jrec
+ {
+ public:
+ jrec();
+ virtual ~jrec();
+
+ /**
+ * \brief Encode this instance of jrec into the write buffer at the disk-block-aligned
+ * pointer wptr starting at position rec_offs_dblks in the encoded record to a
+ * maximum size of max_size_dblks.
+ *
+ * This call encodes the content of the data contianed in this instance of jrec into a
+ * disk-softblock-aligned (defined by JRNL_SBLK_SIZE) buffer pointed to by parameter
+ * wptr. No more than paramter max_size_dblks data-blocks may be written to the buffer.
+ * The parameter rec_offs_dblks is the offset in data-blocks within the fully encoded
+ * data block this instance represents at which to start encoding.
+ *
+ * Encoding entails writing the record header (struct enq_hdr), the data and the record tail
+ * (struct enq_tail). The record must be data-block-aligned (defined by JRNL_DBLK_SIZE),
+ * thus any remaining space in the final data-block is ignored; the returned value is the
+ * number of data-blocks consumed from the page by the encode action. Provided the initial
+ * alignment requirements are met, records may be of arbitrary size and may span multiple
+ * data-blocks, disk-blocks and/or pages.
+ *
+ * Since the record size in data-blocks is known, the general usage pattern is to call
+ * encode() as many times as is needed to fully encode the data. Each call to encode()
+ * will encode as much of the record as it can to what remains of the current page cache,
+ * and will return the number of data-blocks actually encoded.
+ *
+ * <b>Example:</b> Assume that record r1 was previously written to page 0, and that this
+ * is an instance representing record r2. Being larger than the page size ps, r2 would span
+ * multiple pages as follows:
+ * <pre>
+ * |<---ps--->|
+ * +----------+----------+----------+----...
+ * | |r2a| r2b | r2c | |
+ * |<-r1-><----------r2----------> |
+ * +----------+----------+----------+----...
+ * page: p0 p1 p2
+ * </pre>
+ * Encoding record r2 will require multiple calls to encode; one for each page which
+ * is involved. Record r2 is divided logically into sections r2a, r2b and r2c at the
+ * points where the page boundaries intersect with the record. Assuming a page size
+ * of ps, the page boundary pointers are represented by their names p0, p1... and the
+ * sizes of the record segments are represented by their names r1, r2a, r2b..., the calls
+ * should be as follows:
+ * <pre>
+ * encode(p0+r1, 0, ps-r1); (returns r2a data-blocks)
+ * encode(p1, r2a, ps); (returns r2b data-blocks which equals ps)
+ * encode(p2, r2a+r2b, ps); (returns r2c data-blocks)
+ * </pre>
+ *
+ * \param wptr Data-block-aligned pointer to position in page buffer where encoding is to
+ * take place.
+ * \param rec_offs_dblks Offset in data-blocks within record from which to start encoding.
+ * \param max_size_dblks Maximum number of data-blocks to write to pointer wptr.
+ * \returns Number of data-blocks encoded.
+ */
+ virtual u_int32_t encode(void* wptr, u_int32_t rec_offs_dblks,
+ u_int32_t max_size_dblks) = 0;
+
+ /**
+ * \brief Decode into this instance of jrec from the read buffer at the disk-block-aligned
+ * pointer rptr starting at position jrec_offs_dblks in the encoded record to a
+ * maximum size of max_size_blks.
+ *
+ * This call decodes a record in the page buffer pointed to by the data-block-aligned
+ * (defined by JRNL_DBLK_SIZE) parameter rptr into this instance of jrec. No more than
+ * paramter max_size_dblks data-blocks may be read from the buffer. The parameter
+ * jrec_offs_dblks is the offset in data-blocks within the encoded record at which to start
+ * decoding.
+ *
+ * Decoding entails reading the record header, the data and the tail. The record is
+ * data-block-aligned (defined by JRNL_DBLK_SIZE); the returned value is the number of
+ * data-blocks read from the buffer by the decode action. As the record data size is only
+ * known once the header is read, the number of calls required to complete reading the
+ * record will depend on the vlaues within this instance which are set when the
+ * header is decoded.
+ *
+ * A non-zero value for jrec_offs_dblks implies that this is not the first call to
+ * decode and the record data will be appended at this offset.
+ *
+ * \param h Reference to instance of struct hdr, already read from page buffer and used
+ * to determine record type
+ * \param rptr Data-block-aligned pointer to position in page buffer where decoding is to
+ * begin.
+ * \param rec_offs_dblks Offset within record from which to start appending the decoded
+ * record.
+ * \param max_size_dblks Maximum number of data-blocks to read from pointer rptr.
+ * \returns Number of data-blocks read (consumed).
+ */
+ virtual u_int32_t decode(rec_hdr& h, void* rptr, u_int32_t rec_offs_dblks,
+ u_int32_t max_size_dblks) = 0;
+
+ virtual bool rcv_decode(rec_hdr h, std::ifstream* ifsp, std::size_t& rec_offs) = 0;
+
+ virtual std::string& str(std::string& str) const = 0;
+ virtual std::size_t data_size() const = 0;
+ virtual std::size_t xid_size() const = 0;
+ virtual std::size_t rec_size() const = 0;
+ inline virtual u_int32_t rec_size_dblks() const { return size_dblks(rec_size()); }
+ static inline u_int32_t size_dblks(const std::size_t size)
+ { return size_blks(size, JRNL_DBLK_SIZE); }
+ static inline u_int32_t size_sblks(const std::size_t size)
+ { return size_blks(size, JRNL_DBLK_SIZE * JRNL_SBLK_SIZE); }
+ static inline u_int32_t size_blks(const std::size_t size, const std::size_t blksize)
+ { return (size + blksize - 1)/blksize; }
+ virtual u_int64_t rid() const = 0;
+
+ protected:
+ virtual void chk_hdr() const = 0;
+ virtual void chk_hdr(u_int64_t rid) const = 0;
+ virtual void chk_tail() const = 0;
+ static void chk_hdr(const rec_hdr& hdr);
+ static void chk_rid(const rec_hdr& hdr, u_int64_t rid);
+ static void chk_tail(const rec_tail& tail, const rec_hdr& hdr);
+ virtual void clean() = 0;
+ }; // class jrec
+
+} // namespace journal
+} // namespace mrg
+
+#endif // ifndef mrg_journal_jrec_hpp
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org