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 &lt;basename&gt;.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