Author: kpvdr
Date: 2009-01-15 10:57:43 -0500 (Thu, 15 Jan 2009)
New Revision: 3045
Added:
store/trunk/cpp/lib/jrnl/lpmgr.cpp
store/trunk/cpp/lib/jrnl/lpmgr.hpp
store/trunk/cpp/tests/jrnl/_ut_lpmgr.cpp
Removed:
store/trunk/cpp/lib/jrnl/lfmgr.cpp
store/trunk/cpp/lib/jrnl/lfmgr.hpp
store/trunk/cpp/tests/jrnl/_ut_lfmgr.cpp
Modified:
store/trunk/cpp/lib/JournalImpl.cpp
store/trunk/cpp/lib/Makefile.am
store/trunk/cpp/lib/jrnl/jcntl.cpp
store/trunk/cpp/lib/jrnl/jcntl.hpp
store/trunk/cpp/lib/jrnl/jinf.hpp
store/trunk/cpp/lib/jrnl/rfc.cpp
store/trunk/cpp/lib/jrnl/rfc.hpp
store/trunk/cpp/lib/jrnl/rrfc.cpp
store/trunk/cpp/lib/jrnl/rrfc.hpp
store/trunk/cpp/lib/jrnl/wrfc.cpp
store/trunk/cpp/lib/jrnl/wrfc.hpp
store/trunk/cpp/tests/jrnl/Makefile.am
store/trunk/cpp/tests/jrnl/_st_helper_fns.hpp
store/trunk/cpp/tests/jrnl/_ut_jinf.cpp
Log:
More code tidy-up in preparation for auto-expanding queues.
Modified: store/trunk/cpp/lib/JournalImpl.cpp
===================================================================
--- store/trunk/cpp/lib/JournalImpl.cpp 2009-01-15 12:59:10 UTC (rev 3044)
+++ store/trunk/cpp/lib/JournalImpl.cpp 2009-01-15 15:57:43 UTC (rev 3045)
@@ -141,9 +141,9 @@
if (_mgmtObject != 0)
{
- _mgmtObject->set_initialFileCount(_lfmgr.num_jfiles());
+ _mgmtObject->set_initialFileCount(_lpmgr.num_jfiles());
_mgmtObject->set_dataFileSize(_jfsize_sblks * JRNL_SBLK_SIZE *
JRNL_DBLK_SIZE);
- _mgmtObject->set_currentFileCount(_lfmgr.num_jfiles());
+ _mgmtObject->set_currentFileCount(_lpmgr.num_jfiles());
_mgmtObject->set_writePageSize(wcache_pgsize_sblks * JRNL_SBLK_SIZE *
JRNL_DBLK_SIZE);
_mgmtObject->set_writePages(wcache_num_pages);
}
@@ -170,9 +170,9 @@
if (_mgmtObject != 0)
{
- _mgmtObject->set_initialFileCount(_lfmgr.num_jfiles());
+ _mgmtObject->set_initialFileCount(_lpmgr.num_jfiles());
_mgmtObject->set_dataFileSize(_jfsize_sblks * JRNL_SBLK_SIZE *
JRNL_DBLK_SIZE);
- _mgmtObject->set_currentFileCount(_lfmgr.num_jfiles());
+ _mgmtObject->set_currentFileCount(_lpmgr.num_jfiles());
_mgmtObject->set_writePageSize(wcache_pgsize_sblks * JRNL_SBLK_SIZE *
JRNL_DBLK_SIZE);
_mgmtObject->set_writePages(wcache_num_pages);
}
Modified: store/trunk/cpp/lib/Makefile.am
===================================================================
--- store/trunk/cpp/lib/Makefile.am 2009-01-15 12:59:10 UTC (rev 3044)
+++ store/trunk/cpp/lib/Makefile.am 2009-01-15 15:57:43 UTC (rev 3045)
@@ -56,7 +56,7 @@
jrnl/jinf.cpp \
jrnl/jrec.cpp \
jrnl/lp_map.cpp \
- jrnl/lfmgr.cpp \
+ jrnl/lpmgr.cpp \
jrnl/pmgr.cpp \
jrnl/rmgr.cpp \
jrnl/rfc.cpp \
@@ -88,7 +88,7 @@
jrnl/jinf.hpp \
jrnl/jrec.hpp \
jrnl/lp_map.hpp \
- jrnl/lfmgr.hpp \
+ jrnl/lpmgr.hpp \
jrnl/pmgr.hpp \
jrnl/rcvdat.hpp \
jrnl/rec_hdr.hpp \
Modified: store/trunk/cpp/lib/jrnl/jcntl.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/jcntl.cpp 2009-01-15 12:59:10 UTC (rev 3044)
+++ store/trunk/cpp/lib/jrnl/jcntl.cpp 2009-01-15 15:57:43 UTC (rev 3045)
@@ -63,11 +63,11 @@
_readonly_flag(false),
_autostop(true),
_jfsize_sblks(0),
- _lfmgr(),
+ _lpmgr(),
_emap(),
_tmap(),
- _rrfc(&_lfmgr),
- _wrfc(&_lfmgr),
+ _rrfc(&_lpmgr),
+ _wrfc(&_lpmgr),
_rmgr(this, _emap, _tmap, _rrfc),
_wmgr(this, _emap, _tmap, _wrfc),
_rcvdat()
@@ -81,7 +81,7 @@
if (_init_flag && !_stop_flag)
try { stop(true); }
catch (const jexception& e) { std::cerr << e << std::endl; }
- _lfmgr.finalize();
+ _lpmgr.finalize();
::pthread_mutex_destroy(&_gev_mutex);
::pthread_mutex_destroy(&_wr_mutex);
}
@@ -98,7 +98,7 @@
_emap.clear();
_tmap.clear();
- _lfmgr.finalize();
+ _lpmgr.finalize();
// Set new file geometry parameters
assert(num_jfiles >= JRNL_MIN_NUM_FILES);
@@ -112,7 +112,7 @@
// Clear any existing journal files
_jdir.clear_dir();
- _lfmgr.initialize(num_jfiles, auto_expand, ae_max_jfiles, this, &new_fcntl);
+ _lpmgr.initialize(num_jfiles, auto_expand, ae_max_jfiles, this, &new_fcntl);
_wrfc.initialize(_jfsize_sblks);
_rrfc.initialize();
@@ -140,7 +140,7 @@
_emap.clear();
_tmap.clear();
- _lfmgr.finalize();
+ _lpmgr.finalize();
assert(num_jfiles >= JRNL_MIN_NUM_FILES);
assert(num_jfiles <= JRNL_MAX_NUM_FILES);
@@ -158,7 +158,7 @@
throw jexception(jerrno::JERR_JCNTL_RECOVERJFULL, "jcntl",
"recover");
this->log(LOG_DEBUG, _rcvdat.to_log(_jid));
- _lfmgr.recover(_rcvdat, this, &new_fcntl);
+ _lpmgr.recover(_rcvdat, this, &new_fcntl);
_wrfc.initialize(_jfsize_sblks, &_rcvdat);
_rrfc.initialize();
@@ -176,8 +176,8 @@
{
if (!_readonly_flag)
throw jexception(jerrno::JERR_JCNTL_NOTRECOVERED, "jcntl",
"recover_complete");
- for (u_int16_t i=0; i<_lfmgr.num_jfiles(); i++)
- _lfmgr.get_fcntlp(i)->reset(&_rcvdat);
+ for (u_int16_t i=0; i<_lpmgr.num_jfiles(); i++)
+ _lpmgr.get_fcntlp(i)->reset(&_rcvdat);
_wrfc.initialize(_jfsize_sblks, &_rcvdat);
_rrfc.initialize();
_rrfc.set_findex(_rcvdat.ffid());
@@ -383,7 +383,7 @@
u_int16_t fid = _wrfc.index();
while ( _emap.get_enq_cnt(ffid) == 0 && _tmap.get_txn_fid_cnt(ffid) == 0
&& ffid != fid)
{
- if (++ffid >= _lfmgr.num_jfiles())
+ if (++ffid >= _lpmgr.num_jfiles())
ffid = 0;
}
if (!_rrfc.is_active())
@@ -437,7 +437,7 @@
jcntl::fhdr_wr_sync(const u_int16_t lid)
{
long cnt = 0;
- fcntl* fcntlp = _lfmgr.get_fcntlp(lid);
+ fcntl* fcntlp = _lpmgr.get_fcntlp(lid);
get_wr_events();
while (fcntlp->wr_fhdr_aio_outstanding())
{
@@ -489,7 +489,7 @@
oss << FORMAT_SYSERR(errno);
throw jexception(jerrno::JERR__RTCLOCK, oss.str(), "jcntl",
"write_infofile");
}
- jinf ji(_jid, _jdir.dirname(), _base_filename, _lfmgr.num_jfiles(), _lfmgr.is_ae(),
_lfmgr.ae_max_jfiles(),
+ jinf ji(_jid, _jdir.dirname(), _base_filename, _lpmgr.num_jfiles(), _lpmgr.is_ae(),
_lpmgr.ae_max_jfiles(),
_jfsize_sblks, _wmgr.cache_pgsize_sblks(), _wmgr.cache_num_pages(), ts);
ji.write();
}
Modified: store/trunk/cpp/lib/jrnl/jcntl.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/jcntl.hpp 2009-01-15 12:59:10 UTC (rev 3044)
+++ store/trunk/cpp/lib/jrnl/jcntl.hpp 2009-01-15 15:57:43 UTC (rev 3045)
@@ -43,7 +43,7 @@
#include <deque>
#include "jrnl/jdir.hpp"
#include "jrnl/fcntl.hpp"
-#include "jrnl/lfmgr.hpp"
+#include "jrnl/lpmgr.hpp"
#include "jrnl/rcvdat.hpp"
#include "jrnl/rmgr.hpp"
#include "jrnl/wmgr.hpp"
@@ -133,7 +133,7 @@
// Journal control structures
u_int32_t _jfsize_sblks; ///< Journal file size in sblks
- lfmgr _lfmgr; ///< LID-FID manager tracks inserted journal
files
+ lpmgr _lpmgr; ///< LFID-PFID manager tracks inserted journal
files
enq_map _emap; ///< Enqueue map for low water mark management
txn_map _tmap; ///< Transaction map open transactions
rrfc _rrfc; ///< Read journal rotating file controller
@@ -562,13 +562,13 @@
{ return _wrfc.aio_outstanding_dblks(); }
inline u_int32_t get_wr_outstanding_aio_dblks(u_int16_t pi) const
- { return _lfmgr.get_fcntlp(pi)->wr_aio_outstanding_dblks(); }
+ { return _lpmgr.get_fcntlp(pi)->wr_aio_outstanding_dblks(); }
inline u_int32_t get_rd_outstanding_aio_dblks() const
{ return _rrfc.aio_outstanding_dblks(); }
inline u_int32_t get_rd_outstanding_aio_dblks(u_int16_t pi) const
- { return _lfmgr.get_fcntlp(pi)->rd_aio_outstanding_dblks(); }
+ { return _lpmgr.get_fcntlp(pi)->rd_aio_outstanding_dblks(); }
inline u_int16_t get_rd_fid() const { return _rrfc.index(); }
inline u_int16_t get_wr_fid() const { return _wrfc.index(); }
@@ -632,9 +632,9 @@
*/
inline const std::string& base_filename() const { return _base_filename; }
- inline u_int16_t num_jfiles() const { return _lfmgr.num_jfiles(); }
+ inline u_int16_t num_jfiles() const { return _lpmgr.num_jfiles(); }
- inline fcntl* get_fcntlp(const u_int16_t fid) const { return
_lfmgr.get_fcntlp(fid); }
+ inline fcntl* get_fcntlp(const u_int16_t fid) const { return
_lpmgr.get_fcntlp(fid); }
inline u_int32_t jfsize_sblks() const { return _jfsize_sblks; }
Modified: store/trunk/cpp/lib/jrnl/jinf.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/jinf.hpp 2009-01-15 12:59:10 UTC (rev 3044)
+++ store/trunk/cpp/lib/jrnl/jinf.hpp 2009-01-15 15:57:43 UTC (rev 3045)
@@ -48,7 +48,7 @@
class jinf
{
public:
- typedef std::vector<u_int16_t> fid_list;
+ typedef std::vector<u_int16_t> fid_list; // pfids
typedef fid_list::const_iterator fidl_citr;
private:
Deleted: store/trunk/cpp/lib/jrnl/lfmgr.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/lfmgr.cpp 2009-01-15 12:59:10 UTC (rev 3044)
+++ store/trunk/cpp/lib/jrnl/lfmgr.cpp 2009-01-15 15:57:43 UTC (rev 3045)
@@ -1,224 +0,0 @@
-/**
-* \file lfmgr.cpp
-*
-* Red Hat Messaging - Message Journal
-*
-* File containing code for class mrg::journal::lfmgr (non-logging file
-* handle), used for controlling journal log files. See comments in file
-* lfmgr.hpp for details.
-*
-* Copyright 2007, 2008 Red Hat, Inc.
-*
-* This file is part of Red Hat Messaging.
-*
-* Red Hat Messaging is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 2.1 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
-* USA
-*
-* The GNU Lesser General Public License is available in the file COPYING.
-*/
-
-#include "jrnl/lfmgr.hpp"
-
-#include <cassert>
-#include <jrnl/jerrno.hpp>
-#include <jrnl/jexception.hpp>
-
-namespace mrg
-{
-namespace journal
-{
-
-lfmgr::lfmgr() : _ae(false), _ae_max_jfiles(0)
-{}
-
-lfmgr::~lfmgr()
-{
- finalize();
-}
-
-void
-lfmgr::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(), "lfmgr",
"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
-lfmgr::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(), "lfmgr",
"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> lid_list(rd._fid_list.size(), 0);
- for (std::size_t lid = 0; lid < rd._fid_list.size(); lid++)
- lid_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 fid = 0; fid < rd._njf; fid++)
- if (fid < rd._fid_list.size())
- _fcntl_arr[lid_list[fid]] = fp(jcp, lid_list[fid], fid, &rd);
- else
- _fcntl_arr[fid] = fp(jcp, fid, fid, &rd);
-}
-
-void
-lfmgr::insert(const u_int16_t after_index,
- jcntl* const jcp,
- new_obj_fn_ptr fp,
- const u_int16_t num_jfiles)
-{
- assert(jcp != 0);
- assert(after_index < _fcntl_arr.size());
- if (!_ae) throw jexception(jerrno::JERR_LFMGR_AEDISABLED, "lfmgr",
"insert");
- if (num_jfiles == 0) return;
- std::size_t fid = _fcntl_arr.size();
- const u_int16_t eff_ae_max_jfiles = _ae_max_jfiles ? _ae_max_jfiles :
JRNL_MAX_NUM_FILES;
- if (fid + num_jfiles > eff_ae_max_jfiles)
- {
- std::ostringstream oss;
- oss << "num_files=" << fid << " incr="
<< num_jfiles << " limit=" << _ae_max_jfiles;
- throw jexception(jerrno::JERR_LFMGR_AEFNUMLIMIT, oss.str(), "lfmgr",
"insert");
- }
- for (std::size_t lid = after_index + 1; lid <= after_index + num_jfiles; lid++,
fid++)
- _fcntl_arr.insert(_fcntl_arr.begin() + lid, fp(jcp, lid, fid, 0));
- for (std::size_t lid = after_index + num_jfiles + 1; lid < _fcntl_arr.size();
lid++)
- {
- fcntl* p = _fcntl_arr[lid];
- assert(p != 0);
- p->set_lid(p->lid() + num_jfiles);
- }
-}
-
-void
-lfmgr::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
-lfmgr::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(), "lfmgr",
"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
-lfmgr::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(), "lfmgr",
"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
-lfmgr::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
-lfmgr::get_fid_list(std::vector<u_int16_t>& fid_list) const
-{
- fid_list.clear();
- for (std::size_t i = 0; i < _fcntl_arr.size(); i++)
- fid_list.push_back(_fcntl_arr[i]->fid());
-}
-
-void
-lfmgr::get_lid_list(std::vector<u_int16_t>& lid_list) const
-{
- lid_list.clear();
- lid_list.assign(_fcntl_arr.size(), 0);
- for (std::size_t i = 0; i < _fcntl_arr.size(); i++)
- lid_list[_fcntl_arr[i]->fid()] = i;
-}
-
-// === protected fns ===
-
-void
-lfmgr::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(), "lfmgr",
"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
Deleted: store/trunk/cpp/lib/jrnl/lfmgr.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/lfmgr.hpp 2009-01-15 12:59:10 UTC (rev 3044)
+++ store/trunk/cpp/lib/jrnl/lfmgr.hpp 2009-01-15 15:57:43 UTC (rev 3045)
@@ -1,300 +0,0 @@
-/**
-* \file lfmgr.hpp
-*
-* Red Hat Messaging - Message Journal
-*
-* Class mrg::journal::lfmgr. See class documentation for details.
-*
-* Copyright 2007, 2008 Red Hat, Inc.
-*
-* This file is part of Red Hat Messaging.
-*
-* Red Hat Messaging is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 2.1 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
-* USA
-*
-* The GNU Lesser General Public License is available in the file COPYING.
-*/
-
-#ifndef mrg_journal_lfmgr_hpp
-#define mrg_journal_lfmgr_hpp
-
-namespace mrg
-{
-namespace journal
-{
- class jcntl;
- class lfmgr;
-}
-}
-
-#include "jrnl/fcntl.hpp"
-#include <vector>
-
-namespace mrg
-{
-namespace journal
-{
-
- /**
- * \brief LID-FID manager. This class maps the logical id (lid) to the physical file
id (fid) so that files may be
- * inserted into the file ring buffer in (nearly) arbitrary logical locations while
the physical ids continue to
- * be appended. NOTE: NOT THREAD SAFE.
- *
- * The entire functionality of the LID-FID manager is to maintain an array of pointers
to fcntl objects which have a
- * one-to-one relationship to the physical %journal files. The logical id (lid) is
used as an index to the array to
- * read the mapped file-id (fid). By altering the order of these pointers within the
array, the mapping of logical to
- * physical files may be altered. This can be used to allow for the logical insertion
of %journal files into a ring
- * buffer, even though the physical file ids must be appended to those that preceded
them.
- *
- * Since the insert() operation uses after-lid as the position parameter, it is not
possible to insert before lid 0.
- * Consequently, lid 0 and fid 0 are always coincident in a %journal. Note, however,
that this operation is logically
- * equivilent to inserting a new file after the last lid.
- *
- * When one or more files are inserted after a particular lid, the lids of the
following files are incremented. The
- * fids of the inserted files follow those of all existing files, thus leading to a
lid-fid discreppancy (ie no
- * longer a one-to-one mapping):
- *
- * Example: Before insertion, %journal file headers would look as follows:
- * <pre>
- * Logical view (sorted by lid): Physical view (sorted by
fid):
- * +---+---+---+---+---+---+ +---+---+---+---+---+---+
- * fid --> | 0 | 1 | 2 | 3 | 4 | 5 | fid --> | 0 | 1 | 2 | 3 | 4 | 5
|
- * lid --> | 0 | 1 | 2 | 3 | 4 | 5 | lid --> | 0 | 1 | 2 | 3 | 4 | 5
|
- * +---+---+---+---+---+---+ +---+---+---+---+---+---+
- * </pre>
- *
- * After insertion of 2 files after lid 2 (marked with *s):
- * <pre>
- * Logical view (sorted by lid): Physical view (sorted by
fid):
- * +---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
- * fid --> | 0 | 1 | 2 |*6*|*7*| 3 | 4 | 5 | fid --> | 0 | 1 | 2 | 3 | 4 | 5
|*6*|*7*|
- * lid --> | 0 | 1 | 2 |*3*|*4*| 5 | 6 | 7 | lid --> | 0 | 1 | 2 | 5 | 6 | 7
|*3*|*4*|
- * +---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
- * </pre>
- *
- * The insert() function updates the internal map immediately, but the physical files
(which have both the fid and
- * lid written into the file header) are only updated as they are overwirtten in the
normal course of enqueueing
- * and dequeueing messages. If the %journal should fail after insertion but before the
files following those inserted
- * are overwritten, then duplicate lids will be present (though no duplicate fids are
possible). The overwrite
- * indicator (owi) flag and the fid numbers may be used to resolve the ambiguity and
determine the logically earlier
- * lid in this case as follows:
- *
- * Example: Before insertion, the current active write file being lid/fid 2 as
determined by the owi flag, %journal
- * file headers would look as follows:
- * <pre>
- * Logical view (sorted by lid): Physical view (sorted by
fid):
- * +---+---+---+---+---+---+ +---+---+---+---+---+---+
- * fid --> | 0 | 1 | 2 | 3 | 4 | 5 | fid --> | 0 | 1 | 2 | 3 | 4 | 5
|
- * lid --> | 0 | 1 | 2 | 3 | 4 | 5 | lid --> | 0 | 1 | 2 | 3 | 4 | 5
|
- * owi --> | t | t | t | f | f | f | owi --> | t | t | t | f | f | f
|
- * +---+---+---+---+---+---+ +---+---+---+---+---+---+
- * </pre>
- *
- * After 2 insertions after lid 2 and then 3 (the newly inserted file) - marked with
*s, and then a
- * broker failure/stoppage:
- * <pre>
- * Logical view (sorted by lid): Physical view (sorted by
fid):
- * +---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
- * fid --> | 0 | 1 | 2 |*6*|*7*| 3 | 4 | 5 | fid --> | 0 | 1 | 2 | 3 | 4 | 5
|*3*|*4*|
- * lid --> | 0 | 1 | 2 |*3*|*4*| 3 | 4 | 5 | lid --> | 0 | 1 | 2 | 3 | 4 | 5
|*3*|*4*|
- * owi --> | t | t | t | t | t | f | f | f | owi --> | t | t | t | f | f | f
| t | t |
- * +---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
- * </pre>
- *
- * There are two independent tests that may be made to resolve duplicate lids during
recovery in such cases:
- * <ol>
- * <li>The correct lid has owi flag that matches that of fid/lid 0</li>
- * <li>The most recently inserted (hence correct) lid has fids that are higher
than the duplicat that was not
- * overwritten</li>
- * </ol>
- *
- * NOTE: NOT THREAD SAFE. Provide external thread protection if used in multi-threaded
environments.
- */
- class lfmgr
- {
- public:
- /**
- * \brief Function pointer to function that will create a new fcntl object and
return its pointer.
- *
- * \param jcp Pointer to jcntl instance from which journal file details
will be obtained.
- * \param lid Logical ID for new fcntl instance.
- * \param fid Physical file ID for file associated with new fcntl
instance.
- * \param rdp Pointer to rcvdat instance which conatins recovery
information for new fcntl instance when
- * recovering an existing file, or null if a new file is to be
created.
- */
- typedef fcntl* (new_obj_fn_ptr)(jcntl* const jcp,
- const u_int16_t lid,
- const u_int16_t fid,
- const rcvdat* const rdp);
-
- private:
- bool _ae; ///< Auto-expand mode
- u_int16_t _ae_max_jfiles; ///< Max file count for auto-expansion; 0 = no
limit
- std::vector<fcntl*> _fcntl_arr; ///< Array of pointers to objects
-
- public:
- lfmgr();
- virtual ~lfmgr();
-
- /**
- * \brief Initialize from scratch for a known number of %journal files. All lid
values are identical to fid
- * values (which is normal before any inserts have occurred).
- *
- * \param num_jfiles Number of files to be created, and consequently the number of
fcntl objects in array
- * _fcntl_arr.
- * \param ae If true, allows auto-expansion; if false, disables
auto-expansion.
- * \param ae_max_jfiles The maximum number of files allowed for auto-expansion.
Cannot be lower than the current
- * number of files. However, a zero value disables the limit
checks, and allows unlimited
- * expansion.
- * \param jcp Pointer to jcntl instance. This is used to find the file path
and base filename so that
- * new files may be created.
- * \param fp Pointer to function which creates and returns a pointer to a
new fcntl object (and hence
- * causes a new %journal file to be created).
- */
- void 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);
-
- /**
- * \brief Initialize from a known lid-fid map fid_list, which is usually obtained
from a recover. The index of
- * fid_list is the logical id (lid); the value contained in the vector is the file
id (fid).
- *
- * \param rd Ref to rcvdat struct which contains recovery data.
- * \param jcp Pointer to jcntl instance. This is used to find the file path
and base filename so that
- * new files may be created.
- * \param fp Pointer to function which creates and returns a pointer to a
new fcntl object (and hence
- * causes a new %journal file to be created).
- */
- void recover(const rcvdat& rd,
- jcntl* const jcp,
- new_obj_fn_ptr fp);
-
- /**
- * \brief Insert num_jfiles files after lid index after_index. This causes all
lids after after_index to be
- * increased by num_jfiles.
- *
- * Note that it is not possible to insert <i>before</i> lid 0, and
thus lid 0 should always point to fid 0.
- * Inserting before index 0 is logically equivilent to inserting after the last
lid in a circular buffer.
- *
- * \param after_index Lid index after which to insert file(s).
- * \param jcp Pointer to jcntl instance. This is used to find the file path
and base filename so that
- * new files may be created.
- * \param fp Pointer to function which creates and returns a pointer to a
new fcntl object (and hence
- * causes a new %journal file to be created).
- * \param num_jfiles The number of files by which to increase.
- */
- void insert(const u_int16_t after_index,
- jcntl* const jcp,
- new_obj_fn_ptr fp,
- const u_int16_t num_jfiles = 1);
-
- /**
- * \brief Clears _fcntl_arr and deletes all fcntl instances.
- */
- void finalize();
-
- /**
- * \brief Returns true if initialized; false otherwise. After instantiation, will
return false until
- * either initialize() is called; thereafter true until finalize() is called,
whereupon it will
- * return false again.
- *
- * \return True if initialized; false otherwise.
- */
- inline bool is_init() const { return _fcntl_arr.size() > 0; }
-
- /**
- * \brief Returns true if auto-expand mode is enabled; false if not.
- *
- * \return True if auto-expand mode is enabled; false if not.
- */
- inline bool is_ae() const { return _ae; }
-
- /**
- * \brief Sets the auto-expand mode to enabled if ae is true, to disabled
otherwise. The value of _ae_max_jfiles
- * must be valid to succeed (i.e. _ae_max_jfiles must be greater than the current
number of files or be zero).
- *
- * \param ae If true will enable auto-expand mode; if false will disable
it.
- */
- void set_ae(const bool ae);
-
- /**
- * \brief Returns the number of %journal files, including any that were appended
or inserted since
- * initialization.
- *
- * \return Number of %journal files if initialized; 0 otherwise.
- */
- inline u_int16_t num_jfiles() const { return
static_cast<u_int16_t>(_fcntl_arr.size()); }
-
- /**
- * \brief Returns the maximum number of files allowed for auto-expansion.
- *
- * \return Maximum number of files allowed for auto-expansion. A zero value
represents a disabled limit
- * - i.e. unlimited expansion.
- */
- inline u_int16_t ae_max_jfiles() const { return _ae_max_jfiles; }
-
- /**
- * \brief Sets the maximum number of files allowed for auto-expansion. A zero
value disables the limit.
- *
- * \param ae_max_jfiles The maximum number of files allowed for auto-expansion.
Cannot be lower than the current
- * number of files. However, a zero value disables the limit
checks, and allows unlimited
- * expansion.
- */
- void set_ae_max_jfiles(const u_int16_t ae_max_jfiles);
-
- /**
- * \brief Calculates the number of future files available for auto-expansion.
- *
- * \return The number of future files available for auto-expansion.
- */
- u_int16_t ae_jfiles_rem() const;
-
- /**
- * \brief Get a pointer to fcntl instance for a given lid.
- *
- * \return Pointer to fcntl object corresponding to logical id lid, or 0 if lid is
out of range
- * (greater than number of files in use).
- */
- inline fcntl* get_fcntlp(const u_int16_t lid) const
- { if (lid >= _fcntl_arr.size()) return 0; return _fcntl_arr[lid]; }
-
- // Testing functions
- void get_fid_list(std::vector<u_int16_t>& fid_list) const;
- void get_lid_list(std::vector<u_int16_t>& lid_list) const;
-
- private:
-
- /**
- * \brief Append num_jfiles files to the end of the logical and file id sequence.
This is similar to extending
- * the from-scratch initialization.
- *
- * \param jcp Pointer to jcntl instance. This is used to find the file path
and base filename so that
- * new files may be created.
- * \param fp Pointer to function which creates and returns a pointer to a
new fcntl object (and hence
- * causes a new %journal file to be created).
- * \param num_jfiles The number of files by which to increase.
- */
- void append(jcntl* const jcp,
- new_obj_fn_ptr fp,
- const u_int16_t num_jfiles = 1);
-
- };
-
-} // namespace journal
-} // namespace mrg
-
-#endif // ifndef mrg_journal_lfmgr_hpp
Copied: store/trunk/cpp/lib/jrnl/lpmgr.cpp (from rev 3043,
store/trunk/cpp/lib/jrnl/lfmgr.cpp)
===================================================================
--- store/trunk/cpp/lib/jrnl/lpmgr.cpp (rev 0)
+++ store/trunk/cpp/lib/jrnl/lpmgr.cpp 2009-01-15 15:57:43 UTC (rev 3045)
@@ -0,0 +1,224 @@
+/**
+* \file lpmgr.cpp
+*
+* Red Hat Messaging - Message Journal
+*
+* File containing code for class mrg::journal::lpmgr (non-logging file
+* handle), used for controlling journal log files. See comments in file
+* lpmgr.hpp for details.
+*
+* Copyright 2008, 2009 Red Hat, Inc.
+*
+* This file is part of Red Hat Messaging.
+*
+* Red Hat Messaging is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+* USA
+*
+* The GNU Lesser General Public License is available in the file COPYING.
+*/
+
+#include "jrnl/lpmgr.hpp"
+
+#include <cassert>
+#include <jrnl/jerrno.hpp>
+#include <jrnl/jexception.hpp>
+
+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_lid(p->lid() + 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]->fid());
+}
+
+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]->fid()] = 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
Property changes on: store/trunk/cpp/lib/jrnl/lpmgr.cpp
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: store/trunk/cpp/lib/jrnl/lpmgr.hpp (from rev 3043,
store/trunk/cpp/lib/jrnl/lfmgr.hpp)
===================================================================
--- store/trunk/cpp/lib/jrnl/lpmgr.hpp (rev 0)
+++ store/trunk/cpp/lib/jrnl/lpmgr.hpp 2009-01-15 15:57:43 UTC (rev 3045)
@@ -0,0 +1,301 @@
+/**
+* \file lpmgr.hpp
+*
+* Red Hat Messaging - Message Journal
+*
+* Class mrg::journal::lpmgr. See class documentation for details.
+*
+* Copyright 2008, 2009 Red Hat, Inc.
+*
+* This file is part of Red Hat Messaging.
+*
+* Red Hat Messaging is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+* USA
+*
+* The GNU Lesser General Public License is available in the file COPYING.
+*/
+
+#ifndef mrg_journal_lpmgr_hpp
+#define mrg_journal_lpmgr_hpp
+
+namespace mrg
+{
+namespace journal
+{
+ class jcntl;
+ class lpmgr;
+}
+}
+
+#include "jrnl/fcntl.hpp"
+#include <vector>
+
+namespace mrg
+{
+namespace journal
+{
+
+ /**
+ * \brief LFID-PFID manager. This class maps the logical file id (lfid) to the
physical file id (pfid) so that files
+ * may be inserted into the file ring buffer in (nearly) arbitrary logical locations
while the physical ids continue
+ * to be appended. NOTE: NOT THREAD SAFE.
+ *
+ * The entire functionality of the LFID-PFID manager is to maintain an array of
pointers to fcntl objects which have
+ * a one-to-one relationship to the physical %journal files. The logical file id
(lfid) is used as an index to the
+ * array to read the mapped physical file id (pfid). By altering the order of these
pointers within the array, the
+ * mapping of logical to physical files may be altered. This can be used to allow for
the logical insertion of
+ * %journal files into a ring buffer, even though the physical file ids must be
appended to those that preceded them.
+ *
+ * Since the insert() operation uses after-lfid as its position parameter, it is not
possible to insert before lfid
+ * 0 - i.e. It is only possible to insert after an existing lfid. Consequently, lfid 0
and pfid 0 are always
+ * coincident in a %journal. Note, however, that inserting before lfid 0 is logically
equivilent to inserting after
+ * the last lfid.
+ *
+ * When one or more files are inserted after a particular lfid, the lfids of the
following files are incremented. The
+ * pfids of the inserted files follow those of all existing files, thus leading to a
lfid-pfid discreppancy (ie no
+ * longer a one-to-one mapping):
+ *
+ * Example: Before insertion, %journal file headers would look as follows:
+ * <pre>
+ * Logical view (sorted by lfid): Physical view (sorted by
pfid):
+ * +---+---+---+---+---+---+ +---+---+---+---+---+---+
+ * pfid --> | 0 | 1 | 2 | 3 | 4 | 5 | pfid --> | 0 | 1 | 2 | 3 | 4 | 5
|
+ * lfid --> | 0 | 1 | 2 | 3 | 4 | 5 | lfid --> | 0 | 1 | 2 | 3 | 4 | 5
|
+ * +---+---+---+---+---+---+ +---+---+---+---+---+---+
+ * </pre>
+ *
+ * After insertion of 2 files after lid 2 (marked with *s):
+ * <pre>
+ * Logical view (sorted by lfid): Physical view (sorted by
pfid):
+ * +---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
+ * pfid --> | 0 | 1 | 2 |*6*|*7*| 3 | 4 | 5 | pfid --> | 0 | 1 | 2 | 3 | 4 | 5
|*6*|*7*|
+ * lfid --> | 0 | 1 | 2 |*3*|*4*| 5 | 6 | 7 | lfid --> | 0 | 1 | 2 | 5 | 6 | 7
|*3*|*4*|
+ * +---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
+ * </pre>
+ *
+ * The insert() function updates the internal map immediately, but the physical files
(which have both the pfid and
+ * lfid written into the file header) are only updated as they are overwirtten in the
normal course of enqueueing
+ * and dequeueing messages. If the %journal should fail after insertion but before the
files following those inserted
+ * are overwritten, then duplicate lfids will be present (though no duplicate pfids
are possible). The overwrite
+ * indicator (owi) flag and the pfid numbers may be used to resolve the ambiguity and
determine the logically earlier
+ * lfid in this case.
+ *
+ * Example: Before insertion, the current active write file being lfid/pfid 2 as
determined by the owi flag, %journal
+ * file headers would look as follows:
+ * <pre>
+ * Logical view (sorted by lfid): Physical view (sorted by
pfid):
+ * +---+---+---+---+---+---+ +---+---+---+---+---+---+
+ * pfid --> | 0 | 1 | 2 | 3 | 4 | 5 | pfid --> | 0 | 1 | 2 | 3 | 4 | 5
|
+ * lfid --> | 0 | 1 | 2 | 3 | 4 | 5 | lfid --> | 0 | 1 | 2 | 3 | 4 | 5
|
+ * owi --> | t | t | t | f | f | f | owi --> | t | t | t | f | f | f
|
+ * +---+---+---+---+---+---+ +---+---+---+---+---+---+
+ * </pre>
+ *
+ * After inserting 2 files after lfid 2 and then 3 (the newly inserted file) - marked
with *s:
+ * <pre>
+ * Logical view (sorted by lfid): Physical view (sorted by
pfid):
+ * +---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
+ * pfid --> | 0 | 1 | 2 |*6*|*7*| 3 | 4 | 5 | pfid --> | 0 | 1 | 2 | 3 | 4 | 5
|*3*|*4*|
+ * lfid --> | 0 | 1 | 2 |*3*|*4*| 3 | 4 | 5 | lfid --> | 0 | 1 | 2 | 3 | 4 | 5
|*3*|*4*|
+ * owi --> | t | t | t | t | t | f | f | f | owi --> | t | t | t | f | f | f
| t | t |
+ * +---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
+ * </pre>
+ *
+ * If a broker failure occurs at this point, then there are two independent tests that
may be made to resolve
+ * duplicate lfids during recovery in such cases:
+ * <ol>
+ * <li>The correct lfid has owi flag that matches that of pfid/lfid
0</li>
+ * <li>The most recently inserted (hence correct) lfid has pfids that are
higher than the duplicate that was not
+ * overwritten</li>
+ * </ol>
+ *
+ * NOTE: NOT THREAD SAFE. Provide external thread protection if used in multi-threaded
environments.
+ */
+ class lpmgr
+ {
+ public:
+ /**
+ * \brief Function pointer to function that will create a new fcntl object and
return its pointer.
+ *
+ * \param jcp Pointer to jcntl instance from which journal file details
will be obtained.
+ * \param lfid Logical file ID for new fcntl instance.
+ * \param pfid Physical file ID for file associated with new fcntl
instance.
+ * \param rdp Pointer to rcvdat instance which conatins recovery
information for new fcntl instance when
+ * recovering an existing file, or null if a new file is to be
created.
+ */
+ typedef fcntl* (new_obj_fn_ptr)(jcntl* const jcp,
+ const u_int16_t lfid,
+ const u_int16_t pfid,
+ const rcvdat* const rdp);
+
+ private:
+ bool _ae; ///< Auto-expand mode
+ u_int16_t _ae_max_jfiles; ///< Max file count for auto-expansion; 0 = no
limit
+ std::vector<fcntl*> _fcntl_arr; ///< Array of pointers to fcntl objects
+
+ public:
+ lpmgr();
+ virtual ~lpmgr();
+
+ /**
+ * \brief Initialize from scratch for a known number of %journal files. All lfid
values are identical to pfid
+ * values (which is normal before any inserts have occurred).
+ *
+ * \param num_jfiles Number of files to be created, and consequently the number of
fcntl objects in array
+ * _fcntl_arr.
+ * \param ae If true, allows auto-expansion; if false, disables
auto-expansion.
+ * \param ae_max_jfiles The maximum number of files allowed for auto-expansion.
Cannot be lower than the current
+ * number of files. However, a zero value disables the limit
checks, and allows unlimited
+ * expansion.
+ * \param jcp Pointer to jcntl instance. This is used to find the file path
and base filename so that
+ * new files may be created.
+ * \param fp Pointer to function which creates and returns a pointer to a
new fcntl object (and hence
+ * causes a new %journal file to be created).
+ */
+ void 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);
+
+ /**
+ * \brief Initialize from a known lfid-pfid map pfid_list (within rcvdat param
rd), which is usually obtained
+ * from a recover. The index of pfid_list is the logical file id (lfid); the value
contained in the vector is
+ * the physical file id (pfid).
+ *
+ * \param rd Ref to rcvdat struct which contains recovery data and the
pfid_list.
+ * \param jcp Pointer to jcntl instance. This is used to find the file path
and base filename so that
+ * new files may be created.
+ * \param fp Pointer to function which creates and returns a pointer to a
new fcntl object (and hence
+ * causes a new %journal file to be created).
+ */
+ void recover(const rcvdat& rd,
+ jcntl* const jcp,
+ new_obj_fn_ptr fp);
+
+ /**
+ * \brief Insert num_jfiles files after lfid index after_lfid. This causes all
lfids after after_lfid to be
+ * increased by num_jfiles.
+ *
+ * Note that it is not possible to insert <i>before</i> lfid 0, and
thus lfid 0 should always point to pfid 0.
+ * Inserting before lfid 0 is logically equivilent to inserting after the last
lfid in a circular buffer.
+ *
+ * \param after_lfid Lid index after which to insert file(s).
+ * \param jcp Pointer to jcntl instance. This is used to find the file path
and base filename so that
+ * new files may be created.
+ * \param fp Pointer to function which creates and returns a pointer to a
new fcntl object (and hence
+ * causes a new %journal file to be created).
+ * \param num_jfiles The number of files by which to increase.
+ */
+ void insert(const u_int16_t after_lfid,
+ jcntl* const jcp,
+ new_obj_fn_ptr fp,
+ const u_int16_t num_jfiles = 1);
+
+ /**
+ * \brief Clears _fcntl_arr and deletes all fcntl instances.
+ */
+ void finalize();
+
+ /**
+ * \brief Returns true if initialized; false otherwise. After construction, will
return false until initialize()
+ * is called; thereafter true until finalize() is called, whereupon it will return
false again.
+ *
+ * \return True if initialized; false otherwise.
+ */
+ inline bool is_init() const { return _fcntl_arr.size() > 0; }
+
+ /**
+ * \brief Returns true if auto-expand mode is enabled; false if not.
+ *
+ * \return True if auto-expand mode is enabled; false if not.
+ */
+ inline bool is_ae() const { return _ae; }
+
+ /**
+ * \brief Sets the auto-expand mode to enabled if ae is true, to disabled
otherwise. The value of _ae_max_jfiles
+ * must be valid to succeed (i.e. _ae_max_jfiles must be greater than the current
number of files or be zero).
+ *
+ * \param ae If true will enable auto-expand mode; if false will disable
it.
+ */
+ void set_ae(const bool ae);
+
+ /**
+ * \brief Returns the number of %journal files, including any that were appended
or inserted since
+ * initialization.
+ *
+ * \return Number of %journal files if initialized; 0 otherwise.
+ */
+ inline u_int16_t num_jfiles() const { return
static_cast<u_int16_t>(_fcntl_arr.size()); }
+
+ /**
+ * \brief Returns the maximum number of files allowed for auto-expansion.
+ *
+ * \return Maximum number of files allowed for auto-expansion. A zero value
represents a disabled limit
+ * - i.e. unlimited expansion.
+ */
+ inline u_int16_t ae_max_jfiles() const { return _ae_max_jfiles; }
+
+ /**
+ * \brief Sets the maximum number of files allowed for auto-expansion. A zero
value disables the limit.
+ *
+ * \param ae_max_jfiles The maximum number of files allowed for auto-expansion.
Cannot be lower than the current
+ * number of files. However, a zero value disables the limit
checks, and allows unlimited
+ * expansion.
+ */
+ void set_ae_max_jfiles(const u_int16_t ae_max_jfiles);
+
+ /**
+ * \brief Calculates the number of future files available for auto-expansion.
+ *
+ * \return The number of future files available for auto-expansion.
+ */
+ u_int16_t ae_jfiles_rem() const;
+
+ /**
+ * \brief Get a pointer to fcntl instance for a given lfid.
+ *
+ * \return Pointer to fcntl object corresponding to logical file id lfid, or 0 if
lfid is out of range
+ * (greater than number of files in use).
+ */
+ inline fcntl* get_fcntlp(const u_int16_t lfid) const
+ { if (lfid >= _fcntl_arr.size()) return 0; return _fcntl_arr[lfid]; }
+
+ // Testing functions
+ void get_pfid_list(std::vector<u_int16_t>& pfid_list) const;
+ void get_lfid_list(std::vector<u_int16_t>& lfid_list) const;
+
+ protected:
+
+ /**
+ * \brief Append num_jfiles files to the end of the logical and file id sequence.
This is similar to extending
+ * the from-scratch initialization.
+ *
+ * \param jcp Pointer to jcntl instance. This is used to find the file path
and base filename so that
+ * new files may be created.
+ * \param fp Pointer to function which creates and returns a pointer to a
new fcntl object (and hence
+ * causes a new %journal file to be created).
+ * \param num_jfiles The number of files by which to increase.
+ */
+ void append(jcntl* const jcp,
+ new_obj_fn_ptr fp,
+ const u_int16_t num_jfiles = 1);
+
+ };
+
+} // namespace journal
+} // namespace mrg
+
+#endif // ifndef mrg_journal_lpmgr_hpp
Property changes on: store/trunk/cpp/lib/jrnl/lpmgr.hpp
___________________________________________________________________
Name: svn:mergeinfo
+
Modified: store/trunk/cpp/lib/jrnl/rfc.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/rfc.cpp 2009-01-15 12:59:10 UTC (rev 3044)
+++ store/trunk/cpp/lib/jrnl/rfc.cpp 2009-01-15 15:57:43 UTC (rev 3045)
@@ -37,7 +37,7 @@
namespace journal
{
-rfc::rfc(const lfmgr* lfmp): _lfmp(lfmp), _fc_index(0), _curr_fc(0)
+rfc::rfc(const lpmgr* lpmp): _lpmp(lpmp), _fc_index(0), _curr_fc(0)
{}
rfc::~rfc()
@@ -53,7 +53,7 @@
rfc::set_findex(const u_int16_t fc_index)
{
_fc_index = fc_index;
- _curr_fc = _lfmp->get_fcntlp(fc_index);
+ _curr_fc = _lpmp->get_fcntlp(fc_index);
_curr_fc->rd_reset();
}
@@ -67,7 +67,7 @@
std::string
rfc::status_str() const
{
- if (!_lfmp->is_init())
+ if (!_lpmp->is_init())
return "state: Uninitialized";
if (_curr_fc == 0)
return "state: Inactive";
Modified: store/trunk/cpp/lib/jrnl/rfc.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/rfc.hpp 2009-01-15 12:59:10 UTC (rev 3044)
+++ store/trunk/cpp/lib/jrnl/rfc.hpp 2009-01-15 15:57:43 UTC (rev 3045)
@@ -41,7 +41,7 @@
}
}
-#include "jrnl/lfmgr.hpp"
+#include "jrnl/lpmgr.hpp"
#include "jrnl/enums.hpp"
namespace mrg
@@ -58,7 +58,7 @@
*
* <pre>
* is_init()
is_active()
- * +===+ _lfmp.is_init() == false
+ * +===+ _lpmp.is_init() == false
* +---------->| | Uninitialized: _curr_fc == 0 F
F
* | +-->+===+ --+
* | | |
@@ -66,7 +66,7 @@
* | finalize() initialize()
* | | |
* | | |
- * | +-- +===+<--+ _lfmp.is_init() == true
+ * | +-- +===+<--+ _lpmp.is_init() == true
* finalize() | | Inactive: _curr_fc == 0 T
F
* | +-->+===+ --+
* | | |
@@ -74,7 +74,7 @@
* | unset_findex() set_findex()
* | | |
* | | |
- * | +-- +===+<--+ _lfmp.is_init() == true
+ * | +-- +===+<--+ _lpmp.is_init() == true
* +---------- | | Active: _curr_fc != 0 T
T
* +===+
* </pre>
@@ -88,17 +88,17 @@
* index of the active file is known, then calling set_findex() will set the index and
internal pointer
* to the currently active file controller. This moves the state to Active.
*
- * Note TODO: Comment on sync issues between change in num files in _lfmp and
_fc_index/_curr_fc.
+ * Note TODO: Comment on sync issues between change in num files in _lpmp and
_fc_index/_curr_fc.
*/
class rfc
{
protected:
- const lfmgr* _lfmp; ///< Pointer to jcntl's lfmgr instance containing
lid/fid map and fcntl objects
+ const lpmgr* _lpmp; ///< Pointer to jcntl's lpmgr instance containing
lfid/pfid map and fcntl objects
u_int16_t _fc_index; ///< Index of current file controller
fcntl* _curr_fc; ///< Pointer to current file controller
public:
- rfc(const lfmgr* lfmp);
+ rfc(const lpmgr* lpmp);
virtual ~rfc();
/**
@@ -116,12 +116,12 @@
/**
* /brief Check initialization state: true = Not Uninitialized, ie Initialized or
Active; false = Uninitialized.
*/
- virtual inline bool is_init() const { return _lfmp->is_init(); }
+ virtual inline bool is_init() const { return _lpmp->is_init(); }
/**
* /brief Check active state: true = Initialized and _curr_fc not null; false
otherwise.
*/
- virtual inline bool is_active() const { return _lfmp->is_init() &&
_curr_fc != 0; }
+ virtual inline bool is_active() const { return _lpmp->is_init() &&
_curr_fc != 0; }
/**
* /brief Sets the current file index and active fcntl object. Moves to state
Active.
@@ -159,13 +159,13 @@
inline u_int32_t enqcnt() const { return _curr_fc->enqcnt(); }
inline u_int32_t incr_enqcnt() { return _curr_fc->incr_enqcnt(); }
- inline u_int32_t incr_enqcnt(const u_int16_t fid) { return
_lfmp->get_fcntlp(fid)->incr_enqcnt(); }
+ inline u_int32_t incr_enqcnt(const u_int16_t fid) { return
_lpmp->get_fcntlp(fid)->incr_enqcnt(); }
inline u_int32_t add_enqcnt(const u_int32_t a) { return
_curr_fc->add_enqcnt(a); }
inline u_int32_t add_enqcnt(const u_int16_t fid, const u_int32_t a)
- { return _lfmp->get_fcntlp(fid)->add_enqcnt(a); }
- inline u_int32_t decr_enqcnt(const u_int16_t fid) { return
_lfmp->get_fcntlp(fid)->decr_enqcnt(); }
+ { return _lpmp->get_fcntlp(fid)->add_enqcnt(a); }
+ inline u_int32_t decr_enqcnt(const u_int16_t fid) { return
_lpmp->get_fcntlp(fid)->decr_enqcnt(); }
inline u_int32_t subtr_enqcnt(const u_int16_t fid, const u_int32_t s)
- { return _lfmp->get_fcntlp(fid)->subtr_enqcnt(s); }
+ { return _lpmp->get_fcntlp(fid)->subtr_enqcnt(s); }
virtual inline u_int32_t subm_cnt_dblks() const = 0;
virtual inline std::size_t subm_offs() const = 0;
Modified: store/trunk/cpp/lib/jrnl/rrfc.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/rrfc.cpp 2009-01-15 12:59:10 UTC (rev 3044)
+++ store/trunk/cpp/lib/jrnl/rrfc.cpp 2009-01-15 15:57:43 UTC (rev 3045)
@@ -41,7 +41,7 @@
namespace journal
{
-rrfc::rrfc(const lfmgr* lfmp): rfc(lfmp), _fh(-1), _valid(false)
+rrfc::rrfc(const lpmgr* lpmp): rfc(lpmp), _fh(-1), _valid(false)
{}
rrfc::~rrfc()
@@ -74,10 +74,10 @@
iores
rrfc::rotate()
{
- if (!_lfmp->num_jfiles())
+ if (!_lpmp->num_jfiles())
throw jexception(jerrno::JERR__NINIT, "rrfc", "rotate");
u_int16_t next_fc_index = _fc_index + 1;
- if (next_fc_index == _lfmp->num_jfiles())
+ if (next_fc_index == _lpmp->num_jfiles())
next_fc_index = 0;
set_findex(next_fc_index);
return RHM_IORES_SUCCESS;
Modified: store/trunk/cpp/lib/jrnl/rrfc.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/rrfc.hpp 2009-01-15 12:59:10 UTC (rev 3044)
+++ store/trunk/cpp/lib/jrnl/rrfc.hpp 2009-01-15 15:57:43 UTC (rev 3045)
@@ -60,7 +60,7 @@
*
* <pre>
* is_init()
is_active()
- * +===+ _lfmp.is_init() == false
+ * +===+ _lpmp.is_init() == false
* +---------->| | Uninitialized: _curr_fc == 0 F
F
* | +-->+===+ --+ _fh == -1
* | | |
@@ -68,7 +68,7 @@
* | finalize() initialize()
* | | |
* | | |
- * | +-- +===+<--+ _lfmp.is_init() == true
+ * | +-- +===+<--+ _lpmp.is_init() == true
* finalize() | | Inactive: _curr_fc == 0 T
F
* | +-->+===+ --+ _fh == -1
* | | |
@@ -76,7 +76,7 @@
* | unset_findex() set_findex()
* | | |
* | | |
- * | +-- +===+<--+ _lfmp.is_init() == true
+ * | +-- +===+<--+ _lpmp.is_init() == true
* +---------- | | Active: _curr_fc != 0 T
T
* +===+ _fh >= 0
* </pre>
@@ -93,7 +93,7 @@
bool _valid; ///< Flag is true when read pages contain vailid data
public:
- rrfc(const lfmgr* lfmp);
+ rrfc(const lpmgr* lpmp);
virtual ~rrfc();
/**
Modified: store/trunk/cpp/lib/jrnl/wrfc.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/wrfc.cpp 2009-01-15 12:59:10 UTC (rev 3044)
+++ store/trunk/cpp/lib/jrnl/wrfc.cpp 2009-01-15 15:57:43 UTC (rev 3045)
@@ -39,8 +39,8 @@
namespace journal
{
-wrfc::wrfc(const lfmgr* lfmp):
- rfc(lfmp),
+wrfc::wrfc(const lpmgr* lpmp):
+ rfc(lpmp),
_fsize_sblks(0),
_fsize_dblks(0),
_enq_cap_offs_dblks(0),
@@ -59,7 +59,7 @@
if (rdp)
{
_fc_index = rdp->_lfid;
- _curr_fc = _lfmp->get_fcntlp(_fc_index);
+ _curr_fc = _lpmp->get_fcntlp(_fc_index);
_curr_fc->wr_reset(rdp);
_rid = rdp->_h_rid + 1;
_reset_ok = true;
@@ -77,7 +77,7 @@
}
_fsize_sblks = fsize_sblks;
_fsize_dblks = fsize_sblks * JRNL_SBLK_SIZE;
- _enq_cap_offs_dblks = (u_int32_t)std::ceil(_fsize_dblks * _lfmp->num_jfiles() *
(100.0 - JRNL_ENQ_THRESHOLD) / 100);
+ _enq_cap_offs_dblks = (u_int32_t)std::ceil(_fsize_dblks * _lpmp->num_jfiles() *
(100.0 - JRNL_ENQ_THRESHOLD) / 100);
// Check the offset is at least one file; if not, make it so
if (_enq_cap_offs_dblks < _fsize_dblks)
_enq_cap_offs_dblks = _fsize_dblks;
@@ -85,16 +85,16 @@
iores wrfc::rotate()
{
- if (!_lfmp->num_jfiles())
+ if (!_lpmp->num_jfiles())
throw jexception(jerrno::JERR__NINIT, "wrfc", "rotate");
_fc_index++;
- if (_fc_index == _lfmp->num_jfiles())
+ if (_fc_index == _lpmp->num_jfiles())
{
_fc_index = 0;
_owi = !_owi;
_frot = false;
}
- _curr_fc = _lfmp->get_fcntlp(_fc_index);
+ _curr_fc = _lpmp->get_fcntlp(_fc_index);
if (_curr_fc->aio_cnt())
return RHM_IORES_FILE_AIOWAIT;
if (!wr_reset()) //Checks if file is still in use (ie not fully dequeued yet)
@@ -107,7 +107,7 @@
if (_frot)
return 0;
u_int16_t next_index = _fc_index + 1;
- if (next_index >= _lfmp->num_jfiles())
+ if (next_index >= _lpmp->num_jfiles())
next_index = 0;
return next_index;
}
@@ -129,9 +129,9 @@
fwd_dblks -= fwd_dblks > _fsize_dblks ? _fsize_dblks : fwd_dblks;
if (fwd_dblks)
{
- if (++findex == _lfmp->num_jfiles())
+ if (++findex == _lpmp->num_jfiles())
findex = 0;
- fcp = _lfmp->get_fcntlp(findex);
+ fcp = _lpmp->get_fcntlp(findex);
}
in_use |= fcp->enqcnt() > 0;
}
Modified: store/trunk/cpp/lib/jrnl/wrfc.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/wrfc.hpp 2009-01-15 12:59:10 UTC (rev 3044)
+++ store/trunk/cpp/lib/jrnl/wrfc.hpp 2009-01-15 15:57:43 UTC (rev 3045)
@@ -64,7 +64,7 @@
bool _frot; ///< Flag is true for first rotation, false
otherwise
public:
- wrfc(const lfmgr* lfmp);
+ wrfc(const lpmgr* lpmp);
virtual ~wrfc();
/**
Modified: store/trunk/cpp/tests/jrnl/Makefile.am
===================================================================
--- store/trunk/cpp/tests/jrnl/Makefile.am 2009-01-15 12:59:10 UTC (rev 3044)
+++ store/trunk/cpp/tests/jrnl/Makefile.am 2009-01-15 15:57:43 UTC (rev 3045)
@@ -51,7 +51,7 @@
_ut_jinf \
_ut_enq_map \
_ut_txn_map \
- _ut_lfmgr \
+ _ut_lpmgr \
_st_basic \
_st_basic_txn \
_st_read \
@@ -70,7 +70,7 @@
_ut_jdir \
_ut_enq_map \
_ut_txn_map \
- _ut_lfmgr \
+ _ut_lpmgr \
_st_basic \
_st_basic_txn \
_st_read \
@@ -107,8 +107,8 @@
_ut_txn_map_SOURCES = _ut_txn_map.cpp $(UNIT_TEST_SRCS)
_ut_txn_map_LDADD = $(UNIT_TEST_LDADD) -lrt
-_ut_lfmgr_SOURCES = _ut_lfmgr.cpp $(UNIT_TEST_SRCS)
-_ut_lfmgr_LDADD = $(UNIT_TEST_LDADD) -lrt
+_ut_lpmgr_SOURCES = _ut_lpmgr.cpp $(UNIT_TEST_SRCS)
+_ut_lpmgr_LDADD = $(UNIT_TEST_LDADD) -lrt
_st_basic_SOURCES = _st_basic.cpp _st_helper_fns.hpp $(UNIT_TEST_SRCS)
_st_basic_LDADD = $(UNIT_TEST_LDADD) -lrt
Modified: store/trunk/cpp/tests/jrnl/_st_helper_fns.hpp
===================================================================
--- store/trunk/cpp/tests/jrnl/_st_helper_fns.hpp 2009-01-15 12:59:10 UTC (rev 3044)
+++ store/trunk/cpp/tests/jrnl/_st_helper_fns.hpp 2009-01-15 15:57:43 UTC (rev 3045)
@@ -91,7 +91,7 @@
};
/*
-* This class is for testing recover functionality by maintaining an internal lid-fid map,
then creating physical
+* This class is for testing recover functionality by maintaining an internal lfid-pfid
map, then creating physical
* journal file stubs (just the fhdr section of the journal) and jinf file. This allows
the recover functionality (which
* analyzes these components to determine recover order).
*
@@ -100,49 +100,49 @@
* against what is expected.
*
* General usage pattern:
-* 1. Create instance of lid_fid_map.
-* 2. Call lid_fid_map::journal_create() to simulate initial journal creation.
-* 3. (optional) Call lid_fid_map::journal_append() one or more times to simulate the
addition of journal files.
-* 4. Call lid_fid_map::write_journal() to create dummy journal files (files containing
only file headers)
+* 1. Create instance of lfid_pfid_map.
+* 2. Call lfid_pfid_map::journal_create() to simulate initial journal creation.
+* 3. (optional) Call lfid_pfid_map::journal_append() one or more times to simulate the
addition of journal files.
+* 4. Call lfid_pfid_map::write_journal() to create dummy journal files (files containing
only file headers)
* 5. Create and initialize the jinf object under test
-* 6. Call jinf::analyze() to determine the fid order - and thus also first and last lids
-* 7. Call lid_fid_map::check_analysis() to check the conclusions of the analysis
-* 8. Call lid_fid_map::destroy_journal() to delete the journal files and reset the
lid_fid_map object.
+* 6. Call jinf::analyze() to determine the pfid order - and thus also first and last
lids
+* 7. Call lfid_pfid_map::check_analysis() to check the conclusions of the analysis
+* 8. Call lfid_pfid_map::destroy_journal() to delete the journal files and reset the
lfid_pfid_map object.
* 9. (optional) Back to step 2 for more tests
*
* See the individual methods below for more details.
*/
-class lid_fid_map
+class lfid_pfid_map
{
public:
- typedef pair<u_int16_t, file_hdr> lfpair; // Used for loading the
map
- typedef multimap<u_int16_t, file_hdr> lfmap; // Stores the journal
"plan" before it is created on-disk
- typedef lfmap::const_iterator lfmap_citr; // General purpose iterator
- typedef pair<lfmap_citr, lfmap_citr> lfmap_range; // Range of values
returned by multimap's equal_range() fn
+ typedef pair<u_int16_t, file_hdr> lppair; // Used for loading the
map
+ typedef multimap<u_int16_t, file_hdr> lpmap; // Stores the journal
"plan" before it is created on-disk
+ typedef lpmap::const_iterator lpmap_citr; // General purpose iterator
+ typedef pair<lpmap_citr, lpmap_citr> lpmap_range; // Range of values
returned by multimap's equal_range() fn
private:
string _jid; // Journal id
string _base_filename; // Base filename
- lfmap _map; // Stores the journal "blueprint" before it
is created on-disk
+ lpmap _map; // Stores the journal "blueprint" before it
is created on-disk
u_int16_t _num_used_files; // number of files which contain jorunals
- u_int16_t _oldest_lid; // lid where owi flips; always 0 if !_full
- u_int16_t _last_fid; // last fid (ie file added)
+ u_int16_t _oldest_lfid; // lfid where owi flips; always 0 if !_full
+ u_int16_t _last_pfid; // last pfid (ie last file added)
public:
- lid_fid_map(const string& jid, const string& base_filename) :
- _jid(jid), _base_filename(base_filename), _num_used_files(0),
_oldest_lid(0), _last_fid(0)
+ lfid_pfid_map(const string& jid, const string& base_filename) :
+ _jid(jid), _base_filename(base_filename), _num_used_files(0),
_oldest_lfid(0), _last_pfid(0)
{}
- virtual ~lid_fid_map() {}
+ virtual ~lfid_pfid_map() {}
// Mainly used for debugging
void print()
{
int cnt = 0;
- for (lfmap_citr i=_map.begin(); i!=_map.end(); i++, cnt++)
+ for (lpmap_citr i=_map.begin(); i!=_map.end(); i++, cnt++)
{
const file_hdr fh = i->second;
cout << " " << cnt << ": owi="
<< (fh.get_owi()?"t":"f") << hex << "
frid=0x" << fh._rid;
- cout << " fid=0x" << fh._fid << "
lid=0x" << fh._lid << " fro=0x" << fh._fro << dec
<< endl;
+ cout << " pfid=0x" << fh._fid << "
lfid=0x" << fh._lid << " fro=0x" << fh._fro << dec
<< endl;
}
}
@@ -159,20 +159,20 @@
* num_used_jfiles: If this number is less than num_jfiles, it indicates a clean
journal that has not yet
* completed its first rotation, and some files are empty (ie all
null). The first
* num_used_jfiles will contain file headers, the remainder will
be blank.
- * oldest_lid: The lid (==fid, see note 1 below) at which the owi flag flips.
During normal operation, each
- * time the journal rotates back to file 0, a flag (called the
overwrite indicator or owi) is
- * flipped. This flag is saved in the file header. During
recovery, if scanning from logical
+ * oldest_lfid: The lfid (==pfid, see note 1 below) at which the owi flag
flips. During normal operation,
+ * each time the journal rotates back to file 0, a flag (called
the overwrite indicator or owi)
+ * is flipped. This flag is saved in the file header. During
recovery, if scanning from logical
* file 0 upwards, the file at which this flag reverses from its
value in file 0 is the file
* that was to have been overwritten next, and is thus the
"oldest" file. Recovery analysis must
- * start with this file. oldest_lid sets the file at which this
flag will flip value for the
+ * start with this file. oldest_lfid sets the file at which this
flag will flip value for the
* simulated recovery analysis. Note that this will be ignored if
num_used_jfiles < num_jfiles,
* as it is not possible for an overwrite to have occurred if not
all the files have been used.
* first_owi: Sets the value of the owi flag in file 0. If set to false,
then the flip will be found with
* a true flag (and visa versa).
*
* NOTES:
- * 1. By definition, the lids and fids coincide for a journal containing no
inserted files. Thus fid == lid for
- * all journals created after using initial_journal_create() alone.
+ * 1. By definition, the lfids and pfids coincide for a journal containing no
inserted files. Thus pfid == lfid
+ * for all journals created after using initial_journal_create() alone.
* 2. By definition, if a journal is not full (num_used_jfiles < num_jfiles),
then all owi flags for those files
* that are used must be the same. It is not possible for an overwrite
situation to arise if a journal is not
* full.
@@ -182,43 +182,43 @@
* result in invalid journals which cannot be recovered.
*/
void journal_create(const u_int16_t num_jfiles, // Total number of files
- const u_int16_t num_used_jfiles, // Number of used
files, rest empty at end
- const u_int16_t oldest_lid = 0, // Fid where owi
reverses
- const bool first_owi = false) // Value of first
owi flag (ie fid=0)
+ const u_int16_t num_used_jfiles, // Number of used files,
rest empty at end
+ const u_int16_t oldest_lfid = 0, // Fid where owi reverses
+ const bool first_owi = false) // Value of first owi flag
(ie pfid=0)
{
const bool full = num_used_jfiles == num_jfiles;
bool owi = first_owi;
- _oldest_lid = full ? oldest_lid : 0;
- for (u_int16_t lid = 0; lid < num_jfiles; lid++)
+ _oldest_lfid = full ? oldest_lfid : 0;
+ for (u_int16_t lfid = 0; lfid < num_jfiles; lfid++)
{
- const u_int16_t fid = lid;
+ const u_int16_t pfid = lfid;
file_hdr fh;
- if (fid < num_used_jfiles)
+ if (pfid < num_used_jfiles)
{
_num_used_files = num_used_jfiles;
- if (full && oldest_lid > 0 && lid == oldest_lid)
- owi = ~owi; // Flip owi if all files in use and oldest_lid >
0
+ if (full && oldest_lfid > 0 && lfid ==
oldest_lfid)
+ owi = ~owi; // Flip owi if all files in use and oldest_lfid >
0
const u_int64_t frid = u_int64_t(random());
- init_fhdr(fh, frid, fid, lid, owi);
+ init_fhdr(fh, frid, pfid, lfid, owi);
}
- _map.insert(lfpair(lid, fh));
+ _map.insert(lppair(lfid, fh));
}
}
/*
* Method journal_append(): Used to simulate the insertion of journal files into
an existing journal.
*
- * after_lid: The logical id (lid) after which the new file is to be inserted.
+ * after_lfid: The logical file id (lfid) after which the new file is to be
inserted.
* num_files: The number of files to be inserted.
* adjust_lids: Flag indicating that the lids of files _following_ the inserted
files are to be adjusted upwards
* by the number of inserted files. Not doing so simulates a recovery
immediatly after insertion
* but before the following files are overwritten with their new
lids. If this is set false, then:
- * a) after_lid MUST be the most recent file (_oldest_lid-1 ie last
lid before owi changes).
+ * a) after_lfid MUST be the most recent file (_oldest_lfid-1 ie last
lfid before owi changes).
* b) This call must be the last insert call.
*
* NOTES:
- * 1. It is not possible to insert before lid/fid 0; thus these are always
coincident. This operation is
- * logically equivilent to inserting after the last lid, which is possible.
+ * 1. It is not possible to insert before lfid/pfid 0; thus these are always
coincident. This operation is
+ * logically equivilent to inserting after the last lfid, which is possible.
* 2. It is not possible to append to a journal that is not full. Doing so will
result in an unrecoverable
* journal (one that is logically inconsistent that can never occur in
reality).
* 3. If a journal is stopped/interrupted immediately after a file insertion,
there could be duplicate lids in
@@ -226,151 +226,152 @@
* eventually written to during normal operation. The owi flags, however, are
used to determine which of the
* ambiguous lids are the inserted files.
*/
- void journal_insert(const u_int16_t after_lid, // Insert files after this
lid
+ void journal_insert(const u_int16_t after_lfid, // Insert files after this
lfid
const u_int16_t num_files = 1, // Number of files to insert
const bool adjust_lids = true) // Adjust lids following
inserted files
{
if (num_files == 0) return;
_num_used_files += num_files;
const u_int16_t num_jfiles_before_append = _map.size();
- lfmap_citr i = _map.find(after_lid);
- if (i == _map.end()) BOOST_FAIL("Unable to find lid=" <<
after_lid << " in map.");
+ lpmap_citr i = _map.find(after_lfid);
+ if (i == _map.end()) BOOST_FAIL("Unable to find lfid=" <<
after_lfid << " in map.");
const file_hdr fh_before = (*i).second;
// Move overlapping lids (if req'd)
- if (adjust_lids && after_lid < num_jfiles_before_append - 1)
+ if (adjust_lids && after_lfid < num_jfiles_before_append - 1)
{
- for (u_int16_t lid = num_jfiles_before_append - 1; lid > after_lid;
lid--)
+ for (u_int16_t lfid = num_jfiles_before_append - 1; lfid > after_lfid;
lfid--)
{
- lfmap_citr itr = _map.find(lid);
- if (itr == _map.end()) BOOST_FAIL("Unable to find lid="
<< after_lid << " in map.");
+ lpmap_citr itr = _map.find(lfid);
+ if (itr == _map.end()) BOOST_FAIL("Unable to find lfid="
<< after_lfid << " in map.");
file_hdr fh = itr->second;
- _map.erase(lid);
+ _map.erase(lfid);
fh._lid += num_files;
- if (lid == _oldest_lid)
- _oldest_lid += num_files;
- _map.insert(lfpair(fh._lid, fh));
+ if (lfid == _oldest_lfid)
+ _oldest_lfid += num_files;
+ _map.insert(lppair(fh._lid, fh));
}
}
// Add new file headers
- u_int16_t fid = num_jfiles_before_append;
- u_int16_t lid = after_lid + 1;
- while (fid < num_jfiles_before_append + num_files)
+ u_int16_t pfid = num_jfiles_before_append;
+ u_int16_t lfid = after_lfid + 1;
+ while (pfid < num_jfiles_before_append + num_files)
{
const u_int64_t frid = u_int64_t(random());
const size_t fro = 0x200;
- const file_hdr fh(RHM_JDAT_FILE_MAGIC, RHM_JDAT_VERSION, frid, fid, lid,
fro, fh_before.get_owi(), true);
- _map.insert(lfpair(lid, fh));
- _last_fid = fid;
- fid++;
- lid++;
+ const file_hdr fh(RHM_JDAT_FILE_MAGIC, RHM_JDAT_VERSION, frid, pfid,
lfid, fro, fh_before.get_owi(),
+ true);
+ _map.insert(lppair(lfid, fh));
+ _last_pfid = pfid;
+ pfid++;
+ lfid++;
}
}
- void get_fid_list(vector<u_int16_t>& fid_list)
+ void get_pfid_list(vector<u_int16_t>& pfid_list)
{
- fid_list.clear();
- for (lfmap_citr i = _map.begin(); i != _map.end(); i++)
- fid_list.push_back(i->second._fid);
+ pfid_list.clear();
+ for (lpmap_citr i = _map.begin(); i != _map.end(); i++)
+ pfid_list.push_back(i->second._fid);
}
- void get_lid_list(vector<u_int16_t>& lid_list)
+ void get_lfid_list(vector<u_int16_t>& lfid_list)
{
- lid_list.clear();
- lid_list.assign(_map.size(), 0);
- for (lfmap_citr i = _map.begin(); i != _map.end(); i++)
- lid_list[i->second._fid] = i->first;
+ lfid_list.clear();
+ lfid_list.assign(_map.size(), 0);
+ for (lpmap_citr i = _map.begin(); i != _map.end(); i++)
+ lfid_list[i->second._fid] = i->first;
}
/*
- * Method check_analysis(): Used to check the result of the test jinf object
analysis by comparing the fid order
+ * Method check_analysis(): Used to check the result of the test jinf object
analysis by comparing the pfid order
* array it produces against the internal map.
*
* ji: A ref to the jinf object under test.
*/
void check_analysis(jinf& ji) // jinf object under test after analyze() has
been called
{
- BOOST_CHECK_EQUAL(ji.get_first_fid(), get_first_fid());
- BOOST_CHECK_EQUAL(ji.get_last_fid(), get_last_fid());
+ BOOST_CHECK_EQUAL(ji.get_first_fid(), get_first_pfid());
+ BOOST_CHECK_EQUAL(ji.get_last_fid(), get_last_pfid());
- jinf::fid_list& fidl = ji.get_fid_list();
+ jinf::fid_list& pfidl = ji.get_fid_list();
const u_int16_t num_jfiles = _map.size();
const bool all_used = _num_used_files == num_jfiles;
- BOOST_CHECK_EQUAL(fidl.size(), _num_used_files);
+ BOOST_CHECK_EQUAL(pfidl.size(), _num_used_files);
- const u_int16_t lid_start = all_used ? _oldest_lid : 0;
- // Because a simulated failure would leave lid dups in map and last_fid would
not exist in map in this
- // case, we must find lid_stop via fid instead. Search for fid == num_files.
- lfmap_citr itr = _map.begin();
+ const u_int16_t lfid_start = all_used ? _oldest_lfid : 0;
+ // Because a simulated failure would leave lfid dups in map and last_fid
would not exist in map in this
+ // case, we must find lfid_stop via pfid instead. Search for pfid ==
num_files.
+ lpmap_citr itr = _map.begin();
while (itr != _map.end() && itr->second._fid != _num_used_files -
1) itr++;
if (itr == _map.end())
- BOOST_FAIL("check(): Unable to find fid=" <<
(_num_used_files - 1) << " in map.");
- const u_int16_t lid_stop = itr->second._lid;
+ BOOST_FAIL("check(): Unable to find pfid=" <<
(_num_used_files - 1) << " in map.");
+ const u_int16_t lfid_stop = itr->second._lid;
std::size_t fidl_index = 0;
- for (u_int16_t lid_cnt = lid_start; lid_cnt < lid_stop; lid_cnt++,
fidl_index++)
+ for (u_int16_t lfid_cnt = lfid_start; lfid_cnt < lfid_stop; lfid_cnt++,
fidl_index++)
{
- const u_int16_t lid = lid_cnt % num_jfiles;
- lfmap_citr itr = _map.find(lid);
+ const u_int16_t lfid = lfid_cnt % num_jfiles;
+ lpmap_citr itr = _map.find(lfid);
if (itr == _map.end())
- BOOST_FAIL("check(): Unable to find lid=" << lid
<< " in map.");
- BOOST_CHECK_EQUAL(itr->second._fid, fidl[fidl_index]);
+ BOOST_FAIL("check(): Unable to find lfid=" << lfid
<< " in map.");
+ BOOST_CHECK_EQUAL(itr->second._fid, pfidl[fidl_index]);
}
}
/*
- * Method get_fid(): Look up a fid from a known lid.
+ * Method get_pfid(): Look up a pfid from a known lfid.
*/
- u_int16_t get_fid(const u_int16_t lid, const bool initial_owi = false)
+ u_int16_t get_pfid(const u_int16_t lfid, const bool initial_owi = false)
{
- switch (_map.count(lid))
+ switch (_map.count(lfid))
{
case 1:
- return _map.find(lid)->second._fid;
+ return _map.find(lfid)->second._fid;
case 2:
- for (lfmap_citr itr = _map.lower_bound(lid); itr !=
_map.upper_bound(lid); itr++)
+ for (lpmap_citr itr = _map.lower_bound(lfid); itr !=
_map.upper_bound(lfid); itr++)
{
if (itr->second.get_owi() != initial_owi)
return itr->second._fid;
}
default:;
}
- BOOST_FAIL("get_fid(): lid=" << lid << " not found
in map.");
+ BOOST_FAIL("get_pfid(): lfid=" << lfid << " not
found in map.");
return 0xffff;
}
/*
- * Method get_first_fid(): Look up the first (oldest, or next-to-be-overwritten)
fid in the analysis sequence.
+ * Method get_first_pfid(): Look up the first (oldest, or next-to-be-overwritten)
pfid in the analysis sequence.
*/
- u_int16_t get_first_fid()
+ u_int16_t get_first_pfid()
{
- return get_fid(_oldest_lid);
+ return get_pfid(_oldest_lfid);
}
/*
- * Method get_last_fid(): Look up the last (newest, or most recently written) fid
in the analysis sequence.
+ * Method get_last_pfid(): Look up the last (newest, or most recently written)
pfid in the analysis sequence.
*/
- u_int16_t get_last_fid()
+ u_int16_t get_last_pfid()
{
- u_int16_t flid = 0;
+ u_int16_t flfid = 0;
if (_num_used_files == _map.size()) // journal full?
{
- if (_oldest_lid)
+ if (_oldest_lfid)
{
// if failed insert, cycle past duplicate lids
- while (_map.count(_oldest_lid) == 2)
- _oldest_lid++;
- while (_map.find(_oldest_lid) != _map.end() &&
_map.find(_oldest_lid)->second.get_owi() == false)
- _oldest_lid++;
- flid = _oldest_lid - 1;
+ while (_map.count(_oldest_lfid) == 2)
+ _oldest_lfid++;
+ while (_map.find(_oldest_lfid) != _map.end() &&
_map.find(_oldest_lfid)->second.get_owi() == false)
+ _oldest_lfid++;
+ flfid = _oldest_lfid - 1;
}
else
- flid = _map.size() - 1;
+ flfid = _map.size() - 1;
}
else
- flid = _num_used_files - 1;
- return get_fid(flid, true);
+ flfid = _num_used_files - 1;
+ return get_pfid(flfid, true);
}
/*
@@ -383,32 +384,32 @@
void write_journal(const bool ae, const u_int16_t ae_max_jfiles)
{
create_jinf(ae, ae_max_jfiles);
- u_int16_t fid = 0;
- for (lfmap_citr itr = _map.begin(); itr != _map.end(); itr++, fid++)
+ u_int16_t pfid = 0;
+ for (lpmap_citr itr = _map.begin(); itr != _map.end(); itr++, pfid++)
{
- if (itr->second._fid == 0 && itr->second._magic == 0) //
empty header, use fid counter instaed
- create_journal_file(fid, itr->second, _base_filename);
+ if (itr->second._fid == 0 && itr->second._magic == 0) //
empty header, use pfid counter instaed
+ create_journal_file(pfid, itr->second, _base_filename);
else
create_journal_file(itr->second._fid, itr->second,
_base_filename);
}
}
/*
- * Method destroy_journal(): Destroy the files created by create_journal() and
reset the lid_fid_map test object.
- * A new test may be started using the same lid_fid_map test object once this call
has been made.
+ * Method destroy_journal(): Destroy the files created by create_journal() and
reset the lfid_pfid_map test
+ * object. A new test may be started using the same lfid_pfid_map test object once
this call has been made.
*/
void destroy_journal()
{
- for (u_int16_t fid = 0; fid < _map.size(); fid++)
+ for (u_int16_t pfid = 0; pfid < _map.size(); pfid++)
{
- string fn = create_journal_filename(fid, _base_filename);
+ string fn = create_journal_filename(pfid, _base_filename);
BOOST_WARN_MESSAGE(::unlink(fn.c_str()) == 0, "destroy_journal():
Failed to remove file " << fn);
}
clean_journal_info_file(_base_filename);
_map.clear();
_num_used_files = 0;
- _oldest_lid = 0;
- _last_fid = 0;
+ _oldest_lfid = 0;
+ _last_pfid = 0;
}
/*
@@ -437,8 +438,8 @@
private:
static void init_fhdr(file_hdr& fh,
const u_int64_t frid,
- const u_int16_t fid,
- const u_int16_t lid,
+ const u_int16_t pfid,
+ const u_int16_t lfid,
const bool owi,
const bool no_enq = false)
{
@@ -451,8 +452,8 @@
#endif
fh._uflag = owi ? rec_hdr::HDR_OVERWRITE_INDICATOR_MASK : 0;
fh._rid = frid;
- fh._fid = fid;
- fh._lid = lid;
+ fh._fid = pfid;
+ fh._lid = lfid;
fh._fro = no_enq ? 0 : 0x200;
timespec ts;
::clock_gettime(CLOCK_REALTIME, &ts);
@@ -478,9 +479,9 @@
ji.write();
}
- static void create_journal_file(const u_int16_t fid, const file_hdr& fh,
const string base_filename)
+ static void create_journal_file(const u_int16_t pfid, const file_hdr& fh,
const string base_filename)
{
- write_file_header(fh, create_journal_filename(fid, base_filename));
+ write_file_header(fh, create_journal_filename(pfid, base_filename));
}
static void write_file_header(const file_hdr& fh,
@@ -509,11 +510,11 @@
BOOST_FAIL("Error closing test journal file \"" <<
filename << "\".");
}
- static string create_journal_filename(const u_int16_t fid, const string
base_filename)
+ static string create_journal_filename(const u_int16_t pfid, const string
base_filename)
{
stringstream fn;
fn << test_dir << "/" << base_filename <<
".";
- fn << setfill('0') << hex << setw(4) << fid
<< "." << JRNL_DATA_EXTENSION;
+ fn << setfill('0') << hex << setw(4) << pfid
<< "." << JRNL_DATA_EXTENSION;
return fn.str();
}
};
Modified: store/trunk/cpp/tests/jrnl/_ut_jinf.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/_ut_jinf.cpp 2009-01-15 12:59:10 UTC (rev 3044)
+++ store/trunk/cpp/tests/jrnl/_ut_jinf.cpp 2009-01-15 15:57:43 UTC (rev 3045)
@@ -79,7 +79,7 @@
string test_name = get_test_name(test_filename, "read_constructor");
const string jid = test_name + "_jid";
const string base_filename = test_name + "_bfn";
- lid_fid_map::create_new_jinf(jid, base_filename, false);
+ lfid_pfid_map::create_new_jinf(jid, base_filename, false);
stringstream fn;
fn << test_dir << "/" <<base_filename <<
"." << JRNL_INFO_EXTENSION;
@@ -110,7 +110,7 @@
string test_name = get_test_name(test_filename, "set_functions");
const string jid = test_name + "_jid";
const string base_filename = test_name + "_bfn";
- lid_fid_map::create_new_jinf(jid, base_filename, false);
+ lfid_pfid_map::create_new_jinf(jid, base_filename, false);
stringstream fn;
fn << test_dir << "/" << base_filename <<
"." << JRNL_INFO_EXTENSION;
@@ -125,7 +125,7 @@
ji.incr_num_jfiles();
BOOST_CHECK_EQUAL(ji.num_jfiles(), u_int16_t(NUM_JFILES+2));
- lid_fid_map::clean_journal_info_file(test_dir);
+ lfid_pfid_map::clean_journal_info_file(test_dir);
cout << "done" << endl;
}
@@ -134,14 +134,14 @@
string test_name = get_test_name(test_filename, "validate");
const string jid = test_name + "_jid";
const string base_filename = test_name + "_bfn";
- lid_fid_map::create_new_jinf(jid, base_filename, false);
+ lfid_pfid_map::create_new_jinf(jid, base_filename, false);
stringstream fn;
fn << test_dir << "/" << base_filename <<
"." << JRNL_INFO_EXTENSION;
jinf ji(fn.str(), true);
// TODO: Check validation picks up conflict, but need to be friend to jinf to do it
- lid_fid_map::clean_journal_info_file(test_dir);
+ lfid_pfid_map::clean_journal_info_file(test_dir);
cout << "done" << endl;
}
@@ -152,7 +152,7 @@
const string base_filename = test_name + "_bfn";
jdir::create_dir(test_dir); // Check test dir exists; create it if not
- lid_fid_map m(jid, base_filename);
+ lfid_pfid_map m(jid, base_filename);
m.journal_create(NUM_JFILES, 0, 0);
m.write_journal(false, 0);
@@ -175,7 +175,7 @@
string test_name = get_test_name(test_filename,
"analyze_part_full_journal");
const string jid = test_name + "_jid";
const string base_filename = test_name + "_bfn";
- lid_fid_map m(jid, base_filename);
+ lfid_pfid_map m(jid, base_filename);
for (u_int16_t num_files = 1; num_files < NUM_JFILES; num_files++)
{
m.journal_create(NUM_JFILES, num_files, 0);
@@ -197,7 +197,7 @@
string test_name = get_test_name(test_filename, "analyze_full_journal");
const string jid = test_name + "_jid";
const string base_filename = test_name + "_bfn";
- lid_fid_map m(jid, base_filename);
+ lfid_pfid_map m(jid, base_filename);
for (u_int16_t file_num = 0; file_num < NUM_JFILES; file_num++)
{
m.journal_create(NUM_JFILES, NUM_JFILES, file_num);
@@ -219,7 +219,7 @@
string test_name = get_test_name(test_filename,
"analyze_single_appended_journal");
const string jid = test_name + "_jid";
const string base_filename = test_name + "_bfn";
- lid_fid_map m(jid, base_filename);
+ lfid_pfid_map m(jid, base_filename);
for (u_int16_t oldest_lid = 0; oldest_lid < NUM_JFILES; oldest_lid++)
for (u_int16_t after_lid = 0; after_lid < NUM_JFILES; after_lid++)
for (u_int16_t num_files = 1; num_files <= 5; num_files++)
@@ -244,7 +244,7 @@
string test_name = get_test_name(test_filename,
"analyze_multi_appended_journal");
const string jid = test_name + "_jid";
const string base_filename = test_name + "_bfn";
- lid_fid_map m(jid, base_filename);
+ lfid_pfid_map m(jid, base_filename);
::srand48(1);
for (u_int16_t num_appends = 1; num_appends <= 2*NUM_JFILES; num_appends++)
@@ -276,7 +276,7 @@
string test_name = get_test_name(test_filename,
"analyze_multi_appended_then_failed_journal");
const string jid = test_name + "_jid";
const string base_filename = test_name + "_bfn";
- lid_fid_map m(jid, base_filename);
+ lfid_pfid_map m(jid, base_filename);
::srand48(1);
// As this test relies on repeatable but random sequences, use many ierations for
coverage
Deleted: store/trunk/cpp/tests/jrnl/_ut_lfmgr.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/_ut_lfmgr.cpp 2009-01-15 12:59:10 UTC (rev 3044)
+++ store/trunk/cpp/tests/jrnl/_ut_lfmgr.cpp 2009-01-15 15:57:43 UTC (rev 3045)
@@ -1,857 +0,0 @@
-/**
-* \file _ut_lfmgr.cpp
-*
-* Red Hat Messaging - Message Journal
-*
-* This file contains the unit tests for the journal.
-*
-* Copyright 2007, 2008 Red Hat, Inc.
-*
-* This file is part of Red Hat Messaging.
-*
-* Red Hat Messaging is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 2.1 of the License, or (at your option) any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
-* USA
-*
-* The GNU Lesser General Public License is available in the file COPYING.
-*/
-
-#include "../unit_test.h"
-#include <cmath>
-#include <iostream>
-#include "jrnl/jcntl.hpp"
-#include "jrnl/lfmgr.hpp"
-
-using namespace boost::unit_test;
-using namespace mrg::journal;
-using namespace std;
-
-QPID_AUTO_TEST_SUITE(arr_cnt_suite)
-
-const string test_filename("_ut_lfmgr");
-
-#include "_st_helper_fns.hpp"
-
-// === Helper functions and definitions ===
-
-typedef vector<u_int16_t> flist;
-typedef flist::const_iterator flist_citr;
-
-class lfmgr_test_helper
-{
- lfmgr_test_helper() {}
- virtual ~lfmgr_test_helper() {}
-
-public:
- static void check_fids_lids(const lfmgr& lm, const u_int16_t fids[], const
u_int16_t lids[],
- const size_t fid_lid_size)
- {
- vector<u_int16_t> res;
- lm.get_fid_list(res);
- vectors_equal(lm, fids, fid_lid_size, res, true);
- lm.get_lid_list(res);
- vectors_equal(lm, lids, fid_lid_size, res, false);
- }
-
- static void check_fids_lids(const lfmgr& lm, const flist& fids, const flist
lids)
- {
- vector<u_int16_t> res;
- lm.get_fid_list(res);
- vectors_equal(lm, fids, res, true);
- lm.get_lid_list(res);
- vectors_equal(lm, lids, res, false);
- }
-
- static void check_linear_fids_lids(const lfmgr& lm, const size_t fid_lid_size)
- {
- vector<u_int16_t> res;
- lm.get_fid_list(res);
- linear_vectors_equal(lm, fid_lid_size, res, true);
- lm.get_lid_list(res);
- linear_vectors_equal(lm, fid_lid_size, res, false);
- }
-
- static void rcvdat_init(rcvdat& rd, const u_int16_t num_jfiles, const bool ae,
const u_int16_t ae_max_jfiles,
- const u_int16_t fids[])
- {
- rd.reset(num_jfiles, ae, ae_max_jfiles);
- load_vector(fids, num_jfiles, rd._fid_list);
- rd._jempty = false;
- rd._lfid = fids[num_jfiles - 1];
- rd._eo = 100 * JRNL_DBLK_SIZE * JRNL_SBLK_SIZE;
- }
-
- static void rcvdat_init(rcvdat& rd, const flist& fidl, const bool ae, const
u_int16_t ae_max_jfiles)
- {
- const u_int16_t num_jfiles = fidl.size();
- rd.reset(num_jfiles, ae, ae_max_jfiles);
- load_vector(fidl, rd._fid_list);
- rd._jempty = false;
- rd._lfid = fidl[num_jfiles - 1];
- rd._eo = 100 * JRNL_DBLK_SIZE * JRNL_SBLK_SIZE;
- }
-
- static void initialize(lfmgr& lm, test_jrnl& jc, const u_int16_t num_jfiles,
const bool ae,
- const u_int16_t ae_max_jfiles)
- {
- lm.initialize(num_jfiles, ae, ae_max_jfiles, &jc, &jc.new_fcntl);
- BOOST_CHECK_EQUAL(lm.is_init(), true);
- BOOST_CHECK_EQUAL(lm.is_ae(), ae);
- BOOST_CHECK_EQUAL(lm.ae_max_jfiles(), ae_max_jfiles);
- BOOST_CHECK_EQUAL(lm.num_jfiles(), num_jfiles);
- if (num_jfiles)
- check_linear_fids_lids(lm, num_jfiles);
- else
- BOOST_CHECK_EQUAL(lm.get_fcntlp(0), (void*)0);
- }
-
- // version which sets up the lid_fid_map for later manipulation by insert tests
- static void initialize(lid_fid_map& lfm, lfmgr& lm, test_jrnl& jc, const
u_int16_t num_jfiles, const bool ae,
- const u_int16_t ae_max_jfiles)
- {
- lfm.journal_create(num_jfiles, num_jfiles);
- initialize(lm, jc, num_jfiles, ae, ae_max_jfiles);
- }
-
- static void prepare_recover(lid_fid_map& lfm, const u_int16_t size)
- {
- if (size < 4) BOOST_FAIL("prepare_recover(): size parameter ("
<< size << ") too small.");
- lfm.journal_create(4, 4); // initial journal of size 4
- u_int16_t s = 4; // cumulative size
- while (s < size)
- {
- const u_int16_t ins_posn = u_int16_t(s * ::drand48()); // this insert posn
- if (3.0 * ::drand48() > 1.0 || size - s < 2) // 2:1 chance of single
insert when >= 2 still to insert
- {
- lfm.journal_insert(ins_posn); // single insert
- s++;
- }
- else
- {
- // multiple insert, either 2 - 5
- const u_int16_t max_ins_size = size - s >5 ? 5 : size - s;
- const u_int16_t ins_size = 2 + u_int16_t((max_ins_size - 2) *
::drand48()); // this insert size
- lfm.journal_insert(ins_posn, ins_size);
- s += ins_size;
- }
- }
- }
-
- static void recover(lid_fid_map& lfm, lfmgr& lm, test_jrnl& jc, const
bool ae, const u_int16_t ae_max_jfiles)
- {
- flist fidl;
- flist lidl;
- rcvdat rd;
- const u_int16_t num_jfiles = lfm.size();
-
- lfm.get_fid_list(fidl);
- lfm.get_lid_list(lidl);
- lfm.write_journal(ae, ae_max_jfiles);
-
- lfmgr_test_helper::rcvdat_init(rd, fidl, ae, ae_max_jfiles);
- lm.recover(rd, &jc, &jc.new_fcntl);
- BOOST_CHECK_EQUAL(lm.is_init(), true);
- BOOST_CHECK_EQUAL(lm.is_ae(), ae);
- BOOST_CHECK_EQUAL(lm.ae_max_jfiles(), ae_max_jfiles);
- BOOST_CHECK_EQUAL(lm.num_jfiles(), num_jfiles);
- if (num_jfiles)
- check_fids_lids(lm, fidl, lidl);
- else
- BOOST_CHECK_EQUAL(lm.get_fcntlp(0), (void*)0);
- }
-
- static void finalize(lfmgr& lm)
- {
- lm.finalize();
- BOOST_CHECK_EQUAL(lm.is_init(), false);
- BOOST_CHECK_EQUAL(lm.is_ae(), false);
- BOOST_CHECK_EQUAL(lm.ae_max_jfiles(), u_int16_t(0));
- BOOST_CHECK_EQUAL(lm.num_jfiles(), u_int16_t(0));
- BOOST_CHECK_EQUAL(lm.get_fcntlp(0), (void*)0);
- vector<u_int16_t> res;
- lm.get_fid_list(res);
- BOOST_CHECK_EQUAL(res.size(), u_int16_t(0));
- lm.get_lid_list(res);
- BOOST_CHECK_EQUAL(res.size(), u_int16_t(0));
- }
-
- static void insert(lid_fid_map& lfm, lfmgr& lm, test_jrnl& jc, const
u_int16_t after_lid, const u_int16_t incr = 1)
- {
- flist fidl;
- flist lidl;
- const u_int16_t num_jfiles = lm.num_jfiles();
- lfm.journal_insert(after_lid, incr);
- lfm.get_fid_list(fidl);
- lfm.get_lid_list(lidl);
- lm.insert(after_lid, &jc, &jc.new_fcntl, incr);
- BOOST_CHECK_EQUAL(lm.num_jfiles(), num_jfiles + incr);
- lfmgr_test_helper::check_fids_lids(lm, fidl, lidl);
- }
-
- static void check_ae_max_jfiles(lfmgr& lm, const u_int16_t num_jfiles, const
u_int16_t ae_max_jfiles)
- {
- bool legal = ae_max_jfiles > num_jfiles || ae_max_jfiles == 0;
-
- lm.set_ae(false);
- BOOST_CHECK(!lm.is_ae());
- if (legal)
- {
- lm.set_ae_max_jfiles(ae_max_jfiles);
- BOOST_CHECK_EQUAL(lm.ae_max_jfiles(), ae_max_jfiles);
- lm.set_ae(true);
- BOOST_CHECK(lm.is_ae());
- BOOST_CHECK_EQUAL(lm.ae_jfiles_rem(), ae_max_jfiles
- ? ae_max_jfiles - num_jfiles
- : JRNL_MAX_NUM_FILES - num_jfiles);
- }
- else
- {
- lm.set_ae_max_jfiles(ae_max_jfiles);
- BOOST_CHECK_EQUAL(lm.ae_max_jfiles(), ae_max_jfiles);
- try
- {
- lm.set_ae(true); // should raise exception
- BOOST_ERROR("Auto-expand enabled with out-of-range
ae_max_jfiles");
- }
- catch (const jexception& e) { BOOST_CHECK_EQUAL(e.err_code(),
jerrno::JERR_LFMGR_BADAEFNUMLIM); }
- BOOST_CHECK(!lm.is_ae());
- BOOST_CHECK_EQUAL(lm.ae_jfiles_rem(), 0);
- }
- BOOST_CHECK_EQUAL(lm.ae_max_jfiles(), ae_max_jfiles);
- }
-
- static void check_multiple_initialization_recover(lid_fid_map& lfm,
test_jrnl& jc,
- const u_int16_t num_jfiles_arr[][2], const bool init_flag_0, const bool
finalize_flag,
- const bool init_flag_1)
- {
- unsigned i_njf = 0;
- while (num_jfiles_arr[i_njf][0] && num_jfiles_arr[i_njf][1])
- {
- for (unsigned i1_njf = 0; i1_njf <= 1; i1_njf++)
- {
- const u_int16_t num_jfiles_0 = num_jfiles_arr[i_njf][i1_njf == 0];
- const u_int16_t num_jfiles_1 = num_jfiles_arr[i_njf][i1_njf != 0];
-
- for (unsigned i_ae = 0; i_ae < 4; i_ae++)
- {
- const bool ae_0 = i_ae & 0x1;
- const bool ae_1 = i_ae & 0x2;
- for (unsigned i_aemjf = 0; i_aemjf < 4; i_aemjf++)
- {
- const u_int16_t ae_max_jfiles_0 = i_aemjf & 0x1 ? 3 *
num_jfiles_0 : 0;
- const u_int16_t ae_max_jfiles_1 = i_aemjf & 0x2 ? 4 *
num_jfiles_1 : 0;
-
- lfmgr lm;
-
- if (init_flag_0)
- initialize(lm, jc, num_jfiles_0, ae_0, ae_max_jfiles_0);
- else
- {
- prepare_recover(lfm, num_jfiles_0);
- recover(lfm, lm, jc, ae_1, ae_max_jfiles_0);
- lfm.destroy_journal();
- }
-
- if (finalize_flag) finalize(lm);
-
- if (init_flag_1)
- initialize(lm, jc, num_jfiles_1, ae_1, ae_max_jfiles_1);
- else
- {
- prepare_recover(lfm, num_jfiles_1);
- recover(lfm, lm, jc, ae_1, ae_max_jfiles_1);
- lfm.destroy_journal();
- }
- }
- }
- }
- i_njf++;
- }
- }
-
- static void check_insert(lid_fid_map& lfm, lfmgr& lm, test_jrnl& jc,
const u_int16_t after_lid,
- const u_int16_t incr = 1)
- {
- const u_int16_t num_jfiles = lm.num_jfiles();
- const u_int16_t ae_max_jfiles = lm.ae_max_jfiles();
- const u_int16_t effective_ae_max_jfiles = ae_max_jfiles ? ae_max_jfiles :
JRNL_MAX_NUM_FILES;
- BOOST_CHECK_EQUAL(lm.ae_jfiles_rem(), effective_ae_max_jfiles - num_jfiles);
- bool legal = lm.is_ae() && num_jfiles + incr <=
effective_ae_max_jfiles;
- if (legal)
- {
- insert(lfm, lm, jc, after_lid, incr);
- BOOST_CHECK_EQUAL(lm.num_jfiles(), num_jfiles + incr);
- BOOST_CHECK_EQUAL(lm.ae_jfiles_rem(), effective_ae_max_jfiles - num_jfiles -
incr);
- }
- else
- {
- try
- {
- insert(lfm, lm, jc, after_lid, incr);
- if (lm.is_ae())
- BOOST_ERROR("lfmgr::insert() succeeded and exceeded
limit");
- else
- BOOST_ERROR("lfmgr::insert() succeeded with auto-expand
disabled");
- }
- catch (const jexception& e)
- {
- if (lm.is_ae())
- BOOST_CHECK_EQUAL(e.err_code(), jerrno::JERR_LFMGR_AEFNUMLIMIT);
- else
- BOOST_CHECK_EQUAL(e.err_code(), jerrno::JERR_LFMGR_AEDISABLED);
- }
- BOOST_CHECK_EQUAL(lm.num_jfiles(), num_jfiles);
- BOOST_CHECK_EQUAL(lm.ae_jfiles_rem(), effective_ae_max_jfiles - num_jfiles);
- }
- }
-
- static void check_limit(lid_fid_map& lfm, test_jrnl& jc, const bool ae, const
u_int16_t num_jfiles,
- const u_int16_t ae_max_jfiles)
- {
- lfmgr lm;
-
- for (unsigned i = 0; i < 2; i++)
- {
- if (i)
- initialize(lfm, lm, jc, num_jfiles, ae, ae_max_jfiles);
- else
- {
- prepare_recover(lfm, num_jfiles);
- recover(lfm, lm, jc, ae, ae_max_jfiles);
- }
-
- // use up all available files
- unsigned j = ae_max_jfiles ? ae_max_jfiles : JRNL_MAX_NUM_FILES;
- while (ae && j > num_jfiles)
- {
- const u_int16_t posn = static_cast<u_int16_t>((lm.num_jfiles() - 1)
* ::drand48());
- const u_int16_t incr = 1 +
static_cast<u_int16_t>((lm.ae_jfiles_rem() > 4
- ? 3 : lm.ae_jfiles_rem() - 1) * ::drand48());
- check_insert(lfm, lm, jc, posn, incr);
- j -= incr;
- }
- // these should be over the limit or illegal
- check_insert(lfm, lm, jc, 0);
- check_insert(lfm, lm, jc, 2, 2);
- lfm.destroy_journal();
- }
- }
-
-private:
- static void load_vector(const u_int16_t a[], const size_t n, flist& v)
- {
- for (size_t i = 0; i < n; i++)
- v.push_back(a[i]);
- }
-
- static void load_vector(const flist& a, flist& b)
- {
- for (flist_citr i = a.begin(); i < a.end(); i++)
- b.push_back(*i);
- }
-
- static void vectors_equal(const lfmgr& lm, const u_int16_t a[], const size_t n,
const flist& b,
- const bool fid_check)
- {
- BOOST_CHECK_EQUAL(n, b.size());
- for (size_t i = 0; i < n; i++)
- {
- BOOST_CHECK_EQUAL(a[i], b[i]);
- fcntl* fp = lm.get_fcntlp(i);
- BOOST_CHECK_MESSAGE(fp != (void*)0, "Unexpected void pointer returned by
lfmgr::get_fcntlp()");
- if (fp) BOOST_CHECK_EQUAL(fid_check ? fp->fid() : fp->lid(), fid_check
? a[i] : i);
- }
- }
-
- static void vectors_equal(const lfmgr& lm, const flist& a, const flist&
b, const bool fid_check)
- {
- BOOST_CHECK_EQUAL(a.size(), b.size());
- for (size_t i = 0; i < a.size(); i++)
- {
- BOOST_CHECK_EQUAL(a[i], b[i]);
- fcntl* fp = lm.get_fcntlp(i);
- BOOST_CHECK_MESSAGE(fp != (void*)0, "Unexpected void pointer returned by
lfmgr::get_fcntlp()");
- if (fp) BOOST_CHECK_EQUAL(fid_check ? fp->fid() : fp->lid(), fid_check
? a[i] : i);
- }
- }
-
- static void linear_vectors_equal(const lfmgr& lm, const size_t n, const
flist& f, const bool fid_check)
- {
- BOOST_CHECK_EQUAL(n, f.size());
- for (size_t i = 0; i < n; i++)
- {
- BOOST_CHECK_EQUAL(i, f[i]);
- fcntl* fp = lm.get_fcntlp(i);
- BOOST_CHECK_MESSAGE(fp != (void*)0, "Unexpected void pointer returned by
lfmgr::get_fcntlp()");
- if (fp) BOOST_CHECK_EQUAL(fid_check ? fp->fid() : fp->lid(), i);
- }
- }
-};
-
-// === Tests ===
-
-/*
-* Check that after construction, the fid array _fcntl_arr is empty and the is_init()
function returns false.
-*/
-QPID_AUTO_TEST_CASE(default_constructor)
-{
- string test_name = get_test_name(test_filename, "default_constructor");
- try
- {
- lfmgr lm;
- BOOST_CHECK_EQUAL(lm.is_init(), false);
- BOOST_CHECK_EQUAL(lm.is_ae(), false);
- BOOST_CHECK_EQUAL(lm.ae_max_jfiles(), u_int16_t(0));
- BOOST_CHECK_EQUAL(lm.num_jfiles(), u_int16_t(0));
- BOOST_CHECK_EQUAL(lm.get_fcntlp(0), (void*)0);
- }
- catch(const exception& e) { BOOST_FAIL(e.what()); }
- cout << "done" << endl;
-}
-
-/*
-* Check that initialize() correctly creates an ordered fid array _fcntl_arr.
-*/
-QPID_AUTO_TEST_CASE(initialize)
-{
- string test_name = get_test_name(test_filename, "initialize");
- const u_int16_t num_jfiles = 8;
- try
- {
- jdir::create_dir(test_dir); // Check test dir exists; create it if not
- test_jrnl jc(test_name, test_dir, test_name);
- {
- lfmgr lm;
- lfmgr_test_helper::initialize(lm, jc, num_jfiles, false, 0);
- }
- {
- lfmgr lm;
- lfmgr_test_helper::initialize(lm, jc, num_jfiles, true, 0);
- }
- {
- lfmgr lm;
- lfmgr_test_helper::initialize(lm, jc, num_jfiles, true, 5 * num_jfiles);
- }
- }
- catch(const exception& e) { BOOST_FAIL(e.what()); }
- cout << "done" << endl;
-}
-
-/*
-* Check that recover() correctly sets up the specified fid list order.
-*/
-QPID_AUTO_TEST_CASE(recover)
-{
- string test_name = get_test_name(test_filename, "recover");
- ::srand48(1); // init random gen for repeatable tests when using
lfmgr_test_helper::prepare_recover()
- try
- {
- test_jrnl jc(test_name, test_dir, test_name);
- lid_fid_map lfm(test_name, test_name);
-
- {
- lfmgr lm;
- lfmgr_test_helper::prepare_recover(lfm, 8);
- lfmgr_test_helper::recover(lfm, lm, jc, false, 0);
- lfm.destroy_journal();
- }
- {
- lfmgr lm;
- lfmgr_test_helper::prepare_recover(lfm, 8);
- lfmgr_test_helper::recover(lfm, lm, jc, true, 0);
- lfm.destroy_journal();
- }
- {
- lfmgr lm;
- lfmgr_test_helper::prepare_recover(lfm, 8);
- lfmgr_test_helper::recover(lfm, lm, jc, true, 5 * lfm.size());
- lfm.destroy_journal();
- }
- }
- catch(const exception& e) { BOOST_FAIL(e.what()); }
- cout << "done" << endl;
-}
-
-/*
-* Check that finalize() after an initialize() empties _fcntl_arr and that afterwards
is_init() returns false.
-*/
-QPID_AUTO_TEST_CASE(initialize_finalize)
-{
- string test_name = get_test_name(test_filename, "initialize_finalize");
- const u_int16_t num_jfiles = 8;
- try
- {
- jdir::create_dir(test_dir); // Check test dir exists; create it if not
- test_jrnl jc(test_name, test_dir, test_name);
- {
- lfmgr lm;
- lfmgr_test_helper::initialize(lm, jc, num_jfiles, false, 0);
- lfmgr_test_helper::finalize(lm);
- }
- {
- lfmgr lm;
- lfmgr_test_helper::initialize(lm, jc, num_jfiles, true, 0);
- lfmgr_test_helper::finalize(lm);
- }
- {
- lfmgr lm;
- lfmgr_test_helper::initialize(lm, jc, num_jfiles, true, 5 * num_jfiles);
- lfmgr_test_helper::finalize(lm);
- }
- }
- catch(const exception& e) { BOOST_FAIL(e.what()); }
- cout << "done" << endl;
-}
-
-/*
-* Check that finalize() after a recover() empties _fcntl_arr and that afterwards
is_init() returns false.
-*/
-QPID_AUTO_TEST_CASE(recover_finalize)
-{
- string test_name = get_test_name(test_filename, "recover_finalize");
- const u_int16_t num_jfiles = 8;
- ::srand48(1); // init random gen for repeatable tests when using
lfmgr_test_helper::prepare_recover()
- try
- {
- test_jrnl jc(test_name, test_dir, test_name);
- lid_fid_map lfm(test_name, test_name);
-
- {
- lfmgr lm;
- lfmgr_test_helper::prepare_recover(lfm, num_jfiles);
- lfmgr_test_helper::recover(lfm, lm, jc, false, 0);
- lfmgr_test_helper::finalize(lm);
- lfm.destroy_journal();
- }
- {
- lfmgr lm;
- lfmgr_test_helper::prepare_recover(lfm, num_jfiles);
- lfmgr_test_helper::recover(lfm, lm, jc, true, 0);
- lfmgr_test_helper::finalize(lm);
- lfm.destroy_journal();
- }
- {
- lfmgr lm;
- lfmgr_test_helper::prepare_recover(lfm, num_jfiles);
- lfmgr_test_helper::recover(lfm, lm, jc, true, 5 * lfm.size());
- lfmgr_test_helper::finalize(lm);
- lfm.destroy_journal();
- }
- }
- catch(const exception& e) { BOOST_FAIL(e.what()); }
- cout << "done" << endl;
-}
-
-/*
-* Check that 0 and/or null and other extreme/boundary parameters behave as expected.
-*/
-QPID_AUTO_TEST_CASE(zero_null_params)
-{
- string test_name = get_test_name(test_filename, "zero_null_params");
- const u_int16_t num_jfiles = 8;
- try
- {
- test_jrnl jc(test_name, test_dir, test_name);
- lid_fid_map lfm(test_name, test_name);
- lfmgr lm;
- lfmgr_test_helper::initialize(lfm, lm, jc, num_jfiles, true, 0);
-
- // Check that inserting 0 files works ok
- lfmgr_test_helper::insert(lfm, lm, jc, 0, 0);
- lfmgr_test_helper::insert(lfm, lm, jc, 2, 0);
- lfmgr_test_helper::insert(lfm, lm, jc, num_jfiles - 1, 0);
- }
- catch(const exception& e) { BOOST_FAIL(e.what()); }
- cout << "done" << endl;
-}
-
-/*
-* Check that initialize()/recover() works correctly after a previous
initialize()/recover() with/without an intervening
-* finalize().
-*/
-QPID_AUTO_TEST_CASE(multiple_initialization_recover)
-{
- string test_name = get_test_name(test_filename,
"multiple_initialization_recover");
- ::srand48(1); // init random gen for repeatable tests when using
lfmgr_test_helper::prepare_recover()
-
- // Set combinations of value pairs to be used for number of journal files in first
and second init
- u_int16_t num_jfiles_arr[][2] = {{8, 12}, {4, 7}, {0, 0}}; // end with zeros
- try
- {
- test_jrnl jc(test_name, test_dir, test_name);
- lid_fid_map lfm(test_name, test_name);
- for (unsigned p = 0; p < 8; p++)
- {
- const bool i_0 = p & 0x01; // first bit
- const bool i_1 = p & 0x02; // second bit
- const bool f = p & 0x04; // third bit
- lfmgr_test_helper::check_multiple_initialization_recover(lfm, jc,
num_jfiles_arr, i_0,f, i_1);
- }
- }
- catch(const exception& e) { BOOST_FAIL(e.what()); }
- cout << "done" << endl;
-}
-
-/*
-* Check that insert() works correctly after initialize() and shifts the fid sequence
beyond the insert point correctly:
-*
-* The following sequence is tested:
-* initialize 4 fids=[0,1,2,3] lids=[0,1,2,3]
-* insert 1 after lid 0 fids=[0,4,1,2,3] lids=[0,2,3,4,1]
-* insert 2 after lid 2 fids=[0,4,1,5,6,2,3] lids=[0,2,5,6,1,3,4]
-* insert 1 after lid 6 fids=[0,4,1,5,6,2,3,7] lids=[0,2,5,6,1,3,4,7]
-* issert 1 after lid 3 fids=[0,4,1,5,8,6,2,3,7] lids=[0,2,6,7,1,3,5,8,4]
-*/
-QPID_AUTO_TEST_CASE(initialize_insert)
-{
- string test_name = get_test_name(test_filename, "initialize_insert");
- const u_int16_t initial_num_jfiles = 8;
- try
- {
- jdir::create_dir(test_dir); // Check test dir exists; create it if not
- test_jrnl jc(test_name, test_dir, test_name);
- lid_fid_map lfm(test_name, test_name);
- lfmgr lm;
- lfmgr_test_helper::initialize(lfm, lm, jc, initial_num_jfiles, true, 0);
-
- lfmgr_test_helper::insert(lfm, lm, jc, 0);
- lfmgr_test_helper::insert(lfm, lm, jc, 2, 2);
- lfmgr_test_helper::insert(lfm, lm, jc, 6);
- lfmgr_test_helper::insert(lfm, lm, jc, 3);
- }
- catch(const exception& e) { BOOST_FAIL(e.what()); }
- cout << "done" << endl;
-}
-
-/*
-* Check that insert() works correctly after recover() and shifts the fid sequence beyond
the insert point correctly:
-*
-* The following sequence is tested:
-* recover 4 fids=[0,2,3,1] lids=[0,3,1,2]
-* insert 1 after lid 0 fids=[0,4,2,3,1] lids=[0,4,2,3,1]
-* insert 2 after lid 2 fids=[0,4,2,5,6,3,1] lids=[0,6,2,5,1,3,4]
-* insert 1 after lid 6 fids=[0,4,2,5,6,3,1,7] lids=[0,6,2,5,1,3,4,7]
-* issert 1 after lid 3 fids=[0,4,2,5,8,6,3,1,7] lids=[0,7,2,6,1,3,5,8,4]
-*/
-QPID_AUTO_TEST_CASE(recover_insert)
-{
- string test_name = get_test_name(test_filename, "recover_insert");
- const u_int16_t initial_num_jfiles = 4;
- ::srand48(1); // init random gen for repeatable tests when using
lfmgr_test_helper::prepare_recover()
- try
- {
- jdir::create_dir(test_dir); // Check test dir exists; create it if not
- test_jrnl jc(test_name, test_dir, test_name);
- lid_fid_map lfm(test_name, test_name);
- lfmgr lm;
- lfmgr_test_helper::prepare_recover(lfm, initial_num_jfiles);
- lfmgr_test_helper::recover(lfm, lm, jc, true, 0);
-
- lfmgr_test_helper::insert(lfm, lm, jc, 0);
- lfmgr_test_helper::insert(lfm, lm, jc, 2, 2);
- lfmgr_test_helper::insert(lfm, lm, jc, 6);
- lfmgr_test_helper::insert(lfm, lm, jc, 3);
- }
- catch(const exception& e) { BOOST_FAIL(e.what()); }
- cout << "done" << endl;
-}
-
-/*
-* Check that illegal ae parameter combinations are caught and result in an exception
being thrown.
-*/
-QPID_AUTO_TEST_CASE(ae_parameters)
-{
- string test_name = get_test_name(test_filename, "ae_parameters");
- ::srand48(1); // init random gen for repeatable tests when using
lfmgr_test_helper::prepare_recover()
- try
- {
- jdir::create_dir(test_dir); // Check test dir exists; create it if not
- test_jrnl jc(test_name, test_dir, test_name);
- lid_fid_map lfm(test_name, test_name);
- const u_int16_t num_jfiles = 8;
- lfmgr lm;
-
- for (unsigned i = 0; i < 2; i++)
- {
- if (i)
- lfmgr_test_helper::initialize(lfm, lm, jc, num_jfiles, false, 0);
- else
- {
- lfmgr_test_helper::prepare_recover(lfm, num_jfiles);
- lfmgr_test_helper::recover(lfm, lm, jc, false, 0);
- }
-
- lfmgr_test_helper::check_ae_max_jfiles(lm, num_jfiles, num_jfiles - 2);
- lfmgr_test_helper::check_ae_max_jfiles(lm, num_jfiles, 0);
- lfmgr_test_helper::check_ae_max_jfiles(lm, num_jfiles, 2 * num_jfiles);
- lfmgr_test_helper::check_ae_max_jfiles(lm, num_jfiles, num_jfiles);
- lfm.destroy_journal();
- }
- }
- catch(const exception& e) { BOOST_FAIL(e.what()); }
- cout << "done" << endl;
-}
-
-/*
-* Check that initialized or recovered journals with auto-expand disabled will not allow
either inserts or appends.
-*/
-QPID_AUTO_TEST_CASE(ae_disabled)
-{
- string test_name = get_test_name(test_filename, "ae_disabled");
- ::srand48(1); // init random gen for repeatable tests when using
lfmgr_test_helper::prepare_recover()
- try
- {
- jdir::create_dir(test_dir); // Check test dir exists; create it if not
- test_jrnl jc(test_name, test_dir, test_name);
- lid_fid_map lfm(test_name, test_name);
- lfmgr_test_helper::check_limit(lfm, jc, false, 8, 0);
- }
- catch(const exception& e) { BOOST_FAIL(e.what()); }
- cout << "done" << endl;
-}
-
-/*
-* Check that initialized or recovered journals with auto-expand enabled and a file limit
set will enforce the correct
-* limits on inserts and appends.
-*/
-QPID_AUTO_TEST_CASE(ae_enabled_limit)
-{
- string test_name = get_test_name(test_filename, "ae_enabled_limit");
- ::srand48(1); // init random gen for repeatable tests when using
lfmgr_test_helper::prepare_recover()
- try
- {
- jdir::create_dir(test_dir); // Check test dir exists; create it if not
- test_jrnl jc(test_name, test_dir, test_name);
- lid_fid_map lfm(test_name, test_name);
- lfmgr_test_helper::check_limit(lfm, jc, true, 8, 32);
- }
- catch(const exception& e) { BOOST_FAIL(e.what()); }
- cout << "done" << endl;
-}
-
-/*
-* Check that initialized or recovered journals with auto-expand enabled and no file limit
set (0) will allow inserts and
-* appends up to the file limit JRNL_MAX_NUM_FILES.
-*/
-QPID_AUTO_TEST_CASE(ae_enabled_unlimited)
-{
- string test_name = get_test_name(test_filename, "ae_enabled_unlimited");
- ::srand48(1); // init random gen for repeatable tests when using
lfmgr_test_helper::prepare_recover()
- try
- {
- jdir::create_dir(test_dir); // Check test dir exists; create it if not
- test_jrnl jc(test_name, test_dir, test_name);
- lid_fid_map lfm(test_name, test_name);
- lfmgr_test_helper::check_limit(lfm, jc, true, 8, 0);
- }
- catch(const exception& e) { BOOST_FAIL(e.what()); }
- cout << "done" << endl;
-}
-
-/*
-* Tests randomized combinations of initialization/recovery, initial size, number, size
and location of inserts.
-*
-* To reproduce a specific test, comment out the get_seed() statement and uncomment the
literal below, adjusting the seed
-* value to that required.
-*/
-QPID_AUTO_TEST_CASE(randomized_tests)
-{
- string test_name = get_test_name(test_filename, "randomized_tests");
- const long seed = get_seed();
- // const long seed = 0x2d9b69d32;
- cout << "seed=0x" << hex << seed << dec <<
" " << flush;
- ::srand48(seed);
-
- lid_fid_map lfm(test_name, test_name);
- flist fidl;
- flist lidl;
- rcvdat rd;
- u_int16_t curr_ae_max_jfiles = 0;
- jdir::create_dir(test_dir); // Check test dir exists; create it if not
-
- for (int test_num = 0; test_num < 100; test_num++)
- {
- test_jrnl jc(test_name, test_dir, test_name);
- lfmgr lm;
- // 50% chance of recovery except first run and if there is still ae space left
- const bool recover_flag = test_num > 0 &&
- curr_ae_max_jfiles > lfm.size() &&
- 2.0 * ::drand48() < 1.0;
- if (recover_flag)
- {
- // Recover from previous iteration
- lfm.get_fid_list(fidl);
- lfm.get_lid_list(lidl);
- lfm.write_journal(true, curr_ae_max_jfiles);
- lfmgr_test_helper::rcvdat_init(rd, fidl, true, curr_ae_max_jfiles);
- lm.recover(rd, &jc, &jc.new_fcntl);
- lfmgr_test_helper::check_fids_lids(lm, fidl, lidl);
- }
- else
- {
- // Initialize from scratch
- const u_int16_t num_jfiles = 4 + u_int16_t(21.0 * ::drand48()); // size: 4 -
25 files
- curr_ae_max_jfiles = u_int16_t(4 * num_jfiles * ::drand48()); // size: 0 -
100 files
- if (curr_ae_max_jfiles > JRNL_MAX_NUM_FILES) curr_ae_max_jfiles =
JRNL_MAX_NUM_FILES;
- else if (curr_ae_max_jfiles <= num_jfiles) curr_ae_max_jfiles = 0;
- lfm.destroy_journal();
- lfm.journal_create(num_jfiles, num_jfiles);
- lfm.get_fid_list(fidl);
- lfm.get_lid_list(lidl);
- lm.initialize(num_jfiles, true, curr_ae_max_jfiles, &jc,
&jc.new_fcntl);
- lfmgr_test_helper::check_linear_fids_lids(lm, num_jfiles);
- }
-
- // Loop to insert fids
- const int num_inserts = 1 + int(lfm.size() * ::drand48());
- for (int i = 0; i < num_inserts; i++)
- {
- const u_int16_t size = lm.num_jfiles();
- const u_int16_t after_lid = u_int16_t(1.0 * size * ::drand48());
- const u_int16_t num_jfiles = 1 + u_int16_t(4.0 * ::drand48());
- const bool legal = lm.ae_max_jfiles()
- ? size + num_jfiles <= lm.ae_max_jfiles()
- : size + num_jfiles <= JRNL_MAX_NUM_FILES;
- if (legal)
- {
- lfm.journal_insert(after_lid, num_jfiles);
- lfm.get_fid_list(fidl);
- lfm.get_lid_list(lidl);
-
- lm.insert(after_lid, &jc, &jc.new_fcntl, num_jfiles);
- lfmgr_test_helper::check_fids_lids(lm, fidl, lidl);
- }
- else
- {
- try
- {
- lm.insert(after_lid, &jc, &jc.new_fcntl, num_jfiles);
- BOOST_FAIL("lfmgr::insert() succeeded and exceeded
limit");
- }
- catch (const jexception& e)
- {
- BOOST_CHECK_EQUAL(e.err_code(), jerrno::JERR_LFMGR_AEFNUMLIMIT);
- break; // no more inserts...
- }
- }
- }
- lm.finalize();
- BOOST_CHECK_EQUAL(lm.is_init(), false);
- BOOST_CHECK_EQUAL(lm.num_jfiles(), u_int16_t(0));
- BOOST_CHECK_EQUAL(lm.get_fcntlp(0), (void*)0);
- }
- cout << "done" << endl;
-}
-
-QPID_AUTO_TEST_SUITE_END()
Copied: store/trunk/cpp/tests/jrnl/_ut_lpmgr.cpp (from rev 3043,
store/trunk/cpp/tests/jrnl/_ut_lfmgr.cpp)
===================================================================
--- store/trunk/cpp/tests/jrnl/_ut_lpmgr.cpp (rev 0)
+++ store/trunk/cpp/tests/jrnl/_ut_lpmgr.cpp 2009-01-15 15:57:43 UTC (rev 3045)
@@ -0,0 +1,857 @@
+/**
+* \file _ut_lfmgr.cpp
+*
+* Red Hat Messaging - Message Journal
+*
+* This file contains the unit tests for the journal.
+*
+* Copyright 2007, 2008 Red Hat, Inc.
+*
+* This file is part of Red Hat Messaging.
+*
+* Red Hat Messaging is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+* USA
+*
+* The GNU Lesser General Public License is available in the file COPYING.
+*/
+
+#include "../unit_test.h"
+#include <cmath>
+#include <iostream>
+#include "jrnl/jcntl.hpp"
+#include "jrnl/lpmgr.hpp"
+
+using namespace boost::unit_test;
+using namespace mrg::journal;
+using namespace std;
+
+QPID_AUTO_TEST_SUITE(arr_cnt_suite)
+
+const string test_filename("_ut_lpmgr");
+
+#include "_st_helper_fns.hpp"
+
+// === Helper functions and definitions ===
+
+typedef vector<u_int16_t> flist;
+typedef flist::const_iterator flist_citr;
+
+class lpmgr_test_helper
+{
+ lpmgr_test_helper() {}
+ virtual ~lpmgr_test_helper() {}
+
+public:
+ static void check_pfids_lfids(const lpmgr& lm, const u_int16_t pfids[], const
u_int16_t lfids[],
+ const size_t pfid_lfid_size)
+ {
+ vector<u_int16_t> res;
+ lm.get_pfid_list(res);
+ vectors_equal(lm, pfids, pfid_lfid_size, res, true);
+ lm.get_lfid_list(res);
+ vectors_equal(lm, lfids, pfid_lfid_size, res, false);
+ }
+
+ static void check_pfids_lfids(const lpmgr& lm, const flist& pfids, const
flist lfids)
+ {
+ vector<u_int16_t> res;
+ lm.get_pfid_list(res);
+ vectors_equal(lm, pfids, res, true);
+ lm.get_lfid_list(res);
+ vectors_equal(lm, lfids, res, false);
+ }
+
+ static void check_linear_pfids_lfids(const lpmgr& lm, const size_t
pfid_lfid_size)
+ {
+ vector<u_int16_t> res;
+ lm.get_pfid_list(res);
+ linear_vectors_equal(lm, pfid_lfid_size, res, true);
+ lm.get_lfid_list(res);
+ linear_vectors_equal(lm, pfid_lfid_size, res, false);
+ }
+
+ static void rcvdat_init(rcvdat& rd, const u_int16_t num_jfiles, const bool ae,
const u_int16_t ae_max_jfiles,
+ const u_int16_t pfids[])
+ {
+ rd.reset(num_jfiles, ae, ae_max_jfiles);
+ load_vector(pfids, num_jfiles, rd._fid_list);
+ rd._jempty = false;
+ rd._lfid = pfids[num_jfiles - 1];
+ rd._eo = 100 * JRNL_DBLK_SIZE * JRNL_SBLK_SIZE;
+ }
+
+ static void rcvdat_init(rcvdat& rd, const flist& pfidl, const bool ae, const
u_int16_t ae_max_jfiles)
+ {
+ const u_int16_t num_jfiles = pfidl.size();
+ rd.reset(num_jfiles, ae, ae_max_jfiles);
+ load_vector(pfidl, rd._fid_list);
+ rd._jempty = false;
+ rd._lfid = pfidl[num_jfiles - 1];
+ rd._eo = 100 * JRNL_DBLK_SIZE * JRNL_SBLK_SIZE;
+ }
+
+ static void initialize(lpmgr& lm, test_jrnl& jc, const u_int16_t num_jfiles,
const bool ae,
+ const u_int16_t ae_max_jfiles)
+ {
+ lm.initialize(num_jfiles, ae, ae_max_jfiles, &jc, &jc.new_fcntl);
+ BOOST_CHECK_EQUAL(lm.is_init(), true);
+ BOOST_CHECK_EQUAL(lm.is_ae(), ae);
+ BOOST_CHECK_EQUAL(lm.ae_max_jfiles(), ae_max_jfiles);
+ BOOST_CHECK_EQUAL(lm.num_jfiles(), num_jfiles);
+ if (num_jfiles)
+ check_linear_pfids_lfids(lm, num_jfiles);
+ else
+ BOOST_CHECK_EQUAL(lm.get_fcntlp(0), (void*)0);
+ }
+
+ // version which sets up the lfid_pfid_map for later manipulation by insert tests
+ static void initialize(lfid_pfid_map& lfm, lpmgr& lm, test_jrnl& jc,
const u_int16_t num_jfiles, const bool ae,
+ const u_int16_t ae_max_jfiles)
+ {
+ lfm.journal_create(num_jfiles, num_jfiles);
+ initialize(lm, jc, num_jfiles, ae, ae_max_jfiles);
+ }
+
+ static void prepare_recover(lfid_pfid_map& lfm, const u_int16_t size)
+ {
+ if (size < 4) BOOST_FAIL("prepare_recover(): size parameter ("
<< size << ") too small.");
+ lfm.journal_create(4, 4); // initial journal of size 4
+ u_int16_t s = 4; // cumulative size
+ while (s < size)
+ {
+ const u_int16_t ins_posn = u_int16_t(s * ::drand48()); // this insert posn
+ if (3.0 * ::drand48() > 1.0 || size - s < 2) // 2:1 chance of single
insert when >= 2 still to insert
+ {
+ lfm.journal_insert(ins_posn); // single insert
+ s++;
+ }
+ else
+ {
+ // multiple insert, either 2 - 5
+ const u_int16_t max_ins_size = size - s >5 ? 5 : size - s;
+ const u_int16_t ins_size = 2 + u_int16_t((max_ins_size - 2) *
::drand48()); // this insert size
+ lfm.journal_insert(ins_posn, ins_size);
+ s += ins_size;
+ }
+ }
+ }
+
+ static void recover(lfid_pfid_map& lfm, lpmgr& lm, test_jrnl& jc, const
bool ae, const u_int16_t ae_max_jfiles)
+ {
+ flist pfidl;
+ flist lfidl;
+ rcvdat rd;
+ const u_int16_t num_jfiles = lfm.size();
+
+ lfm.get_pfid_list(pfidl);
+ lfm.get_lfid_list(lfidl);
+ lfm.write_journal(ae, ae_max_jfiles);
+
+ lpmgr_test_helper::rcvdat_init(rd, pfidl, ae, ae_max_jfiles);
+ lm.recover(rd, &jc, &jc.new_fcntl);
+ BOOST_CHECK_EQUAL(lm.is_init(), true);
+ BOOST_CHECK_EQUAL(lm.is_ae(), ae);
+ BOOST_CHECK_EQUAL(lm.ae_max_jfiles(), ae_max_jfiles);
+ BOOST_CHECK_EQUAL(lm.num_jfiles(), num_jfiles);
+ if (num_jfiles)
+ check_pfids_lfids(lm, pfidl, lfidl);
+ else
+ BOOST_CHECK_EQUAL(lm.get_fcntlp(0), (void*)0);
+ }
+
+ static void finalize(lpmgr& lm)
+ {
+ lm.finalize();
+ BOOST_CHECK_EQUAL(lm.is_init(), false);
+ BOOST_CHECK_EQUAL(lm.is_ae(), false);
+ BOOST_CHECK_EQUAL(lm.ae_max_jfiles(), u_int16_t(0));
+ BOOST_CHECK_EQUAL(lm.num_jfiles(), u_int16_t(0));
+ BOOST_CHECK_EQUAL(lm.get_fcntlp(0), (void*)0);
+ vector<u_int16_t> res;
+ lm.get_pfid_list(res);
+ BOOST_CHECK_EQUAL(res.size(), u_int16_t(0));
+ lm.get_lfid_list(res);
+ BOOST_CHECK_EQUAL(res.size(), u_int16_t(0));
+ }
+
+ static void insert(lfid_pfid_map& lfm, lpmgr& lm, test_jrnl& jc, const
u_int16_t after_lid, const u_int16_t incr = 1)
+ {
+ flist pfidl;
+ flist lfidl;
+ const u_int16_t num_jfiles = lm.num_jfiles();
+ lfm.journal_insert(after_lid, incr);
+ lfm.get_pfid_list(pfidl);
+ lfm.get_lfid_list(lfidl);
+ lm.insert(after_lid, &jc, &jc.new_fcntl, incr);
+ BOOST_CHECK_EQUAL(lm.num_jfiles(), num_jfiles + incr);
+ lpmgr_test_helper::check_pfids_lfids(lm, pfidl, lfidl);
+ }
+
+ static void check_ae_max_jfiles(lpmgr& lm, const u_int16_t num_jfiles, const
u_int16_t ae_max_jfiles)
+ {
+ bool legal = ae_max_jfiles > num_jfiles || ae_max_jfiles == 0;
+
+ lm.set_ae(false);
+ BOOST_CHECK(!lm.is_ae());
+ if (legal)
+ {
+ lm.set_ae_max_jfiles(ae_max_jfiles);
+ BOOST_CHECK_EQUAL(lm.ae_max_jfiles(), ae_max_jfiles);
+ lm.set_ae(true);
+ BOOST_CHECK(lm.is_ae());
+ BOOST_CHECK_EQUAL(lm.ae_jfiles_rem(), ae_max_jfiles
+ ? ae_max_jfiles - num_jfiles
+ : JRNL_MAX_NUM_FILES - num_jfiles);
+ }
+ else
+ {
+ lm.set_ae_max_jfiles(ae_max_jfiles);
+ BOOST_CHECK_EQUAL(lm.ae_max_jfiles(), ae_max_jfiles);
+ try
+ {
+ lm.set_ae(true); // should raise exception
+ BOOST_ERROR("Auto-expand enabled with out-of-range
ae_max_jfiles");
+ }
+ catch (const jexception& e) { BOOST_CHECK_EQUAL(e.err_code(),
jerrno::JERR_LFMGR_BADAEFNUMLIM); }
+ BOOST_CHECK(!lm.is_ae());
+ BOOST_CHECK_EQUAL(lm.ae_jfiles_rem(), 0);
+ }
+ BOOST_CHECK_EQUAL(lm.ae_max_jfiles(), ae_max_jfiles);
+ }
+
+ static void check_multiple_initialization_recover(lfid_pfid_map& lfm,
test_jrnl& jc,
+ const u_int16_t num_jfiles_arr[][2], const bool init_flag_0, const bool
finalize_flag,
+ const bool init_flag_1)
+ {
+ unsigned i_njf = 0;
+ while (num_jfiles_arr[i_njf][0] && num_jfiles_arr[i_njf][1])
+ {
+ for (unsigned i1_njf = 0; i1_njf <= 1; i1_njf++)
+ {
+ const u_int16_t num_jfiles_0 = num_jfiles_arr[i_njf][i1_njf == 0];
+ const u_int16_t num_jfiles_1 = num_jfiles_arr[i_njf][i1_njf != 0];
+
+ for (unsigned i_ae = 0; i_ae < 4; i_ae++)
+ {
+ const bool ae_0 = i_ae & 0x1;
+ const bool ae_1 = i_ae & 0x2;
+ for (unsigned i_aemjf = 0; i_aemjf < 4; i_aemjf++)
+ {
+ const u_int16_t ae_max_jfiles_0 = i_aemjf & 0x1 ? 3 *
num_jfiles_0 : 0;
+ const u_int16_t ae_max_jfiles_1 = i_aemjf & 0x2 ? 4 *
num_jfiles_1 : 0;
+
+ lpmgr lm;
+
+ if (init_flag_0)
+ initialize(lm, jc, num_jfiles_0, ae_0, ae_max_jfiles_0);
+ else
+ {
+ prepare_recover(lfm, num_jfiles_0);
+ recover(lfm, lm, jc, ae_1, ae_max_jfiles_0);
+ lfm.destroy_journal();
+ }
+
+ if (finalize_flag) finalize(lm);
+
+ if (init_flag_1)
+ initialize(lm, jc, num_jfiles_1, ae_1, ae_max_jfiles_1);
+ else
+ {
+ prepare_recover(lfm, num_jfiles_1);
+ recover(lfm, lm, jc, ae_1, ae_max_jfiles_1);
+ lfm.destroy_journal();
+ }
+ }
+ }
+ }
+ i_njf++;
+ }
+ }
+
+ static void check_insert(lfid_pfid_map& lfm, lpmgr& lm, test_jrnl& jc,
const u_int16_t after_lid,
+ const u_int16_t incr = 1)
+ {
+ const u_int16_t num_jfiles = lm.num_jfiles();
+ const u_int16_t ae_max_jfiles = lm.ae_max_jfiles();
+ const u_int16_t effective_ae_max_jfiles = ae_max_jfiles ? ae_max_jfiles :
JRNL_MAX_NUM_FILES;
+ BOOST_CHECK_EQUAL(lm.ae_jfiles_rem(), effective_ae_max_jfiles - num_jfiles);
+ bool legal = lm.is_ae() && num_jfiles + incr <=
effective_ae_max_jfiles;
+ if (legal)
+ {
+ insert(lfm, lm, jc, after_lid, incr);
+ BOOST_CHECK_EQUAL(lm.num_jfiles(), num_jfiles + incr);
+ BOOST_CHECK_EQUAL(lm.ae_jfiles_rem(), effective_ae_max_jfiles - num_jfiles -
incr);
+ }
+ else
+ {
+ try
+ {
+ insert(lfm, lm, jc, after_lid, incr);
+ if (lm.is_ae())
+ BOOST_ERROR("lpmgr::insert() succeeded and exceeded
limit");
+ else
+ BOOST_ERROR("lpmgr::insert() succeeded with auto-expand
disabled");
+ }
+ catch (const jexception& e)
+ {
+ if (lm.is_ae())
+ BOOST_CHECK_EQUAL(e.err_code(), jerrno::JERR_LFMGR_AEFNUMLIMIT);
+ else
+ BOOST_CHECK_EQUAL(e.err_code(), jerrno::JERR_LFMGR_AEDISABLED);
+ }
+ BOOST_CHECK_EQUAL(lm.num_jfiles(), num_jfiles);
+ BOOST_CHECK_EQUAL(lm.ae_jfiles_rem(), effective_ae_max_jfiles - num_jfiles);
+ }
+ }
+
+ static void check_limit(lfid_pfid_map& lfm, test_jrnl& jc, const bool ae,
const u_int16_t num_jfiles,
+ const u_int16_t ae_max_jfiles)
+ {
+ lpmgr lm;
+
+ for (unsigned i = 0; i < 2; i++)
+ {
+ if (i)
+ initialize(lfm, lm, jc, num_jfiles, ae, ae_max_jfiles);
+ else
+ {
+ prepare_recover(lfm, num_jfiles);
+ recover(lfm, lm, jc, ae, ae_max_jfiles);
+ }
+
+ // use up all available files
+ unsigned j = ae_max_jfiles ? ae_max_jfiles : JRNL_MAX_NUM_FILES;
+ while (ae && j > num_jfiles)
+ {
+ const u_int16_t posn = static_cast<u_int16_t>((lm.num_jfiles() - 1)
* ::drand48());
+ const u_int16_t incr = 1 +
static_cast<u_int16_t>((lm.ae_jfiles_rem() > 4
+ ? 3 : lm.ae_jfiles_rem() - 1) * ::drand48());
+ check_insert(lfm, lm, jc, posn, incr);
+ j -= incr;
+ }
+ // these should be over the limit or illegal
+ check_insert(lfm, lm, jc, 0);
+ check_insert(lfm, lm, jc, 2, 2);
+ lfm.destroy_journal();
+ }
+ }
+
+private:
+ static void load_vector(const u_int16_t a[], const size_t n, flist& v)
+ {
+ for (size_t i = 0; i < n; i++)
+ v.push_back(a[i]);
+ }
+
+ static void load_vector(const flist& a, flist& b)
+ {
+ for (flist_citr i = a.begin(); i < a.end(); i++)
+ b.push_back(*i);
+ }
+
+ static void vectors_equal(const lpmgr& lm, const u_int16_t a[], const size_t n,
const flist& b,
+ const bool pfid_check)
+ {
+ BOOST_CHECK_EQUAL(n, b.size());
+ for (size_t i = 0; i < n; i++)
+ {
+ BOOST_CHECK_EQUAL(a[i], b[i]);
+ fcntl* fp = lm.get_fcntlp(i);
+ BOOST_CHECK_MESSAGE(fp != (void*)0, "Unexpected void pointer returned by
lpmgr::get_fcntlp()");
+ if (fp) BOOST_CHECK_EQUAL(pfid_check ? fp->fid() : fp->lid(),
pfid_check ? a[i] : i);
+ }
+ }
+
+ static void vectors_equal(const lpmgr& lm, const flist& a, const flist&
b, const bool pfid_check)
+ {
+ BOOST_CHECK_EQUAL(a.size(), b.size());
+ for (size_t i = 0; i < a.size(); i++)
+ {
+ BOOST_CHECK_EQUAL(a[i], b[i]);
+ fcntl* fp = lm.get_fcntlp(i);
+ BOOST_CHECK_MESSAGE(fp != (void*)0, "Unexpected void pointer returned by
lpmgr::get_fcntlp()");
+ if (fp) BOOST_CHECK_EQUAL(pfid_check ? fp->fid() : fp->lid(),
pfid_check ? a[i] : i);
+ }
+ }
+
+ static void linear_vectors_equal(const lpmgr& lm, const size_t n, const
flist& f, const bool pfid_check)
+ {
+ BOOST_CHECK_EQUAL(n, f.size());
+ for (size_t i = 0; i < n; i++)
+ {
+ BOOST_CHECK_EQUAL(i, f[i]);
+ fcntl* fp = lm.get_fcntlp(i);
+ BOOST_CHECK_MESSAGE(fp != (void*)0, "Unexpected void pointer returned by
lpmgr::get_fcntlp()");
+ if (fp) BOOST_CHECK_EQUAL(pfid_check ? fp->fid() : fp->lid(), i);
+ }
+ }
+};
+
+// === Tests ===
+
+/*
+* Check that after construction, the fcntl array _fcntl_arr is empty and the is_init()
function returns false.
+*/
+QPID_AUTO_TEST_CASE(default_constructor)
+{
+ string test_name = get_test_name(test_filename, "default_constructor");
+ try
+ {
+ lpmgr lm;
+ BOOST_CHECK_EQUAL(lm.is_init(), false);
+ BOOST_CHECK_EQUAL(lm.is_ae(), false);
+ BOOST_CHECK_EQUAL(lm.ae_max_jfiles(), u_int16_t(0));
+ BOOST_CHECK_EQUAL(lm.num_jfiles(), u_int16_t(0));
+ BOOST_CHECK_EQUAL(lm.get_fcntlp(0), (void*)0);
+ }
+ catch(const exception& e) { BOOST_FAIL(e.what()); }
+ cout << "done" << endl;
+}
+
+/*
+* Check that initialize() correctly creates an ordered fcntl array _fcntl_arr.
+*/
+QPID_AUTO_TEST_CASE(initialize)
+{
+ string test_name = get_test_name(test_filename, "initialize");
+ const u_int16_t num_jfiles = 8;
+ try
+ {
+ jdir::create_dir(test_dir); // Check test dir exists; create it if not
+ test_jrnl jc(test_name, test_dir, test_name);
+ {
+ lpmgr lm;
+ lpmgr_test_helper::initialize(lm, jc, num_jfiles, false, 0);
+ }
+ {
+ lpmgr lm;
+ lpmgr_test_helper::initialize(lm, jc, num_jfiles, true, 0);
+ }
+ {
+ lpmgr lm;
+ lpmgr_test_helper::initialize(lm, jc, num_jfiles, true, 5 * num_jfiles);
+ }
+ }
+ catch(const exception& e) { BOOST_FAIL(e.what()); }
+ cout << "done" << endl;
+}
+
+/*
+* Check that recover() correctly sets up the specified pfid list order.
+*/
+QPID_AUTO_TEST_CASE(recover)
+{
+ string test_name = get_test_name(test_filename, "recover");
+ ::srand48(1); // init random gen for repeatable tests when using
lpmgr_test_helper::prepare_recover()
+ try
+ {
+ test_jrnl jc(test_name, test_dir, test_name);
+ lfid_pfid_map lfm(test_name, test_name);
+
+ {
+ lpmgr lm;
+ lpmgr_test_helper::prepare_recover(lfm, 8);
+ lpmgr_test_helper::recover(lfm, lm, jc, false, 0);
+ lfm.destroy_journal();
+ }
+ {
+ lpmgr lm;
+ lpmgr_test_helper::prepare_recover(lfm, 8);
+ lpmgr_test_helper::recover(lfm, lm, jc, true, 0);
+ lfm.destroy_journal();
+ }
+ {
+ lpmgr lm;
+ lpmgr_test_helper::prepare_recover(lfm, 8);
+ lpmgr_test_helper::recover(lfm, lm, jc, true, 5 * lfm.size());
+ lfm.destroy_journal();
+ }
+ }
+ catch(const exception& e) { BOOST_FAIL(e.what()); }
+ cout << "done" << endl;
+}
+
+/*
+* Check that finalize() after an initialize() empties _fcntl_arr and that afterwards
is_init() returns false.
+*/
+QPID_AUTO_TEST_CASE(initialize_finalize)
+{
+ string test_name = get_test_name(test_filename, "initialize_finalize");
+ const u_int16_t num_jfiles = 8;
+ try
+ {
+ jdir::create_dir(test_dir); // Check test dir exists; create it if not
+ test_jrnl jc(test_name, test_dir, test_name);
+ {
+ lpmgr lm;
+ lpmgr_test_helper::initialize(lm, jc, num_jfiles, false, 0);
+ lpmgr_test_helper::finalize(lm);
+ }
+ {
+ lpmgr lm;
+ lpmgr_test_helper::initialize(lm, jc, num_jfiles, true, 0);
+ lpmgr_test_helper::finalize(lm);
+ }
+ {
+ lpmgr lm;
+ lpmgr_test_helper::initialize(lm, jc, num_jfiles, true, 5 * num_jfiles);
+ lpmgr_test_helper::finalize(lm);
+ }
+ }
+ catch(const exception& e) { BOOST_FAIL(e.what()); }
+ cout << "done" << endl;
+}
+
+/*
+* Check that finalize() after a recover() empties _fcntl_arr and that afterwards
is_init() returns false.
+*/
+QPID_AUTO_TEST_CASE(recover_finalize)
+{
+ string test_name = get_test_name(test_filename, "recover_finalize");
+ const u_int16_t num_jfiles = 8;
+ ::srand48(1); // init random gen for repeatable tests when using
lpmgr_test_helper::prepare_recover()
+ try
+ {
+ test_jrnl jc(test_name, test_dir, test_name);
+ lfid_pfid_map lfm(test_name, test_name);
+
+ {
+ lpmgr lm;
+ lpmgr_test_helper::prepare_recover(lfm, num_jfiles);
+ lpmgr_test_helper::recover(lfm, lm, jc, false, 0);
+ lpmgr_test_helper::finalize(lm);
+ lfm.destroy_journal();
+ }
+ {
+ lpmgr lm;
+ lpmgr_test_helper::prepare_recover(lfm, num_jfiles);
+ lpmgr_test_helper::recover(lfm, lm, jc, true, 0);
+ lpmgr_test_helper::finalize(lm);
+ lfm.destroy_journal();
+ }
+ {
+ lpmgr lm;
+ lpmgr_test_helper::prepare_recover(lfm, num_jfiles);
+ lpmgr_test_helper::recover(lfm, lm, jc, true, 5 * lfm.size());
+ lpmgr_test_helper::finalize(lm);
+ lfm.destroy_journal();
+ }
+ }
+ catch(const exception& e) { BOOST_FAIL(e.what()); }
+ cout << "done" << endl;
+}
+
+/*
+* Check that 0 and/or null and other extreme/boundary parameters behave as expected.
+*/
+QPID_AUTO_TEST_CASE(zero_null_params)
+{
+ string test_name = get_test_name(test_filename, "zero_null_params");
+ const u_int16_t num_jfiles = 8;
+ try
+ {
+ test_jrnl jc(test_name, test_dir, test_name);
+ lfid_pfid_map lfm(test_name, test_name);
+ lpmgr lm;
+ lpmgr_test_helper::initialize(lfm, lm, jc, num_jfiles, true, 0);
+
+ // Check that inserting 0 files works ok
+ lpmgr_test_helper::insert(lfm, lm, jc, 0, 0);
+ lpmgr_test_helper::insert(lfm, lm, jc, 2, 0);
+ lpmgr_test_helper::insert(lfm, lm, jc, num_jfiles - 1, 0);
+ }
+ catch(const exception& e) { BOOST_FAIL(e.what()); }
+ cout << "done" << endl;
+}
+
+/*
+* Check that initialize()/recover() works correctly after a previous
initialize()/recover() with/without an intervening
+* finalize().
+*/
+QPID_AUTO_TEST_CASE(multiple_initialization_recover)
+{
+ string test_name = get_test_name(test_filename,
"multiple_initialization_recover");
+ ::srand48(1); // init random gen for repeatable tests when using
lpmgr_test_helper::prepare_recover()
+
+ // Set combinations of value pairs to be used for number of journal files in first
and second init
+ u_int16_t num_jfiles_arr[][2] = {{8, 12}, {4, 7}, {0, 0}}; // end with zeros
+ try
+ {
+ test_jrnl jc(test_name, test_dir, test_name);
+ lfid_pfid_map lfm(test_name, test_name);
+ for (unsigned p = 0; p < 8; p++)
+ {
+ const bool i_0 = p & 0x01; // first bit
+ const bool i_1 = p & 0x02; // second bit
+ const bool f = p & 0x04; // third bit
+ lpmgr_test_helper::check_multiple_initialization_recover(lfm, jc,
num_jfiles_arr, i_0,f, i_1);
+ }
+ }
+ catch(const exception& e) { BOOST_FAIL(e.what()); }
+ cout << "done" << endl;
+}
+
+/*
+* Check that insert() works correctly after initialize() and shifts the pfid sequence
beyond the insert point correctly:
+*
+* The following sequence is tested:
+* initialize 4 pfids=[0,1,2,3] lfids=[0,1,2,3]
+* insert 1 after lid 0 pfids=[0,4,1,2,3] lfids=[0,2,3,4,1]
+* insert 2 after lid 2 pfids=[0,4,1,5,6,2,3] lfids=[0,2,5,6,1,3,4]
+* insert 1 after lid 6 pfids=[0,4,1,5,6,2,3,7] lfids=[0,2,5,6,1,3,4,7]
+* issert 1 after lid 3 pfids=[0,4,1,5,8,6,2,3,7] lfids=[0,2,6,7,1,3,5,8,4]
+*/
+QPID_AUTO_TEST_CASE(initialize_insert)
+{
+ string test_name = get_test_name(test_filename, "initialize_insert");
+ const u_int16_t initial_num_jfiles = 8;
+ try
+ {
+ jdir::create_dir(test_dir); // Check test dir exists; create it if not
+ test_jrnl jc(test_name, test_dir, test_name);
+ lfid_pfid_map lfm(test_name, test_name);
+ lpmgr lm;
+ lpmgr_test_helper::initialize(lfm, lm, jc, initial_num_jfiles, true, 0);
+
+ lpmgr_test_helper::insert(lfm, lm, jc, 0);
+ lpmgr_test_helper::insert(lfm, lm, jc, 2, 2);
+ lpmgr_test_helper::insert(lfm, lm, jc, 6);
+ lpmgr_test_helper::insert(lfm, lm, jc, 3);
+ }
+ catch(const exception& e) { BOOST_FAIL(e.what()); }
+ cout << "done" << endl;
+}
+
+/*
+* Check that insert() works correctly after recover() and shifts the pfid sequence beyond
the insert point correctly:
+*
+* The following sequence is tested:
+* recover 4 pfids=[0,2,3,1] lfids=[0,3,1,2]
+* insert 1 after lid 0 pfids=[0,4,2,3,1] lfids=[0,4,2,3,1]
+* insert 2 after lid 2 pfids=[0,4,2,5,6,3,1] lfids=[0,6,2,5,1,3,4]
+* insert 1 after lid 6 pfids=[0,4,2,5,6,3,1,7] lfids=[0,6,2,5,1,3,4,7]
+* issert 1 after lid 3 pfids=[0,4,2,5,8,6,3,1,7] lfids=[0,7,2,6,1,3,5,8,4]
+*/
+QPID_AUTO_TEST_CASE(recover_insert)
+{
+ string test_name = get_test_name(test_filename, "recover_insert");
+ const u_int16_t initial_num_jfiles = 4;
+ ::srand48(1); // init random gen for repeatable tests when using
lpmgr_test_helper::prepare_recover()
+ try
+ {
+ jdir::create_dir(test_dir); // Check test dir exists; create it if not
+ test_jrnl jc(test_name, test_dir, test_name);
+ lfid_pfid_map lfm(test_name, test_name);
+ lpmgr lm;
+ lpmgr_test_helper::prepare_recover(lfm, initial_num_jfiles);
+ lpmgr_test_helper::recover(lfm, lm, jc, true, 0);
+
+ lpmgr_test_helper::insert(lfm, lm, jc, 0);
+ lpmgr_test_helper::insert(lfm, lm, jc, 2, 2);
+ lpmgr_test_helper::insert(lfm, lm, jc, 6);
+ lpmgr_test_helper::insert(lfm, lm, jc, 3);
+ }
+ catch(const exception& e) { BOOST_FAIL(e.what()); }
+ cout << "done" << endl;
+}
+
+/*
+* Check that illegal ae parameter combinations are caught and result in an exception
being thrown.
+*/
+QPID_AUTO_TEST_CASE(ae_parameters)
+{
+ string test_name = get_test_name(test_filename, "ae_parameters");
+ ::srand48(1); // init random gen for repeatable tests when using
lpmgr_test_helper::prepare_recover()
+ try
+ {
+ jdir::create_dir(test_dir); // Check test dir exists; create it if not
+ test_jrnl jc(test_name, test_dir, test_name);
+ lfid_pfid_map lfm(test_name, test_name);
+ const u_int16_t num_jfiles = 8;
+ lpmgr lm;
+
+ for (unsigned i = 0; i < 2; i++)
+ {
+ if (i)
+ lpmgr_test_helper::initialize(lfm, lm, jc, num_jfiles, false, 0);
+ else
+ {
+ lpmgr_test_helper::prepare_recover(lfm, num_jfiles);
+ lpmgr_test_helper::recover(lfm, lm, jc, false, 0);
+ }
+
+ lpmgr_test_helper::check_ae_max_jfiles(lm, num_jfiles, num_jfiles - 2);
+ lpmgr_test_helper::check_ae_max_jfiles(lm, num_jfiles, 0);
+ lpmgr_test_helper::check_ae_max_jfiles(lm, num_jfiles, 2 * num_jfiles);
+ lpmgr_test_helper::check_ae_max_jfiles(lm, num_jfiles, num_jfiles);
+ lfm.destroy_journal();
+ }
+ }
+ catch(const exception& e) { BOOST_FAIL(e.what()); }
+ cout << "done" << endl;
+}
+
+/*
+* Check that initialized or recovered journals with auto-expand disabled will not allow
either inserts or appends.
+*/
+QPID_AUTO_TEST_CASE(ae_disabled)
+{
+ string test_name = get_test_name(test_filename, "ae_disabled");
+ ::srand48(1); // init random gen for repeatable tests when using
lpmgr_test_helper::prepare_recover()
+ try
+ {
+ jdir::create_dir(test_dir); // Check test dir exists; create it if not
+ test_jrnl jc(test_name, test_dir, test_name);
+ lfid_pfid_map lfm(test_name, test_name);
+ lpmgr_test_helper::check_limit(lfm, jc, false, 8, 0);
+ }
+ catch(const exception& e) { BOOST_FAIL(e.what()); }
+ cout << "done" << endl;
+}
+
+/*
+* Check that initialized or recovered journals with auto-expand enabled and a file limit
set will enforce the correct
+* limits on inserts and appends.
+*/
+QPID_AUTO_TEST_CASE(ae_enabled_limit)
+{
+ string test_name = get_test_name(test_filename, "ae_enabled_limit");
+ ::srand48(1); // init random gen for repeatable tests when using
lpmgr_test_helper::prepare_recover()
+ try
+ {
+ jdir::create_dir(test_dir); // Check test dir exists; create it if not
+ test_jrnl jc(test_name, test_dir, test_name);
+ lfid_pfid_map lfm(test_name, test_name);
+ lpmgr_test_helper::check_limit(lfm, jc, true, 8, 32);
+ }
+ catch(const exception& e) { BOOST_FAIL(e.what()); }
+ cout << "done" << endl;
+}
+
+/*
+* Check that initialized or recovered journals with auto-expand enabled and no file limit
set (0) will allow inserts and
+* appends up to the file limit JRNL_MAX_NUM_FILES.
+*/
+QPID_AUTO_TEST_CASE(ae_enabled_unlimited)
+{
+ string test_name = get_test_name(test_filename, "ae_enabled_unlimited");
+ ::srand48(1); // init random gen for repeatable tests when using
lpmgr_test_helper::prepare_recover()
+ try
+ {
+ jdir::create_dir(test_dir); // Check test dir exists; create it if not
+ test_jrnl jc(test_name, test_dir, test_name);
+ lfid_pfid_map lfm(test_name, test_name);
+ lpmgr_test_helper::check_limit(lfm, jc, true, 8, 0);
+ }
+ catch(const exception& e) { BOOST_FAIL(e.what()); }
+ cout << "done" << endl;
+}
+
+/*
+* Tests randomized combinations of initialization/recovery, initial size, number, size
and location of inserts.
+*
+* To reproduce a specific test, comment out the get_seed() statement and uncomment the
literal below, adjusting the seed
+* value to that required.
+*/
+QPID_AUTO_TEST_CASE(randomized_tests)
+{
+ string test_name = get_test_name(test_filename, "randomized_tests");
+ const long seed = get_seed();
+ // const long seed = 0x2d9b69d32;
+ cout << "seed=0x" << hex << seed << dec <<
" " << flush;
+ ::srand48(seed);
+
+ lfid_pfid_map lfm(test_name, test_name);
+ flist pfidl;
+ flist lfidl;
+ rcvdat rd;
+ u_int16_t curr_ae_max_jfiles = 0;
+ jdir::create_dir(test_dir); // Check test dir exists; create it if not
+
+ for (int test_num = 0; test_num < 100; test_num++)
+ {
+ test_jrnl jc(test_name, test_dir, test_name);
+ lpmgr lm;
+ // 50% chance of recovery except first run and if there is still ae space left
+ const bool recover_flag = test_num > 0 &&
+ curr_ae_max_jfiles > lfm.size() &&
+ 2.0 * ::drand48() < 1.0;
+ if (recover_flag)
+ {
+ // Recover from previous iteration
+ lfm.get_pfid_list(pfidl);
+ lfm.get_lfid_list(lfidl);
+ lfm.write_journal(true, curr_ae_max_jfiles);
+ lpmgr_test_helper::rcvdat_init(rd, pfidl, true, curr_ae_max_jfiles);
+ lm.recover(rd, &jc, &jc.new_fcntl);
+ lpmgr_test_helper::check_pfids_lfids(lm, pfidl, lfidl);
+ }
+ else
+ {
+ // Initialize from scratch
+ const u_int16_t num_jfiles = 4 + u_int16_t(21.0 * ::drand48()); // size: 4 -
25 files
+ curr_ae_max_jfiles = u_int16_t(4 * num_jfiles * ::drand48()); // size: 0 -
100 files
+ if (curr_ae_max_jfiles > JRNL_MAX_NUM_FILES) curr_ae_max_jfiles =
JRNL_MAX_NUM_FILES;
+ else if (curr_ae_max_jfiles <= num_jfiles) curr_ae_max_jfiles = 0;
+ lfm.destroy_journal();
+ lfm.journal_create(num_jfiles, num_jfiles);
+ lfm.get_pfid_list(pfidl);
+ lfm.get_lfid_list(lfidl);
+ lm.initialize(num_jfiles, true, curr_ae_max_jfiles, &jc,
&jc.new_fcntl);
+ lpmgr_test_helper::check_linear_pfids_lfids(lm, num_jfiles);
+ }
+
+ // Loop to insert pfids
+ const int num_inserts = 1 + int(lfm.size() * ::drand48());
+ for (int i = 0; i < num_inserts; i++)
+ {
+ const u_int16_t size = lm.num_jfiles();
+ const u_int16_t after_lid = u_int16_t(1.0 * size * ::drand48());
+ const u_int16_t num_jfiles = 1 + u_int16_t(4.0 * ::drand48());
+ const bool legal = lm.ae_max_jfiles()
+ ? size + num_jfiles <= lm.ae_max_jfiles()
+ : size + num_jfiles <= JRNL_MAX_NUM_FILES;
+ if (legal)
+ {
+ lfm.journal_insert(after_lid, num_jfiles);
+ lfm.get_pfid_list(pfidl);
+ lfm.get_lfid_list(lfidl);
+
+ lm.insert(after_lid, &jc, &jc.new_fcntl, num_jfiles);
+ lpmgr_test_helper::check_pfids_lfids(lm, pfidl, lfidl);
+ }
+ else
+ {
+ try
+ {
+ lm.insert(after_lid, &jc, &jc.new_fcntl, num_jfiles);
+ BOOST_FAIL("lpmgr::insert() succeeded and exceeded
limit");
+ }
+ catch (const jexception& e)
+ {
+ BOOST_CHECK_EQUAL(e.err_code(), jerrno::JERR_LFMGR_AEFNUMLIMIT);
+ break; // no more inserts...
+ }
+ }
+ }
+ lm.finalize();
+ BOOST_CHECK_EQUAL(lm.is_init(), false);
+ BOOST_CHECK_EQUAL(lm.num_jfiles(), u_int16_t(0));
+ BOOST_CHECK_EQUAL(lm.get_fcntlp(0), (void*)0);
+ }
+ cout << "done" << endl;
+}
+
+QPID_AUTO_TEST_SUITE_END()
Property changes on: store/trunk/cpp/tests/jrnl/_ut_lpmgr.cpp
___________________________________________________________________
Name: svn:mergeinfo
+