You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by tr...@apache.org on 2013/07/10 20:20:20 UTC
svn commit: r1501895 [7/10] - in /qpid/branches/linearstore/qpid/cpp/src: ./
qpid/linearstore/ qpid/linearstore/jrnl/
Added: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jerrno.h
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jerrno.h?rev=1501895&view=auto
==============================================================================
--- qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jerrno.h (added)
+++ qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jerrno.h Wed Jul 10 18:20:19 2013
@@ -0,0 +1,173 @@
+/*
+ *
+ * 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.h
+ *
+ * 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
+ */
+
+#ifndef QPID_LEGACYSTORE_JRNL_JERRNO_H
+#define QPID_LEGACYSTORE_JRNL_JERRNO_H
+
+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 QPID_LEGACYSTORE_JRNL_JERRNO_H
Propchange: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jerrno.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jerrno.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Rev URL
Added: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jexception.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jexception.cpp?rev=1501895&view=auto
==============================================================================
--- qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jexception.cpp (added)
+++ qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jexception.cpp Wed Jul 10 18:20:19 2013
@@ -0,0 +1,183 @@
+/*
+ *
+ * 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.h for details.
+ *
+ * \author Kim van der Riet
+ */
+
+#include "qpid/legacystore/jrnl/jexception.h"
+
+#include <iomanip>
+#include <sstream>
+#include "qpid/legacystore/jrnl/jerrno.h"
+
+#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
Propchange: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jexception.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jexception.h
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jexception.h?rev=1501895&view=auto
==============================================================================
--- qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jexception.h (added)
+++ qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jexception.h Wed Jul 10 18:20:19 2013
@@ -0,0 +1,142 @@
+/*
+ *
+ * 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.h
+ *
+ * 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
+ */
+
+#ifndef QPID_LEGACYSTORE_JRNL_JEXCEPTION_H
+#define QPID_LEGACYSTORE_JRNL_JEXCEPTION_H
+
+namespace mrg
+{
+namespace journal
+{
+class jexception;
+}
+}
+
+#include <cerrno>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <exception>
+#include "qpid/legacystore/jrnl/jerrno.h"
+#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 QPID_LEGACYSTORE_JRNL_JEXCEPTION_H
Propchange: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jexception.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jexception.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Rev URL
Added: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jinf.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jinf.cpp?rev=1501895&view=auto
==============================================================================
--- qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jinf.cpp (added)
+++ qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jinf.cpp Wed Jul 10 18:20:19 2013
@@ -0,0 +1,540 @@
+/*
+ *
+ * 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.h comments for details of this class.
+ *
+ * \author Kim van der Riet
+ */
+
+#include "qpid/legacystore/jrnl/jinf.h"
+
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <fstream>
+#include "qpid/legacystore/jrnl/file_hdr.h"
+#include "qpid/legacystore/jrnl/jcntl.h"
+#include "qpid/legacystore/jrnl/jerrno.h"
+#include "qpid/legacystore/jrnl/lp_map.h"
+#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
Propchange: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jinf.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jinf.h
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jinf.h?rev=1501895&view=auto
==============================================================================
--- qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jinf.h (added)
+++ qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jinf.h Wed Jul 10 18:20:19 2013
@@ -0,0 +1,133 @@
+/*
+ *
+ * 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.h
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * This file contains the code for the mrg::journal::jinf class.
+ *
+ * \author Kim van der Riet
+ */
+
+#ifndef QPID_LEGACYSTORE_JRNL_JINF_H
+#define QPID_LEGACYSTORE_JRNL_JINF_H
+
+#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 QPID_LEGACYSTORE_JRNL_JINF_H
Propchange: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jinf.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jinf.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Rev URL
Added: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jrec.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jrec.cpp?rev=1501895&view=auto
==============================================================================
--- qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jrec.cpp (added)
+++ qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jrec.cpp Wed Jul 10 18:20:19 2013
@@ -0,0 +1,119 @@
+/*
+ *
+ * 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.h for details.
+ *
+ * \author Kim van der Riet
+ */
+
+#include "qpid/legacystore/jrnl/jrec.h"
+
+#include <iomanip>
+#include "qpid/legacystore/jrnl/jerrno.h"
+#include "qpid/legacystore/jrnl/jexception.h"
+#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
Propchange: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jrec.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jrec.h
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jrec.h?rev=1501895&view=auto
==============================================================================
--- qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jrec.h (added)
+++ qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jrec.h Wed Jul 10 18:20:19 2013
@@ -0,0 +1,183 @@
+/*
+ *
+ * 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.h
+ *
+ * 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
+ */
+
+#ifndef QPID_LEGACYSTORE_JRNL_JREC_H
+#define QPID_LEGACYSTORE_JRNL_JREC_H
+
+namespace mrg
+{
+namespace journal
+{
+class jrec;
+}
+}
+
+#include <cstddef>
+#include <fstream>
+#include "qpid/legacystore/jrnl/rec_hdr.h"
+#include "qpid/legacystore/jrnl/rec_tail.h"
+#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 QPID_LEGACYSTORE_JRNL_JREC_H
Propchange: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jrec.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/jrec.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Rev URL
Added: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/lp_map.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/lp_map.cpp?rev=1501895&view=auto
==============================================================================
--- qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/lp_map.cpp (added)
+++ qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/lp_map.cpp Wed Jul 10 18:20:19 2013
@@ -0,0 +1,82 @@
+/*
+ *
+ * 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 lp_map.cpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * File containing code for class mrg::journal::lp_map (logical file map). See
+ * comments in file lp_map.h for details.
+ *
+ * \author Kim van der Riet
+ */
+
+#include "qpid/legacystore/jrnl/lp_map.h"
+
+#include "qpid/legacystore/jrnl/jerrno.h"
+#include "qpid/legacystore/jrnl/jexception.h"
+#include <sstream>
+
+namespace mrg
+{
+namespace journal
+{
+lp_map::lp_map() : _map() {}
+lp_map::~lp_map() {}
+
+void
+lp_map::insert(u_int16_t lfid, u_int16_t pfid)
+{
+ lfpair ip = lfpair(lfid, pfid);
+ lfret ret = _map.insert(ip);
+ if (ret.second == false)
+ {
+ std::ostringstream oss;
+ oss << std::hex << "lfid=0x" << lfid << " pfid=0x" << pfid;
+ throw jexception(jerrno::JERR_MAP_DUPLICATE, oss.str(), "lp_map", "insert");
+ }
+}
+
+void
+lp_map::get_pfid_list(std::vector<u_int16_t>& pfid_list)
+{
+ for (lp_map_citr_t i = _map.begin(); i != _map.end(); i++)
+ pfid_list.push_back(i->second);
+}
+
+// debug aid
+std::string
+lp_map::to_string()
+{
+ std::ostringstream oss;
+ oss << "{lfid:pfid ";
+ for (lp_map_citr_t i=_map.begin(); i!=_map.end(); i++)
+ {
+ if (i != _map.begin()) oss << ", ";
+ oss << (*i).first << ":" << (*i).second;
+ }
+ oss << "}";
+ return oss.str();
+}
+
+} // namespace journal
+} // namespace mrg
Propchange: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/lp_map.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/lp_map.h
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/lp_map.h?rev=1501895&view=auto
==============================================================================
--- qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/lp_map.h (added)
+++ qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/lp_map.h Wed Jul 10 18:20:19 2013
@@ -0,0 +1,83 @@
+/*
+ *
+ * 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 lp_map.h
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * File containing code for class mrg::journal::lp_map (logical file map).
+ * See class documentation for details.
+ *
+ * \author Kim van der Riet
+ */
+
+#ifndef QPID_LEGACYSTORE_JRNL_LP_MAP_H
+#define QPID_LEGACYSTORE_JRNL_LP_MAP_H
+
+#include <map>
+#include <string>
+#include <sys/types.h>
+#include <vector>
+
+namespace mrg
+{
+namespace journal
+{
+ /**
+ * \class lp_map
+ * \brief Maps the logical file id (lfid) to the physical file id (pfid) in the journal.
+ *
+ * NOTE: NOT THREAD SAFE
+ */
+ class lp_map
+ {
+ public:
+ typedef std::map<u_int16_t, u_int16_t> lp_map_t;
+ typedef lp_map_t::const_iterator lp_map_citr_t;
+ typedef lp_map_t::const_reverse_iterator lp_map_critr_t;
+
+ private:
+ typedef std::pair<u_int16_t, u_int16_t> lfpair;
+ typedef std::pair<lp_map_t::iterator, bool> lfret;
+ lp_map_t _map;
+
+ public:
+ lp_map();
+ virtual ~lp_map();
+
+ void insert(u_int16_t lfid, u_int16_t pfid);
+ inline u_int16_t size() const { return u_int16_t(_map.size()); }
+ inline bool empty() const { return _map.empty(); }
+ inline lp_map_citr_t begin() { return _map.begin(); }
+ inline lp_map_citr_t end() { return _map.end(); }
+ inline lp_map_critr_t rbegin() { return _map.rbegin(); }
+ inline lp_map_critr_t rend() { return _map.rend(); }
+ void get_pfid_list(std::vector<u_int16_t>& pfid_list);
+
+ // debug aid
+ std::string to_string();
+ };
+
+} // namespace journal
+} // namespace mrg
+
+#endif // ifndef QPID_LEGACYSTORE_JRNL_LP_MAP_H
Propchange: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/lp_map.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/lp_map.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Rev URL
Added: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/lpmgr.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/lpmgr.cpp?rev=1501895&view=auto
==============================================================================
--- qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/lpmgr.cpp (added)
+++ qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/lpmgr.cpp Wed Jul 10 18:20:19 2013
@@ -0,0 +1,226 @@
+/*
+ *
+ * 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 lpmgr.cpp
+ *
+ * Qpid asynchronous store plugin library
+ *
+ * File containing code for class mrg::journal::lpmgr (non-logging file
+ * handle), used for controlling journal log files. See comments in file
+ * lpmgr.h for details.
+ *
+ * \author Kim van der Riet
+ */
+
+#include "qpid/legacystore/jrnl/lpmgr.h"
+
+#include <cassert>
+#include <qpid/legacystore/jrnl/jerrno.h>
+#include <qpid/legacystore/jrnl/jexception.h>
+
+namespace mrg
+{
+namespace journal
+{
+
+lpmgr::lpmgr() : _ae(false), _ae_max_jfiles(0)
+{}
+
+lpmgr::~lpmgr()
+{
+ finalize();
+}
+
+void
+lpmgr::initialize(const u_int16_t num_jfiles,
+ const bool ae,
+ const u_int16_t ae_max_jfiles,
+ jcntl* const jcp,
+ new_obj_fn_ptr fp)
+{
+ assert(jcp != 0);
+ finalize();
+
+ // Validate params
+ if (ae && ae_max_jfiles > 0 && ae_max_jfiles <= num_jfiles)
+ {
+ std::ostringstream oss;
+ oss << "ae_max_jfiles (" << ae_max_jfiles << ") <= num_jfiles (" << num_jfiles << ")";
+ throw jexception(jerrno::JERR_LFMGR_BADAEFNUMLIM, oss.str(), "lpmgr", "initialize");
+ }
+ _ae = ae;
+ _ae_max_jfiles = ae_max_jfiles;
+
+ const std::size_t num_res_files = ae
+ ? (ae_max_jfiles ? ae_max_jfiles : JRNL_MAX_NUM_FILES)
+ : num_jfiles;
+ _fcntl_arr.reserve(num_res_files);
+ append(jcp, fp, num_jfiles);
+}
+
+void
+lpmgr::recover(const rcvdat& rd,
+ jcntl* const jcp,
+ new_obj_fn_ptr fp)
+{
+ assert(jcp != 0);
+ finalize();
+
+ // Validate rd params
+ if (rd._aemjf > 0 && rd._aemjf <= rd._njf)
+ {
+ std::ostringstream oss;
+ oss << "ae_max_jfiles (" << rd._aemjf << ") <= num_jfiles (" << rd._njf << ")";
+ throw jexception(jerrno::JERR_LFMGR_BADAEFNUMLIM, oss.str(), "lpmgr", "recover");
+ }
+ _ae = rd._ae;
+ _ae_max_jfiles = rd._aemjf;
+
+ const std::size_t num_res_files = rd._ae
+ ? (rd._aemjf ? rd._aemjf : JRNL_MAX_NUM_FILES)
+ : rd._njf;
+ _fcntl_arr.reserve(num_res_files);
+ _fcntl_arr.assign(rd._njf, 0);
+ std::vector<u_int16_t> lfid_list(rd._fid_list.size(), 0);
+ for (std::size_t lid = 0; lid < rd._fid_list.size(); lid++)
+ lfid_list[rd._fid_list[lid]] = lid;
+ // NOTE: rd._fid_list may be smaller than rd._njf (journal may be empty or not yet file-cycled)
+ for (std::size_t pfid = 0; pfid < rd._njf; pfid++)
+ if (pfid < rd._fid_list.size())
+ _fcntl_arr[lfid_list[pfid]] = fp(jcp, lfid_list[pfid], pfid, &rd);
+ else
+ _fcntl_arr[pfid] = fp(jcp, pfid, pfid, &rd);
+}
+
+void
+lpmgr::insert(const u_int16_t after_lfid,
+ jcntl* const jcp,
+ new_obj_fn_ptr fp,
+ const u_int16_t num_jfiles)
+{
+ assert(jcp != 0);
+ assert(after_lfid < _fcntl_arr.size());
+ if (!_ae) throw jexception(jerrno::JERR_LFMGR_AEDISABLED, "lpmgr", "insert");
+ if (num_jfiles == 0) return;
+ std::size_t pfid = _fcntl_arr.size();
+ const u_int16_t eff_ae_max_jfiles = _ae_max_jfiles ? _ae_max_jfiles : JRNL_MAX_NUM_FILES;
+ if (pfid + num_jfiles > eff_ae_max_jfiles)
+ {
+ std::ostringstream oss;
+ oss << "num_files=" << pfid << " incr=" << num_jfiles << " limit=" << _ae_max_jfiles;
+ throw jexception(jerrno::JERR_LFMGR_AEFNUMLIMIT, oss.str(), "lpmgr", "insert");
+ }
+ for (std::size_t lid = after_lfid + 1; lid <= after_lfid + num_jfiles; lid++, pfid++)
+ _fcntl_arr.insert(_fcntl_arr.begin() + lid, fp(jcp, lid, pfid, 0));
+ for (std::size_t lid = after_lfid + num_jfiles + 1; lid < _fcntl_arr.size(); lid++)
+ {
+ fcntl* p = _fcntl_arr[lid];
+ assert(p != 0);
+ p->set_lfid(p->lfid() + num_jfiles);
+ }
+}
+
+void
+lpmgr::finalize()
+{
+ for (u_int32_t i = 0; i < _fcntl_arr.size(); i++)
+ delete _fcntl_arr[i];
+ _fcntl_arr.clear();
+ _ae = false;
+ _ae_max_jfiles = 0;
+}
+
+void
+lpmgr::set_ae(const bool ae)
+{
+ if (ae && _ae_max_jfiles > 0 && _ae_max_jfiles <= _fcntl_arr.size())
+ {
+ std::ostringstream oss;
+ oss << "ae_max_jfiles (" << _ae_max_jfiles << ") <= _fcntl_arr.size (" << _fcntl_arr.size() << ")";
+ throw jexception(jerrno::JERR_LFMGR_BADAEFNUMLIM, oss.str(), "lpmgr", "set_ae");
+ }
+ if (ae && _fcntl_arr.max_size() < _ae_max_jfiles)
+ _fcntl_arr.reserve(_ae_max_jfiles ? _ae_max_jfiles : JRNL_MAX_NUM_FILES);
+ _ae = ae;
+}
+
+void
+lpmgr::set_ae_max_jfiles(const u_int16_t ae_max_jfiles)
+{
+ if (_ae && ae_max_jfiles > 0 && ae_max_jfiles <= _fcntl_arr.size())
+ {
+ std::ostringstream oss;
+ oss << "ae_max_jfiles (" << _ae_max_jfiles << ") <= _fcntl_arr.size() (" << _fcntl_arr.size() << ")";
+ throw jexception(jerrno::JERR_LFMGR_BADAEFNUMLIM, oss.str(), "lpmgr", "set_ae_max_jfiles");
+ }
+ if (_ae && _fcntl_arr.max_size() < ae_max_jfiles)
+ _fcntl_arr.reserve(ae_max_jfiles ? ae_max_jfiles : JRNL_MAX_NUM_FILES);
+ _ae_max_jfiles = ae_max_jfiles;
+}
+
+u_int16_t
+lpmgr::ae_jfiles_rem() const
+{
+ if (_ae_max_jfiles > _fcntl_arr.size()) return _ae_max_jfiles - _fcntl_arr.size();
+ if (_ae_max_jfiles == 0) return JRNL_MAX_NUM_FILES - _fcntl_arr.size();
+ return 0;
+}
+
+// Testing functions
+
+void
+lpmgr::get_pfid_list(std::vector<u_int16_t>& pfid_list) const
+{
+ pfid_list.clear();
+ for (std::size_t i = 0; i < _fcntl_arr.size(); i++)
+ pfid_list.push_back(_fcntl_arr[i]->pfid());
+}
+
+void
+lpmgr::get_lfid_list(std::vector<u_int16_t>& lfid_list) const
+{
+ lfid_list.clear();
+ lfid_list.assign(_fcntl_arr.size(), 0);
+ for (std::size_t i = 0; i < _fcntl_arr.size(); i++)
+ lfid_list[_fcntl_arr[i]->pfid()] = i;
+}
+
+// === protected fns ===
+
+void
+lpmgr::append(jcntl* const jcp,
+ new_obj_fn_ptr fp,
+ const u_int16_t num_jfiles)
+{
+ std::size_t s = _fcntl_arr.size();
+ if (_ae_max_jfiles && s + num_jfiles > _ae_max_jfiles)
+ {
+ std::ostringstream oss;
+ oss << "num_files=" << s << " incr=" << num_jfiles << " limit=" << _ae_max_jfiles;
+ throw jexception(jerrno::JERR_LFMGR_AEFNUMLIMIT, oss.str(), "lpmgr", "append");
+ }
+ for (std::size_t i = s; i < s + num_jfiles; i++)
+ _fcntl_arr.push_back(fp(jcp, i, i, 0));
+}
+
+} // namespace journal
+} // namespace mrg
Propchange: qpid/branches/linearstore/qpid/cpp/src/qpid/linearstore/jrnl/lpmgr.cpp
------------------------------------------------------------------------------
svn:eol-style = native
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org