rhmessaging commits: r2435 - store/trunk/cpp/rhel4-support.
by rhmessaging-commits@lists.jboss.org
Author: kpvdr
Date: 2008-09-09 16:30:51 -0400 (Tue, 09 Sep 2008)
New Revision: 2435
Modified:
store/trunk/cpp/rhel4-support/rhel4.patch
Log:
Fixed RHEL4 patch to use new name MessageStoreImpl
Modified: store/trunk/cpp/rhel4-support/rhel4.patch
===================================================================
--- store/trunk/cpp/rhel4-support/rhel4.patch 2008-09-09 20:24:44 UTC (rev 2434)
+++ store/trunk/cpp/rhel4-support/rhel4.patch 2008-09-09 20:30:51 UTC (rev 2435)
@@ -251,11 +251,11 @@
gl_COMPILER_FLAGS(-Winvalid-pch)
gl_COMPILER_FLAGS(-Wno-system-headers)
AC_SUBST([WARNING_CFLAGS], [$COMPILER_FLAGS])
-Index: lib/BdbMessageStore.cpp
+Index: lib/MessageStoreImpl.cpp
===================================================================
---- lib/BdbMessageStore.cpp (revision 2259)
-+++ lib/BdbMessageStore.cpp (working copy)
-@@ -230,10 +230,6 @@
+--- lib/MessageStoreImpl.cpp (revision 2259)
++++ lib/MessageStoreImpl.cpp (working copy)
+@@ -232,10 +232,6 @@
try {
env.open(getBdbBaseDir().c_str(), DB_THREAD | DB_CREATE | DB_INIT_TXN | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_USE_ENVIRON, 0);
} catch (const DbException& e) {
17 years, 7 months
rhmessaging commits: r2434 - store/trunk/cpp/tests/jrnl.
by rhmessaging-commits@lists.jboss.org
Author: kpvdr
Date: 2008-09-09 16:24:44 -0400 (Tue, 09 Sep 2008)
New Revision: 2434
Removed:
store/trunk/cpp/tests/jrnl/Makefile.rtest
store/trunk/cpp/tests/jrnl/janalyze.py
store/trunk/cpp/tests/jrnl/jtest.cpp
store/trunk/cpp/tests/jrnl/jtest.hpp
store/trunk/cpp/tests/jrnl/msg_consumer.cpp
store/trunk/cpp/tests/jrnl/msg_consumer.hpp
store/trunk/cpp/tests/jrnl/msg_producer.cpp
store/trunk/cpp/tests/jrnl/msg_producer.hpp
store/trunk/cpp/tests/jrnl/rtest
store/trunk/cpp/tests/jrnl/rtests.csv
store/trunk/cpp/tests/jrnl/rwtests.csv
store/trunk/cpp/tests/jrnl/wtests.csv
Modified:
store/trunk/cpp/tests/jrnl/Makefile.am
Log:
Removed some old test files that are no longer needed
Modified: store/trunk/cpp/tests/jrnl/Makefile.am
===================================================================
--- store/trunk/cpp/tests/jrnl/Makefile.am 2008-09-09 19:25:47 UTC (rev 2433)
+++ store/trunk/cpp/tests/jrnl/Makefile.am 2008-09-09 20:24:44 UTC (rev 2434)
@@ -117,9 +117,4 @@
EXTRA_DIST = \
run-journal-tests \
- rtest \
- janalyze.py \
- tests.ods \
- rtests.csv \
- rwtests.csv \
- wtests.csv
+ tests.ods
Deleted: store/trunk/cpp/tests/jrnl/Makefile.rtest
===================================================================
--- store/trunk/cpp/tests/jrnl/Makefile.rtest 2008-09-09 19:25:47 UTC (rev 2433)
+++ store/trunk/cpp/tests/jrnl/Makefile.rtest 2008-09-09 20:24:44 UTC (rev 2434)
@@ -1,137 +0,0 @@
-# Copyright (C) 2007 Red Hat Software
-#
-# 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 file 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.
-
-
-# RHM Defines
-# The following defines are usable during the build of rhmj:
-# RHM_CLEAN: Writes 0xff to all unused disk space bytes. This makes debugging easier,
-# but the memcpy required incurs a performance penalty. Do not use for
-# production or performance checks.
-# RHM_TESTVALS: Uses special values (e.g. RIDs starting at 0xffeeddcc00000000 rather than 0)
-# for testing purposes, or to expose special test conditions.
-# RHM_JOWRITE: Defeats the relocation of previous journal files into a subdir, makes
-# the execution quicker provided the files are of the same size as previous
-# run. If the files are not present, they will be created.
-# RHM_WRONLY: Defeats the test which check that a journal file has been read before it
-# overwritten. NOTE: ONLY USE FOR PERFORMANCE TESTS!
-# RHM_RDONLY: Defeats the test which check that a journal file has been written before it
-# read. Use together with RHM_JOWRITE if test reads from previously written
-# journal. Ensure journal contains valid entries in all files. NOTE: ONLY USE
-# FOR PERFORMANCE TESTS!
-# RHM_TIMERS: Enable and show times for initialize and run of a test.
-# Prefix each define with -D. (eg RHM_DEFINES = -DRHM_JOWRITE -DRHM_WRONLY)
-
-SHELL = /bin/bash
-
-QPID_HOME_DIR = $(HOME)/qpid
-RHM_JRNL_SRC_DIR = ../../lib/jrnl
-RHM_JRNL_DOC_DIR = ../../docs
-
-VPATH = $(RHM_JRNL_SRC_DIR)
-
-JRNL_OBJ_FILES = \
- jexception.o \
- jerrno.o \
- jinf.o \
- enq_map.o \
- txn_map.o \
- jdir.o \
- data_tok.o \
- jrec.o \
- enq_rec.o \
- deq_rec.o \
- txn_rec.o \
- nlfh.o \
- lfh.o \
- rrfc.o \
- wrfc.o \
- pmgr.o \
- rmgr.o \
- wmgr.o \
- jcntl.o \
-
-JTEST_OBJ_FILES = \
- msg_producer.o \
- msg_consumer.o \
-
-JTEST_FILES = jtest
-
-CXX = g++
-CXXINCLUDES = -I. -I../../lib -I../../../../qpid/cpp/src -I../../../../qpid/cpp/src/gen
-CXXFLAGS = $(RHM_DEFINES) -Wall -Wextra -Werror -Wno-shadow -Wpointer-arith -Wcast-qual -Wcast-align -Wno-long-long -Wvolatile-register-var -Winvalid-pch -Wno-system-headers -pedantic -g -O0 -pthread $(CXXINCLUDES)
-LDFLAGS = -lpthread -laio -lrt -lqpidcommon -L$(QPID_HOME_DIR)/cpp/src/.libs
-
-.SUFFIXES:
-.SUFFIXES: .cpp .o
-
-.PHONY: jrtest jwtest jrwtest
-
-default: jtest
-
-help:
- @echo "The following make options are available: (* is default)"
- @echo " --- Building options ---"
- @echo " all: Run check, build jtest and docs"
- @echo " *jtest: Make the journal test suite"
- @echo " jrtest: Make the journal test suite for read tests"
- @echo " jwtest: Make the journal test suite for write tests"
- @echo " jrwtest: Make the journal test suite for simultaneous write/read tests"
- @echo " jwperf: Make the jorunal test suite for performance write tests"
- @echo " --- Testing options ---"
- @echo " check: Run complete regression test suite; compiles with special flags"
- @echo " --- Documentation options ---"
- @echo " help: This help message"
- @echo " --- Cleaning options ---"
- @echo " clean: Clean build"
- @echo " clean-data: Clean journal data files"
- @echo " clean-docs: Clean documtentation"
- @echo " clean-all: Clean build, journal data files and documentation"
-
-all: check jtest
-
-jtest: $(JRNL_OBJ_FILES) $(JTEST_OBJ_FILES)
-
-jrtest: RHM_DEFINES = -DRHM_JOWRITE -DRHM_RDONLY -DRHM_TESTVALS
-jrtest: $(JTEST_FILES)
-
-jwtest: RHM_DEFINES = -DRHM_CLEAN -DRHM_WRONLY -DRHM_TESTVALS
-jwtest: $(JTEST_FILES)
-
-jrwtest: RHM_DEFINES = -DRHM_CLEAN -DRHM_TESTVALS
-jrwtest: $(JTEST_FILES)
-
-jwperf: RHM_DEFINES = -DRHM_WRONLY -DRHM_TIMERS
-jwperf: $(JTEST_FILES)
-
-check:
- @./rtest
-
-clean:
- @rm -f *.o
- @rm -f jtest
-
-clean-data:
- @rm -rf jdata
-
-clean-test-data:
- @rm -rf rd_test_jrnls
-
-clean-all: clean clean-data clean-test-data
Deleted: store/trunk/cpp/tests/jrnl/janalyze.py
===================================================================
--- store/trunk/cpp/tests/jrnl/janalyze.py 2008-09-09 19:25:47 UTC (rev 2433)
+++ store/trunk/cpp/tests/jrnl/janalyze.py 2008-09-09 20:24:44 UTC (rev 2434)
@@ -1,632 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (C) 2007 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.
-
-import sys
-from struct import unpack, calcsize
-from time import gmtime, strftime
-
-base_file_name = 'test'
-dblk_size = 128
-sblk_size = 4 * dblk_size
-file_size = (3072 + 1) * sblk_size
-num_files = 8
-hdr_ver = 1
-
-TEST_NUM_COL = 0
-NUM_MSGS_COL = 5
-MIN_MSG_SIZE_COL = 7
-MAX_MSG_SIZE_COL = 8
-MIN_XID_SIZE_COL = 9
-MAX_XID_SIZE_COL = 10
-AUTO_DEQ_COL = 11
-TRANSIENT_COL = 12
-EXTERN_COL = 13
-COMMENT_COL = 20
-
-transient_mask = 0x10
-extern_mask = 0x20
-
-def load(f, klass):
- args = load_args(f, klass)
- subclass = klass.descriminate(args)
- result = subclass(*args)
- if subclass != klass:
- result.init(f, *load_args(f, subclass))
- result.skip(f)
- return result;
-
-def load_args(f, klass):
- size = calcsize(klass.format)
- foffs = f.tell(),
- bin = f.read(size)
- if len(bin) != size:
- raise Exception("end of file")
- return foffs + unpack(klass.format, bin)
-
-def size_blks(size, blk_size):
- return (size + blk_size - 1)/blk_size
-
-def rem_in_blk(f, blk_size):
- foffs = f.tell()
- return (size_blks(f.tell(), blk_size) * blk_size) - foffs;
-
-def file_full(f):
- return f.tell() >= file_size
-
-def print_xid(xidsize, xid):
- if xid == None:
- if xidsize > 0:
- raise Exception('Inconsistent XID size: xidsize=%d, xid=None' % xidsize)
- return ''
- if len(xid) > 25:
- xidstr = xid[:10] + ' ... ' + xid[-10:]
- else:
- xidstr = xid
- if xidsize != len(xid):
- raise Exception('Inconsistent XID size: xidsize=%d, xid(%d)=\"%s\"' % (xidsize, len(xid), xidstr))
- return 'xid(%d)=\"%s\" ' % (xidsize, xidstr)
-
-def print_data(dsize, data):
- if data == None:
- return ''
- if len(data) > 25:
- datastr = data[:10] + ' ... ' + data[-10:]
- else:
- datastr = data
- if dsize != len(data):
- raise Exception('Inconsistent data size: dsize=%d, data(%d)=\"%s\"' % (dsize, len(data), datastr))
- return 'data(%d)=\"%s\" ' % (dsize, datastr)
-
-def inv_str(s):
- si = ''
- for i in range(0,len(s)):
- si += chr(~ord(s[i]) & 0xff)
- return si
-
-def load_file_data(f, size, data):
- if size == 0:
- return (data, True)
- if data == None:
- loaded = 0
- else:
- loaded = len(data)
- foverflow = f.tell() + size - loaded > file_size
- if foverflow:
- rsize = file_size - f.tell()
- else:
- rsize = size - loaded
- bin = f.read(rsize)
- if data == None:
- data = unpack('%ds' % (rsize), bin)[0]
- else:
- data = data + unpack('%ds' % (rsize), bin)[0]
- return (data, not foverflow)
-
-def load_tail(self, f):
- if self.tail_bin == None:
- self.tail_offs = f.tell()
- self.tail_bin = f.read(calcsize(RecTail.format))
- if len(self.tail_bin) != calcsize(RecTail.format):
- return
- else:
- self.tail_bin += f.read(calcsize(RecTail.format) - len(self.tail_bin))
- self.enq_tail = RecTail(self.tail_offs, *unpack(RecTail.format, self.tail_bin))
- if self.enq_tail.magic_inv != inv_str(self.magic) or self.enq_tail.rid != self.rid:
- print " > %s" % self
- raise Exception('Invalid enqueue record tail (magic=0x%08x; rid=%d) at 0x%08x' % (self.enq_tail.magic_inv, self.enq_tail.rid, self.enq_tail.foffs))
- self.enq_tail.skip(f)
- self.tail_complete = True
-
-
-class Sizeable:
-
- def size(self):
- classes = [self.__class__]
-
- size = 0
- while classes:
- cls = classes.pop()
- if hasattr(cls, "format"):
- size += calcsize(cls.format)
- classes.extend(cls.__bases__)
-
- return size
-
-class Hdr(Sizeable):
-
- format = '=4sBBHQ'
-
- @staticmethod
- def descriminate(args):
- return CLASSES.get(args[1][-1], Hdr)
-
- def __init__(self, foffs, magic, ver, end, flags, rid):
- self.foffs = foffs
- self.magic = magic
- self.ver = ver
- self.end = end
- self.flags = flags
- self.rid = rid
- if self.magic[-1] not in ['0x00', 'a', 'c', 'd', 'e', 'f', 'x']:
- error = 3
-
- def __str__(self):
- if self.empty():
- return '0x%08x: <empty>' % (self.foffs)
- if self.magic[-1] == 'x':
- return '0x%08x: \"%s\"' % (self.foffs, self.magic)
- if self.magic[-1] in ['a', 'c', 'd', 'e', 'f', 'x']:
- return '0x%08x: \"%s\" v=%d e=%d f=0x%04x rid=%d' % (self.foffs, self.magic, self.ver, self.end, self.flags, self.rid)
- return '0x%08x: <error, unknown magic \"%s\" (possible overwrite boundary?)>' % (self.foffs, self.magic)
-
- def empty(self):
- return self.magic == '\x00'*4
-
- def skip(self, f):
- f.read(rem_in_blk(f, dblk_size))
-
- def check(self):
- if self.empty() or self.magic[-1] not in ['a', 'c', 'd', 'e', 'f', 'x']:
- return True
- if self.ver != hdr_ver and self.magic[-1] != 'x':
- raise Exception('%s: Invalid header version: found %d, expected %d.' % (self, self.ver, hdr_ver))
- return False
-
-
-
-class FileHdr(Hdr):
-
- format = '=I4x3Q'
-
- def init(self, f, foffs, fid, fro, time_sec, time_ns):
- self.fid = fid
- self.fro = fro
- self.time_sec = time_sec
- self.time_ns = time_ns
-
- def __str__(self):
- return '%s fid=%d fro=0x%08x t=%s' % (Hdr.__str__(self), self.fid, self.fro, self.timestamp_str())
-
- def skip(self, f):
- f.read(rem_in_blk(f, sblk_size))
-
- def timestamp(self):
- return (self.time_sec, self.time_ns)
-
- def timestamp_str(self):
- ts = gmtime(self.time_sec)
- fstr = '%%a %%b %%d %%H:%%M:%%S.%d %%Y' % (self.time_ns)
- return strftime(fstr, ts)
-
-
-class DeqHdr(Hdr):
-
- format = '=QQ'
-
- def init(self, f, foffs, deq_rid, xidsize):
- self.deq_rid = deq_rid
- self.xidsize = xidsize
- self.xid = None
- self.deq_tail = None
- self.xid_complete = False
- self.tail_complete = False
- self.tail_bin = None
- self.tail_offs = 0
- self.load(f)
-
- def load(self, f):
- if self.xidsize == 0:
- self.xid_complete = True
- self.tail_complete = True
- else:
- if not self.xid_complete:
- ret = load_file_data(f, self.xidsize, self.xid)
- self.xid = ret[0]
- self.xid_complete = ret[1]
- if self.xid_complete and not self.tail_complete:
- ret = load_file_data(f, calcsize(RecTail.format), self.tail_bin)
- self.tail_bin = ret[0]
- if ret[1]:
- self.enq_tail = RecTail(self.tail_offs, *unpack(RecTail.format, self.tail_bin))
- if self.enq_tail.magic_inv != inv_str(self.magic) or self.enq_tail.rid != self.rid:
- print " > %s" % self
- raise Exception('Invalid enqueue record tail (magic=0x%08x; rid=%d) at 0x%08x' % (self.enq_tail.magic_inv, self.enq_tail.rid, self.enq_tail.foffs))
- self.enq_tail.skip(f)
- self.tail_complete = ret[1]
- return self.complete()
-
- def complete(self):
- return self.xid_complete and self.tail_complete
-
- def __str__(self):
- return '%s %sdrid=%d' % (Hdr.__str__(self), print_xid(self.xidsize, self.xid), self.deq_rid)
-
-
-class TxnHdr(Hdr):
-
- format = '=Q'
-
- def init(self, f, foffs, xidsize):
- self.xidsize = xidsize
- self.xid = None
- self.tx_tail = None
- self.xid_complete = False
- self.tail_complete = False
- self.tail_bin = None
- self.tail_offs = 0
- self.load(f)
-
- def load(self, f):
- if not self.xid_complete:
- ret = load_file_data(f, self.xidsize, self.xid)
- self.xid = ret[0]
- self.xid_complete = ret[1]
- if self.xid_complete and not self.tail_complete:
- ret = load_file_data(f, calcsize(RecTail.format), self.tail_bin)
- self.tail_bin = ret[0]
- if ret[1]:
- self.enq_tail = RecTail(self.tail_offs, *unpack(RecTail.format, self.tail_bin))
- if self.enq_tail.magic_inv != inv_str(self.magic) or self.enq_tail.rid != self.rid:
- print " > %s" % self
- raise Exception('Invalid enqueue record tail (magic=0x%08x; rid=%d) at 0x%08x' % (self.enq_tail.magic_inv, self.enq_tail.rid, self.enq_tail.foffs))
- self.enq_tail.skip(f)
- self.tail_complete = ret[1]
- return self.complete()
-
- def complete(self):
- return self.xid_complete and self.tail_complete
-
- def __str__(self):
- return '%s %s' % (Hdr.__str__(self), print_xid(self.xidsize, self.xid))
-
-
-class RecTail(Sizeable):
-
- format = '=4sQ'
-
- def __init__(self, foffs, magic_inv, rid):
- self.foffs = foffs
- self.magic_inv = magic_inv
- self.rid = rid
-
- def __str__(self):
- magic = inv_str(self.magic_inv)
- return '[\"%s\" rid=%d]' % (magic, self.rid)
-
- def skip(self, f):
- f.read(rem_in_blk(f, dblk_size))
-
-
-class EnqRec(Hdr):
-
- format = '=QQ'
-
- def init(self, f, foffs, xidsize, dsize):
- self.xidsize = xidsize
- self.dsize = dsize
- self.transient = self.flags & transient_mask > 0
- self.extern = self.flags & extern_mask > 0
- self.xid = None
- self.data = None
- self.enq_tail = None
- self.xid_complete = False
- self.data_complete = False
- self.tail_complete = False
- self.tail_bin = None
- self.tail_offs = 0
- self.load(f)
-
- def load(self, f):
- if not self.xid_complete:
- ret = load_file_data(f, self.xidsize, self.xid)
- self.xid = ret[0]
- self.xid_complete = ret[1]
- if self.xid_complete and not self.data_complete:
- if self.extern:
- self.data_complete = True
- else:
- ret = load_file_data(f, self.dsize, self.data)
- self.data = ret[0]
- self.data_complete = ret[1]
- if self.data_complete and not self.tail_complete:
- ret = load_file_data(f, calcsize(RecTail.format), self.tail_bin)
- self.tail_bin = ret[0]
- if ret[1]:
- self.enq_tail = RecTail(self.tail_offs, *unpack(RecTail.format, self.tail_bin))
- if self.enq_tail.magic_inv != inv_str(self.magic) or self.enq_tail.rid != self.rid:
- print " > %s" % self
- raise Exception('Invalid enqueue record tail (magic=0x%08x; rid=%d) at 0x%08x' % (self.enq_tail.magic_inv, self.enq_tail.rid, self.enq_tail.foffs))
- self.enq_tail.skip(f)
- self.tail_complete = ret[1]
- return self.complete()
-
- def complete(self):
- return self.xid_complete and self.data_complete and self.tail_complete
-
- def print_flags(self):
- s = ''
- if self.transient:
- s = '*TRANSIENT'
- if self.extern:
- if len(s) > 0:
- s += ',EXTERNAL'
- else:
- s = '*EXTERNAL'
- if len(s) > 0:
- s += '*'
- return s
-
- def __str__(self):
- return '%s %s%s %s %s' % (Hdr.__str__(self), print_xid(self.xidsize, self.xid), print_data(self.dsize, self.data), self.enq_tail, self.print_flags())
-
-
-class Main:
-
- def __init__(self, tfile, tnum):
- if tfile != None:
- self.tnum = tnum
- tparams = self.get_test(tfile, tnum)
- if tparams == None:
- raise Exception('Test %d not found in file %s' % (tnum, tfile))
- self.num_msgs = tparams['num_msgs']
- if tparams['min_size'] == tparams['max_size']:
- self.msg_len = tparams['max_size']
- else:
- self.msg_len = 0
- self.auto_deq = tparams['auto_deq']
- if tparams['xid_min_size'] == tparams['xid_max_size']:
- self.xid_len = tparams['xid_max_size']
- else:
- self.xid_len = 0
- self.transient = tparams['transient']
- self.extern = tparams['extern']
- else:
- self.tnum = None
- self.num_msgs = None
- self.msg_len = None
- self.auto_deq = None
- self.xid_len = None
- self.transient = None
- self.extern = None
- self.file_start = 0
- self.file_num = 0
- self.fro = 0x200
- self.enqueued = {}
- self.msg_cnt = 0
- self.fhdr = None
- self.f = None
- self.first_rec = False
- self.last_file = False
- self.last_rid = -1
-
-
- def run(self):
- try:
- start_info = self.analyze_files()
- stop = self.advance_file(*start_info)
- except Exception:
- print 'WARNING: All journal files are empty.'
- if self.num_msgs > 0:
- raise Exception('All journal files are empty.')
- else:
- stop = True
- while not stop:
- warn = ''
- if file_full(self.f):
- stop = self.advance_file()
- if stop:
- break
- hdr = load(self.f, Hdr)
- if hdr.empty():
- stop = True;
- break
- if hdr.check():
- stop = True;
- if self.first_rec:
- if self.fhdr.fro != hdr.foffs:
- raise Exception('File header first record offset mismatch: fro=0x%08x; rec_offs=0x%08x' % (self.fhdr.fro, hdr.foffs))
- else:
- print ' * fro ok: 0x%08x' % self.fhdr.fro
- self.first_rec = False
- if isinstance(hdr, EnqRec) and not stop:
- while not hdr.complete():
- stop = self.advance_file()
- if stop:
- break
- hdr.load(self.f)
- if self.extern != None:
- if hdr.extern:
- if hdr.data != None:
- raise Exception('Message data found on external record')
- else:
- if self.msg_len > 0 and len(hdr.data) != self.msg_len:
- raise Exception('Message length (%d) incorrect; expected %d' % (len(hdr.data), self.msg_len))
- else:
- if self.msg_len > 0 and len(hdr.data) != self.msg_len:
- raise Exception('Message length (%d) incorrect; expected %d' % (len(hdr.data), self.msg_len))
- if self.xid_len > 0 and len(hdr.xid) != self.xid_len:
- raise Exception('XID length (%d) incorrect; expected %d' % (len(hdr.xidsize), self.xid_len))
- if self.transient != None:
- if self.transient:
- if not hdr.transient:
- raise Exception('Expected transient record, found persistent')
- else:
- if hdr.transient:
- raise Exception('Expected persistent record, found transient')
- stop = not self.check_rid(hdr)
- if stop:
- warn = ' (WARNING: rid out of order, rid = %d; last rid = %d - could be overwrite boundary.)' % (hdr.rid, self.last_rid)
- else:
- self.msg_cnt += 1
- if self.auto_deq:
- self.enqueued[hdr.rid] = hdr
- elif isinstance(hdr, DeqHdr) and not stop:
- while not hdr.complete():
- stop = self.advance_file()
- if stop:
- break
- hdr.load(self.f)
- if self.auto_deq:
- if hdr.deq_rid in self.enqueued:
- del self.enqueued[hdr.deq_rid]
- else:
- warn = ' (WARNING: dequeue rid %d not found in enqueued records)' % hdr.deq_rid
- stop = not self.check_rid(hdr)
- if stop:
- warn = ' (WARNING: rid out of order, rid = %d; last rid = %d - could be overwrite boundary.)' % (hdr.rid, self.last_rid)
- elif self.auto_deq != None:
- if not self.auto_deq:
- warn = ' WARNING: Dequeue record rid=%d found in non-dequeue test - ignoring.' % hdr.rid
- elif isinstance(hdr, TxnHdr) and not stop:
- while not hdr.complete():
- stop = self.advance_file()
- if stop:
- break
- hdr.load(self.f)
- stop = not self.check_rid(hdr)
- if stop:
- warn = ' (WARNING: rid out of order, rid = %d; last rid = %d - could be overwrite boundary.)' % (hdr.rid, self.last_rid)
- print ' > %s%s' % (hdr, warn)
- if not stop:
- stop = (self.last_file and hdr.check()) or hdr.empty() or self.fhdr.empty()
-
- def report(self):
- if self.num_msgs > 0 and self.msg_cnt != self.num_msgs:
- print 'WARNING: Found %d messages; %d expected.' % (self.msg_cnt, self.num_msgs)
- if len(self.enqueued) > 0:
- print 'Remaining enqueued records: ', len(self.enqueued)
- for h in self.enqueued:
- print self.enqueued[h]
- print 'WARNING: Enqueue-Dequeue mismatch, %d enqueued records remain.' % len(self.enqueued)
- print 'Test passed; %d records processed.' % self.msg_cnt
-
- def advance_file(self, *start_info):
- seek_flag = False
- if len(start_info) == 3:
- self.file_start = self.file_num = start_info[0]
- self.fro = start_info[2]
- seek_flag = True
- if self.f != None and file_full(self.f):
- self.file_num = self.incr_fnum()
- if self.file_num == self.file_start:
- return True
- if self.file_start == 0:
- self.last_file = self.file_num == num_files - 1
- else:
- self.last_file = self.file_num == self.file_start - 1
- if self.file_num < 0 or self.file_num >= num_files:
- raise Exception('Bad file number %d' % self.file_num)
- file_name = 'jdata/' + base_file_name + '.%04d.jdat' % self.file_num
- self.f = open(file_name)
- self.fhdr = load(self.f, Hdr)
- if seek_flag and self.f.tell() != self.fro:
- self.f.seek(self.fro)
- self.first_rec = True
- print file_name, ": ", self.fhdr
- return False
-
- def incr_fnum(self):
- self.file_num += 1
- if self.file_num >= num_files:
- self.file_num = 0;
- return self.file_num
-
- def check_rid(self, hdr):
- if self.last_rid != -1 and hdr.rid != self.last_rid + 1:
- return False
- self.last_rid = hdr.rid
- return True
-
- def get_test(self, filename, tnum):
- f=open(filename, 'r')
- for l in f:
- sl = l.strip().split(',')
- if len(sl[0]) > 0 and sl[0][0] != '"':
- try:
- if (int(sl[TEST_NUM_COL]) == tnum):
- return { 'num_msgs':int(sl[NUM_MSGS_COL]),
- 'min_size':int(sl[MIN_MSG_SIZE_COL]),
- 'max_size':int(sl[MAX_MSG_SIZE_COL]),
- 'auto_deq':not (sl[AUTO_DEQ_COL] == 'FALSE' or sl[AUTO_DEQ_COL] == '0'),
- 'xid_min_size':int(sl[MIN_XID_SIZE_COL]),
- 'xid_max_size':int(sl[MAX_XID_SIZE_COL]),
- 'transient':not (sl[TRANSIENT_COL] == 'FALSE' or sl[TRANSIENT_COL] == '0'),
- 'extern':not (sl[EXTERN_COL] == 'FALSE' or sl[EXTERN_COL] == '0'),
- 'comment':sl[COMMENT_COL] }
- except Exception:
- pass
- return None
-
- def analyze_files(self):
- fname = ''
- fnum = -1
- rid = -1
- fro = -1
- tss = ''
- print 'Analyzing journal files:'
- for i in range(0, num_files):
- file_name = 'jdata/' + base_file_name + '.%04d.jdat' % i
- f = open(file_name)
- fhdr = load(f, Hdr)
- if fhdr.empty():
- break
- if (rid == -1 or fhdr.rid < rid) and fhdr.fro > 0:
- fname = file_name
- fnum = i
- rid = fhdr.rid
- fro = fhdr.fro
- tss = fhdr.timestamp_str()
- print ' %s: rid=%d, fro=0x%08x ts=%s' % (file_name, fhdr.rid, fhdr.fro, fhdr.timestamp_str())
- if fnum < 0 or rid < 0 or fro < 0:
- raise Exception('All journal files empty')
- print ' Lowest rid found in file %s: rid=%d, fro=0x%08x ts=%s' % (fname, rid, fro, tss)
- return (fnum, rid, fro)
-
-
-CLASSES = {
- "a": TxnHdr,
- "c": TxnHdr,
- "d": DeqHdr,
- "e": EnqRec,
- "f": FileHdr
-}
-
-if len(sys.argv) != 1 and len(sys.argv) != 3:
- print 'Incorrect number of command-line arguments (expected 0 or 2, found %d).' % (len(sys.argv) - 1)
- print 'Usage: ftest test-file test-number'
- raise Exception('Bad command-line arguments')
-if len(sys.argv) == 3 and not sys.argv[2].isdigit():
- print 'Illegal argument (\"%s\"): test-number must be a number' % a
- print 'Usage: ftest test-file test-number'
- raise Exception('Illegal argument value')
-
-if len(sys.argv) == 1:
- m = Main(None, None)
- m.run()
-else:
- tnum = int(sys.argv[2])
- print 'Test number: %d' % tnum
- print 'Test file: %s' %sys.argv[1]
- m = Main(sys.argv[1], tnum)
- m.run()
- m.report()
Deleted: store/trunk/cpp/tests/jrnl/jtest.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/jtest.cpp 2008-09-09 19:25:47 UTC (rev 2433)
+++ store/trunk/cpp/tests/jrnl/jtest.cpp 2008-09-09 20:24:44 UTC (rev 2434)
@@ -1,523 +0,0 @@
-/**
-* \file jtest.cpp
-*
-* Test framework for RHM journalling.
-*
-* \author Kim van der Riet
-*
-* Copyright (C) 2007 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 "jtest.hpp"
-
-#include <cassert>
-#include <cstdlib>
-#include <cstring>
-#include <fstream>
-#include <iomanip>
-#include <iostream>
-#include <sstream>
-#include <vector>
-#include <sys/time.h>
-
-#define EXCEPTION_BASE 0x30
-
-int main(int argc, char** argv)
-{
- jtest::print_compile_defs(false);
- char* test_csv_file = NULL;
- int tnum = -1;
- try
- {
- jtest::proc_args(argc, argv, &test_csv_file, &tnum);
- assert(test_csv_file != NULL);
- assert(tnum >= 0);
- std::cout << "Test data file: \"" << test_csv_file << "\"" << std::endl;
- cout << "jtest: starting test " << tnum << endl;
- jtest t;
- t.initialize(tnum, test_csv_file);
-#ifdef RHM_TIMERS
- usleep(1000000); // Sleep for 1 sec so disks can rest after initialize
-#endif
- t.run();
- t.report();
- t.finalize();
- }
- catch (const rhm::journal::jexception& e)
- {
- cerr << e << endl;
- cerr << std::hex << std::setfill('0');
- cerr << "*** jtest failed with code 0x" << std::setw(4) << e.err_code() << " ***" << endl;
- return(1);
- }
- cout << "*** jtest done." << endl << endl;
- return 0;
-}
-
-jtest::targs::targs():
- _num_msgs(0),
- _min_msg_size(0),
- _max_msg_size(0),
- _auto_deq(false),
- _min_xid_size(0),
- _max_xid_size(0),
- _transient(false),
- _external(false),
- _comment(NULL)
-{}
-
-jtest::targs::targs(const u_int32_t num_msgs, const std::size_t min_msg_size,
- const std::size_t max_msg_size, const bool auto_deq, const std::size_t min_xid_size,
- const std::size_t max_xid_size, const bool transient, const bool external, char* comment):
- _num_msgs(num_msgs),
- _min_msg_size(min_msg_size),
- _max_msg_size(max_msg_size),
- _auto_deq(auto_deq),
- _min_xid_size(min_xid_size),
- _max_xid_size(max_xid_size),
- _transient(transient),
- _external(external),
- _comment(comment)
-{}
-
-jtest::jtest():
- _start_time(new timeval),
- _end_time(new timeval),
- _tz_ptr(NULL)
-{}
-
-jtest::~jtest()
-{
- delete _start_time;
- delete _end_time;
- if (p_args)
- {
- delete p_args;
- p_args = NULL;
- }
- if (c_args)
- {
- delete c_args;
- c_args = NULL;
- }
-}
-
-void
-jtest::initialize(const int test_num, const char* test_csv_file) throw (rhm::journal::jexception)
-{
- targs ta;
- jtest::get_test(&ta, std::string(test_csv_file), test_num);
- initialize(ta);
-}
-
-void
-jtest::initialize(const targs& ta) throw (rhm::journal::jexception)
-{
- assert(_dtok_master_list.size() == 0);
- assert(_dtok_wr_aio_list.size() == 0);
- assert(_dtok_rd_aio_list.size() == 0);
-
-#ifdef RHM_TIMERS
- gettimeofday(_start_time, _tz_ptr);
-#endif
-
- p_args = new msg_producer::_p_args(_jc, ta._num_msgs, ta._min_msg_size, ta._max_msg_size,
- ta._auto_deq, ta._min_xid_size, ta._max_xid_size, ta._transient, ta._external);
- c_args = new msg_consumer::_c_args(_jc, ta._num_msgs, ta._min_msg_size, ta._max_msg_size,
- ta._min_xid_size, ta._max_xid_size, ta._transient, ta._external);
-
-#ifndef RHM_RDONLY
- _mp.initialize(p_args);
-#endif
-#ifndef RHM_WRONLY
- _mc.initialize(c_args);
-#endif
- _jc.initialize(&mc_aio_cb, &mp_aio_cb);
-
- for (u_int32_t i=0; i<p_args->_num_msgs; i++)
- {
- rhm::journal::data_tok* dtp = new rhm::journal::data_tok;
-#ifdef RHM_RDONLY
- dtp->set_wstate(rhm::journal::data_tok::ENQ); // Assume all msgs enqueued OK
-#endif
- _dtok_master_list.push_back(dtp);
- }
-
-#ifdef RHM_TIMERS
- gettimeofday(_end_time, _tz_ptr);
- string str;
- cout << "initialize(): " << report_time(str) << endl;
-#endif
-}
-
-void
-jtest::run() throw (rhm::journal::jexception)
-{
-#ifdef RHM_TIMERS
- gettimeofday(_start_time, _tz_ptr);
-#endif
-
- // === Do something spectacular here... ===
-
- // Use ONE OF the following two execution blocks below:
-
- // Serial execution - uncomment these lines...
-#ifndef RHM_RDONLY
-// produce(p_args);
-#ifndef RHM_WRONLY
-// std::cout << "-----" << std::endl;
-// usleep(500000); // 0.5 sec
-#endif
-#endif
-
-#ifndef RHM_WRONLY
-// consume(c_args);
-#endif
-
- // Concurrent execution - uncomment these lines...
-#ifndef RHM_RDONLY
- pthread_create(&_p_thread, NULL, produce, (void*)p_args);
-#endif
-#ifndef RHM_WRONLY
- pthread_create(&_c_thread, NULL, consume, (void*)c_args);
-#endif
-#ifndef RHM_RDONLY
- pthread_join(_p_thread, NULL);
-#endif
-#ifndef RHM_WRONLY
- pthread_join(_c_thread, NULL);
-#endif
-
- if (p_args->_err)
- if (p_args->_err != 1) // This is the zero msg length err, ignore
- throw (rhm::journal::jexception(p_args->_err));
- if (c_args->_err)
- throw (rhm::journal::jexception(c_args->_err));
-
- // === End: Do something spectacular here... ===
-
-#ifdef RHM_TIMERS
- gettimeofday(_end_time, _tz_ptr);
- string str;
- cout << "run(): " << report_time(str) << endl;
- double rate = c_args->_num_msgs / time_diff(_start_time, _end_time) / 1000.0;
- cout.precision(3);
- cout << "rate = " << fixed << rate << " kmsgs/sec" << endl;
-#endif
-}
-
-void
-jtest::report() throw (rhm::journal::jexception)
-{}
-
-void
-jtest::finalize() throw (rhm::journal::jexception)
-{
- _mp.finalize();
- _mc.finalize();
- if (p_args)
- {
- delete p_args;
- p_args = NULL;
- }
- if (c_args)
- {
- delete c_args;
- c_args = NULL;
- }
- for (u_int32_t i=0; i<_dtok_master_list.size(); i++)
- {
- if (_dtok_master_list[i])
- {
- delete _dtok_master_list[i];
- _dtok_master_list[i] = NULL;
- }
- }
- _dtok_master_list.clear();
-}
-
-double
-jtest::time_diff(const struct timeval* start, const struct timeval* end)
-{
- return end->tv_sec - start->tv_sec + (end->tv_usec - start->tv_usec)/1e6;
-}
-
-string&
-jtest::report_time(string& str) const
-{
- double diff = time_diff(_start_time, _end_time);
- stringstream ss;
- ss.precision(6);
- ss << fixed << diff << " sec";
- str.assign(ss.str());
- return str;
-}
-
-// static varialbe declarations
-std::deque<rhm::journal::data_tok*> jtest::_dtok_master_list;
-std::deque<rhm::journal::data_tok*> jtest::_dtok_wr_aio_list;
-std::deque<rhm::journal::data_tok*> jtest::_dtok_rd_aio_list;
-msg_producer::_p_args* jtest::p_args = NULL;
-msg_consumer::_c_args* jtest::c_args = NULL;
-msg_producer jtest::_mp(_dtok_master_list, _dtok_wr_aio_list);
-msg_consumer jtest::_mc(_dtok_master_list, _dtok_rd_aio_list);
-rhm::journal::jcntl jtest::_jc(JOURNAL_ID, JOURNAL_DIR, JOURNAL_BASE_FILENAME, NUM_JFILES,
- JFSIZE_SBLKS);
-
-// static method
-
-void
-jtest::mc_aio_cb(rhm::journal::jcntl* jc, std::vector<u_int16_t>& pil)
-{
- jtest::_mc.aio_callback(jc, pil);
-}
-
-void
-jtest::mp_aio_cb(rhm::journal::jcntl* jc, std::vector<rhm::journal::data_tok*>& dtokl)
-{
- jtest::_mp.aio_callback(jc, dtokl);
-}
-
-// static method
-void
-jtest::proc_args(int argc, char** argv, char** test_file_name, int* test_num)
- throw (rhm::journal::jexception)
-{
- char num_chars[] = "0123456789";
- stringstream ss;
- if (argc != 3)
- {
- ss << "Illegal number of args: expected 2, found " << (argc - 1) <<
- " (Hint: use \"jtest [test_def_file] [testnum]\")";
- throw rhm::journal::jexception(EXCEPTION_BASE+0, ss.str().c_str());
- }
- *test_file_name = argv[1];
- if (argv[2][0] == '-')
- {
- if (std::strcspn(argv[2], num_chars) != 1)
- {
- ss << "Test number argument \"" << argv[2] << "\" not a valid number.";
- throw rhm::journal::jexception(EXCEPTION_BASE+1, ss.str().c_str());
- }
- }
- else
- {
- if (std::strcspn(argv[2], num_chars) != 0)
- {
- ss << "Test number argument \"" << argv[2] << "\" not a valid number.";
- throw rhm::journal::jexception(EXCEPTION_BASE+2, ss.str().c_str());
- }
- }
- *test_num = std::atoi(argv[2]);
- if (*test_num < 0)
- {
- ss << "Illegal test number \""<< test_num << "\"";
- throw rhm::journal::jexception(EXCEPTION_BASE+3, ss.str().c_str());
- }
-}
-
-// static method
-void*
-jtest::produce(void* ptr)
-{
- msg_producer::_p_args* p_args_ptr = (msg_producer::_p_args*)ptr;
- try { _mp.produce(p_args_ptr); }
- catch (const rhm::journal::jexception& e)
- {
- msg_consumer::interrupt(); // Wheels fell off; stop consumer thread
- cout << "Producer failed with exception 0x" << hex << setw(4) << setfill('0')
- << e.err_code() << "; consumer thread aborted." << dec << endl;
- cout << e << endl;
- p_args_ptr->_err = e.err_code();
- }
- return NULL;
-}
-
-// static method
-void*
-jtest::consume(void* ptr)
-{
- msg_consumer::_c_args* c_args_ptr = (msg_consumer::_c_args*)ptr;
- try { _mc.consume(c_args_ptr); }
- catch (const rhm::journal::jexception& e)
- {
- msg_producer::interrupt(); // Train smash; stop producer thread
- cout << "Consumer failed with exception 0x" << hex << setw(4) << setfill('0')
- << e.err_code() << "; producer thread aborted." << dec << endl;
- cout << e << endl;
- c_args_ptr->_err = e.err_code();
- }
- return NULL;
-}
-
-// Set spreadsheet cols here: A=0, B=1...
-#define TEST_NUM_COL 0
-#define NUM_MSGS_COL 5
-#define MIN_MSG_SIZE_COL 7
-#define MAX_MSG_SIZE_COL 8
-#define MIN_XID_SIZE_COL 9
-#define MAX_XID_SIZE_COL 10
-#define AUTO_DEQ_COL 11
-#define TRANSIENT_COL 12
-#define EXTERN_COL 13
-#define COMMENT_COL 20
-
-// static method
-void
-jtest::get_test(targs* tap, const std::string& filename, const unsigned tnum)
- throw (rhm::journal::jexception)
-{
- if (tap == NULL)
- throw rhm::journal::jexception(EXCEPTION_BASE+4, "targs NULL", "jtest", "get_test");
- char line[MAX_LINE_LEN];
- std::ifstream ifs(filename.c_str());
- if (!ifs.good())
- {
- std::cerr << "ERROR: Unable to open file \"" << filename << "\"!" << std:: endl;
- throw rhm::journal::jexception(EXCEPTION_BASE+5, "CSV file not found", "jtest", "get_test");
- }
- std::vector<char*> toks;
- bool found = false;
- while (ifs.good() && !found)
- {
- ifs.getline(line, MAX_LINE_LEN);
- toks.clear();
- char* pch = std::strtok(line, ",");
- while (pch != NULL)
- {
- toks.push_back(pch);
- pch = std::strtok(NULL, ",");
- }
- if (toks.size() > TRANSIENT_COL && toks[TEST_NUM_COL][0] != '"')
- {
- unsigned this_tnum = std::atoi(toks[TEST_NUM_COL]);
- if (this_tnum == tnum)
- {
- found = true;
- tap->_num_msgs = std::atol(toks[NUM_MSGS_COL]);
- tap->_min_msg_size = std::atol(toks[MIN_MSG_SIZE_COL]);
- tap->_max_msg_size = std::atol(toks[MAX_MSG_SIZE_COL]);
- tap->_min_xid_size = std::atol(toks[MIN_XID_SIZE_COL]);
- tap->_max_xid_size = std::atol(toks[MAX_XID_SIZE_COL]);
- tap->_auto_deq = !(std::strcmp(toks[AUTO_DEQ_COL], "FALSE") == 0 ||
- std::strcmp(toks[AUTO_DEQ_COL], "0") == 0);
- tap->_transient = !(std::strcmp(toks[TRANSIENT_COL], "FALSE") == 0 ||
- std::strcmp(toks[TRANSIENT_COL], "0") == 0);
- tap->_external = !(std::strcmp(toks[EXTERN_COL], "FALSE") == 0 ||
- std::strcmp(toks[EXTERN_COL], "0") == 0);
- if (toks.size() > COMMENT_COL)
- {
- tap->_comment = toks[COMMENT_COL];
- if (tap->_comment[0] == '"')
- tap->_comment++;
- if (tap->_comment[std::strlen(tap->_comment) - 1] == '"')
- tap->_comment[std::strlen(tap->_comment) - 1] = 0;
- }
- else
- tap->_comment = NULL;
- std::cout << "Test " << tnum << ": Messages=" << tap->_num_msgs << " Size=" <<
- tap->_min_msg_size;
- if (tap->_min_msg_size == tap->_max_msg_size)
- std::cout << " (fixed)";
- else
- std::cout << " - " << tap->_max_msg_size << " (random)";
- std::cout << (tap->_auto_deq ? " auto-dequeue" : " no dequeue");
- if (tap->_max_xid_size > 0)
- {
- std::cout << " XID_size=" << tap->_min_xid_size;
- if (tap->_min_xid_size == tap->_max_xid_size)
- std::cout << " (fixed)";
- else
- std::cout << " - " << tap->_max_xid_size << " (random)";
- }
- std::cout << (tap->_transient ? " transient" : " persistent");
- if (tap->_comment)
- std::cout << " [" << tap->_comment << "]";
- std::cout << std::endl;
- }
- }
- }
- ifs.close();
- if (!found)
- {
- std::cout << "ERROR: Failed to find test " << tnum << " in test file \"" << filename <<
- "\"." << std::endl;
- throw rhm::journal::jexception(EXCEPTION_BASE+6,
- "Test data not found in CSV test data file.");
- }
-}
-
-// static method
-void
-jtest::print_compile_defs(bool verbose)
-{
-#ifdef RHM_CLEAN
- cout << "*** WARNING: Compiled with RHM_CLEAN defined." << endl;
-#endif
-#ifdef RHM_TESTVALS
- cout << "*** WARNING: Compiled with RHM_TESTVALS defined." << endl;
-#endif
-#ifdef RHM_JOWRITE
- cout << "*** WARNING: Compiled with RHM_JOWRITE defined." << endl;
-#endif
-#ifdef RHM_WRONLY
- cout << "*** WARNING: Compiled with RHM_WRONLY defined." << endl;
-#endif
-#ifdef RHM_RDONLY
- cout << "*** WARNING: Compiled with RHM_RDONLY defined." << endl;
-#endif
-#ifdef RHM_TIMERS
- cout << "*** WARNING: Compiled with RHM_TIMERS defined." << endl;
-#endif
-#if defined(RHM_CLEAN) || defined(RHM_TESTVALS) || defined(RHM_JOWRITE) || defined(RHM_WRONLY) || defined(RHM_RDONLY) || defined(RHM_TIMERS)
- cout << endl;
-#endif
-
- if (verbose)
- {
-#ifdef JRNL_BIG_ENDIAN
- cout << "JRNL_BIG_ENDIAN defined." << endl;
-#endif
-#ifdef JRNL_LITTLE_ENDIAN
- cout << "JRNL_LITTLE_ENDIAN defined." << endl;
-#endif
-#ifdef JRNL_32_BIT
- cout << "JRNL_32_BIT defined." << endl;
-#endif
-#ifdef JRNL_64_BIT
- cout << "JRNL_64_BIT defined." << endl;
-#endif
- cout << "JRNL_DBLK_SIZE = " << JRNL_DBLK_SIZE << " bytes" << endl;
- cout << "JRNL_SBLK_SIZE = " << JRNL_SBLK_SIZE << " dblks (" <<
- (JRNL_DBLK_SIZE * JRNL_SBLK_SIZE) << " bytes)" << endl;
- cout << "JRNL_RMGR_PAGE_SIZE = " << JRNL_RMGR_PAGE_SIZE << " sblocks (" <<
- (JRNL_DBLK_SIZE * JRNL_SBLK_SIZE * JRNL_RMGR_PAGE_SIZE / 1024.0) << " KiB)" << endl;
- cout << "JRNL_RMGR_PAGES = " << JRNL_RMGR_PAGES << " pages (" <<
- (JRNL_DBLK_SIZE * JRNL_SBLK_SIZE * JRNL_RMGR_PAGE_SIZE * JRNL_RMGR_PAGES / 1024.0) <<
- " KiB)" << endl;
- cout << "JRNL_WMGR_PAGE_SIZE = " << JRNL_WMGR_PAGE_SIZE << " sblocks (" <<
- (JRNL_DBLK_SIZE * JRNL_SBLK_SIZE * JRNL_WMGR_PAGE_SIZE / 1024.0) << " KiB)" << endl;
- cout << "JRNL_WMGR_PAGES = " << JRNL_WMGR_PAGES << " pages (" <<
- (JRNL_DBLK_SIZE * JRNL_SBLK_SIZE * JRNL_WMGR_PAGE_SIZE * JRNL_WMGR_PAGES / 1024.0) <<
- " KiB)" << endl;
- }
-}
Deleted: store/trunk/cpp/tests/jrnl/jtest.hpp
===================================================================
--- store/trunk/cpp/tests/jrnl/jtest.hpp 2008-09-09 19:25:47 UTC (rev 2433)
+++ store/trunk/cpp/tests/jrnl/jtest.hpp 2008-09-09 20:24:44 UTC (rev 2434)
@@ -1,114 +0,0 @@
-/**
-* \file jtest.hpp
-*
-* Test framework for RHM journalling.
-*
-* \author Kim van der Riet
-*
-* Copyright (C) 2007 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 _jtest_hpp_
-#define _jtest_hpp_
-
-#include <cstddef>
-#include "jrnl/jcfg.hpp"
-#include "jrnl/jcntl.hpp"
-#include "jrnl/jexception.hpp"
-#include "msg_producer.hpp"
-#include "msg_consumer.hpp"
-
-#define JOURNAL_ID "Test Journal"
-#define JOURNAL_DIR "jdata"
-#define JOURNAL_BASE_FILENAME "test"
-#define NUM_JFILES 8
-#define JFSIZE_SBLKS 3072
-#define MAX_LINE_LEN 1024
-
-using namespace std;
-
-class jtest
-{
-public:
- struct targs
- {
- u_int32_t _num_msgs;
- std::size_t _min_msg_size;
- std::size_t _max_msg_size;
- bool _auto_deq;
- std::size_t _min_xid_size;
- std::size_t _max_xid_size;
- bool _transient;
- bool _external;
- char* _comment;
- targs();
- targs(const u_int32_t num_msgs, const std::size_t min_msg_size,
- const std::size_t max_msg_size, const bool auto_deq, const std::size_t min_xid_size,
- const std::size_t max_xid_size, const bool transient, const bool external,
- char* comment = NULL);
- };
-
-private:
- static msg_producer::_p_args* p_args;
- static msg_consumer::_c_args* c_args;
- static rhm::journal::jcntl _jc;
- static std::deque<rhm::journal::data_tok*> _dtok_master_list;
- static std::deque<rhm::journal::data_tok*> _dtok_wr_aio_list;
- static std::deque<rhm::journal::data_tok*> _dtok_rd_aio_list;
-
- struct timeval* _start_time;
- struct timeval* _end_time;
- struct timezone* _tz_ptr;
- pthread_t _p_thread;
- pthread_t _c_thread;
-
-public:
- jtest();
- ~jtest();
-
- static void proc_args(int argc, char** argv, char** test_file_name, int* test_num)
- throw (rhm::journal::jexception);
- void initialize(const int test_num, const char* test_csv_file) throw (rhm::journal::jexception);
- void initialize(const targs& ta) throw (rhm::journal::jexception);
- void run() throw (rhm::journal::jexception);
- void report() throw (rhm::journal::jexception);
- void finalize() throw (rhm::journal::jexception);
- static void get_test(targs* tap, const std::string& filename, const unsigned test_num)
- throw (rhm::journal::jexception);
- static void print_compile_defs(bool verbose);
-
- // Methods called by threads
- static void* produce(void* ptr);
- static void* consume(void* ptr);
- static msg_producer _mp;
- static msg_consumer _mc;
-
-private:
- static double time_diff(const struct timeval* start, const struct timeval* end);
- string& report_time(string& str) const;
-
- // AIO callback functions
- static void mp_aio_cb(rhm::journal::jcntl* jc, std::vector<rhm::journal::data_tok*>& dtokl);
- static void mc_aio_cb(rhm::journal::jcntl* jc, std::vector<u_int16_t>& pil);
-};
-
-#endif
Deleted: store/trunk/cpp/tests/jrnl/msg_consumer.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/msg_consumer.cpp 2008-09-09 19:25:47 UTC (rev 2433)
+++ store/trunk/cpp/tests/jrnl/msg_consumer.cpp 2008-09-09 20:24:44 UTC (rev 2434)
@@ -1,390 +0,0 @@
-/**
-* \file msg_consumer.cpp
-*
-* Message producer; part of test framework for RHM journalling
-*
-* \author Kim van der Riet
-*
-* Copyright (C) 2007 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 "msg_consumer.hpp"
-
-#include <cstdlib>
-#include <cstring>
-#include <iostream>
-#include <sstream>
-#include <unistd.h>
-#include "jrnl/jerrno.hpp"
-
-#define EXCEPTION_BASE 0x40
-
-msg_consumer::_c_args::_c_args(rhm::journal::jcntl& jc, const u_int32_t num_msgs,
- const std::size_t min_msg_size, const std::size_t max_msg_size,
- const std::size_t min_xid_size, const std::size_t max_xid_size, const bool transient,
- const bool external):
- _jc(jc),
- _num_msgs(num_msgs),
- _min_msg_size(min_msg_size),
- _max_msg_size(max_msg_size),
- _min_xid_size(min_xid_size),
- _max_xid_size(max_xid_size),
- _transient(transient),
- _external(external),
- _err(0)
-{}
-
-msg_consumer::msg_consumer(std::deque<rhm::journal::data_tok*>& dtok_master_list,
- std::deque<rhm::journal::data_tok*>& aio_cmpl_dtok_list):
- _dtok_master_list(dtok_master_list),
- _aio_cmpl_dtok_list(aio_cmpl_dtok_list),
- _tot_dblks(0),
- _tot_dsize(0)
-{
- instCnt++;
-}
-
-msg_consumer::~msg_consumer()
-{
- for (u_int32_t i=0; i<_dtok_master_list.size(); i++)
- {
- if (_dtok_master_list[i])
- {
- delete _dtok_master_list[i];
- _dtok_master_list[i] = NULL;
- }
- }
- instCnt--;
-}
-
-void
-msg_consumer::initialize(const u_int32_t numMsgs)
-{
- _num_msgs = numMsgs;
-}
-
-void
-msg_consumer::initialize(_c_args* args)
-{
- if (args)
- initialize(args->_num_msgs);
-}
-
-void
-msg_consumer::finalize()
-{
- _tot_dblks = 0;
- _tot_dsize = 0;
- _aio_cmpl_dtok_list.clear();
-}
-
-u_int32_t
-msg_consumer::consume(rhm::journal::jcntl& _jcntl, const u_int32_t num_msgs,
-#ifdef RHM_TIMERS
- const std::size_t, const std::size_t, const std::size_t, const std::size_t,
- const bool, const bool)
-#else
- const std::size_t min_msg_size, const std::size_t max_msg_size,
- const std::size_t min_xid_size, const std::size_t max_xid_size,
- const bool transient_expected, const bool external_expected)
-#endif
- throw (rhm::journal::jexception)
-{
-//std::cout << "msg_consumer::consume() num_msgs=" << num_msgs << std::endl;
- void* datap = NULL;
- std::size_t data_size = 0;
- void* xidp = NULL;
- std::size_t xid_size = 0;
- bool transient_flag = false;
- bool external_flag = false;
-
- u_int32_t msgCntr = 0;
- for (msgCntr = 0; msgCntr < num_msgs && !_interrupt_flag; msgCntr++)
- {
- rhm::journal::data_tok* dtokp = _dtok_master_list[msgCntr];
-//std::cout << " R" << msgCntr << " " << std::flush;
- unsigned aio_sleep_cnt = 0;
- unsigned jempty_sleep_cnt = 0;
- unsigned enq_wait_cnt = 0;
- bool read = false;
- while (!read)
- {
- if (dtokp->wstate() >= rhm::journal::data_tok::ENQ)
- {
- rhm::journal::iores res = _jcntl.read_data_record(&datap, data_size, &xidp,
- xid_size, transient_flag, external_flag, dtokp);
- rhm::journal::data_tok::read_state rs = dtokp->rstate();
- rhm::journal::data_tok::write_state ws = dtokp->wstate();
- switch (res)
- {
- case rhm::journal::RHM_IORES_SUCCESS:
- if (rs != rhm::journal::data_tok::READ || ws != rhm::journal::data_tok::ENQ)
- std::cout << "msg_consumer::consume(): Unexpected state: res=" <<
- iores_str[res] << " ws=" << dtokp->wstate_str() << "; rs=" <<
- dtokp->rstate_str();
- data_size = dtokp->dsize();
- read = true;
- _tot_dblks += dtokp->dblocks_read();
- _tot_dsize += data_size;
-
-#ifndef RHM_TIMERS
- // Comment out these for performance checks/measurements
- check_msg(msgCntr, data_size, min_msg_size, max_msg_size, !external_flag,
- datap);
- check_xid(msgCntr, xid_size, min_xid_size, max_xid_size, true, xidp);
- check_transience(msgCntr, transient_flag, transient_expected);
- check_external(msgCntr, external_flag, external_expected);
- //print_dbug(msgCntr, data_size, _msg_buff, true);
-#endif
- break;
- case rhm::journal::RHM_IORES_AIO_WAIT:
-//std::cout << "a" << std::flush;
- if (rs == rhm::journal::data_tok::READ ||
- ws != rhm::journal::data_tok::ENQ)
- std::cout << "msg_consumer::consume(): Unexpected state: res=" <<
- iores_str[res] << " ws=" << dtokp->wstate_str() << "; rs=" <<
- dtokp->rstate_str();
- if (aio_sleep_cnt >= MAX_AIO_SLEEPS)
- throw rhm::journal::jexception(EXCEPTION_BASE+0,
- "Page cache full (AIO events outstanding for all pages); "
- "exceeced wait time for pages to free.", "msg_consumer",
- "consume");
- usleep(AIO_SLEEP_TIME);
- aio_sleep_cnt++;
- break;
- case rhm::journal::RHM_IORES_EMPTY:
-//std::cout << "e" << std::flush;
- if (rs == rhm::journal::data_tok::READ ||
- ws != rhm::journal::data_tok::ENQ)
- std::cout << "msg_consumer::consume(): Unexpected state: res=" <<
- iores_str[res] << " ws=" << dtokp->wstate_str() << "; rs=" <<
- dtokp->rstate_str();
- if (jempty_sleep_cnt >= MAX_EMPTY_SLEEPS)
- throw rhm::journal::jexception(EXCEPTION_BASE+1,
- "Journal empty (no further data written to journal); "
- "exceeded wait time for journal to fill.", "msg_consumer",
- "consume");
- usleep(EMPTY_SLEEP_TIME);
- jempty_sleep_cnt++;
- break;
- default:
- std::cout << "msg_consumer::consume(): Unexpected msg state: id=" <<
- dtokp->id() << " ms=" << dtokp->wstate_str() << " res=" <<
- iores_str[res] << std::flush;
- }
- }
- else
- {
- if (enq_wait_cnt > MAX_ENQ_WAIT_SLEEPS)
- throw rhm::journal::jexception(EXCEPTION_BASE+2,
- "Exceeded max. wait time for next read token to reach state ENQ.",
- "msg_consumer", "consume");
- usleep(ENQ_WAIT_SLEEP_TIME);
- }
- } // while(!read)
-
- // Clean up allocated message/xid memory
- if (xidp)
- std::free(xidp);
- else if (datap)
- std::free(datap);
- datap = NULL;
- data_size = 0;
- xidp = NULL;
- xid_size = 0;
- transient_flag = false;
- }
- _interrupt_flag = false;
- return msgCntr;
-}
-
-u_int32_t
-msg_consumer::consume(_c_args* args) throw (rhm::journal::jexception)
-{
- return consume(args->_jc, args->_num_msgs, args->_min_msg_size, args->_max_msg_size,
- args->_min_xid_size, args->_max_xid_size, args->_transient, args->_external);
-}
-
-void
-msg_consumer::aio_callback(rhm::journal::jcntl* /*jc*/, std::vector<u_int16_t>& /*pil*/)
-{}
-
-void
-msg_consumer::interrupt()
-{
- _interrupt_flag = true;
-}
-
-void
-msg_consumer::check_msg(const u_int32_t msgCntr, const std::size_t msg_size,
- const std::size_t min_msg_size, const std::size_t max_msg_size, bool chk_data,
- void* datap) const
- throw (rhm::journal::jexception)
-{
- if (max_msg_size > 0 && (msg_size < min_msg_size || msg_size > max_msg_size))
- {
- std::stringstream ss;
- ss << "Message " << msgCntr << " of size " << msg_size;
- if (min_msg_size == max_msg_size)
- ss << " is valid, but exptected size is " << min_msg_size;
- else
- {
- ss << " is valid, but exptected size must lie between " << min_msg_size;
- ss << " and " << max_msg_size;
- }
- throw rhm::journal::jexception(EXCEPTION_BASE+3, ss.str().c_str(), "msg_consumer",
- "check_msg");
- }
- if (chk_data)
- {
- for (unsigned i=0; i<msg_size; i++)
- {
- char found = ((char*)datap)[i];
- char expected = '0' + (((msgCntr%10) + i + 1) % 10);
- if (found != expected)
- {
- std::stringstream ss;
- ss << "Message " << msgCntr << " failed content check at char " << i;
- ss << ": found \'" << found << "\'; expected \'" << expected << "\'";
- throw rhm::journal::jexception(EXCEPTION_BASE+4, ss.str().c_str(), "msg_consumer",
- "check_msg");
- }
- }
- }
-}
-
-void
-msg_consumer::check_xid(const u_int32_t msgCntr, const std::size_t xid_size,
- const std::size_t min_xid_size, const std::size_t max_xid_size, bool chk_xid_data,
- void* xidp) const
- throw (rhm::journal::jexception)
-{
- if (max_xid_size > 0 && (xid_size < min_xid_size || xid_size > max_xid_size))
- {
- std::stringstream ss;
- ss << "Message " << msgCntr << " of size " << xid_size;
- if (min_xid_size == max_xid_size)
- ss << " is valid, but exptected size is " << max_xid_size;
- else
- {
- ss << " is valid, but exptected size must lie between " << min_xid_size;
- ss << " and " << max_xid_size;
- }
- throw rhm::journal::jexception(EXCEPTION_BASE+5, ss.str().c_str(), "msg_consumer",
- "check_xid");
- }
- if (chk_xid_data)
- {
- int xid_num_size = xid_size - 5 > 16 ? 16 : xid_size - 5;
- std::stringstream xid;
- xid << "xid:" << std::hex << std::setfill('0') << std::setw(xid_num_size) << msgCntr << ":";
- for (unsigned i = xid_num_size + 5; i < xid_size; i++)
- xid << (char)('a' + (i%26));
- for (unsigned i=0; i<xid_size; i++)
- {
- char found = ((char*)xidp)[i];
- char expected = xid.str().at(i);
- if (found != expected)
- {
- std::stringstream ss;
- ss << "Message " << msgCntr << " failed XID check at char " << i;
- ss << ": found \'" << found << "\'; expected \'" << expected << "\'";
- throw rhm::journal::jexception(EXCEPTION_BASE+6, ss.str().c_str(), "msg_consumer",
- "check_xid");
- }
- }
- }
-}
-
-void
-msg_consumer::check_transience(const u_int32_t msgCntr, const bool transient_flag,
- const bool transient_expected_flag) const throw (rhm::journal::jexception)
-{
- if ((transient_flag && !transient_expected_flag) ||
- (!transient_flag && transient_expected_flag))
- {
- std::stringstream ss;
- ss << "Message " << msgCntr << " failed transience check: found ";
- ss << (transient_flag?"transient":"persistent") << "; expected ";
- ss << (transient_expected_flag?"transient":"persistent") << ".";
- throw rhm::journal::jexception(EXCEPTION_BASE+7, ss.str().c_str(), "msg_consumer",
- "check_transience");
- }
-}
-
-void
-msg_consumer::check_external(const u_int32_t msgCntr, const bool external_flag,
- const bool external_expected_flag) const throw (rhm::journal::jexception)
-{
- if ((external_flag && !external_expected_flag) ||
- (!external_flag &&external_expected_flag))
- {
- std::stringstream ss;
- ss << "Message " << msgCntr << " failed external check: found ";
- ss << (external_flag?"external":"internal") << "; expected ";
- ss << (external_expected_flag?"external":"internal") << ".";
- throw rhm::journal::jexception(EXCEPTION_BASE+8, ss.str().c_str(), "msg_consumer",
- "check_transience");
- }
-}
-
-void
-msg_consumer::print_dbug(const u_int32_t msgCntr, const std::size_t msg_size, char* buff,
- const bool show_msg) const
-{
-// std::cout << 'c' << std::flush;
- std::cout << "msg_consumer::consume(): read msg " << msgCntr << " size=" << msg_size;
- if (show_msg)
- {
- std::cout << " msg=\"";
- if (msg_size <= 50)
- std::cout << buff;
- else
- {
- std::size_t i=0;
- for (; i<20; i++)
- std::cout << buff[i];
- std::cout << " ... ";
- i=msg_size-20;
- for (; i<msg_size; i++)
- std::cout << buff[i];
- }
- std::cout << "\"";
- }
- std::cout << std::endl;
- std::cout.flush();
-}
-
-// *** Static member declarations ***
-
-const char* msg_consumer::iores_str[] = {
- "RHM_IORES_SUCCESS",
- "RHM_IORES_AIO_WAIT",
- "RHM_IORES_EMPTY",
- "RHM_IORES_FULL",
- "RHM_IORES_BUSY"
- };
-
-u_int16_t msg_consumer::instCnt = 0;
-// const std::size_t msg_consumer::buffSize = JRNL_DBLK_SIZE * JRNL_SBLK_SIZE * JRNL_FILE_SIZE * JRNL_NUM_FILES;
-// char msg_consumer::_msg_buff[msg_consumer::buffSize];
-bool msg_consumer::_interrupt_flag = false;
Deleted: store/trunk/cpp/tests/jrnl/msg_consumer.hpp
===================================================================
--- store/trunk/cpp/tests/jrnl/msg_consumer.hpp 2008-09-09 19:25:47 UTC (rev 2433)
+++ store/trunk/cpp/tests/jrnl/msg_consumer.hpp 2008-09-09 20:24:44 UTC (rev 2434)
@@ -1,115 +0,0 @@
-/**
-* \file msg_consumer.hpp
-*
-* Message producer; part of test framework for RHM journalling
-*
-* \author Kim van der Riet
-*
-* Copyright (C) 2007 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 msg_consumer_hpp
-#define msg_consumer_hpp
-
-#include <cstddef>
-#include "jrnl/jcntl.hpp"
-#include "jrnl/jexception.hpp"
-
-#define MAX_AIO_SLEEPS 500
-#define AIO_SLEEP_TIME 1000
-#define MAX_ENQ_WAIT_SLEEPS 1000
-
-#define MAX_EMPTY_SLEEPS 1000
-#define EMPTY_SLEEP_TIME 10000
-#define ENQ_WAIT_SLEEP_TIME 1000
-
-class msg_consumer
-{
-public:
- struct _c_args
- {
- rhm::journal::jcntl& _jc;
- u_int32_t _num_msgs;
- std::size_t _min_msg_size;
- std::size_t _max_msg_size;
- std::size_t _min_xid_size;
- std::size_t _max_xid_size;
- bool _transient;
- bool _external;
- u_int32_t _err;
- _c_args(rhm::journal::jcntl& jc, const u_int32_t num_msgs, const std::size_t min_msg_size,
- const std::size_t max_msg_size, const std::size_t min_xid_size,
- const std::size_t max_xid_size, const bool transient, const bool external);
- };
-
- static const char* iores_str[];
-
-private:
- static u_int16_t instCnt;
-// static const std::size_t buffSize;
-// static char _msg_buff[];
- static bool _interrupt_flag;
- u_int32_t _num_msgs;
- std::deque<rhm::journal::data_tok*>& _dtok_master_list; // One dtok per msg to be received
- std::deque<rhm::journal::data_tok*>& _aio_cmpl_dtok_list; // Dtoks from completed AIOs go here
- u_int64_t _tot_dblks;
- u_int64_t _tot_dsize;
-
-public:
- msg_consumer(std::deque<rhm::journal::data_tok*>& dtok_master_list,
- std::deque<rhm::journal::data_tok*>& aio_cmpl_dtok_list);
- ~msg_consumer();
-
- void initialize(const u_int32_t numMsgs);
- void initialize(_c_args* args);
- void finalize();
-
- u_int32_t consume(rhm::journal::jcntl& _jcntl, const u_int32_t numMsgs,
- const std::size_t min_msg_size, const std::size_t max_msg_size,
- const std::size_t min_xid_size, const std::size_t max_xid_size,
- const bool transient_expected, const bool external_expected)
- throw (rhm::journal::jexception);
- u_int32_t consume(_c_args* args) throw (rhm::journal::jexception);
- void aio_callback(rhm::journal::jcntl* jc, std::vector<u_int16_t>& pil);
-
- inline u_int64_t get_tot_dblks() const { return _tot_dblks; }
- inline u_int64_t get_tot_dsize() const { return _tot_dsize; }
- inline std::deque<rhm::journal::data_tok*>& aio_dtokl() { return _aio_cmpl_dtok_list; }
- static void interrupt();
-private:
- void check_msg(const u_int32_t msgCntr, const std::size_t msg_size,
- const std::size_t min_msg_size, const std::size_t max_msg_size, bool chk_data,
- void* datap) const
- throw (rhm::journal::jexception);
- void check_xid(const u_int32_t msgCntr, const std::size_t xid_size,
- const std::size_t min_xid_size, const std::size_t max_xid_size, bool chk_xid_data,
- void* xidp) const
- throw (rhm::journal::jexception);
- void check_transience(const u_int32_t msgCntr, const bool transient_flag,
- const bool transient_expected_flag) const throw (rhm::journal::jexception);
- void check_external(const u_int32_t msgCntr, const bool external_flag,
- const bool external_expected_flag) const throw (rhm::journal::jexception);
- void print_dbug(const u_int32_t msgCntr, const std::size_t msg_size, char* buff,
- const bool show_msg = false) const;
-
-}; // class msg_consumer
-
-#endif // ifndef msg_consumer_hpp
Deleted: store/trunk/cpp/tests/jrnl/msg_producer.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/msg_producer.cpp 2008-09-09 19:25:47 UTC (rev 2433)
+++ store/trunk/cpp/tests/jrnl/msg_producer.cpp 2008-09-09 20:24:44 UTC (rev 2434)
@@ -1,510 +0,0 @@
-/**
-* \file msg_producer.cpp
-*
-* Message producer; part of test framework for RHM journalling
-*
-* \author Kim van der Riet
-*
-* Copyright (C) 2007 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 "msg_producer.hpp"
-
-#include <cassert>
-#include <cstdlib>
-#include <iostream>
-#include <sstream>
-
-#define EXCEPTION_BASE 0x50
-
-msg_producer::_p_args::_p_args(rhm::journal::jcntl& jc, u_int32_t num_msgs,
- std::size_t min_msg_size, std::size_t max_msg_size, bool auto_dequeue,
- std::size_t min_xid_size, std::size_t max_xid_size, bool transient, bool external):
- _jc(jc),
- _num_msgs(num_msgs),
- _min_msg_size(min_msg_size),
- _max_msg_size(max_msg_size),
- _auto_dequeue(auto_dequeue),
- _min_xid_size(min_xid_size),
- _max_xid_size(max_xid_size),
- _transient(transient),
- _external(external),
- _err(0)
-{}
-
-msg_producer::msg_producer(std::deque<rhm::journal::data_tok*>& dtok_master_list,
- std::deque<rhm::journal::data_tok*>& aio_cmpl_dtok_list):
- _jcptr(NULL),
- _num_msgs(0),
- _num_msgs_enq_subm(0),
- _num_msgs_enq(0),
- _num_msgs_deq_subm(0),
- _num_msgs_deq(0),
- _num_txn_subm(0),
- _num_txn(0),
- _dtok_master_list(dtok_master_list),
- _aio_cmpl_dtok_list(aio_cmpl_dtok_list),
- _tot_dblks(0),
- _tot_dsize(0)
-{
- instance_cnt++;
- init_msg_buff();
- _aio_cmpl_dtok_list.clear();
- _dd_dtok_list.clear();
-}
-
-msg_producer::~msg_producer()
-{
- instance_cnt--;
-}
-
-void
-msg_producer::initialize(const u_int32_t numMsgs, bool auto_dequeue)
-{
- _num_msgs = numMsgs;
- _auto_dequeue = auto_dequeue;
-}
-
-void
-msg_producer::initialize(_p_args* args)
-{
- if (args)
- initialize(args->_num_msgs, args->_auto_dequeue);
-}
-
-void
-msg_producer::finalize()
-{
- _num_msgs_enq_subm = 0;
- _num_msgs_enq = 0;
- _num_msgs_deq_subm = 0;
- _num_msgs_deq = 0;
- _num_txn_subm = 0;
- _num_txn = 0;
- _tot_dblks = 0;
- _tot_dsize = 0;
- _aio_cmpl_dtok_list.clear();
- _dd_dtok_list.clear();
-}
-
-u_int32_t
-msg_producer::produce(rhm::journal::jcntl& jc, const std::size_t minMsgSize,
- const std::size_t maxMsgSize, const std::size_t minXidSize, const std::size_t maxXidSize,
- const bool transient, const bool external)
- throw (rhm::journal::jexception)
-{
- _jcptr = &jc;
- if (!_num_msgs)
- return 0;
- if (maxMsgSize > _msg_buff_size)
- throw rhm::journal::jexception(EXCEPTION_BASE+0,
- "Message size exceeds internal buffer limit", "msg_producer", "produce");
-
- {
-//std::cout << "[" << _num_msgs << "]" << std::flush;
- for(u_int32_t msgCntr = 0; msgCntr < _num_msgs && !_interrupt_flag; msgCntr++)
- {
- unsigned aio_sleep_cnt = 0;
- unsigned jfull_sleep_cnt = 0;
- std::size_t xid_size = maxXidSize;
- if (minXidSize < maxXidSize)
- {
- std::size_t sizeRange = maxXidSize - minXidSize + 1;
- xid_size = minXidSize + (int)(1.0*std::rand()*sizeRange/(RAND_MAX + 1.0));
- }
- int xid_num_size = xid_size - 5 > 16 ? 16 : xid_size - 5;
- std::stringstream xid;
- xid << "xid:" << std::hex << std::setfill('0');
- xid << std::setw(xid_num_size) << msgCntr << ":";
- for (unsigned i = xid_num_size + 5; i < xid_size; i++)
- xid << (char)('a' + (i%26));
- std::size_t size = maxMsgSize;
- if (minMsgSize < maxMsgSize)
- {
- std::size_t sizeRange = maxMsgSize - minMsgSize + 1;
- size = minMsgSize + (int)(1.0*std::rand()*sizeRange/(RAND_MAX + 1.0));
- }
- const void* const msg = (char*)_msg_buff + (msgCntr%10);
- rhm::journal::data_tok* dtokp = _dtok_master_list[msgCntr];
-//std::cout << " E" << dtokp->id() << /*"-" << dtokp->wstate_str() <<*/ " " << std::flush;
- bool written = false;
- while (!written)
- {
- rhm::journal::iores eres;
- if (maxXidSize)
- {
- if (external)
- eres = jc.enqueue_extern_txn_data_record(size, dtokp, xid.str(), transient);
- else
- eres = jc.enqueue_txn_data_record(msg, size, size, dtokp, xid.str(),
- transient);
- }
- else
- {
- if (external)
- eres = jc.enqueue_extern_data_record(size, dtokp, transient);
- else
- eres = jc.enqueue_data_record(msg, size, size, dtokp, transient);
- }
- rhm::journal::data_tok::write_state ws = dtokp->wstate();
- const char* wsstr = dtokp->wstate_str();
- switch (eres)
- {
- case rhm::journal::RHM_IORES_SUCCESS:
- if (ws >= rhm::journal::data_tok::ENQ_SUBM)
- {
- written = true;
- _num_msgs_enq_subm++;
- _tot_dblks += dtokp->dblocks_written();
- _tot_dsize += dtokp->dsize();
- }
- else
- std::cout << "msg_producer::produce() Unexpected msg state: id=" <<
- dtokp->id() << " ws=" << wsstr << " eres=" << iores_str(eres) <<
- std::flush;
- break;
- case rhm::journal::RHM_IORES_AIO_WAIT:
- if (ws >= rhm::journal::data_tok::ENQ_SUBM)
- std::cout << "msg_producer::produce() Unexpected msg state: id=" <<
- dtokp->id() << " ws=" << wsstr << " eres=" << iores_str(eres) <<
- std::flush;
- if (aio_sleep_cnt >= MAX_AIO_SLEEPS)
- throw rhm::journal::jexception(EXCEPTION_BASE+2,
- "Page cache full (AIO events outstanding for all pages); "
- "exceeded wait time for pages to free.", "msg_producer",
- "produce");
-//std::cout << "$" << dtokp->id() << " " << std::flush;
- usleep(AIO_SLEEP_TIME);
- jc.get_wr_events();
- aio_sleep_cnt++;
- break;
- case rhm::journal::RHM_IORES_FULL:
- if (ws >= rhm::journal::data_tok::ENQ_SUBM)
- {
- written = true;
- _tot_dblks += dtokp->dblocks_written();
- _tot_dsize += dtokp->dsize();
- std::cout << "WARNING: Journal full." << std::flush;
- }
- if (jfull_sleep_cnt >= MAX_FULL_SLEEPS)
- throw rhm::journal::jexception(EXCEPTION_BASE+3,
- "Journal full (next file to write still has undequeued data); "
- "exceeded wait time for journal to free.", "msg_producer",
- "produce");
-//std::cout << "#" << dtokp->id() << " " << std::flush;
- usleep(FULL_SLEEP_TIME);
- jfull_sleep_cnt++;
- break;
- default:
- std::stringstream ss;
- ss << "msg_producer::produce() Unexpected msg state: id=" <<
- dtokp->id() << " ws=" << wsstr << " res=" << iores_str(eres);
- throw rhm::journal::jexception(EXCEPTION_BASE+4, ss.str().c_str(),
- "msg_producer", "produce");
- }
-
- //print_dbug(msgCntr, size, (char*)msg, true);
- }
- // If transactional, write commit
- if (xid_size)
- {
- written = false;
- // Create new data_tok, push to back of maseter list
- rhm::journal::data_tok* txn_dtokp = new rhm::journal::data_tok;
- _dtok_master_list.push_back(txn_dtokp);
-//std::cout << " T" << dtokp->id() << " " << std::flush;
- while (!written)
- {
- rhm::journal::iores dres;
- dres = _jcptr->txn_commit(txn_dtokp, dtokp->xid());
-
- const char* wsstr = dtokp->wstate_str();
- switch (dres)
- {
- case rhm::journal::RHM_IORES_SUCCESS:
- written = true;
- _num_txn_subm++;
- break;
- case rhm::journal::RHM_IORES_AIO_WAIT:
- if (aio_sleep_cnt >= MAX_AIO_SLEEPS)
- throw rhm::journal::jexception(EXCEPTION_BASE+8,
- "Page cache full (AIO events outstanding for all pages); "
- "exceeded wait time for pages to free.", "msg_producer",
- "send_deferred_dequeues");
- jc.get_wr_events();
- usleep(AIO_SLEEP_TIME);
- aio_sleep_cnt++;
- break;
- default:
- std::stringstream ss;
- ss << "msg_producer::send_deferred_dequeues() "
- "Unexpected msg state: id=" << dtokp->id() << " ws=" <<
- wsstr << " res=" << iores_str(dres);
- throw rhm::journal::jexception(EXCEPTION_BASE+9, ss.str().c_str(),
- "msg_producer", "send_deferred_dequeues");
- }
- }
- }
-
- // Submit deferred dequeues (if any)
- if (_auto_dequeue)
- {
-//std::cout << "auto_dequeue: " << _dd_dtok_list.size() << " dequeues waiting. " << std::flush;
- u_int32_t cnt = 0;
- send_deferred_dequeues(jc);
- while (!_dd_dtok_list.empty() && !_interrupt_flag)
- {
- if (++cnt > 10000)
- throw rhm::journal::jexception(EXCEPTION_BASE+5,
- "Timeout waiting for all messages to be read.", "msg_producer",
- "produce");
- usleep(1000);
- send_deferred_dequeues(jc);
- }
-//std::cout << "auto_dequeue: done. " << std::flush;
- }
- }
- jrnl_flush(jc, _num_msgs);
- }
- _interrupt_flag = false;
-//std::cout << std::endl;
-// std::cout << std::dec;
-// std::cout << "Messages sent = " << _num_msgs << std::endl;
-// std::cout << "Total enqueue events = " << _num_msgs_enq << std::endl;
-// std::cout << "Total dequeue events = " << _num_msgs_deq << std::endl;
-//std::cout << std::endl;
- return _num_msgs;
-}
-
-u_int32_t
-msg_producer::produce(_p_args* args) throw (rhm::journal::jexception)
-{
- return produce(args->_jc, args->_min_msg_size, args->_max_msg_size, args->_min_xid_size,
- args->_max_xid_size, args->_transient, args->_external);
-}
-
-void
-msg_producer::aio_callback(rhm::journal::jcntl* /*jc*/, std::vector<rhm::journal::data_tok*>& dtokl)
-{
- for (std::vector<rhm::journal::data_tok*>::const_iterator i=dtokl.begin(); i!=dtokl.end(); i++)
- {
- rhm::journal::data_tok::write_state st = (*i)->wstate();
- if (st == rhm::journal::data_tok::ENQ)
- {
- _num_msgs_enq++;
-//std::cout << " >E" << dtokp->id() << " " << std::flush;
- _dd_dtok_list.push_back(*i);
- }
- else if (st == rhm::journal::data_tok::DEQ)
- {
-//std::cout << " >D" << dtokp->id() << " " << std::flush;
- _num_msgs_deq++;
- }
- else if (st == rhm::journal::data_tok::ABORTED ||
- st == rhm::journal::data_tok::COMMITTED)
- {
-//std::cout << " >T" << dtokp->id() << " " << std::flush;
- _num_txn++;
- }
-//else std::cout << " >?" << dtokp->id() << " st=" << dtokp->wstate_str() << " " << std::flush;
- }
-}
-
-void
-msg_producer::interrupt()
-{
- _interrupt_flag = true;
-}
-
-void
-msg_producer::init_msg_buff()
-{
- for (unsigned int i=0; i<_msg_buff_size; i++)
- _msg_buff[i] = '0' + (i + 1)%10;
-}
-
-void
-msg_producer::send_deferred_dequeues(rhm::journal::jcntl& jc)
-{
- for (unsigned i=0; i<_dd_dtok_list.size(); i++)
- {
- rhm::journal::data_tok* ddtokp = _dd_dtok_list[i];
-
-#ifndef RHM_WRONLY
- // Wait until data token is read before dequeueing
- if (ddtokp->rstate() == rhm::journal::data_tok::READ)
-#endif
- {
-//std::cout << " D" << ddtokp->id() << " " << std::flush;
- _dd_dtok_list.erase(_dd_dtok_list.begin() + i--);
- unsigned aio_sleep_cnt;
- bool written;
- if (_auto_dequeue)
- {
- aio_sleep_cnt = 0;
- written = false;
- while (!written)
- {
- rhm::journal::iores dres;
- if (ddtokp->has_xid())
- dres = _jcptr->dequeue_txn_data_record(ddtokp, ddtokp->xid());
- else
- dres = _jcptr->dequeue_data_record(ddtokp);
-
- const char* wsstr = ddtokp->wstate_str();
- switch (dres)
- {
- case rhm::journal::RHM_IORES_SUCCESS:
- written = true;
- _num_msgs_deq_subm++;
- break;
- case rhm::journal::RHM_IORES_AIO_WAIT:
- if (aio_sleep_cnt >= MAX_AIO_SLEEPS)
- throw rhm::journal::jexception(EXCEPTION_BASE+6,
- "Page cache full (AIO events outstanding for all pages); "
- "exceeded wait time for pages to free.", "msg_producer",
- "send_deferred_dequeues");
-//std::cout << "$" << dres << " " << std::flush;
- jc.get_wr_events();
- usleep(AIO_SLEEP_TIME);
- aio_sleep_cnt++;
- break;
- default:
- std::stringstream ss;
- ss << "Unexpected msg state: id=" << ddtokp->id();
- ss << " ws=" << wsstr << " res=" << iores_str(dres);
- throw rhm::journal::jexception(EXCEPTION_BASE+7, ss.str().c_str(),
- "msg_producer", "send_deferred_dequeues");
- } // switch (dres)
- } // while (!written)
- } // if (_auto_dequeue)
- }
- }
-}
-
-void
-msg_producer::jrnl_flush(rhm::journal::jcntl& jc, u_int32_t num_msgs_sent)
-{
-//std::cout << "msg_producer::jrnl_flush(" << num_msgs_sent << ")" << std::endl << std::flush;
- // Clear any unsent enqueues in buffer, then wait for all enqueues to return
- unsigned flush_cnt = 0;
- assert(num_msgs_sent == _num_msgs_enq_subm);
- if (_num_msgs_enq < _num_msgs_enq_subm)
- {
- jc.flush();
- while (_num_msgs_enq < _num_msgs_enq_subm && !_interrupt_flag)
- {
- if (flush_cnt >= MAX_FLUSH_SLEEPS)
- {
- std::stringstream ss;
- ss << "Journal flush phase 1 failed, _num_msgs_enq=" << _num_msgs_enq;
- ss << " num_msgs_sent=" << num_msgs_sent;
- throw rhm::journal::jexception(EXCEPTION_BASE+10, ss.str().c_str(), "msg_producer",
- "jrnl_flush");
- }
-//std::cout << "+" << std::flush;
- jc.get_wr_events();
- usleep(FLUSH_SLEEPTIME);
- flush_cnt++;
- }
- }
-
- // Submit deferred dequeues (if any)
- if (_auto_dequeue)
- {
-//std::cout << "auto_dequeue: " << _dd_dtok_list.size() << " dequeues waiting. " << std::flush;
- u_int32_t cnt = 0;
- send_deferred_dequeues(jc);
- while (!_dd_dtok_list.empty() && !_interrupt_flag)
- {
- if (++cnt > 10000)
- throw rhm::journal::jexception(EXCEPTION_BASE+11,
- "Timeout waiting for all messages to be read.", "msg_producer",
- "jrnl_flush");
- usleep(1000);
- send_deferred_dequeues(jc);
- }
-//std::cout << "auto_dequeue: done. " << std::flush;
-
- // Clear any unsent dequeues in buffer, then wait for all dequeues to return
- flush_cnt = 0;
-//std::cout << "_num_msgs_deq_subm=" << _num_msgs_deq_subm << std::endl << std::flush;
- assert(num_msgs_sent == _num_msgs_deq_subm);
- if (_num_msgs_deq < _num_msgs_deq_subm || _num_txn < _num_txn_subm)
- {
- jc.flush();
- while ((_num_msgs_deq < _num_msgs_deq_subm || _num_txn < _num_txn_subm) &&
- !_interrupt_flag)
- {
- if (flush_cnt >= MAX_FLUSH_SLEEPS)
- {
- std::stringstream ss;
- ss << "Journal flush phase 2 failed, _num_msgs_deq=" << _num_msgs_deq;
- ss << " num_msgs_sent=" << num_msgs_sent;
- throw rhm::journal::jexception(EXCEPTION_BASE+12, ss.str().c_str(),
- "msg_producer", "jrnl_flush");
- }
-//std::cout << "*" << std::flush;
- jc.get_wr_events();
- usleep(1000);
- flush_cnt++;
- }
- }
- }
-}
-
-void
-msg_producer::print_dbug(u_int32_t msg_cnt, std::size_t msg_size, char* _msg_buff,
- bool show_msg) const
-{
- std::cout << "msg_producer::produce(): wrote msg " << msg_cnt << " size=" << msg_size;
- if (show_msg)
- {
- std::cout << " msg=\"";
- if (msg_size <= 50)
- {
- // Since _msg_buff points to a *very* large buffer of data, we must still
- // count out how much we are printing here.
- for (std::size_t i=0; i<msg_size; i++)
- std::cout << _msg_buff[i];
- }
- else
- {
- std::size_t i=0;
- for (; i<20; i++)
- std::cout << _msg_buff[i];
- std::cout << " ... ";
- i=msg_size-20;
- for (; i<msg_size; i++)
- std::cout << _msg_buff[i];
- }
- std::cout << "\"";
- }
- std::cout << std::endl;
- std::cout.flush();
-}
-
-u_int16_t msg_producer::instance_cnt = 0;
-const std::size_t msg_producer::_msg_buff_size = 0x1000000;
-char msg_producer::_msg_buff[msg_producer::_msg_buff_size];
-bool msg_producer::_interrupt_flag = false;
-
Deleted: store/trunk/cpp/tests/jrnl/msg_producer.hpp
===================================================================
--- store/trunk/cpp/tests/jrnl/msg_producer.hpp 2008-09-09 19:25:47 UTC (rev 2433)
+++ store/trunk/cpp/tests/jrnl/msg_producer.hpp 2008-09-09 20:24:44 UTC (rev 2434)
@@ -1,114 +0,0 @@
-/**
-* \file msg_producer.hpp
-*
-* Message producer; part of test framework for RHM journalling
-*
-* \author Kim van der Riet
-*
-* Copyright (C) 2007 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 msg_producer_hpp
-#define msg_producer_hpp
-
-#include <cstddef>
-#include "jrnl/jcntl.hpp"
-
-#define MAX_AIO_SLEEPS 500
-#define AIO_SLEEP_TIME 1000
-
-#define MAX_FULL_SLEEPS 1000
-#define FULL_SLEEP_TIME 10000
-
-#define MAX_FLUSH_SLEEPS 1000
-#define FLUSH_SLEEPTIME 1000
-
-class msg_producer
-{
-public:
- struct _p_args
- {
- rhm::journal::jcntl& _jc;
- u_int32_t _num_msgs;
- std::size_t _min_msg_size;
- std::size_t _max_msg_size;
- bool _auto_dequeue;
- std::size_t _min_xid_size;
- std::size_t _max_xid_size;
- bool _transient;
- bool _external;
- u_int32_t _err;
- _p_args(rhm::journal::jcntl& jc, u_int32_t num_msgs, std::size_t min_msg_size,
- std::size_t max_msg_size, bool auto_dequeue, std::size_t min_xid_size,
- std::size_t max_xid_size, bool transient, bool external);
- };
-
-private:
- static u_int16_t instance_cnt;
- static const std::size_t _msg_buff_size;
- static char _msg_buff[];
- static bool _interrupt_flag;
- rhm::journal::jcntl* _jcptr;
- u_int32_t _num_msgs;
- bool _auto_dequeue;
- u_int32_t _num_msgs_enq_subm;
- u_int32_t _num_msgs_enq;
- u_int32_t _num_msgs_deq_subm;
- u_int32_t _num_msgs_deq;
- u_int32_t _num_txn_subm;
- u_int32_t _num_txn;
- std::deque<rhm::journal::data_tok*>& _dtok_master_list; // One dtok per msg to be sent
- std::deque<rhm::journal::data_tok*>& _aio_cmpl_dtok_list; // Dtoks from completed AIOs go here
- std::deque<rhm::journal::data_tok*> _dd_dtok_list; // Deferred dequeues
- u_int64_t _tot_dblks;
- u_int64_t _tot_dsize;
-
-public:
- msg_producer(std::deque<rhm::journal::data_tok*>& dtok_master_list,
- std::deque<rhm::journal::data_tok*>& aio_cmpl_dtok_list);
- ~msg_producer();
-
- void initialize(const u_int32_t numMsgs, bool auto_dequeue);
- void initialize(_p_args* args);
- void finalize();
-
- u_int32_t produce(rhm::journal::jcntl& jc, const std::size_t minMsgSize,
- const std::size_t maxMsgSize, const std::size_t minXidSize,
- const std::size_t maxXidSize, const bool transient, const bool external)
- throw (rhm::journal::jexception);
- u_int32_t produce(_p_args* args) throw (rhm::journal::jexception);
- void aio_callback(rhm::journal::jcntl* jc, std::vector<rhm::journal::data_tok*>& dtokl);
-
- inline u_int64_t get_tot_dblks() const { return _tot_dblks; }
- inline u_int64_t get_tot_dsize() const { return _tot_dsize; }
- inline std::deque<rhm::journal::data_tok*>& aio_dtokl() { return _aio_cmpl_dtok_list; }
- static void interrupt();
-
-private:
- void init_msg_buff();
- void send_deferred_dequeues(rhm::journal::jcntl& jc);
- void jrnl_flush(rhm::journal::jcntl& jc, u_int32_t num_msgs_sent);
- void print_dbug(u_int32_t msg_cnt, std::size_t msg_size, char* _msg_buff,
- bool show_msg = false) const;
-
-}; // class msg_producer
-
-#endif // ifndef msg_producer_hpp
Deleted: store/trunk/cpp/tests/jrnl/rtest
===================================================================
--- store/trunk/cpp/tests/jrnl/rtest 2008-09-09 19:25:47 UTC (rev 2433)
+++ store/trunk/cpp/tests/jrnl/rtest 2008-09-09 20:24:44 UTC (rev 2434)
@@ -1,550 +0,0 @@
-#!/bin/bash
-
-# Copyright (C) 2007 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.
-
-JDATA_DIR=jdata
-TAR_DIR=rd_test_jrnls
-NULL_FILE=/dev/null
-TEMP_T_FILE=/tmp/t.txt
-TEMP_C_FILE=/tmp/c.txt
-TEMP_V_FILE=/tmp/v.txt
-
-NUM_JFILES=8
-VG_ITERATIONS=1
-VG_NORM_FILESIZE=11
-#VG_NORM_FILESIZE=18 # RHEL5 triggers extra valgrind messages when pthreads are in use
-
-# Write test
-W_DO_TEST=T
-W_TEST_FILE=wtests.csv
-W_TEST_START=0
-W_TEST_STOP=234
-W_NITER=5
-
-# Read test
-R_DO_TEST=T
-R_TEST_FILE=rtests.csv
-R_TEST_START=0
-R_TEST_STOP=164
-R_NITER=5
-
-# Read-Write test
-RW_DO_TEST=T
-RW_TEST_FILE=rwtests.csv
-RW_TEST_START=0
-RW_TEST_STOP=186
-RW_NITER=5
-
-RM=rm
-RM_DIR="${RM} -rf"
-TEST_PROG="./jtest"
-CHK_PROG="./janalyze.py"
-VALGRIND="valgrind -q --track-fds=yes --leak-check=full --leak-resolution=high --show-reachable=yes"
-#VALGRIND="valgrind -q --track-fds=yes --leak-check=full --leak-resolution=high --show-reachable=yes --suppressions=/usr/lib/valgrind/glibc-2.5.supp"
-MAKE="make -f Makefile.rtest"
-
-
-function usage
-{
- echo "Usage:"
- echo " rtest [w [start [stop [numit]]]] [r [start [stop [numit]]]] [rw start [stop [numit]]]]"
-}
-
-function print_test_args
-{
- echo "Test summary:"
- echo -n " jwtest: "
- if [[ ${W_DO_TEST} == T ]]; then
- if (( ${W_TEST_START} == ${W_TEST_STOP} )); then
- echo "${W_TEST_START} x ${W_NITER}"
- else
- echo "${W_TEST_START} - ${W_TEST_STOP} x ${W_NITER}"
- fi
- else
- echo "disabled"
- fi
- echo -n " jrtest: "
- if [[ ${R_DO_TEST} == T ]]; then
- if (( ${R_TEST_START} == ${R_TEST_STOP} )); then
- echo "${R_TEST_START} x ${R_NITER}"
- else
- echo "${R_TEST_START} - ${R_TEST_STOP} x ${R_NITER}"
- fi
- else
- echo "disabled"
- fi
- echo -n " jrwtest: "
- if [[ ${RW_DO_TEST} == T ]]; then
- if (( ${RW_TEST_START} == ${RW_TEST_STOP} )); then
- echo "${RW_TEST_START} x ${RW_NITER}"
- else
- echo "${RW_TEST_START} - ${RW_TEST_STOP} x ${RW_NITER}"
- fi
- else
- echo "disabled"
- fi
-}
-
-function assign_test_args
-{
- if (( $# < 1 )); then
- echo "assign_test_args args!"
- return -1
- fi
- tt=$1
- tstart=$2
- tstop=$3
- iter=$4
- case ${tt} in
- r)
- if [[ -n ${tstart} ]]; then
- R_TEST_START=${tstart}
- if [[ -n ${tstop} ]]; then
- R_TEST_STOP=${tstop}
- if [[ -n ${iter} ]]; then
- R_NITER=${iter}
- fi
- else
- R_TEST_STOP=${tstart}
- fi
- fi
- ;;
- w)
- if [[ -n ${tstart} ]]; then
- W_TEST_START=${tstart}
- if [[ -n ${tstop} ]]; then
- W_TEST_STOP=${tstop}
- if [[ -n ${iter} ]]; then
- W_NITER=${iter}
- fi
- else
- W_TEST_STOP=${tstart}
- fi
- fi
- ;;
- rw)
- if [[ -n ${tstart} ]]; then
- RW_TEST_START=${tstart}
- if [[ -n ${tstop} ]]; then
- RW_TEST_STOP=${tstop}
- if [[ -n ${iter} ]]; then
- RW_NITER=${iter}
- fi
- else
- RW_TEST_STOP=${tstart}
- fi
- fi
- ;;
- esac
-}
-
-function handle_args
-{
- # Modify test start/stop from params
- # Format: [w [start [stop [numit]]]] [r [start [stop [numit]]]] [rw start [stop [numit]]]]
- if (( $# >= 1 )); then
- W_DO_TEST=F
- R_DO_TEST=F
- RW_DO_TEST=F
-
- for p in $*; do
- case $p in
- w)
- if [[ ${W_DO_TEST} == T ]]; then
- echo "Error: Parameter w already set: \"$@\""
- usage
- exit
- fi
- W_DO_TEST=T
- if [[ -n ${tt} ]]; then
- assign_test_args ${tt} ${tstart} ${tstop} ${iter}
- unset tt tstart tstop iter
- fi
- local tt=w
- ;;
- r)
- if [[ ${R_DO_TEST} == T ]]; then
- echo "Error: Parameter r already set: \"$@\""
- usage
- exit
- fi
- R_DO_TEST=T
- if [[ -n ${tt} ]]; then
- assign_test_args ${tt} ${tstart} ${tstop} ${iter}
- unset tt tstart tstop iter
- fi
- local tt=r
- ;;
- rw)
- if [[ ${RW_DO_TEST} == T ]]; then
- echo "Error: Parameter rw already set: \"$@\""
- usage
- exit
- fi
- RW_DO_TEST=T
- if [[ -n ${tt} ]]; then
- assign_test_args ${tt} ${tstart} ${tstop} ${iter}
- unset tt tstart tstop iter
- fi
- local tt=rw
- ;;
- *)
- if [[ ${tt} == w ]]; then
- if [[ -z ${tstart} ]]; then
- local tstart=$p
- elif [[ -z ${tstop} ]]; then
- local tstop=$p
- elif [[ -z ${iter} ]]; then
- local iter=$p
- else
- echo "Error: Too many params for ${tt}: \"$@\""
- usage
- exit
- fi
- elif [[ ${tt} == r ]]; then
- if [[ -z ${tstart} ]]; then
- local tstart=$p
- elif [[ -z ${tstop} ]]; then
- local tstop=$p
- elif [[ -z ${iter} ]]; then
- local iter=$p
- else
- echo "Error: Too many params for ${tt}: \"$@\""
- usage
- exit
- fi
- elif [[ ${tt} == rw ]]; then
- if [[ -z ${tstart} ]]; then
- local tstart=$p
- elif [[ -z ${tstop} ]]; then
- local tstop=$p
- elif [[ -z ${iter} ]]; then
- local iter=$p
- else
- echo "Error: Too many params for ${tt}: \"$@\""
- usage
- exit
- fi
- else
- echo "Error: bad parameters - no test type set: \"$@\""
- usage
- exit
- fi
- ;;
- esac
- done
- if [[ -n ${tt} ]]; then
- assign_test_args ${tt} ${tstart} ${tstop} ${iter}
- fi
- fi
- print_test_args
-}
-
-function get_filename
-{
- if (( $# != 3 )); then
- echo "get_filename args!"
- return -1
- fi
- local prefix=$1
- local file_num=$2
- local suffix=$3
-
- if (( file_num < 10 )); then
- local num="000${file_num}"
- elif (( file_num < 100 )); then
- local num="00${file_num}"
- elif (( file_num < 1000 )); then
- local num="0${file_num}"
- else
- local num="${file_num}"
- fi
- FILENAME=${prefix}${num}${suffix}
- return 0
-}
-
-function build
-{
- if (( $# != 1 )); then
- echo "build args!"
- return -1
- fi
- local build_target=$1
-
- # Remove all previous data and build
- echo -n "Clearing previous build and test files..."
- ${MAKE} clean
- ${MAKE} clean-data
- echo " ok"
-
- # Make for write pipeline tests
- echo "Making ${build_target} ..."
- ${MAKE} ${build_target}
- local ret=$?
- if [[ ${ret} -ne 0 || ! -x ${TEST_PROG} ]]; then
- echo "Sorry, make ${build_target} failed; tests aborted."
- return 1
- fi
- return 0
-}
-
-function run_test
-{
- if (( $# != 4 )); then
- echo "run_test args!"
- return -1
- fi
- local test_name=$1
- local test_num=$2
- local it_num=$3
- local test_file=$4
-
- if (( (it_num - 1) % 10 == 0 )); then
- echo -n " "
- fi
-
- # Run test
- echo -n "."
- ${TEST_PROG} ${test_file} ${test_num} > ${TEMP_T_FILE}
- local ret=$?
- if (( ${ret} != 0 )); then
- echo "${TEST_PROG} ${test_file} ${test_num} returned ${ret}; exiting."
- echo
- cat ${TEMP_T_FILE}
- return 2
- fi
-
- # Analyze journal written by test
- if [[ ${test_name} != jrtest ]]; then
- echo -n ":"
- ${CHK_PROG} ${test_file} ${test_num} > ${TEMP_C_FILE}
- local ret=$?
- if (( $ret != 0 )); then
- echo "${CHK_PROG} ${NUM_RECS[${test_num}]} ${REC_SIZE[${test_num}]} returned ${ret}; exiting."
- echo
- cat ${TEMP_C_FILE}
- return 3
- fi
- fi
- return 0
-}
-
-function valgrind_memchk
-{
- if (( $# != 2 )); then
- echo "valgrind_memchk args!"
- return -1
- fi
- local test_file=$1
- local test_num=$2
-
- # Perform valgrind test (memory leak check)
- echo -n "*"
- ${VALGRIND} ${TEST_PROG} ${test_file} ${test_num} > ${NULL_FILE} 2> ${TEMP_V_FILE}
- local ret=$?
- if (( ${ret} != 0 )); then
- echo "${VALGRIND} ${TEST_PROG} ${test_file} ${test_num} returned ${ret}; exiting."
- echo
- cat ${TEMP_V_FILE}
- return 4
- fi
- lc=`wc -l < ${TEMP_V_FILE}`
- if (( ${lc} != ${VG_NORM_FILESIZE} )); then
- echo "${VALGRIND} ${TEST_PROG} ${test_file} ${test_num} exposed errors; exiting."
- echo
- cat ${TEMP_V_FILE}
- return 5
- fi
- return 0
-}
-
-function create_rd_jrnls
-{
- if (( $# != 3 )); then
- echo "create_rd_jrnls args!"
- return -1
- fi
- local test_file=$1
- local test_start=$2
- local test_stop=$3
-
- # To generate journals for reading, we must first compile in write mode
- build jwtest
-
- echo -n "Creating test journal archives: "
- if [[ -d ${TAR_DIR} ]]; then
- rm -rf ${TAR_DIR}/*
- else
- mkdir -p ${TAR_DIR}
- fi
-
- # Create journal file name list
- get_filename "test." 0 ".jdat"
- local jfiles=${FILENAME}
- for (( f=1; f<${NUM_JFILES}; f++ )); do
- get_filename "test." $f ".jdat"
- local jfiles=${jfiles}" "${FILENAME}
- done
-
- for (( f=${test_start}; f<=${test_stop}; f++ )); do
- ${MAKE} clean-data
- run_test jrtest $f 0 ${test_file}
- local ret=$?
- if (( ${ret} != 0 )); then
- return ${ret}
- fi
- get_filename "t" $f ".tar.gz"
- tar -C ${JDATA_DIR} -czf "${TAR_DIR}/${FILENAME}" ${jfiles}
- local ret=$?
- if (( ${ret} != 0 )); then
- return ${ret}
- fi
- done
- echo " ok"
- return 0
-}
-
-function prepare_rd_jrnl
-{
- if (( $# != 1 )); then
- echo "prepare_rd_jrnl args!"
- return -1
- fi
- local test_num=$1
-
- get_filename "t" ${test_num} ".tar.gz"
-
- if [[ -d ${JDATA_DIR} ]]; then
- rm -rf ${JDATA_DIR}/*
- else
- mkdir -p ${JDATA_DIR}
- fi
- tar -C ${JDATA_DIR} -xzf "${TAR_DIR}/${FILENAME}"
- # returns with tar return code
-}
-
-function run_tests
-{
- if (( $# != 5 )); then
- echo "run_tests args!"
- return -1
- fi
- local test_name=$1
- local test_file=$2
- local test_start=$3
- local test_stop=$4
- local test_iterations=$5
-
- for (( t=${test_start}; t<=${test_stop}; t++ )); do
- echo -n "Test $t: "
-
- # Get journal ready for read tests
- if [[ ${test_name} == jrtest ]]; then
- prepare_rd_jrnl $t
- fi
-
- for (( i=1; i<=${test_iterations}; i++ )); do
- run_test ${test_name} $t $i ${test_file}
- local ret=$?
- if (( ${ret} != 0 )); then
- return ${ret}
- fi
- done
-
- for (( i=1; i<=${VG_ITERATIONS}; i++ )); do
- valgrind_memchk ${test_file} $t
- local ret=$?
- if (( ${ret} != 0 )); then
- return ${ret}
- fi
- done
-
- # Remove journals accumulated during test
- echo -n " ~"
- ${RM_DIR} ${JDATA_DIR}/*
- echo " ok"
- done
- return 0
-}
-
-function do_test
-{
- if (( $# != 5 )); then
- echo "do_test args!"
- exit -1
- fi
- local test_name=$1
- local test_file=$2
- local test_start=$3
- local test_stop=$4
- local test_iterations=$5
-
- echo
- echo "===== TEST: ${test_name} ====="
-
- # For read-only tests, first generate and archive journals to read using a write-only build
- if [[ $test_name == jrtest ]]; then
- create_rd_jrnls ${test_file} ${test_start} ${test_stop}
- ret=$?
- if (( ${ret} != 0 )); then
- exit ${ret}
- fi
- fi
-
- build ${test_name}
- ret=$?
- if (( ${ret} != 0 )); then
- exit ${ret}
- fi
- echo
-
- run_tests ${test_name} ${test_file} ${test_start} ${test_stop} ${test_iterations}
- ret=$?
- if (( ${ret} != 0 )); then
- exit ${ret}
- fi
-}
-
-function cleanup
-{
- # Clean up temp files
- ${RM} -f ${TEMP_T_FILE}
- ${RM} -f ${TEMP_C_FILE}
- ${RM} -f ${TEMP_V_FILE}
- return 0
-}
-
-
-#Main program starts here
-
-handle_args "$@"
-if [[ ${W_DO_TEST} == T ]]; then
- do_test jwtest ${W_TEST_FILE} ${W_TEST_START} ${W_TEST_STOP} ${W_NITER}
-fi
-if [[ ${R_DO_TEST} == T ]]; then
- do_test jrtest ${R_TEST_FILE} ${R_TEST_START} ${R_TEST_STOP} ${R_NITER}
-fi
-if [[ ${RW_DO_TEST} == T ]]; then
- do_test jrwtest ${RW_TEST_FILE} ${RW_TEST_START} ${RW_TEST_STOP} ${RW_NITER}
-fi
-cleanup
-
Deleted: store/trunk/cpp/tests/jrnl/rtests.csv
===================================================================
--- store/trunk/cpp/tests/jrnl/rtests.csv 2008-09-09 19:25:47 UTC (rev 2433)
+++ store/trunk/cpp/tests/jrnl/rtests.csv 2008-09-09 20:24:44 UTC (rev 2434)
@@ -1,185 +0,0 @@
-,,,,,,,"Msg size",,"Xid size",,,,,"enq-size",,"deq-size",,"txn-size",,
-"Test #","tf","pf","amn","mn incr","#msgs","ms incr","Min","Max","Min","Max","auto-deq","transient","extern","bytes","dblks","bytes","dblks","bytes","dblks","comment"
-,,,,,,,,,,,,,,,,,,,,
-"Initialize only",,,,,,,,,,,,,,,,,,,,
-0,"L",0,0,0,0,0,0,0,0,0,FALSE,FALSE,FALSE,44,1,0,0,0,0,"No messages – journal creation/initialization only"
-,,,,,,,,,,,,,,,,,,,,
-"Simple message combinations of persistent/deq transientueued/non-dequeued, transactional/non-transactional",,,,,,,,,,,,,,,,,,,,
-1,"L",1,1,0,1,0,10,10,0,0,FALSE,FALSE,FALSE,54,1,0,0,0,0,"1 * 10-byte message"
-2,"L",1,10,0,10,0,10,10,0,0,FALSE,FALSE,FALSE,54,1,0,0,0,0,"10 * 10-byte message"
-3,"L",1,1,0,1,0,10,10,0,0,FALSE,TRUE,FALSE,54,1,0,0,0,0,"1 * 10-byte message [transient]"
-4,"L",1,10,0,10,0,10,10,0,0,FALSE,TRUE,FALSE,54,1,0,0,0,0,"10 * 10-byte message [transient]"
-5,"L",1,1,0,1,0,10,10,10,10,FALSE,FALSE,FALSE,64,1,0,0,0,0,"1 * 10-byte message [txn]"
-6,"L",1,10,0,10,0,10,10,10,10,FALSE,FALSE,FALSE,64,1,0,0,0,0,"10 * 10-byte message [txn]"
-7,"L",1,1,0,1,0,10,10,10,10,FALSE,TRUE,FALSE,64,1,0,0,0,0,"1 * 10-byte message [txn transient]"
-8,"L",1,10,0,10,0,10,10,10,10,FALSE,TRUE,FALSE,64,1,0,0,0,0,"10 * 10-byte message [txn transient]"
-9,"L",1,1,0,1,0,10,10,0,0,TRUE,FALSE,FALSE,54,1,32,1,0,0,"1 * 10-byte message [deq]"
-10,"L",1,10,0,10,0,10,10,0,0,TRUE,FALSE,FALSE,54,1,32,1,0,0,"10 * 10-byte message [deq]"
-11,"L",1,1,0,1,0,10,10,0,0,TRUE,TRUE,FALSE,54,1,32,1,0,0,"1 * 10-byte message [deq transient]"
-12,"L",1,10,0,10,0,10,10,0,0,TRUE,TRUE,FALSE,54,1,32,1,0,0,"10 * 10-byte message [deq transient]"
-13,"L",1,1,0,1,0,10,10,10,10,TRUE,FALSE,FALSE,64,1,54,1,46,1,"1 * 10-byte message [deq txn]"
-14,"L",1,10,0,10,0,10,10,10,10,TRUE,FALSE,FALSE,64,1,54,1,46,1,"10 * 10-byte message [deq txn]"
-15,"L",1,1,0,1,0,10,10,10,10,TRUE,TRUE,FALSE,64,1,54,1,46,1,"1 * 10-byte message [txn deq transient]"
-16,"L",1,10,0,10,0,10,10,10,10,TRUE,TRUE,FALSE,64,1,54,1,46,1,"10 * 10-byte message [txn deq transient]"
-17,"L",1,1,0,1,0,10,10,0,0,FALSE,FALSE,TRUE,54,1,0,0,0,0,"1 * 10-byte message [extern]"
-18,"L",1,10,0,10,0,10,10,0,0,FALSE,FALSE,TRUE,54,1,0,0,0,0,"10 * 10-byte message [extern]"
-19,"L",1,1,0,1,0,10,10,0,0,FALSE,TRUE,TRUE,54,1,0,0,0,0,"1 * 10-byte message [transient extern]"
-20,"L",1,10,0,10,0,10,10,0,0,FALSE,TRUE,TRUE,54,1,0,0,0,0,"10 * 10-byte message [transient extern]"
-21,"L",1,1,0,1,0,10,10,10,10,FALSE,FALSE,TRUE,64,1,0,0,0,0,"1 * 10-byte message [txn extern]"
-22,"L",1,10,0,10,0,10,10,10,10,FALSE,FALSE,TRUE,64,1,0,0,0,0,"10 * 10-byte message [txn extern]"
-23,"L",1,1,0,1,0,10,10,10,10,FALSE,TRUE,TRUE,64,1,0,0,0,0,"1 * 10-byte message [txn transient extern]"
-24,"L",1,10,0,10,0,10,10,10,10,FALSE,TRUE,TRUE,64,1,0,0,0,0,"10 * 10-byte message [txn transient extern]"
-25,"L",1,1,0,1,0,10,10,0,0,TRUE,FALSE,TRUE,54,1,32,1,0,0,"1 * 10-byte message [deq extern]"
-26,"L",1,10,0,10,0,10,10,0,0,TRUE,FALSE,TRUE,54,1,32,1,0,0,"10 * 10-byte message [deq extern]"
-27,"L",1,1,0,1,0,10,10,0,0,TRUE,TRUE,TRUE,54,1,32,1,0,0,"1 * 10-byte message [deq transient extern]"
-28,"L",1,10,0,10,0,10,10,0,0,TRUE,TRUE,TRUE,54,1,32,1,0,0,"10 * 10-byte message [deq transient extern]"
-29,"L",1,1,0,1,0,10,10,10,10,TRUE,FALSE,TRUE,64,1,54,1,46,1,"1 * 10-byte message [deq txn extern]"
-30,"L",1,10,0,10,0,10,10,10,10,TRUE,FALSE,TRUE,64,1,54,1,46,1,"10 * 10-byte message [deq txn extern]"
-31,"L",1,1,0,1,0,10,10,10,10,TRUE,TRUE,TRUE,64,1,54,1,46,1,"1 * 10-byte message [txn deq transient extern]"
-32,"L",1,10,0,10,0,10,10,10,10,TRUE,TRUE,TRUE,64,1,54,1,46,1,"10 * 10-byte message [txn deq transient extern]"
-,,,,,,,,,,,,,,,,,,,,
-"Transition from one d-block to two per message",,,,,,,,,,,,,,,,,,,,
-33,"L",1,10,0,10,0,84,84,0,0,FALSE,FALSE,FALSE,128,1,0,0,0,0,"1 dblk exact fit"
-34,"L",1,10,0,10,1,85,85,0,0,FALSE,FALSE,FALSE,129,2,0,0,0,0,"1 dblk + 1 byte"
-35,"L",1,10,0,10,0,58,58,26,26,FALSE,FALSE,FALSE,128,1,0,0,0,0,"1 dblk exact fit [txn]"
-36,"L",1,10,0,10,1,59,59,26,26,FALSE,FALSE,FALSE,129,2,0,0,0,0,"1 dblk + 1 byte [txn]"
-,,,,,,,,,,,,,,,,,,,,
-"Transition from one s-block to two per message",,,,,,,,,,,,,,,,,,,,
-37,"L",1,10,0,10,0,468,468,0,0,FALSE,FALSE,FALSE,512,4,0,0,0,0,"1 sblk exact fit"
-38,"L",1,10,0,10,1,469,469,0,0,FALSE,FALSE,FALSE,513,5,0,0,0,0,"1 sblk + 1 byte"
-39,"L",1,10,0,10,0,442,442,26,26,FALSE,FALSE,FALSE,512,4,0,0,0,0,"1 sblk exact fit [txn]"
-40,"L",1,10,0,10,1,443,443,26,26,FALSE,FALSE,FALSE,513,5,0,0,0,0,"1 sblk + 1 byte [txn]"
-,,,,,,,,,,,,,,,,,,,,
-"Transition from first page to second",,,,,,,,,,,,,,,,,,,,
-41,"L",1,8,0,8,0,8148,8148,0,0,FALSE,FALSE,FALSE,8192,64,0,0,0,0,"1/8 page"
-42,"L",1,8,1,9,0,8148,8148,0,0,FALSE,FALSE,FALSE,8192,64,0,0,0,0,"1/8 page"
-43,"L",1,8,0,8,1,8149,8149,0,0,FALSE,FALSE,FALSE,8193,65,0,0,0,0,"1/8 page + 1 byte"
-44,"L",1,8,0,8,0,7892,7892,256,256,FALSE,FALSE,FALSE,8192,64,0,0,0,0,"1/8 page [txn]"
-45,"L",1,8,1,9,0,7892,7892,256,256,FALSE,FALSE,FALSE,8192,64,0,0,0,0,"1/8 page [txn]"
-46,"L",1,8,0,8,1,7893,7893,256,256,FALSE,FALSE,FALSE,8193,65,0,0,0,0,"1/8 page + 1 byte [txn]"
-47,"L",1,8,0,8,0,8020,8020,0,0,TRUE,FALSE,FALSE,8064,63,32,1,0,0,"1/8 page incl deq [deq]"
-48,"L",1,8,1,9,0,8020,8020,0,0,TRUE,FALSE,FALSE,8064,63,32,1,0,0,"1/8 page incl deq [deq]"
-49,"L",1,8,0,8,1,8021,8021,0,0,TRUE,FALSE,FALSE,8065,64,32,1,0,0,"1/8 page incl deq + 1 byte [deq]"
-50,"L",1,8,0,8,0,7124,7124,256,256,TRUE,FALSE,FALSE,7424,58,300,3,292,3,"1/8 page incl deq & txn [deq txn]"
-51,"L",1,8,1,9,0,7124,7124,256,256,TRUE,FALSE,FALSE,7424,58,300,3,292,3,"1/8 page incl deq & txn [deq txn]"
-52,"L",1,8,0,8,1,7125,7125,256,256,TRUE,FALSE,FALSE,7425,59,300,3,292,3,"1/8 page incl deq & txn + 1 byte [deq txn]"
-,,,,,,,,,,,,,,,,,,,,
-"Page cache rollover (from page 16 back to page 0)",,,,,,,,,,,,,,,,,,,,
-53,"L",1,16,0,16,0,65492,65492,0,0,FALSE,FALSE,FALSE,65536,512,0,0,0,0,"1 page"
-54,"L",1,16,1,17,0,65492,65492,0,0,FALSE,FALSE,FALSE,65536,512,0,0,0,0,"1 page"
-55,"L",1,16,0,16,1,65493,65493,0,0,FALSE,FALSE,FALSE,65537,513,0,0,0,0,"1 page + 1 byte"
-56,"L",1.5,11,0,11,0,98260,98260,0,0,FALSE,FALSE,FALSE,98304,768,0,0,0,0,"1.5 pages"
-57,"L",1,16,0,16,0,65236,65236,256,256,FALSE,FALSE,FALSE,65536,512,0,0,0,0,"1 page [txn]"
-58,"L",1,16,1,17,0,65236,65236,256,256,FALSE,FALSE,FALSE,65536,512,0,0,0,0,"1 page [txn]"
-59,"L",1,16,0,16,1,65237,65237,256,256,FALSE,FALSE,FALSE,65537,513,0,0,0,0,"1 page + 1 byte [txn]"
-60,"L",1.5,11,0,11,0,98004,98004,256,256,FALSE,FALSE,FALSE,98304,768,0,0,0,0,"1.5 pages [txn]"
-61,"L",1,16,0,16,0,65364,65364,0,0,TRUE,FALSE,FALSE,65408,511,32,1,0,0,"1 page incl deq [deq]"
-62,"L",1,16,1,17,0,65364,65364,0,0,TRUE,FALSE,FALSE,65408,511,32,1,0,0,"1 page incl deq [deq]"
-63,"L",1,16,0,16,1,65365,65365,0,0,TRUE,FALSE,FALSE,65409,512,32,1,0,0,"1 page incl deq + 1 byte [deq]"
-64,"L",1.5,11,0,11,0,98132,98132,0,0,TRUE,FALSE,FALSE,98176,767,32,1,0,0,"1.5 pages incl deq [deq]"
-65,"L",1,16,0,16,0,64468,64468,256,256,TRUE,FALSE,FALSE,64768,506,300,3,292,3,"1 page incl deq & txn [deq txn]"
-66,"L",1,16,1,17,0,64468,64468,256,256,TRUE,FALSE,FALSE,64768,506,300,3,292,3,"1 page incl deq & txn [deq txn]"
-67,"L",1,16,0,16,1,64469,64469,256,256,TRUE,FALSE,FALSE,64769,507,300,3,292,3,"1 page incl deq & txn + 1 byte [deq txn]"
-68,"L",1.5,11,0,11,0,97236,97236,256,256,TRUE,FALSE,FALSE,97536,762,300,3,292,3,"1.5 pages incl deq & txn [deq txn]"
-,,,,,,,,,,,,,,,,,,,,
-"File transition (from file 0000 to 0001)",,,,,,,,,,,,,,,,,,,,
-69,"L",1,24,0,24,0,65492,65492,0,0,FALSE,FALSE,FALSE,65536,512,0,0,0,0,"1 page"
-70,"L",1,24,1,25,0,65492,65492,0,0,FALSE,FALSE,FALSE,65536,512,0,0,0,0,"1 page"
-71,"L",1,24,0,24,1,65493,65493,0,0,FALSE,FALSE,FALSE,65537,513,0,0,0,0,"1 page + 1 byte"
-72,"L",2.5,10,0,10,0,163796,163796,0,0,FALSE,FALSE,FALSE,163840,1280,0,0,0,0,"2.5 pages"
-73,"L",1,24,0,24,0,65236,65236,256,256,FALSE,FALSE,FALSE,65536,512,0,0,0,0,"1 page [txn]"
-74,"L",1,24,1,25,0,65236,65236,256,256,FALSE,FALSE,FALSE,65536,512,0,0,0,0,"1 page [txn]"
-75,"L",1,24,0,24,1,65237,65237,256,256,FALSE,FALSE,FALSE,65537,513,0,0,0,0,"1 page + 1 byte [txn]"
-76,"L",2.5,10,0,10,0,163540,163540,256,256,FALSE,FALSE,FALSE,163840,1280,0,0,0,0,"2.5 pages [txn]"
-77,"L",1,24,0,24,0,65364,65364,0,0,TRUE,FALSE,FALSE,65408,511,32,1,0,0,"1 page incl deq [deq]"
-78,"L",1,24,1,25,0,65364,65364,0,0,TRUE,FALSE,FALSE,65408,511,32,1,0,0,"1 page incl deq [deq]"
-79,"L",1,24,0,24,1,65365,65365,0,0,TRUE,FALSE,FALSE,65409,512,32,1,0,0,"1 page incl deq + 1 byte [deq]"
-80,"L",2.5,10,0,10,0,163668,163668,0,0,TRUE,FALSE,FALSE,163712,1279,32,1,0,0,"2.5 pages incl deq [deq]"
-81,"L",1,24,0,24,0,64468,64468,256,256,TRUE,FALSE,FALSE,64768,506,300,3,292,3,"1 page incl deq & txn [deq txn]"
-82,"L",1,24,1,25,0,64468,64468,256,256,TRUE,FALSE,FALSE,64768,506,300,3,292,3,"1 page incl deq & txn [deq txn]"
-83,"L",1,24,0,24,1,64469,64469,256,256,TRUE,FALSE,FALSE,64769,507,300,3,292,3,"1 page incl deq & txn + 1 byte [deq txn]"
-84,"L",2.5,10,0,10,0,162772,162772,256,256,TRUE,FALSE,FALSE,163072,1274,300,3,292,3,"2.5 pages incl deq & txn [deq txn]"
-,,,,,,,,,,,,,,,,,,,,
-"File rollover (from file 0007 to 0000) - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,,,,,,,,,,,,,,,
-85,"L",0.5,16,0,16,0,786388,786388,0,0,FALSE,FALSE,FALSE,786432,6144,0,0,0,0,"12 pages = ½ file"
-86,"L",0.5,16,0,16,0,786132,786132,256,256,FALSE,FALSE,FALSE,786432,6144,0,0,0,0,"12 pages = ½ file"
-,,,,,,,,,,,,,,,,,,,,
-"Multi-page messages (large messages) - tests various paths in encoder.",,,,,,,,,,,,,,,,,,,,
-87,"L",1,8,0,8,0,65492,65492,0,0,FALSE,FALSE,FALSE,65536,512,0,0,0,0,"data 1 page"
-88,"L",1,8,0,8,1,65493,65493,0,0,FALSE,FALSE,FALSE,65537,513,0,0,0,0,"data 1 page + 1 byte (tail split; 1 byte over page boundary)"
-89,"L",1,8,0,8,11,65503,65503,0,0,FALSE,FALSE,FALSE,65547,513,0,0,0,0,"data 1 page + 11 bytes (tail split; 11 bytes over page boundary)"
-90,"L",1,8,0,8,12,65504,65504,0,0,FALSE,FALSE,FALSE,65548,513,0,0,0,0,"data 1 page + 12 bytes (tail separated exactly onto next page)"
-91,"L",1,8,0,8,13,65505,65505,0,0,FALSE,FALSE,FALSE,65549,513,0,0,0,0,"data 1 page + 13 bytes (data split; 1 byte over page boundary)"
-92,"L",1,8,0,8,0,65236,65236,256,256,FALSE,FALSE,FALSE,65536,512,0,0,0,0,"data 1 page [txn]"
-93,"L",1,8,0,8,1,65237,65237,256,256,FALSE,FALSE,FALSE,65537,513,0,0,0,0,"data 1 page + 1 byte (tail split; 1 byte over page boundary) [txn]"
-94,"L",1,8,0,8,11,65247,65247,256,256,FALSE,FALSE,FALSE,65547,513,0,0,0,0,"data 1 page + 11 bytes (tail split; 11 bytes over page boundary) [txn]"
-95,"L",1,8,0,8,12,65248,65248,256,256,FALSE,FALSE,FALSE,65548,513,0,0,0,0,"data 1 page + 12 bytes (tail separated exactly onto next page) [txn]"
-96,"L",1,8,0,8,13,65249,65249,256,256,FALSE,FALSE,FALSE,65549,513,0,0,0,0,"data 1 page + 13 bytes (data split; 1 byte over page boundary) [txn]"
-97,"L",2,8,0,8,0,131028,131028,0,0,FALSE,FALSE,FALSE,131072,1024,0,0,0,0,"data 2 pages"
-98,"L",2,8,0,8,1,131029,131029,0,0,FALSE,FALSE,FALSE,131073,1025,0,0,0,0,"data 2 pages + 1 byte (tail split; 1 byte over page boundary)"
-99,"L",2,8,0,8,11,131039,131039,0,0,FALSE,FALSE,FALSE,131083,1025,0,0,0,0,"data 2 pages + 11 bytes (tail split; 11 bytes over page boundary)"
-100,"L",2,8,0,8,12,131040,131040,0,0,FALSE,FALSE,FALSE,131084,1025,0,0,0,0,"data 2 pages + 12 bytes (tail separated exactly onto next page)"
-101,"L",2,8,0,8,13,131041,131041,0,0,FALSE,FALSE,FALSE,131085,1025,0,0,0,0,"data 2 pages + 13 bytes (data split; 1 byte over page boundary)"
-102,"L",2,8,0,8,0,130772,130772,256,256,FALSE,FALSE,FALSE,131072,1024,0,0,0,0,"data 2 pages [txn]"
-103,"L",2,8,0,8,1,130773,130773,256,256,FALSE,FALSE,FALSE,131073,1025,0,0,0,0,"data 2 pages + 1 byte (tail split; 1 byte over page boundary) [txn]"
-104,"L",2,8,0,8,11,130783,130783,256,256,FALSE,FALSE,FALSE,131083,1025,0,0,0,0,"data 2 pages + 11 bytes (tail split; 11 bytes over page boundary) [txn]"
-105,"L",2,8,0,8,12,130784,130784,256,256,FALSE,FALSE,FALSE,131084,1025,0,0,0,0,"data 2 pages + 12 bytes (tail separated exactly onto next page) [txn]"
-106,"L",2,8,0,8,13,130785,130785,256,256,FALSE,FALSE,FALSE,131085,1025,0,0,0,0,"data 2 pages + 13 bytes (data split; 1 byte over page boundary) [txn]"
-107,"L",4,8,0,8,0,262100,262100,0,0,FALSE,FALSE,FALSE,262144,2048,0,0,0,0,"data 4 pages"
-108,"L",4,8,0,8,1,262101,262101,0,0,FALSE,FALSE,FALSE,262145,2049,0,0,0,0,"data 4 pages + 1 byte (tail split; 1 byte over page boundary)"
-109,"L",4,8,0,8,11,262111,262111,0,0,FALSE,FALSE,FALSE,262155,2049,0,0,0,0,"data 4 pages + 11 bytes (tail split; 11 bytes over page boundary)"
-110,"L",4,8,0,8,12,262112,262112,0,0,FALSE,FALSE,FALSE,262156,2049,0,0,0,0,"data 4 pages + 12 bytes (tail separated exactly onto next page)"
-111,"L",4,8,0,8,13,262113,262113,0,0,FALSE,FALSE,FALSE,262157,2049,0,0,0,0,"data 4 pages + 13 bytes (data split; 1 byte over page boundary)"
-112,"L",4,8,0,8,0,261844,261844,256,256,FALSE,FALSE,FALSE,262144,2048,0,0,0,0,"data 4 pages [txn]"
-113,"L",4,8,0,8,1,261845,261845,256,256,FALSE,FALSE,FALSE,262145,2049,0,0,0,0,"data 4 pages + 1 byte (tail split; 1 byte over page boundary) [txn]"
-114,"L",4,8,0,8,11,261855,261855,256,256,FALSE,FALSE,FALSE,262155,2049,0,0,0,0,"data 4 pages + 11 bytes (tail split; 11 bytes over page boundary) [txn]"
-115,"L",4,8,0,8,12,261856,261856,256,256,FALSE,FALSE,FALSE,262156,2049,0,0,0,0,"data 4 pages + 12 bytes (tail separated exactly onto next page) [txn]"
-116,"L",4,8,0,8,13,261857,261857,256,256,FALSE,FALSE,FALSE,262157,2049,0,0,0,0,"data 4 pages + 13 bytes (data split; 1 byte over page boundary) [txn]"
-117,"L",3.5,8,0,8,0,229332,229332,0,0,FALSE,FALSE,FALSE,229376,1792,0,0,0,0,"data 3.5 pages"
-118,"L",3.5,8,0,8,1,229333,229333,0,0,FALSE,FALSE,FALSE,229377,1793,0,0,0,0,"data 3.5 pages + 1 byte"
-119,"L",3.5,8,0,8,0,229076,229076,256,256,FALSE,FALSE,FALSE,229376,1792,0,0,0,0,"data 3.5 pages [txn]"
-120,"L",3.5,8,0,8,1,229077,229077,256,256,FALSE,FALSE,FALSE,229377,1793,0,0,0,0,"data 3.5 pages + 1 byte [txn]"
-121,"L",1,8,0,8,-1,10,10,65503,65503,FALSE,FALSE,FALSE,65557,513,0,0,0,0,"xid 1 page – 1 byte; data 10 bytes (exact fit) [txn]"
-122,"L",1,8,0,8,0,10,10,65504,65504,FALSE,FALSE,FALSE,65558,513,0,0,0,0,"xid 1 page; data 10 bytes (exact fit) [txn]"
-123,"L",1,8,0,8,1,10,10,65505,65505,FALSE,FALSE,FALSE,65559,513,0,0,0,0,"xid 1 page + 1 byte; data 10 bytes (exact fit) [txn]"
-124,"L",2,8,0,8,-1,10,10,131039,131039,FALSE,FALSE,FALSE,131093,1025,0,0,0,0,"xid 2 pages – 1 byte; data 10 bytes (exact fit) [txn]"
-125,"L",2,8,0,8,0,10,10,131040,131040,FALSE,FALSE,FALSE,131094,1025,0,0,0,0,"xid 2 pages; data 10 bytes (exact fit) [txn]"
-126,"L",2,8,0,8,1,10,10,131041,131041,FALSE,FALSE,FALSE,131095,1025,0,0,0,0,"xid 2 pages + 1 byte; data 10 bytes (exact fit) [txn]"
-127,"L",4,8,0,8,-1,10,10,262111,262111,FALSE,FALSE,FALSE,262165,2049,0,0,0,0,"xid 4 pages – 1 byte; data 10 bytes (exact fit) [txn]"
-128,"L",4,8,0,8,0,10,10,262112,262112,FALSE,FALSE,FALSE,262166,2049,0,0,0,0,"xid 4 pages; data 10 bytes (exact fit) [txn]"
-129,"L",4,8,0,8,1,10,10,262113,262113,FALSE,FALSE,FALSE,262167,2049,0,0,0,0,"xid 4 pages + 1 byte; data 10 bytes (exact fit) [txn]"
-130,"L",3.5,8,0,8,0,10,10,229344,229344,FALSE,FALSE,FALSE,229398,1793,0,0,0,0,"xid 3.5 pages; data 10 bytes (exact fit) [txn]"
-131,"L",3.5,8,0,8,1,10,10,229345,229345,FALSE,FALSE,FALSE,229399,1793,0,0,0,0,"xid 3.5 pages + 1 byte; data 10 bytes (exact fit) [txn]"
-132,"L",1,8,0,8,-1,10,10,65503,65503,TRUE,FALSE,FALSE,65557,513,65547,513,65539,513,"xid 1 page – 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-133,"L",1,8,0,8,0,10,10,65504,65504,TRUE,FALSE,FALSE,65558,513,65548,513,65540,513,"xid 1 page for enq rec; data 10 bytes (exact fit) [deq, txn]"
-134,"L",1,8,0,8,1,10,10,65505,65505,TRUE,FALSE,FALSE,65559,513,65549,513,65541,513,"xid 1 page + 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-135,"L",2,8,0,8,-1,10,10,131039,131039,TRUE,FALSE,FALSE,131093,1025,131083,1025,131075,1025,"xid 2 pages – 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-136,"L",2,8,0,8,0,10,10,131040,131040,TRUE,FALSE,FALSE,131094,1025,131084,1025,131076,1025,"xid 2 pages for enq rec; data 10 bytes (exact fit) [deq, txn]"
-137,"L",2,8,0,8,1,10,10,131041,131041,TRUE,FALSE,FALSE,131095,1025,131085,1025,131077,1025,"xid 2 pages + 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-138,"L",4,8,0,8,-1,10,10,262111,262111,TRUE,FALSE,FALSE,262165,2049,262155,2049,262147,2049,"xid 4 pages – 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-139,"L",4,8,0,8,0,10,10,262112,262112,TRUE,FALSE,FALSE,262166,2049,262156,2049,262148,2049,"xid 4 pages for enq rec; data 10 bytes (exact fit) [deq, txn]"
-140,"L",4,8,0,8,1,10,10,262113,262113,TRUE,FALSE,FALSE,262167,2049,262157,2049,262149,2049,"xid 4 pages + 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-141,"L",3.5,8,0,8,0,10,10,229344,229344,TRUE,FALSE,FALSE,229398,1793,229388,1793,229380,1793,"xid 3.5 pages for enq rec; data 10 bytes (exact fit) [deq, txn]"
-142,"L",3.5,8,0,8,1,10,10,229345,229345,TRUE,FALSE,FALSE,229399,1793,229389,1793,229381,1793,"xid 3.5 pages + 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-143,"L",1,8,0,8,-1,10,10,65503,65503,TRUE,FALSE,FALSE,65557,513,65547,513,65539,513,"xid 1 page – 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-144,"L",1,8,0,8,0,10,10,65504,65504,TRUE,FALSE,FALSE,65558,513,65548,513,65540,513,"xid 1 page for deq rec; data 10 bytes (exact fit) [deq, txn]"
-145,"L",1,8,0,8,1,10,10,65505,65505,TRUE,FALSE,FALSE,65559,513,65549,513,65541,513,"xid 1 page + 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-146,"L",2,8,0,8,-1,10,10,131039,131039,TRUE,FALSE,FALSE,131093,1025,131083,1025,131075,1025,"xid 2 pages – 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-147,"L",2,8,0,8,0,10,10,131040,131040,TRUE,FALSE,FALSE,131094,1025,131084,1025,131076,1025,"xid 2 pages for deq rec; data 10 bytes (exact fit) [deq, txn]"
-148,"L",2,8,0,8,1,10,10,131041,131041,TRUE,FALSE,FALSE,131095,1025,131085,1025,131077,1025,"xid 2 pages + 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-149,"L",4,8,0,8,-1,10,10,262111,262111,TRUE,FALSE,FALSE,262165,2049,262155,2049,262147,2049,"xid 4 pages – 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-150,"L",4,8,0,8,0,10,10,262112,262112,TRUE,FALSE,FALSE,262166,2049,262156,2049,262148,2049,"xid 4 pages for deq rec; data 10 bytes (exact fit) [deq, txn]"
-151,"L",4,8,0,8,1,10,10,262113,262113,TRUE,FALSE,FALSE,262167,2049,262157,2049,262149,2049,"xid 4 pages + 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-152,"L",3.5,8,0,8,0,10,10,229344,229344,TRUE,FALSE,FALSE,229398,1793,229388,1793,229380,1793,"xid 3.5 pages for deq rec; data 10 bytes (exact fit) [deq, txn]"
-153,"L",3.5,8,0,8,1,10,10,229345,229345,TRUE,FALSE,FALSE,229399,1793,229389,1793,229381,1793,"xid 3.5 pages + 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-154,"L",1,8,0,8,-1,10,10,65511,65511,TRUE,FALSE,FALSE,65565,513,65555,513,65547,513,"xid 1 page – 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-155,"L",1,8,0,8,0,10,10,65512,65512,TRUE,FALSE,FALSE,65566,513,65556,513,65548,513,"xid 1 page for txn rec; data 10 bytes (exact fit) [deq, txn]"
-156,"L",1,8,0,8,1,10,10,65513,65513,TRUE,FALSE,FALSE,65567,513,65557,513,65549,513,"xid 1 page + 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-157,"L",2,8,0,8,-1,10,10,131047,131047,TRUE,FALSE,FALSE,131101,1025,131091,1025,131083,1025,"xid 2 pages – 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-158,"L",2,8,0,8,0,10,10,131048,131048,TRUE,FALSE,FALSE,131102,1025,131092,1025,131084,1025,"xid 2 pages for txn rec; data 10 bytes (exact fit) [deq, txn]"
-159,"L",2,8,0,8,1,10,10,131049,131049,TRUE,FALSE,FALSE,131103,1025,131093,1025,131085,1025,"xid 2 pages + 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-160,"L",4,8,0,8,-1,10,10,262119,262119,TRUE,FALSE,FALSE,262173,2049,262163,2049,262155,2049,"xid 4 pages – 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-161,"L",4,8,0,8,0,10,10,262120,262120,TRUE,FALSE,FALSE,262174,2049,262164,2049,262156,2049,"xid 4 pages for txn rec; data 10 bytes (exact fit) [deq, txn]"
-162,"L",4,8,0,8,1,10,10,262121,262121,TRUE,FALSE,FALSE,262175,2049,262165,2049,262157,2049,"xid 4 pages + 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-163,"L",3.5,8,0,8,0,10,10,229352,229352,TRUE,FALSE,FALSE,229406,1793,229396,1793,229388,1793,"xid 3.5 pages for txn rec; data 10 bytes (exact fit) [deq, txn]"
-164,"L",3.5,8,0,8,1,10,10,229353,229353,TRUE,FALSE,FALSE,229407,1793,229397,1793,229389,1793,"xid 3.5 pages + 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
Deleted: store/trunk/cpp/tests/jrnl/rwtests.csv
===================================================================
--- store/trunk/cpp/tests/jrnl/rwtests.csv 2008-09-09 19:25:47 UTC (rev 2433)
+++ store/trunk/cpp/tests/jrnl/rwtests.csv 2008-09-09 20:24:44 UTC (rev 2434)
@@ -1,207 +0,0 @@
-,,,,,,,"Msg size",,"Xid size",,,,,"enq-size",,"deq-size",,"txn-size",,
-"Test #","tf","pf","amn","mn incr","#msgs","ms incr","Min","Max","Min","Max","auto-deq","transient","extern","bytes","dblks","bytes","dblks","bytes","dblks","comment"
-,,,,,,,,,,,,,,,,,,,,
-"Initialize only",,,,,,,,,,,,,,,,,,,,
-0,"L",0,0,0,0,0,0,0,0,0,FALSE,FALSE,FALSE,44,1,0,0,0,0,"No messages - journal creation/initialization only"
-,,,,,,,,,,,,,,,,,,,,
-"Simple message combinations of persistent/deq transientueued/non-dequeued, transactional/non-transactional",,,,,,,,,,,,,,,,,,,,
-1,"L",1,1,0,1,0,10,10,0,0,FALSE,FALSE,FALSE,54,1,0,0,0,0,"1 * 10-byte message"
-2,"L",1,10,0,10,0,10,10,0,0,FALSE,FALSE,FALSE,54,1,0,0,0,0,"10 * 10-byte message"
-3,"L",1,1,0,1,0,10,10,0,0,FALSE,TRUE,FALSE,54,1,0,0,0,0,"1 * 10-byte message [transient]"
-4,"L",1,10,0,10,0,10,10,0,0,FALSE,TRUE,FALSE,54,1,0,0,0,0,"10 * 10-byte message [transient]"
-5,"L",1,1,0,1,0,10,10,10,10,FALSE,FALSE,FALSE,64,1,0,0,0,0,"1 * 10-byte message [txn]"
-6,"L",1,10,0,10,0,10,10,10,10,FALSE,FALSE,FALSE,64,1,0,0,0,0,"10 * 10-byte message [txn]"
-7,"L",1,1,0,1,0,10,10,10,10,FALSE,TRUE,FALSE,64,1,0,0,0,0,"1 * 10-byte message [txn transient]"
-8,"L",1,10,0,10,0,10,10,10,10,FALSE,TRUE,FALSE,64,1,0,0,0,0,"10 * 10-byte message [txn transient]"
-9,"L",1,1,0,1,0,10,10,0,0,TRUE,FALSE,FALSE,54,1,32,1,0,0,"1 * 10-byte message [deq]"
-10,"L",1,10,0,10,0,10,10,0,0,TRUE,FALSE,FALSE,54,1,32,1,0,0,"10 * 10-byte message [deq]"
-11,"L",1,1,0,1,0,10,10,0,0,TRUE,TRUE,FALSE,54,1,32,1,0,0,"1 * 10-byte message [deq transient]"
-12,"L",1,10,0,10,0,10,10,0,0,TRUE,TRUE,FALSE,54,1,32,1,0,0,"10 * 10-byte message [deq transient]"
-13,"L",1,1,0,1,0,10,10,10,10,TRUE,FALSE,FALSE,64,1,54,1,46,1,"1 * 10-byte message [deq txn]"
-14,"L",1,10,0,10,0,10,10,10,10,TRUE,FALSE,FALSE,64,1,54,1,46,1,"10 * 10-byte message [deq txn]"
-15,"L",1,1,0,1,0,10,10,10,10,TRUE,TRUE,FALSE,64,1,54,1,46,1,"1 * 10-byte message [txn deq transient]"
-16,"L",1,10,0,10,0,10,10,10,10,TRUE,TRUE,FALSE,64,1,54,1,46,1,"10 * 10-byte message [txn deq transient]"
-17,"L",1,1,0,1,0,10,10,0,0,FALSE,FALSE,TRUE,54,1,0,0,0,0,"1 * 10-byte message [extern]"
-18,"L",1,10,0,10,0,10,10,0,0,FALSE,FALSE,TRUE,54,1,0,0,0,0,"10 * 10-byte message [extern]"
-19,"L",1,1,0,1,0,10,10,0,0,FALSE,TRUE,TRUE,54,1,0,0,0,0,"1 * 10-byte message [transient extern]"
-20,"L",1,10,0,10,0,10,10,0,0,FALSE,TRUE,TRUE,54,1,0,0,0,0,"10 * 10-byte message [transient extern]"
-21,"L",1,1,0,1,0,10,10,10,10,FALSE,FALSE,TRUE,64,1,0,0,0,0,"1 * 10-byte message [txn extern]"
-22,"L",1,10,0,10,0,10,10,10,10,FALSE,FALSE,TRUE,64,1,0,0,0,0,"10 * 10-byte message [txn extern]"
-23,"L",1,1,0,1,0,10,10,10,10,FALSE,TRUE,TRUE,64,1,0,0,0,0,"1 * 10-byte message [txn transient extern]"
-24,"L",1,10,0,10,0,10,10,10,10,FALSE,TRUE,TRUE,64,1,0,0,0,0,"10 * 10-byte message [txn transient extern]"
-25,"L",1,1,0,1,0,10,10,0,0,TRUE,FALSE,TRUE,54,1,32,1,0,0,"1 * 10-byte message [deq extern]"
-26,"L",1,10,0,10,0,10,10,0,0,TRUE,FALSE,TRUE,54,1,32,1,0,0,"10 * 10-byte message [deq extern]"
-27,"L",1,1,0,1,0,10,10,0,0,TRUE,TRUE,TRUE,54,1,32,1,0,0,"1 * 10-byte message [deq transient extern]"
-28,"L",1,10,0,10,0,10,10,0,0,TRUE,TRUE,TRUE,54,1,32,1,0,0,"10 * 10-byte message [deq transient extern]"
-29,"L",1,1,0,1,0,10,10,10,10,TRUE,FALSE,TRUE,64,1,54,1,46,1,"1 * 10-byte message [deq txn extern]"
-30,"L",1,10,0,10,0,10,10,10,10,TRUE,FALSE,TRUE,64,1,54,1,46,1,"10 * 10-byte message [deq txn extern]"
-31,"L",1,1,0,1,0,10,10,10,10,TRUE,TRUE,TRUE,64,1,54,1,46,1,"1 * 10-byte message [txn deq transient extern]"
-32,"L",1,10,0,10,0,10,10,10,10,TRUE,TRUE,TRUE,64,1,54,1,46,1,"10 * 10-byte message [txn deq transient extern]"
-,,,,,,,,,,,,,,,,,,,,
-"Transition from one d-block to two per message",,,,,,,,,,,,,,,,,,,,
-33,"L",1,10,0,10,0,84,84,0,0,FALSE,FALSE,FALSE,128,1,0,0,0,0,"1 dblk exact fit"
-34,"L",1,10,0,10,1,85,85,0,0,FALSE,FALSE,FALSE,129,2,0,0,0,0,"1 dblk + 1 byte"
-35,"L",1,10,0,10,0,58,58,26,26,FALSE,FALSE,FALSE,128,1,0,0,0,0,"1 dblk exact fit [txn]"
-36,"L",1,10,0,10,1,59,59,26,26,FALSE,FALSE,FALSE,129,2,0,0,0,0,"1 dblk + 1 byte [txn]"
-,,,,,,,,,,,,,,,,,,,,
-"Transition from one s-block to two per message",,,,,,,,,,,,,,,,,,,,
-37,"L",1,10,0,10,0,468,468,0,0,FALSE,FALSE,FALSE,512,4,0,0,0,0,"1 sblk exact fit"
-38,"L",1,10,0,10,1,469,469,0,0,FALSE,FALSE,FALSE,513,5,0,0,0,0,"1 sblk + 1 byte"
-39,"L",1,10,0,10,0,442,442,26,26,FALSE,FALSE,FALSE,512,4,0,0,0,0,"1 sblk exact fit [txn]"
-40,"L",1,10,0,10,1,443,443,26,26,FALSE,FALSE,FALSE,513,5,0,0,0,0,"1 sblk + 1 byte [txn]"
-,,,,,,,,,,,,,,,,,,,,
-"Transition from first page to second",,,,,,,,,,,,,,,,,,,,
-41,"L",1,8,0,8,0,4052,4052,0,0,FALSE,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page"
-42,"L",1,8,1,9,0,4052,4052,0,0,FALSE,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page"
-43,"L",1,8,0,8,1,4053,4053,0,0,FALSE,FALSE,FALSE,4097,33,0,0,0,0,"1/8 page + 1 byte"
-44,"L",1,8,0,8,0,3796,3796,256,256,FALSE,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page [txn]"
-45,"L",1,8,1,9,0,3796,3796,256,256,FALSE,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page [txn]"
-46,"L",1,8,0,8,1,3797,3797,256,256,FALSE,FALSE,FALSE,4097,33,0,0,0,0,"1/8 page + 1 byte [txn]"
-47,"L",1,8,0,8,0,3924,3924,0,0,TRUE,FALSE,FALSE,3968,31,32,1,0,0,"1/8 page incl deq [deq]"
-48,"L",1,8,1,9,0,3924,3924,0,0,TRUE,FALSE,FALSE,3968,31,32,1,0,0,"1/8 page incl deq [deq]"
-49,"L",1,8,0,8,1,3925,3925,0,0,TRUE,FALSE,FALSE,3969,32,32,1,0,0,"1/8 page incl deq + 1 byte [deq]"
-50,"L",1,8,0,8,0,3028,3028,256,256,TRUE,FALSE,FALSE,3328,26,300,3,292,3,"1/8 page incl deq & txn [deq txn]"
-51,"L",1,8,1,9,0,3028,3028,256,256,TRUE,FALSE,FALSE,3328,26,300,3,292,3,"1/8 page incl deq & txn [deq txn]"
-52,"L",1,8,0,8,1,3029,3029,256,256,TRUE,FALSE,FALSE,3329,27,300,3,292,3,"1/8 page incl deq & txn + 1 byte [deq txn]"
-,,,,,,,,,,,,,,,,,,,,
-"Page cache rollover (from page 32 back to page 0)",,,,,,,,,,,,,,,,,,,,
-53,"L",1,32,0,32,0,32724,32724,0,0,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
-54,"L",1,32,1,33,0,32724,32724,0,0,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
-55,"L",1,32,0,32,1,32725,32725,0,0,FALSE,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte"
-56,"L",1.5,22,0,22,0,49108,49108,0,0,FALSE,FALSE,FALSE,49152,384,0,0,0,0,"1.5 pages"
-57,"L",1,32,0,32,0,32468,32468,256,256,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
-58,"L",1,32,1,33,0,32468,32468,256,256,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
-59,"L",1,32,0,32,1,32469,32469,256,256,FALSE,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte [txn]"
-60,"L",1.5,22,0,22,0,48852,48852,256,256,FALSE,FALSE,FALSE,49152,384,0,0,0,0,"1.5 pages [txn]"
-61,"L",1,32,0,32,0,32596,32596,0,0,TRUE,FALSE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
-62,"L",1,32,1,33,0,32596,32596,0,0,TRUE,FALSE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
-63,"L",1,32,0,32,1,32597,32597,0,0,TRUE,FALSE,FALSE,32641,256,32,1,0,0,"1 page incl deq + 1 byte [deq]"
-64,"L",1.5,22,0,22,0,48980,48980,0,0,TRUE,FALSE,FALSE,49024,383,32,1,0,0,"1.5 pages incl deq [deq]"
-65,"L",1,32,0,32,0,31700,31700,256,256,TRUE,FALSE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
-66,"L",1,32,1,33,0,31700,31700,256,256,TRUE,FALSE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
-67,"L",1,32,0,32,1,31701,31701,256,256,TRUE,FALSE,FALSE,32001,251,300,3,292,3,"1 page incl deq & txn + 1 byte [deq txn]"
-68,"L",1.5,22,0,22,0,48084,48084,256,256,TRUE,FALSE,FALSE,48384,378,300,3,292,3,"1.5 pages incl deq & txn [deq txn]"
-,,,,,,,,,,,,,,,,,,,,
-"File transition (from file 0000 to 0001)",,,,,,,,,,,,,,,,,,,,
-69,"L",1,48,0,48,0,32724,32724,0,0,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
-70,"L",1,48,1,49,0,32724,32724,0,0,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
-71,"L",1,48,0,48,1,32725,32725,0,0,FALSE,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte"
-72,"L",2.5,20,0,20,0,81876,81876,0,0,FALSE,FALSE,FALSE,81920,640,0,0,0,0,"2.5 pages"
-73,"L",1,48,0,48,0,32468,32468,256,256,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
-74,"L",1,48,1,49,0,32468,32468,256,256,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
-75,"L",1,48,0,48,1,32469,32469,256,256,FALSE,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte [txn]"
-76,"L",2.5,20,0,20,0,81620,81620,256,256,FALSE,FALSE,FALSE,81920,640,0,0,0,0,"2.5 pages [txn]"
-77,"L",1,48,0,48,0,32596,32596,0,0,TRUE,FALSE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
-78,"L",1,48,1,49,0,32596,32596,0,0,TRUE,FALSE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
-79,"L",1,48,0,48,1,32597,32597,0,0,TRUE,FALSE,FALSE,32641,256,32,1,0,0,"1 page incl deq + 1 byte [deq]"
-80,"L",2.5,20,0,20,0,81748,81748,0,0,TRUE,FALSE,FALSE,81792,639,32,1,0,0,"2.5 pages incl deq [deq]"
-81,"L",1,48,0,48,0,31700,31700,256,256,TRUE,FALSE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
-82,"L",1,48,1,49,0,31700,31700,256,256,TRUE,FALSE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
-83,"L",1,48,0,48,1,31701,31701,256,256,TRUE,FALSE,FALSE,32001,251,300,3,292,3,"1 page incl deq & txn + 1 byte [deq txn]"
-84,"L",2.5,20,0,20,0,80852,80852,256,256,TRUE,FALSE,FALSE,81152,634,300,3,292,3,"2.5 pages incl deq & txn [deq txn]"
-,,,,,,,,,,,,,,,,,,,,
-"File rollover (from file 0007 to 0000) - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,,,,,,,,,,,,,,,
-85,"L",0.5,16,0,16,0,786388,786388,0,0,FALSE,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file"
-86,"L",0.5,16,1,17,0,786388,786388,0,0,FALSE,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file"
-87,"L",0.5,16,0,16,1,786389,786389,0,0,FALSE,FALSE,FALSE,786433,6145,0,0,0,0,"24 pages + 1 byte"
-88,"L",0.5,16,0,16,0,786132,786132,256,256,FALSE,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file [txn]"
-89,"L",0.5,16,1,17,0,786132,786132,256,256,FALSE,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file [txn]"
-90,"L",0.5,16,0,16,1,786133,786133,256,256,FALSE,FALSE,FALSE,786433,6145,0,0,0,0,"24 pages + 1 byte [txn]"
-91,"L",0.25,32,0,32,0,786388,786388,0,0,FALSE,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file"
-92,"L",0.25,32,1,33,0,786388,786388,0,0,FALSE,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file"
-93,"L",0.25,32,0,32,1,786389,786389,0,0,FALSE,FALSE,FALSE,786433,6145,0,0,0,0,"24 pages + 1 byte"
-94,"L",0.25,32,0,32,0,786132,786132,256,256,FALSE,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file [txn]"
-95,"L",0.25,32,1,33,0,786132,786132,256,256,FALSE,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file [txn]"
-96,"L",0.25,32,0,32,1,786133,786133,256,256,FALSE,FALSE,FALSE,786433,6145,0,0,0,0,"24 pages + 1 byte [txn]"
-97,"L",0.5,16,0,16,0,786260,786260,0,0,TRUE,FALSE,FALSE,786304,6143,32,1,0,0,"24 pages incl deq = ½ file [deq]"
-98,"L",0.5,16,1,17,0,786260,786260,0,0,TRUE,FALSE,FALSE,786304,6143,32,1,0,0,"24 pages incl deq = ½ file [deq]"
-99,"L",0.5,16,0,16,1,786261,786261,0,0,TRUE,FALSE,FALSE,786305,6144,32,1,0,0,"24 pages incl deq + 1 byte [deq]"
-100,"L",0.5,16,0,16,0,785364,785364,256,256,TRUE,FALSE,FALSE,785664,6138,300,3,292,3,"24 pages incl deq & txn = ½ file [deq txn]"
-101,"L",0.5,16,1,17,0,785364,785364,256,256,TRUE,FALSE,FALSE,785664,6138,300,3,292,3,"24 pages incl deq & txn = ½ file [deq txn]"
-102,"L",0.5,16,0,16,1,785365,785365,256,256,TRUE,FALSE,FALSE,785665,6139,300,3,292,3,"24 pages incl deq & txn + 1 byte [deq txn]"
-103,"L",0.25,32,0,32,0,786260,786260,0,0,TRUE,FALSE,FALSE,786304,6143,32,1,0,0,"24 pages incl deq = ½ file [deq]"
-104,"L",0.25,32,1,33,0,786260,786260,0,0,TRUE,FALSE,FALSE,786304,6143,32,1,0,0,"24 pages incl deq = ½ file [deq]"
-105,"L",0.25,32,0,32,1,786261,786261,0,0,TRUE,FALSE,FALSE,786305,6144,32,1,0,0,"24 pages incl deq + 1 byte [deq]"
-106,"L",0.25,32,0,32,0,785364,785364,256,256,TRUE,FALSE,FALSE,785664,6138,300,3,292,3,"24 pages incl deq & txn = ½ file [deq txn]"
-107,"L",0.25,32,1,33,0,785364,785364,256,256,TRUE,FALSE,FALSE,785664,6138,300,3,292,3,"24 pages incl deq & txn = ½ file [deq txn]"
-108,"L",0.25,32,0,32,1,785365,785365,256,256,TRUE,FALSE,FALSE,785665,6139,300,3,292,3,"24 pages incl deq & txn + 1 byte [deq txn]"
-,,,,,,,,,,,,,,,,,,,,
-"Multi-page messages (large messages) - tests various paths in encoder.",,,,,,,,,,,,,,,,,,,,
-109,"L",1,16,0,16,0,32724,32724,0,0,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"data 1 page"
-110,"L",1,16,0,16,1,32725,32725,0,0,FALSE,FALSE,FALSE,32769,257,0,0,0,0,"data 1 page + 1 byte (tail split; 1 byte over page boundary)"
-111,"L",1,16,0,16,11,32735,32735,0,0,FALSE,FALSE,FALSE,32779,257,0,0,0,0,"data 1 page + 11 bytes (tail split; 11 bytes over page boundary)"
-112,"L",1,16,0,16,12,32736,32736,0,0,FALSE,FALSE,FALSE,32780,257,0,0,0,0,"data 1 page + 12 bytes (tail separated exactly onto next page)"
-113,"L",1,16,0,16,13,32737,32737,0,0,FALSE,FALSE,FALSE,32781,257,0,0,0,0,"data 1 page + 13 bytes (data split; 1 byte over page boundary)"
-114,"L",1,16,0,16,0,32468,32468,256,256,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"data 1 page [txn]"
-115,"L",1,16,0,16,1,32469,32469,256,256,FALSE,FALSE,FALSE,32769,257,0,0,0,0,"data 1 page + 1 byte (tail split; 1 byte over page boundary) [txn]"
-116,"L",1,16,0,16,11,32479,32479,256,256,FALSE,FALSE,FALSE,32779,257,0,0,0,0,"data 1 page + 11 bytes (tail split; 11 bytes over page boundary) [txn]"
-117,"L",1,16,0,16,12,32480,32480,256,256,FALSE,FALSE,FALSE,32780,257,0,0,0,0,"data 1 page + 12 bytes (tail separated exactly onto next page) [txn]"
-118,"L",1,16,0,16,13,32481,32481,256,256,FALSE,FALSE,FALSE,32781,257,0,0,0,0,"data 1 page + 13 bytes (data split; 1 byte over page boundary) [txn]"
-119,"L",2,16,0,16,0,65492,65492,0,0,FALSE,FALSE,FALSE,65536,512,0,0,0,0,"data 2 pages"
-120,"L",2,16,0,16,1,65493,65493,0,0,FALSE,FALSE,FALSE,65537,513,0,0,0,0,"data 2 pages + 1 byte (tail split; 1 byte over page boundary)"
-121,"L",2,16,0,16,11,65503,65503,0,0,FALSE,FALSE,FALSE,65547,513,0,0,0,0,"data 2 pages + 11 bytes (tail split; 11 bytes over page boundary)"
-122,"L",2,16,0,16,12,65504,65504,0,0,FALSE,FALSE,FALSE,65548,513,0,0,0,0,"data 2 pages + 12 bytes (tail separated exactly onto next page)"
-123,"L",2,16,0,16,13,65505,65505,0,0,FALSE,FALSE,FALSE,65549,513,0,0,0,0,"data 2 pages + 13 bytes (data split; 1 byte over page boundary)"
-124,"L",2,16,0,16,0,65236,65236,256,256,FALSE,FALSE,FALSE,65536,512,0,0,0,0,"data 2 pages [txn]"
-125,"L",2,16,0,16,1,65237,65237,256,256,FALSE,FALSE,FALSE,65537,513,0,0,0,0,"data 2 pages + 1 byte (tail split; 1 byte over page boundary) [txn]"
-126,"L",2,16,0,16,11,65247,65247,256,256,FALSE,FALSE,FALSE,65547,513,0,0,0,0,"data 2 pages + 11 bytes (tail split; 11 bytes over page boundary) [txn]"
-127,"L",2,16,0,16,12,65248,65248,256,256,FALSE,FALSE,FALSE,65548,513,0,0,0,0,"data 2 pages + 12 bytes (tail separated exactly onto next page) [txn]"
-128,"L",2,16,0,16,13,65249,65249,256,256,FALSE,FALSE,FALSE,65549,513,0,0,0,0,"data 2 pages + 13 bytes (data split; 1 byte over page boundary) [txn]"
-129,"L",4,16,0,16,0,131028,131028,0,0,FALSE,FALSE,FALSE,131072,1024,0,0,0,0,"data 4 pages"
-130,"L",4,16,0,16,1,131029,131029,0,0,FALSE,FALSE,FALSE,131073,1025,0,0,0,0,"data 4 pages + 1 byte (tail split; 1 byte over page boundary)"
-131,"L",4,16,0,16,11,131039,131039,0,0,FALSE,FALSE,FALSE,131083,1025,0,0,0,0,"data 4 pages + 11 bytes (tail split; 11 bytes over page boundary)"
-132,"L",4,16,0,16,12,131040,131040,0,0,FALSE,FALSE,FALSE,131084,1025,0,0,0,0,"data 4 pages + 12 bytes (tail separated exactly onto next page)"
-133,"L",4,16,0,16,13,131041,131041,0,0,FALSE,FALSE,FALSE,131085,1025,0,0,0,0,"data 4 pages + 13 bytes (data split; 1 byte over page boundary)"
-134,"L",4,16,0,16,0,130772,130772,256,256,FALSE,FALSE,FALSE,131072,1024,0,0,0,0,"data 4 pages [txn]"
-135,"L",4,16,0,16,1,130773,130773,256,256,FALSE,FALSE,FALSE,131073,1025,0,0,0,0,"data 4 pages + 1 byte (tail split; 1 byte over page boundary) [txn]"
-136,"L",4,16,0,16,11,130783,130783,256,256,FALSE,FALSE,FALSE,131083,1025,0,0,0,0,"data 4 pages + 11 bytes (tail split; 11 bytes over page boundary) [txn]"
-137,"L",4,16,0,16,12,130784,130784,256,256,FALSE,FALSE,FALSE,131084,1025,0,0,0,0,"data 4 pages + 12 bytes (tail separated exactly onto next page) [txn]"
-138,"L",4,16,0,16,13,130785,130785,256,256,FALSE,FALSE,FALSE,131085,1025,0,0,0,0,"data 4 pages + 13 bytes (data split; 1 byte over page boundary) [txn]"
-139,"L",3.5,16,0,16,0,114644,114644,0,0,FALSE,FALSE,FALSE,114688,896,0,0,0,0,"data 3.5 pages"
-140,"L",3.5,16,0,16,1,114645,114645,0,0,FALSE,FALSE,FALSE,114689,897,0,0,0,0,"data 3.5 pages + 1 byte"
-141,"L",3.5,16,0,16,0,114388,114388,256,256,FALSE,FALSE,FALSE,114688,896,0,0,0,0,"data 3.5 pages [txn]"
-142,"L",3.5,16,0,16,1,114389,114389,256,256,FALSE,FALSE,FALSE,114689,897,0,0,0,0,"data 3.5 pages + 1 byte [txn]"
-143,"L",1,16,0,16,-1,10,10,32735,32735,FALSE,FALSE,FALSE,32789,257,0,0,0,0,"xid 1 page – 1 byte; data 10 bytes (exact fit) [txn]"
-144,"L",1,16,0,16,0,10,10,32736,32736,FALSE,FALSE,FALSE,32790,257,0,0,0,0,"xid 1 page; data 10 bytes (exact fit) [txn]"
-145,"L",1,16,0,16,1,10,10,32737,32737,FALSE,FALSE,FALSE,32791,257,0,0,0,0,"xid 1 page + 1 byte; data 10 bytes (exact fit) [txn]"
-146,"L",2,16,0,16,-1,10,10,65503,65503,FALSE,FALSE,FALSE,65557,513,0,0,0,0,"xid 2 pages – 1 byte; data 10 bytes (exact fit) [txn]"
-147,"L",2,16,0,16,0,10,10,65504,65504,FALSE,FALSE,FALSE,65558,513,0,0,0,0,"xid 2 pages; data 10 bytes (exact fit) [txn]"
-148,"L",2,16,0,16,1,10,10,65505,65505,FALSE,FALSE,FALSE,65559,513,0,0,0,0,"xid 2 pages + 1 byte; data 10 bytes (exact fit) [txn]"
-149,"L",4,16,0,16,-1,10,10,131039,131039,FALSE,FALSE,FALSE,131093,1025,0,0,0,0,"xid 4 pages – 1 byte; data 10 bytes (exact fit) [txn]"
-150,"L",4,16,0,16,0,10,10,131040,131040,FALSE,FALSE,FALSE,131094,1025,0,0,0,0,"xid 4 pages; data 10 bytes (exact fit) [txn]"
-151,"L",4,16,0,16,1,10,10,131041,131041,FALSE,FALSE,FALSE,131095,1025,0,0,0,0,"xid 4 pages + 1 byte; data 10 bytes (exact fit) [txn]"
-152,"L",3.5,16,0,16,0,10,10,114656,114656,FALSE,FALSE,FALSE,114710,897,0,0,0,0,"xid 3.5 pages; data 10 bytes (exact fit) [txn]"
-153,"L",3.5,16,0,16,1,10,10,114657,114657,FALSE,FALSE,FALSE,114711,897,0,0,0,0,"xid 3.5 pages + 1 byte; data 10 bytes (exact fit) [txn]"
-154,"L",1,16,0,16,-1,10,10,32735,32735,TRUE,FALSE,FALSE,32789,257,32779,257,32771,257,"xid 1 page – 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-155,"L",1,16,0,16,0,10,10,32736,32736,TRUE,FALSE,FALSE,32790,257,32780,257,32772,257,"xid 1 page for enq rec; data 10 bytes (exact fit) [deq, txn]"
-156,"L",1,16,0,16,1,10,10,32737,32737,TRUE,FALSE,FALSE,32791,257,32781,257,32773,257,"xid 1 page + 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-157,"L",2,16,0,16,-1,10,10,65503,65503,TRUE,FALSE,FALSE,65557,513,65547,513,65539,513,"xid 2 pages – 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-158,"L",2,16,0,16,0,10,10,65504,65504,TRUE,FALSE,FALSE,65558,513,65548,513,65540,513,"xid 2 pages for enq rec; data 10 bytes (exact fit) [deq, txn]"
-159,"L",2,16,0,16,1,10,10,65505,65505,TRUE,FALSE,FALSE,65559,513,65549,513,65541,513,"xid 2 pages + 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-160,"L",4,16,0,16,-1,10,10,131039,131039,TRUE,FALSE,FALSE,131093,1025,131083,1025,131075,1025,"xid 4 pages – 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-161,"L",4,16,0,16,0,10,10,131040,131040,TRUE,FALSE,FALSE,131094,1025,131084,1025,131076,1025,"xid 4 pages for enq rec; data 10 bytes (exact fit) [deq, txn]"
-162,"L",4,16,0,16,1,10,10,131041,131041,TRUE,FALSE,FALSE,131095,1025,131085,1025,131077,1025,"xid 4 pages + 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-163,"L",3.5,16,0,16,0,10,10,114656,114656,TRUE,FALSE,FALSE,114710,897,114700,897,114692,897,"xid 3.5 pages for enq rec; data 10 bytes (exact fit) [deq, txn]"
-164,"L",3.5,16,0,16,1,10,10,114657,114657,TRUE,FALSE,FALSE,114711,897,114701,897,114693,897,"xid 3.5 pages + 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-165,"L",1,16,0,16,-1,10,10,32735,32735,TRUE,FALSE,FALSE,32789,257,32779,257,32771,257,"xid 1 page – 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-166,"L",1,16,0,16,0,10,10,32736,32736,TRUE,FALSE,FALSE,32790,257,32780,257,32772,257,"xid 1 page for deq rec; data 10 bytes (exact fit) [deq, txn]"
-167,"L",1,16,0,16,1,10,10,32737,32737,TRUE,FALSE,FALSE,32791,257,32781,257,32773,257,"xid 1 page + 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-168,"L",2,16,0,16,-1,10,10,65503,65503,TRUE,FALSE,FALSE,65557,513,65547,513,65539,513,"xid 2 pages – 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-169,"L",2,16,0,16,0,10,10,65504,65504,TRUE,FALSE,FALSE,65558,513,65548,513,65540,513,"xid 2 pages for deq rec; data 10 bytes (exact fit) [deq, txn]"
-170,"L",2,16,0,16,1,10,10,65505,65505,TRUE,FALSE,FALSE,65559,513,65549,513,65541,513,"xid 2 pages + 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-171,"L",4,16,0,16,-1,10,10,131039,131039,TRUE,FALSE,FALSE,131093,1025,131083,1025,131075,1025,"xid 4 pages – 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-172,"L",4,16,0,16,0,10,10,131040,131040,TRUE,FALSE,FALSE,131094,1025,131084,1025,131076,1025,"xid 4 pages for deq rec; data 10 bytes (exact fit) [deq, txn]"
-173,"L",4,16,0,16,1,10,10,131041,131041,TRUE,FALSE,FALSE,131095,1025,131085,1025,131077,1025,"xid 4 pages + 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-174,"L",3.5,16,0,16,0,10,10,114656,114656,TRUE,FALSE,FALSE,114710,897,114700,897,114692,897,"xid 3.5 pages for deq rec; data 10 bytes (exact fit) [deq, txn]"
-175,"L",3.5,16,0,16,1,10,10,114657,114657,TRUE,FALSE,FALSE,114711,897,114701,897,114693,897,"xid 3.5 pages + 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-176,"L",1,16,0,16,-1,10,10,32743,32743,TRUE,FALSE,FALSE,32797,257,32787,257,32779,257,"xid 1 page – 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-177,"L",1,16,0,16,0,10,10,32744,32744,TRUE,FALSE,FALSE,32798,257,32788,257,32780,257,"xid 1 page for txn rec; data 10 bytes (exact fit) [deq, txn]"
-178,"L",1,16,0,16,1,10,10,32745,32745,TRUE,FALSE,FALSE,32799,257,32789,257,32781,257,"xid 1 page + 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-179,"L",2,16,0,16,-1,10,10,65511,65511,TRUE,FALSE,FALSE,65565,513,65555,513,65547,513,"xid 2 pages – 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-180,"L",2,16,0,16,0,10,10,65512,65512,TRUE,FALSE,FALSE,65566,513,65556,513,65548,513,"xid 2 pages for txn rec; data 10 bytes (exact fit) [deq, txn]"
-181,"L",2,16,0,16,1,10,10,65513,65513,TRUE,FALSE,FALSE,65567,513,65557,513,65549,513,"xid 2 pages + 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-182,"L",4,16,0,16,-1,10,10,131047,131047,TRUE,FALSE,FALSE,131101,1025,131091,1025,131083,1025,"xid 4 pages – 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-183,"L",4,16,0,16,0,10,10,131048,131048,TRUE,FALSE,FALSE,131102,1025,131092,1025,131084,1025,"xid 4 pages for txn rec; data 10 bytes (exact fit) [deq, txn]"
-184,"L",4,16,0,16,1,10,10,131049,131049,TRUE,FALSE,FALSE,131103,1025,131093,1025,131085,1025,"xid 4 pages + 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-185,"L",3.5,16,0,16,0,10,10,114664,114664,TRUE,FALSE,FALSE,114718,897,114708,897,114700,897,"xid 3.5 pages for txn rec; data 10 bytes (exact fit) [deq, txn]"
-186,"L",3.5,16,0,16,1,10,10,114665,114665,TRUE,FALSE,FALSE,114719,897,114709,897,114701,897,"xid 3.5 pages + 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
Deleted: store/trunk/cpp/tests/jrnl/wtests.csv
===================================================================
--- store/trunk/cpp/tests/jrnl/wtests.csv 2008-09-09 19:25:47 UTC (rev 2433)
+++ store/trunk/cpp/tests/jrnl/wtests.csv 2008-09-09 20:24:44 UTC (rev 2434)
@@ -1,293 +0,0 @@
-,,,,,,,"Msg size",,"Xid size",,,,,"enq-size",,"deq-size",,"txn-size",,
-"Test #","tf","pf","amn","mn incr","#msgs","ms incr","Min","Max","Min","Max","auto-deq","transient","external","bytes","dblks","bytes","dblks","bytes","dblks","comment"
-,,,,,,,,,,,,,,,,,,,,
-"Initialize only",,,,,,,,,,,,,,,,,,,,
-0,"L",0,0,0,0,0,0,0,0,0,FALSE,FALSE,FALSE,44,1,0,0,0,0,"No messages – journal creation/initialization only"
-,,,,,,,,,,,,,,,,,,,,
-"Simple message combinations of persistent/deq transientueued/non-dequeued, transactional/non-transactional",,,,,,,,,,,,,,,,,,,,
-1,"L",1,1,0,1,0,10,10,0,0,FALSE,FALSE,FALSE,54,1,0,0,0,0,"1 * 10-byte message"
-2,"L",1,10,0,10,0,10,10,0,0,FALSE,FALSE,FALSE,54,1,0,0,0,0,"10 * 10-byte message"
-3,"L",1,1,0,1,0,10,10,0,0,FALSE,TRUE,FALSE,54,1,0,0,0,0,"1 * 10-byte message [transient]"
-4,"L",1,10,0,10,0,10,10,0,0,FALSE,TRUE,FALSE,54,1,0,0,0,0,"10 * 10-byte message [transient]"
-5,"L",1,1,0,1,0,10,10,10,10,FALSE,FALSE,FALSE,64,1,0,0,0,0,"1 * 10-byte message [txn]"
-6,"L",1,10,0,10,0,10,10,10,10,FALSE,FALSE,FALSE,64,1,0,0,0,0,"10 * 10-byte message [txn]"
-7,"L",1,1,0,1,0,10,10,10,10,FALSE,TRUE,FALSE,64,1,0,0,0,0,"1 * 10-byte message [txn transient]"
-8,"L",1,10,0,10,0,10,10,10,10,FALSE,TRUE,FALSE,64,1,0,0,0,0,"10 * 10-byte message [txn transient]"
-9,"L",1,1,0,1,0,10,10,0,0,TRUE,FALSE,FALSE,54,1,32,1,0,0,"1 * 10-byte message [deq]"
-10,"L",1,10,0,10,0,10,10,0,0,TRUE,FALSE,FALSE,54,1,32,1,0,0,"10 * 10-byte message [deq]"
-11,"L",1,1,0,1,0,10,10,0,0,TRUE,TRUE,FALSE,54,1,32,1,0,0,"1 * 10-byte message [deq transient]"
-12,"L",1,10,0,10,0,10,10,0,0,TRUE,TRUE,FALSE,54,1,32,1,0,0,"10 * 10-byte message [deq transient]"
-13,"L",1,1,0,1,0,10,10,10,10,TRUE,FALSE,FALSE,64,1,54,1,46,1,"1 * 10-byte message [deq txn]"
-14,"L",1,10,0,10,0,10,10,10,10,TRUE,FALSE,FALSE,64,1,54,1,46,1,"10 * 10-byte message [deq txn]"
-15,"L",1,1,0,1,0,10,10,10,10,TRUE,TRUE,FALSE,64,1,54,1,46,1,"1 * 10-byte message [txn deq transient]"
-16,"L",1,10,0,10,0,10,10,10,10,TRUE,TRUE,FALSE,64,1,54,1,46,1,"10 * 10-byte message [txn deq transient]"
-17,"L",1,1,0,1,0,10,10,0,0,FALSE,FALSE,TRUE,44,1,0,0,0,0,"1 * 10-byte message [extern]"
-18,"L",1,10,0,10,0,10,10,0,0,FALSE,FALSE,TRUE,44,1,0,0,0,0,"10 * 10-byte message [extern]"
-19,"L",1,1,0,1,0,10,10,0,0,FALSE,TRUE,TRUE,44,1,0,0,0,0,"1 * 10-byte message [transient extern]"
-20,"L",1,10,0,10,0,10,10,0,0,FALSE,TRUE,TRUE,44,1,0,0,0,0,"10 * 10-byte message [transient extern]"
-21,"L",1,1,0,1,0,10,10,10,10,FALSE,FALSE,TRUE,54,1,0,0,0,0,"1 * 10-byte message [txn extern]"
-22,"L",1,10,0,10,0,10,10,10,10,FALSE,FALSE,TRUE,54,1,0,0,0,0,"10 * 10-byte message [txn extern]"
-23,"L",1,1,0,1,0,10,10,10,10,FALSE,TRUE,TRUE,54,1,0,0,0,0,"1 * 10-byte message [txn transient extern]"
-24,"L",1,10,0,10,0,10,10,10,10,FALSE,TRUE,TRUE,54,1,0,0,0,0,"10 * 10-byte message [txn transient extern]"
-25,"L",1,1,0,1,0,10,10,0,0,TRUE,FALSE,TRUE,44,1,32,1,0,0,"1 * 10-byte message [deq extern]"
-26,"L",1,10,0,10,0,10,10,0,0,TRUE,FALSE,TRUE,44,1,32,1,0,0,"10 * 10-byte message [deq extern]"
-27,"L",1,1,0,1,0,10,10,0,0,TRUE,TRUE,TRUE,44,1,32,1,0,0,"1 * 10-byte message [deq transient extern]"
-28,"L",1,10,0,10,0,10,10,0,0,TRUE,TRUE,TRUE,44,1,32,1,0,0,"10 * 10-byte message [deq transient extern]"
-29,"L",1,1,0,1,0,10,10,10,10,TRUE,FALSE,TRUE,54,1,54,1,46,1,"1 * 10-byte message [deq txn extern]"
-30,"L",1,10,0,10,0,10,10,10,10,TRUE,FALSE,TRUE,54,1,54,1,46,1,"10 * 10-byte message [deq txn extern]"
-31,"L",1,1,0,1,0,10,10,10,10,TRUE,TRUE,TRUE,54,1,54,1,46,1,"1 * 10-byte message [txn deq transient extern]"
-32,"L",1,10,0,10,0,10,10,10,10,TRUE,TRUE,TRUE,54,1,54,1,46,1,"10 * 10-byte message [txn deq transient extern]"
-,,,,,,,,,,,,,,,,,,,,
-"Transition from one d-block to two per message",,,,,,,,,,,,,,,,,,,,
-33,"L",1,10,0,10,0,84,84,0,0,FALSE,FALSE,FALSE,128,1,0,0,0,0,"1 dblk exact fit"
-34,"L",1,10,0,10,1,85,85,0,0,FALSE,FALSE,FALSE,129,2,0,0,0,0,"1 dblk + 1 byte"
-35,"L",1,10,0,10,0,58,58,26,26,FALSE,FALSE,FALSE,128,1,0,0,0,0,"1 dblk exact fit [txn]"
-36,"L",1,10,0,10,1,59,59,26,26,FALSE,FALSE,FALSE,129,2,0,0,0,0,"1 dblk + 1 byte [txn]"
-,,,,,,,,,,,,,,,,,,,,
-"Transition from one s-block to two per message",,,,,,,,,,,,,,,,,,,,
-37,"L",1,10,0,10,0,468,468,0,0,FALSE,FALSE,FALSE,512,4,0,0,0,0,"1 sblk exact fit"
-38,"L",1,10,0,10,1,469,469,0,0,FALSE,FALSE,FALSE,513,5,0,0,0,0,"1 sblk + 1 byte"
-39,"L",1,10,0,10,0,442,442,26,26,FALSE,FALSE,FALSE,512,4,0,0,0,0,"1 sblk exact fit [txn]"
-40,"L",1,10,0,10,1,443,443,26,26,FALSE,FALSE,FALSE,513,5,0,0,0,0,"1 sblk + 1 byte [txn]"
-,,,,,,,,,,,,,,,,,,,,
-"Transition from first page to second",,,,,,,,,,,,,,,,,,,,
-41,"L",1,8,0,8,0,4052,4052,0,0,FALSE,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page"
-42,"L",1,8,1,9,0,4052,4052,0,0,FALSE,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page"
-43,"L",1,8,0,8,1,4053,4053,0,0,FALSE,FALSE,FALSE,4097,33,0,0,0,0,"1/8 page + 1 byte"
-44,"L",1,8,0,8,0,3796,3796,256,256,FALSE,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page [txn]"
-45,"L",1,8,1,9,0,3796,3796,256,256,FALSE,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page [txn]"
-46,"L",1,8,0,8,1,3797,3797,256,256,FALSE,FALSE,FALSE,4097,33,0,0,0,0,"1/8 page + 1 byte [txn]"
-47,"L",1,8,0,8,0,3924,3924,0,0,TRUE,FALSE,FALSE,3968,31,32,1,0,0,"1/8 page incl deq [deq]"
-48,"L",1,8,1,9,0,3924,3924,0,0,TRUE,FALSE,FALSE,3968,31,32,1,0,0,"1/8 page incl deq [deq]"
-49,"L",1,8,0,8,1,3925,3925,0,0,TRUE,FALSE,FALSE,3969,32,32,1,0,0,"1/8 page incl deq + 1 byte [deq]"
-50,"L",1,8,0,8,0,3028,3028,256,256,TRUE,FALSE,FALSE,3328,26,300,3,292,3,"1/8 page incl deq & txn [deq txn]"
-51,"L",1,8,1,9,0,3028,3028,256,256,TRUE,FALSE,FALSE,3328,26,300,3,292,3,"1/8 page incl deq & txn [deq txn]"
-52,"L",1,8,0,8,1,3029,3029,256,256,TRUE,FALSE,FALSE,3329,27,300,3,292,3,"1/8 page incl deq & txn + 1 byte [deq txn]"
-,,,,,,,,,,,,,,,,,,,,
-"Page cache rollover (from page 32 back to page 0)",,,,,,,,,,,,,,,,,,,,
-53,"L",1,32,0,32,0,32724,32724,0,0,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
-54,"L",1,32,1,33,0,32724,32724,0,0,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
-55,"L",1,32,0,32,1,32725,32725,0,0,FALSE,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte"
-56,"L",1.5,22,0,22,0,49108,49108,0,0,FALSE,FALSE,FALSE,49152,384,0,0,0,0,"1.5 pages"
-57,"L",1,32,0,32,0,32468,32468,256,256,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
-58,"L",1,32,1,33,0,32468,32468,256,256,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
-59,"L",1,32,0,32,1,32469,32469,256,256,FALSE,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte [txn]"
-60,"L",1.5,22,0,22,0,48852,48852,256,256,FALSE,FALSE,FALSE,49152,384,0,0,0,0,"1.5 pages [txn]"
-61,"L",1,32,0,32,0,32596,32596,0,0,TRUE,FALSE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
-62,"L",1,32,1,33,0,32596,32596,0,0,TRUE,FALSE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
-63,"L",1,32,0,32,1,32597,32597,0,0,TRUE,FALSE,FALSE,32641,256,32,1,0,0,"1 page incl deq + 1 byte [deq]"
-64,"L",1.5,22,0,22,0,48980,48980,0,0,TRUE,FALSE,FALSE,49024,383,32,1,0,0,"1.5 pages incl deq [deq]"
-65,"L",1,32,0,32,0,31700,31700,256,256,TRUE,FALSE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
-66,"L",1,32,1,33,0,31700,31700,256,256,TRUE,FALSE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
-67,"L",1,32,0,32,1,31701,31701,256,256,TRUE,FALSE,FALSE,32001,251,300,3,292,3,"1 page incl deq & txn + 1 byte [deq txn]"
-68,"L",1.5,22,0,22,0,48084,48084,256,256,TRUE,FALSE,FALSE,48384,378,300,3,292,3,"1.5 pages incl deq & txn [deq txn]"
-,,,,,,,,,,,,,,,,,,,,
-"File transition (from file 0000 to 0001)",,,,,,,,,,,,,,,,,,,,
-69,"L",1,48,0,48,0,32724,32724,0,0,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
-70,"L",1,48,1,49,0,32724,32724,0,0,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
-71,"L",1,48,0,48,1,32725,32725,0,0,FALSE,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte"
-72,"L",2.5,20,0,20,0,81876,81876,0,0,FALSE,FALSE,FALSE,81920,640,0,0,0,0,"2.5 pages"
-73,"L",1,48,0,48,0,32468,32468,256,256,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
-74,"L",1,48,1,49,0,32468,32468,256,256,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
-75,"L",1,48,0,48,1,32469,32469,256,256,FALSE,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte [txn]"
-76,"L",2.5,20,0,20,0,81620,81620,256,256,FALSE,FALSE,FALSE,81920,640,0,0,0,0,"2.5 pages [txn]"
-77,"L",1,48,0,48,0,32596,32596,0,0,TRUE,FALSE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
-78,"L",1,48,1,49,0,32596,32596,0,0,TRUE,FALSE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
-79,"L",1,48,0,48,1,32597,32597,0,0,TRUE,FALSE,FALSE,32641,256,32,1,0,0,"1 page incl deq + 1 byte [deq]"
-80,"L",2.5,20,0,20,0,81748,81748,0,0,TRUE,FALSE,FALSE,81792,639,32,1,0,0,"2.5 pages incl deq [deq]"
-81,"L",1,48,0,48,0,31700,31700,256,256,TRUE,FALSE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
-82,"L",1,48,1,49,0,31700,31700,256,256,TRUE,FALSE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
-83,"L",1,48,0,48,1,31701,31701,256,256,TRUE,FALSE,FALSE,32001,251,300,3,292,3,"1 page incl deq & txn + 1 byte [deq txn]"
-84,"L",2.5,20,0,20,0,80852,80852,256,256,TRUE,FALSE,FALSE,81152,634,300,3,292,3,"2.5 pages incl deq & txn [deq txn]"
-,,,,,,,,,,,,,,,,,,,,
-"File rollover (from file 0007 to 0000) - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,,,,,,,,,,,,,,,
-85,"L",0.5,16,0,16,0,786388,786388,0,0,FALSE,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file"
-86,"L",0.5,16,1,17,0,786388,786388,0,0,FALSE,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file"
-87,"L",0.5,16,0,16,1,786389,786389,0,0,FALSE,FALSE,FALSE,786433,6145,0,0,0,0,"24 pages + 1 byte"
-88,"L",0.5,16,0,16,0,786132,786132,256,256,FALSE,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file [txn]"
-89,"L",0.5,16,1,17,0,786132,786132,256,256,FALSE,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file [txn]"
-90,"L",0.5,16,0,16,1,786133,786133,256,256,FALSE,FALSE,FALSE,786433,6145,0,0,0,0,"24 pages + 1 byte [txn]"
-91,"L",0.25,32,0,32,0,786388,786388,0,0,FALSE,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file"
-92,"L",0.25,32,1,33,0,786388,786388,0,0,FALSE,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file"
-93,"L",0.25,32,0,32,1,786389,786389,0,0,FALSE,FALSE,FALSE,786433,6145,0,0,0,0,"24 pages + 1 byte"
-94,"L",0.25,32,0,32,0,786132,786132,256,256,FALSE,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file [txn]"
-95,"L",0.25,32,1,33,0,786132,786132,256,256,FALSE,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file [txn]"
-96,"L",0.25,32,0,32,1,786133,786133,256,256,FALSE,FALSE,FALSE,786433,6145,0,0,0,0,"24 pages + 1 byte [txn]"
-97,"L",0.5,16,0,16,0,786260,786260,0,0,TRUE,FALSE,FALSE,786304,6143,32,1,0,0,"24 pages incl deq = ½ file [deq]"
-98,"L",0.5,16,1,17,0,786260,786260,0,0,TRUE,FALSE,FALSE,786304,6143,32,1,0,0,"24 pages incl deq = ½ file [deq]"
-99,"L",0.5,16,0,16,1,786261,786261,0,0,TRUE,FALSE,FALSE,786305,6144,32,1,0,0,"24 pages incl deq + 1 byte [deq]"
-100,"L",0.5,16,0,16,0,785364,785364,256,256,TRUE,FALSE,FALSE,785664,6138,300,3,292,3,"24 pages incl deq & txn = ½ file [deq txn]"
-101,"L",0.5,16,1,17,0,785364,785364,256,256,TRUE,FALSE,FALSE,785664,6138,300,3,292,3,"24 pages incl deq & txn = ½ file [deq txn]"
-102,"L",0.5,16,0,16,1,785365,785365,256,256,TRUE,FALSE,FALSE,785665,6139,300,3,292,3,"24 pages incl deq & txn + 1 byte [deq txn]"
-103,"L",0.25,32,0,32,0,786260,786260,0,0,TRUE,FALSE,FALSE,786304,6143,32,1,0,0,"24 pages incl deq = ½ file [deq]"
-104,"L",0.25,32,1,33,0,786260,786260,0,0,TRUE,FALSE,FALSE,786304,6143,32,1,0,0,"24 pages incl deq = ½ file [deq]"
-105,"L",0.25,32,0,32,1,786261,786261,0,0,TRUE,FALSE,FALSE,786305,6144,32,1,0,0,"24 pages incl deq + 1 byte [deq]"
-106,"L",0.25,32,0,32,0,785364,785364,256,256,TRUE,FALSE,FALSE,785664,6138,300,3,292,3,"24 pages incl deq & txn = ½ file [deq txn]"
-107,"L",0.25,32,1,33,0,785364,785364,256,256,TRUE,FALSE,FALSE,785664,6138,300,3,292,3,"24 pages incl deq & txn = ½ file [deq txn]"
-108,"L",0.25,32,0,32,1,785365,785365,256,256,TRUE,FALSE,FALSE,785665,6139,300,3,292,3,"24 pages incl deq & txn + 1 byte [deq txn]"
-,,,,,,,,,,,,,,,,,,,,
-"Multi-page messages (large messages) - tests various paths in encoder.",,,,,,,,,,,,,,,,,,,,
-109,"L",1,16,0,16,0,32724,32724,0,0,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"data 1 page"
-110,"L",1,16,0,16,1,32725,32725,0,0,FALSE,FALSE,FALSE,32769,257,0,0,0,0,"data 1 page + 1 byte (tail split; 1 byte over page boundary)"
-111,"L",1,16,0,16,11,32735,32735,0,0,FALSE,FALSE,FALSE,32779,257,0,0,0,0,"data 1 page + 11 bytes (tail split; 11 bytes over page boundary)"
-112,"L",1,16,0,16,12,32736,32736,0,0,FALSE,FALSE,FALSE,32780,257,0,0,0,0,"data 1 page + 12 bytes (tail separated exactly onto next page)"
-113,"L",1,16,0,16,13,32737,32737,0,0,FALSE,FALSE,FALSE,32781,257,0,0,0,0,"data 1 page + 13 bytes (data split; 1 byte over page boundary)"
-114,"L",1,16,0,16,0,32468,32468,256,256,FALSE,FALSE,FALSE,32768,256,0,0,0,0,"data 1 page [txn]"
-115,"L",1,16,0,16,1,32469,32469,256,256,FALSE,FALSE,FALSE,32769,257,0,0,0,0,"data 1 page + 1 byte (tail split; 1 byte over page boundary) [txn]"
-116,"L",1,16,0,16,11,32479,32479,256,256,FALSE,FALSE,FALSE,32779,257,0,0,0,0,"data 1 page + 11 bytes (tail split; 11 bytes over page boundary) [txn]"
-117,"L",1,16,0,16,12,32480,32480,256,256,FALSE,FALSE,FALSE,32780,257,0,0,0,0,"data 1 page + 12 bytes (tail separated exactly onto next page) [txn]"
-118,"L",1,16,0,16,13,32481,32481,256,256,FALSE,FALSE,FALSE,32781,257,0,0,0,0,"data 1 page + 13 bytes (data split; 1 byte over page boundary) [txn]"
-119,"L",2,16,0,16,0,65492,65492,0,0,FALSE,FALSE,FALSE,65536,512,0,0,0,0,"data 2 pages"
-120,"L",2,16,0,16,1,65493,65493,0,0,FALSE,FALSE,FALSE,65537,513,0,0,0,0,"data 2 pages + 1 byte (tail split; 1 byte over page boundary)"
-121,"L",2,16,0,16,11,65503,65503,0,0,FALSE,FALSE,FALSE,65547,513,0,0,0,0,"data 2 pages + 11 bytes (tail split; 11 bytes over page boundary)"
-122,"L",2,16,0,16,12,65504,65504,0,0,FALSE,FALSE,FALSE,65548,513,0,0,0,0,"data 2 pages + 12 bytes (tail separated exactly onto next page)"
-123,"L",2,16,0,16,13,65505,65505,0,0,FALSE,FALSE,FALSE,65549,513,0,0,0,0,"data 2 pages + 13 bytes (data split; 1 byte over page boundary)"
-124,"L",2,16,0,16,0,65236,65236,256,256,FALSE,FALSE,FALSE,65536,512,0,0,0,0,"data 2 pages [txn]"
-125,"L",2,16,0,16,1,65237,65237,256,256,FALSE,FALSE,FALSE,65537,513,0,0,0,0,"data 2 pages + 1 byte (tail split; 1 byte over page boundary) [txn]"
-126,"L",2,16,0,16,11,65247,65247,256,256,FALSE,FALSE,FALSE,65547,513,0,0,0,0,"data 2 pages + 11 bytes (tail split; 11 bytes over page boundary) [txn]"
-127,"L",2,16,0,16,12,65248,65248,256,256,FALSE,FALSE,FALSE,65548,513,0,0,0,0,"data 2 pages + 12 bytes (tail separated exactly onto next page) [txn]"
-128,"L",2,16,0,16,13,65249,65249,256,256,FALSE,FALSE,FALSE,65549,513,0,0,0,0,"data 2 pages + 13 bytes (data split; 1 byte over page boundary) [txn]"
-129,"L",4,16,0,16,0,131028,131028,0,0,FALSE,FALSE,FALSE,131072,1024,0,0,0,0,"data 4 pages"
-130,"L",4,16,0,16,1,131029,131029,0,0,FALSE,FALSE,FALSE,131073,1025,0,0,0,0,"data 4 pages + 1 byte (tail split; 1 byte over page boundary)"
-131,"L",4,16,0,16,11,131039,131039,0,0,FALSE,FALSE,FALSE,131083,1025,0,0,0,0,"data 4 pages + 11 bytes (tail split; 11 bytes over page boundary)"
-132,"L",4,16,0,16,12,131040,131040,0,0,FALSE,FALSE,FALSE,131084,1025,0,0,0,0,"data 4 pages + 12 bytes (tail separated exactly onto next page)"
-133,"L",4,16,0,16,13,131041,131041,0,0,FALSE,FALSE,FALSE,131085,1025,0,0,0,0,"data 4 pages + 13 bytes (data split; 1 byte over page boundary)"
-134,"L",4,16,0,16,0,130772,130772,256,256,FALSE,FALSE,FALSE,131072,1024,0,0,0,0,"data 4 pages [txn]"
-135,"L",4,16,0,16,1,130773,130773,256,256,FALSE,FALSE,FALSE,131073,1025,0,0,0,0,"data 4 pages + 1 byte (tail split; 1 byte over page boundary) [txn]"
-136,"L",4,16,0,16,11,130783,130783,256,256,FALSE,FALSE,FALSE,131083,1025,0,0,0,0,"data 4 pages + 11 bytes (tail split; 11 bytes over page boundary) [txn]"
-137,"L",4,16,0,16,12,130784,130784,256,256,FALSE,FALSE,FALSE,131084,1025,0,0,0,0,"data 4 pages + 12 bytes (tail separated exactly onto next page) [txn]"
-138,"L",4,16,0,16,13,130785,130785,256,256,FALSE,FALSE,FALSE,131085,1025,0,0,0,0,"data 4 pages + 13 bytes (data split; 1 byte over page boundary) [txn]"
-139,"L",3.5,16,0,16,0,114644,114644,0,0,FALSE,FALSE,FALSE,114688,896,0,0,0,0,"data 3.5 pages"
-140,"L",3.5,16,0,16,1,114645,114645,0,0,FALSE,FALSE,FALSE,114689,897,0,0,0,0,"data 3.5 pages + 1 byte"
-141,"L",3.5,16,0,16,0,114388,114388,256,256,FALSE,FALSE,FALSE,114688,896,0,0,0,0,"data 3.5 pages [txn]"
-142,"L",3.5,16,0,16,1,114389,114389,256,256,FALSE,FALSE,FALSE,114689,897,0,0,0,0,"data 3.5 pages + 1 byte [txn]"
-143,"L",1,16,0,16,-1,10,10,32735,32735,FALSE,FALSE,FALSE,32789,257,0,0,0,0,"xid 1 page – 1 byte; data 10 bytes (exact fit) [txn]"
-144,"L",1,16,0,16,0,10,10,32736,32736,FALSE,FALSE,FALSE,32790,257,0,0,0,0,"xid 1 page; data 10 bytes (exact fit) [txn]"
-145,"L",1,16,0,16,1,10,10,32737,32737,FALSE,FALSE,FALSE,32791,257,0,0,0,0,"xid 1 page + 1 byte; data 10 bytes (exact fit) [txn]"
-146,"L",2,16,0,16,-1,10,10,65503,65503,FALSE,FALSE,FALSE,65557,513,0,0,0,0,"xid 2 pages – 1 byte; data 10 bytes (exact fit) [txn]"
-147,"L",2,16,0,16,0,10,10,65504,65504,FALSE,FALSE,FALSE,65558,513,0,0,0,0,"xid 2 pages; data 10 bytes (exact fit) [txn]"
-148,"L",2,16,0,16,1,10,10,65505,65505,FALSE,FALSE,FALSE,65559,513,0,0,0,0,"xid 2 pages + 1 byte; data 10 bytes (exact fit) [txn]"
-149,"L",4,16,0,16,-1,10,10,131039,131039,FALSE,FALSE,FALSE,131093,1025,0,0,0,0,"xid 4 pages – 1 byte; data 10 bytes (exact fit) [txn]"
-150,"L",4,16,0,16,0,10,10,131040,131040,FALSE,FALSE,FALSE,131094,1025,0,0,0,0,"xid 4 pages; data 10 bytes (exact fit) [txn]"
-151,"L",4,16,0,16,1,10,10,131041,131041,FALSE,FALSE,FALSE,131095,1025,0,0,0,0,"xid 4 pages + 1 byte; data 10 bytes (exact fit) [txn]"
-152,"L",3.5,16,0,16,0,10,10,114656,114656,FALSE,FALSE,FALSE,114710,897,0,0,0,0,"xid 3.5 pages; data 10 bytes (exact fit) [txn]"
-153,"L",3.5,16,0,16,1,10,10,114657,114657,FALSE,FALSE,FALSE,114711,897,0,0,0,0,"xid 3.5 pages + 1 byte; data 10 bytes (exact fit) [txn]"
-154,"L",1,16,0,16,-1,10,10,32735,32735,TRUE,FALSE,FALSE,32789,257,32779,257,32771,257,"xid 1 page – 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-155,"L",1,16,0,16,0,10,10,32736,32736,TRUE,FALSE,FALSE,32790,257,32780,257,32772,257,"xid 1 page for enq rec; data 10 bytes (exact fit) [deq, txn]"
-156,"L",1,16,0,16,1,10,10,32737,32737,TRUE,FALSE,FALSE,32791,257,32781,257,32773,257,"xid 1 page + 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-157,"L",2,16,0,16,-1,10,10,65503,65503,TRUE,FALSE,FALSE,65557,513,65547,513,65539,513,"xid 2 pages – 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-158,"L",2,16,0,16,0,10,10,65504,65504,TRUE,FALSE,FALSE,65558,513,65548,513,65540,513,"xid 2 pages for enq rec; data 10 bytes (exact fit) [deq, txn]"
-159,"L",2,16,0,16,1,10,10,65505,65505,TRUE,FALSE,FALSE,65559,513,65549,513,65541,513,"xid 2 pages + 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-160,"L",4,16,0,16,-1,10,10,131039,131039,TRUE,FALSE,FALSE,131093,1025,131083,1025,131075,1025,"xid 4 pages – 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-161,"L",4,16,0,16,0,10,10,131040,131040,TRUE,FALSE,FALSE,131094,1025,131084,1025,131076,1025,"xid 4 pages for enq rec; data 10 bytes (exact fit) [deq, txn]"
-162,"L",4,16,0,16,1,10,10,131041,131041,TRUE,FALSE,FALSE,131095,1025,131085,1025,131077,1025,"xid 4 pages + 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-163,"L",3.5,16,0,16,0,10,10,114656,114656,TRUE,FALSE,FALSE,114710,897,114700,897,114692,897,"xid 3.5 pages for enq rec; data 10 bytes (exact fit) [deq, txn]"
-164,"L",3.5,16,0,16,1,10,10,114657,114657,TRUE,FALSE,FALSE,114711,897,114701,897,114693,897,"xid 3.5 pages + 1 byte for enq rec; data 10 bytes (exact fit) [deq, txn]"
-165,"L",1,16,0,16,-1,10,10,32735,32735,TRUE,FALSE,FALSE,32789,257,32779,257,32771,257,"xid 1 page – 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-166,"L",1,16,0,16,0,10,10,32736,32736,TRUE,FALSE,FALSE,32790,257,32780,257,32772,257,"xid 1 page for deq rec; data 10 bytes (exact fit) [deq, txn]"
-167,"L",1,16,0,16,1,10,10,32737,32737,TRUE,FALSE,FALSE,32791,257,32781,257,32773,257,"xid 1 page + 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-168,"L",2,16,0,16,-1,10,10,65503,65503,TRUE,FALSE,FALSE,65557,513,65547,513,65539,513,"xid 2 pages – 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-169,"L",2,16,0,16,0,10,10,65504,65504,TRUE,FALSE,FALSE,65558,513,65548,513,65540,513,"xid 2 pages for deq rec; data 10 bytes (exact fit) [deq, txn]"
-170,"L",2,16,0,16,1,10,10,65505,65505,TRUE,FALSE,FALSE,65559,513,65549,513,65541,513,"xid 2 pages + 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-171,"L",4,16,0,16,-1,10,10,131039,131039,TRUE,FALSE,FALSE,131093,1025,131083,1025,131075,1025,"xid 4 pages – 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-172,"L",4,16,0,16,0,10,10,131040,131040,TRUE,FALSE,FALSE,131094,1025,131084,1025,131076,1025,"xid 4 pages for deq rec; data 10 bytes (exact fit) [deq, txn]"
-173,"L",4,16,0,16,1,10,10,131041,131041,TRUE,FALSE,FALSE,131095,1025,131085,1025,131077,1025,"xid 4 pages + 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-174,"L",3.5,16,0,16,0,10,10,114656,114656,TRUE,FALSE,FALSE,114710,897,114700,897,114692,897,"xid 3.5 pages for deq rec; data 10 bytes (exact fit) [deq, txn]"
-175,"L",3.5,16,0,16,1,10,10,114657,114657,TRUE,FALSE,FALSE,114711,897,114701,897,114693,897,"xid 3.5 pages + 1 byte for deq rec; data 10 bytes (exact fit) [deq, txn]"
-176,"L",1,16,0,16,-1,10,10,32743,32743,TRUE,FALSE,FALSE,32797,257,32787,257,32779,257,"xid 1 page – 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-177,"L",1,16,0,16,0,10,10,32744,32744,TRUE,FALSE,FALSE,32798,257,32788,257,32780,257,"xid 1 page for txn rec; data 10 bytes (exact fit) [deq, txn]"
-178,"L",1,16,0,16,1,10,10,32745,32745,TRUE,FALSE,FALSE,32799,257,32789,257,32781,257,"xid 1 page + 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-179,"L",2,16,0,16,-1,10,10,65511,65511,TRUE,FALSE,FALSE,65565,513,65555,513,65547,513,"xid 2 pages – 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-180,"L",2,16,0,16,0,10,10,65512,65512,TRUE,FALSE,FALSE,65566,513,65556,513,65548,513,"xid 2 pages for txn rec; data 10 bytes (exact fit) [deq, txn]"
-181,"L",2,16,0,16,1,10,10,65513,65513,TRUE,FALSE,FALSE,65567,513,65557,513,65549,513,"xid 2 pages + 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-182,"L",4,16,0,16,-1,10,10,131047,131047,TRUE,FALSE,FALSE,131101,1025,131091,1025,131083,1025,"xid 4 pages – 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-183,"L",4,16,0,16,0,10,10,131048,131048,TRUE,FALSE,FALSE,131102,1025,131092,1025,131084,1025,"xid 4 pages for txn rec; data 10 bytes (exact fit) [deq, txn]"
-184,"L",4,16,0,16,1,10,10,131049,131049,TRUE,FALSE,FALSE,131103,1025,131093,1025,131085,1025,"xid 4 pages + 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-185,"L",3.5,16,0,16,0,10,10,114664,114664,TRUE,FALSE,FALSE,114718,897,114708,897,114700,897,"xid 3.5 pages for txn rec; data 10 bytes (exact fit) [deq, txn]"
-186,"L",3.5,16,0,16,1,10,10,114665,114665,TRUE,FALSE,FALSE,114719,897,114709,897,114701,897,"xid 3.5 pages + 1 byte for txn rec; data 10 bytes (exact fit) [deq, txn]"
-,,,,,,,,,,,,,,,,,,,,
-"Large (multi-megabyte) messages - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,,,,,,,,,,,,,,,
-187,"L",1,32,0,32,0,1572820,1572820,0,0,FALSE,FALSE,FALSE,1572864,12288,0,0,0,0,"48 pages = 1 file exactly"
-188,"L",1,32,0,32,1,1572821,1572821,0,0,FALSE,FALSE,FALSE,1572865,12289,0,0,0,0,"48 pages + 1 byte"
-189,"L",1,32,0,32,0,1605588,1605588,0,0,FALSE,FALSE,FALSE,1605632,12544,0,0,0,0,"49 pages = 1 file + 1 page"
-190,"L",1,32,0,32,1,1589205,1589205,0,0,FALSE,FALSE,FALSE,1589249,12417,0,0,0,0,"49 pages + 1 byte = 1 file + 1 page + 1 byte"
-191,"L",1,32,0,32,0,1572565,1572565,255,255,FALSE,FALSE,FALSE,1572864,12288,0,0,0,0,"48 pages = 1 file exactly [txn]"
-192,"L",1,32,0,32,1,1572566,1572566,255,255,FALSE,FALSE,FALSE,1572865,12289,0,0,0,0,"48 pages + 1 byte [txn]"
-193,"L",1,32,0,32,0,1588949,1588949,255,255,FALSE,FALSE,FALSE,1589248,12416,0,0,0,0,"49 pages = 1 file + 1 page [txn]"
-194,"L",1,32,0,32,1,1584854,1584854,255,255,FALSE,FALSE,FALSE,1585153,12385,0,0,0,0,"49 pages + 1 byte = 1 file + 1 page + 1 byte [txn]"
-195,"L",1,32,0,32,0,1572692,1572692,0,0,TRUE,FALSE,FALSE,1572736,12287,32,1,0,0,"48 pages incl deq = 1 file exactly [deq]"
-196,"L",1,32,0,32,1,1572693,1572693,0,0,TRUE,FALSE,FALSE,1572737,12288,32,1,0,0,"48 pages incl deq + 1 byte [deq]"
-197,"L",1,32,0,32,0,1595220,1595220,0,0,TRUE,FALSE,FALSE,1595264,12463,32,1,0,0,"49 pages incl deq = 1 file + 1 page [deq]"
-198,"L",1,32,0,32,1,1589077,1589077,0,0,TRUE,FALSE,FALSE,1589121,12416,32,1,0,0,"49 pages incl deq + 1 byte = 1 file + 1 page + 1 byte [deq]"
-199,"L",1,32,0,32,0,1571797,1571797,255,255,TRUE,FALSE,FALSE,1572096,12282,299,3,291,3,"48 pages incl deq & txn = 1 file exactly [deq txn]"
-200,"L",1,32,0,32,1,1571798,1571798,255,255,TRUE,FALSE,FALSE,1572097,12283,299,3,291,3,"48 pages incl deq & txn + 1 byte [deq txn]"
-201,"L",1,32,0,32,0,1571797,1571797,255,255,TRUE,FALSE,FALSE,1572096,12282,299,3,291,3,"49 pages incl deq & txn = 1 file + 1 page [deq txn]"
-202,"L",1,32,0,32,1,1571798,1571798,255,255,TRUE,FALSE,FALSE,1572097,12283,299,3,291,3,"49 pages incl deq & txn + 1 byte = 1 file + 1 page + 1 byte [deq txn]"
-203,"L",2,16,0,16,0,3145684,3145684,0,0,FALSE,FALSE,FALSE,3145728,24576,0,0,0,0,"96 pages = 2 files exactly"
-204,"L",2,16,0,16,1,3145685,3145685,0,0,FALSE,FALSE,FALSE,3145729,24577,0,0,0,0,"96 pages + 1 byte"
-205,"L",2,16,0,16,0,3146708,3146708,0,0,FALSE,FALSE,FALSE,3146752,24584,0,0,0,0,"97 pages = 2 files + 1 page"
-206,"L",2,16,0,16,1,3145685,3145685,0,0,FALSE,FALSE,FALSE,3145729,24577,0,0,0,0,"97 pages + 1 byte = 2 files + 1 page + 1 byte"
-207,"L",2,16,0,16,0,3145429,3145429,255,255,FALSE,FALSE,FALSE,3145728,24576,0,0,0,0,"96 pages = 2 files exactly [txn]"
-208,"L",2,16,0,16,1,3145430,3145430,255,255,FALSE,FALSE,FALSE,3145729,24577,0,0,0,0,"96 pages + 1 byte [txn]"
-209,"L",2,16,0,16,0,3145429,3145429,255,255,FALSE,FALSE,FALSE,3145728,24576,0,0,0,0,"97 pages = 2 files + 1 page [txn]"
-210,"L",2,16,0,16,1,3145430,3145430,255,255,FALSE,FALSE,FALSE,3145729,24577,0,0,0,0,"97 pages + 1 byte = 2 files + 1 page + 1 byte [txn]"
-211,"L",2,16,0,16,0,3145556,3145556,0,0,TRUE,FALSE,FALSE,3145600,24575,32,1,0,0,"96 pages incl deq = 2 files exactly [deq]"
-212,"L",2,16,0,16,1,3145557,3145557,0,0,TRUE,FALSE,FALSE,3145601,24576,32,1,0,0,"96 pages incl deq + 1 byte [deq]"
-213,"L",2,16,0,16,0,3145556,3145556,0,0,TRUE,FALSE,FALSE,3145600,24575,32,1,0,0,"97 pages incl deq = 2 files + 1 page [deq]"
-214,"L",2,16,0,16,1,3145557,3145557,0,0,TRUE,FALSE,FALSE,3145601,24576,32,1,0,0,"97 pages incl deq + 1 byte = 2 files + 1 page + 1 byte [deq]"
-215,"L",2,16,0,16,0,3144661,3144661,255,255,TRUE,FALSE,FALSE,3144960,24570,299,3,291,3,"96 pages incl deq & txn = 2 files exactly [deq txn]"
-216,"L",2,16,0,16,1,3144662,3144662,255,255,TRUE,FALSE,FALSE,3144961,24571,299,3,291,3,"96 pages incl deq & txn + 1 byte [deq txn]"
-217,"L",2,16,0,16,0,3144661,3144661,255,255,TRUE,FALSE,FALSE,3144960,24570,299,3,291,3,"97 pages incl deq & txn = 2 files + 1 page [deq txn]"
-218,"L",2,16,0,16,1,3144662,3144662,255,255,TRUE,FALSE,FALSE,3144961,24571,299,3,291,3,"97 pages incl deq & txn + 1 byte = 2 files + 1 page + 1 byte [deq txn]"
-219,"L",4,8,0,8,0,6291412,6291412,0,0,FALSE,FALSE,FALSE,6291456,49152,0,0,0,0,"192 pages = 2 files exactly"
-220,"L",4,8,0,8,1,6291413,6291413,0,0,FALSE,FALSE,FALSE,6291457,49153,0,0,0,0,"192 pages + 1 byte"
-221,"L",4,8,0,8,0,6291412,6291412,0,0,FALSE,FALSE,FALSE,6291456,49152,0,0,0,0,"193 pages = 2 files + 1 page"
-222,"L",4,8,0,8,1,6291413,6291413,0,0,FALSE,FALSE,FALSE,6291457,49153,0,0,0,0,"193 pages + 1 byte = 2 files + 1 page + 1 byte"
-223,"L",4,8,0,8,0,6291157,6291157,255,255,FALSE,FALSE,FALSE,6291456,49152,0,0,0,0,"192 pages = 2 files exactly [txn]"
-224,"L",4,8,0,8,1,6291158,6291158,255,255,FALSE,FALSE,FALSE,6291457,49153,0,0,0,0,"192 pages + 1 byte [txn]"
-225,"L",4,8,0,8,0,6291157,6291157,255,255,FALSE,FALSE,FALSE,6291456,49152,0,0,0,0,"193 pages = 2 files + 1 page [txn]"
-226,"L",4,8,0,8,1,6291158,6291158,255,255,FALSE,FALSE,FALSE,6291457,49153,0,0,0,0,"193 pages + 1 byte = 2 files + 1 page + 1 byte [txn]"
-227,"L",4,8,0,8,0,6291284,6291284,0,0,TRUE,FALSE,FALSE,6291328,49151,32,1,0,0,"192 pages incl deq = 2 files exactly [deq]"
-228,"L",4,8,0,8,1,6291285,6291285,0,0,TRUE,FALSE,FALSE,6291329,49152,32,1,0,0,"192 pages incl deq + 1 byte [deq]"
-229,"L",4,8,0,8,0,6291284,6291284,0,0,TRUE,FALSE,FALSE,6291328,49151,32,1,0,0,"193 pages incl deq = 2 files + 1 page [deq]"
-230,"L",4,8,0,8,1,6291285,6291285,0,0,TRUE,FALSE,FALSE,6291329,49152,32,1,0,0,"193 pages incl deq + 1 byte = 2 files + 1 page + 1 byte [deq]"
-231,"L",4,8,0,8,0,6290389,6290389,255,255,TRUE,FALSE,FALSE,6290688,49146,299,3,291,3,"192 pages incl deq & txn = 2 files exactly [deq txn]"
-232,"L",4,8,0,8,1,6290390,6290390,255,255,TRUE,FALSE,FALSE,6290689,49147,299,3,291,3,"192 pages incl deq & txn + 1 byte [deq txn]"
-233,"L",4,8,0,8,0,6290389,6290389,255,255,TRUE,FALSE,FALSE,6290688,49146,299,3,291,3,"193 pages incl deq & txn = 2 files + 1 page [deq txn]"
-234,"L",4,8,0,8,1,6290390,6290390,255,255,TRUE,FALSE,FALSE,6290689,49147,299,3,291,3,"193 pages incl deq & txn + 1 byte = 2 files + 1 page + 1 byte [deq txn]"
-,,,,,,,,,,,,,,,,,,,,
-"High volume tests of random message lengths - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,,,,,,,,,,,,,,,
-235,"M",1,5000000,0,5000000,0,0,84,0,0,FALSE,FALSE,FALSE,128,1,0,0,0,0,"1 dblk max"
-236,"M",3,3000000,0,3000000,0,0,340,0,0,FALSE,FALSE,FALSE,384,3,0,0,0,0,"3 dblks max"
-237,"M",10,1600000,0,1600000,0,0,1236,0,0,FALSE,FALSE,FALSE,1280,10,0,0,0,0,"10 dblks max"
-238,"M",30,600000,0,600000,0,0,3796,0,0,FALSE,FALSE,FALSE,3840,30,0,0,0,0,"30 dblks max"
-239,"M",100,200000,0,200000,0,0,12756,0,0,FALSE,FALSE,FALSE,12800,100,0,0,0,0,"100 dblks max"
-240,"M",300,60000,0,60000,0,0,38356,0,0,FALSE,FALSE,FALSE,38400,300,0,0,0,0,"300 dblks max"
-241,"M",1000,20000,0,20000,0,0,127956,0,0,FALSE,FALSE,FALSE,128000,1000,0,0,0,0,"1000 dblks max"
-242,"M",1,5000000,0,5000000,0,0,100,1,100,FALSE,FALSE,FALSE,244,2,0,0,0,0,"100 bytes xid max + 100 bytes data max [txn]"
-243,"M",3,3000000,0,3000000,0,0,300,1,300,FALSE,FALSE,FALSE,644,6,0,0,0,0,"300 bytes xid max + 300 bytes data max [txn]"
-244,"M",10,1600000,0,1600000,0,0,1000,1,1000,FALSE,FALSE,FALSE,2044,16,0,0,0,0,"1000 bytes xid max + 1000 bytes data max [txn]"
-245,"M",30,600000,0,600000,0,0,3000,1,3000,FALSE,FALSE,FALSE,6044,48,0,0,0,0,"3000 bytes xid max + 3000 bytes data max [txn]"
-246,"M",100,200000,0,200000,0,0,10000,1,10000,FALSE,FALSE,FALSE,20044,157,0,0,0,0,"10000 bytes xid max + 10000 bytes data max [txn]"
-247,"M",300,60000,0,60000,0,0,30000,1,30000,FALSE,FALSE,FALSE,60044,470,0,0,0,0,"30000 bytes xid max + 30000 bytes data max [txn]"
-248,"M",1000,20000,0,20000,0,0,100000,1,100000,FALSE,FALSE,FALSE,200044,1563,0,0,0,0,"100000 bytes xid max + 100000 bytes data max [txn]"
-249,"M",1,5000000,0,5000000,0,0,84,0,0,TRUE,FALSE,FALSE,128,1,32,1,0,0,"1 dblk max [deq]"
-250,"M",3,3000000,0,3000000,0,0,340,0,0,TRUE,FALSE,FALSE,384,3,32,1,0,0,"3 dblks max [deq]"
-251,"M",10,1600000,0,1600000,0,0,1236,0,0,TRUE,FALSE,FALSE,1280,10,32,1,0,0,"10 dblks max [deq]"
-252,"M",30,600000,0,600000,0,0,3796,0,0,TRUE,FALSE,FALSE,3840,30,32,1,0,0,"30 dblks max [deq]"
-253,"M",100,200000,0,200000,0,0,12756,0,0,TRUE,FALSE,FALSE,12800,100,32,1,0,0,"100 dblks max [deq]"
-254,"M",300,60000,0,60000,0,0,38356,0,0,TRUE,FALSE,FALSE,38400,300,32,1,0,0,"300 dblks max [deq]"
-255,"M",1000,20000,0,20000,0,0,127956,0,0,TRUE,FALSE,FALSE,128000,1000,32,1,0,0,"1000 dblks max [deq]"
-256,"M",1,5000000,0,5000000,0,0,100,1,100,TRUE,FALSE,FALSE,244,2,144,2,136,2,"100 bytes xid max + 100 bytes data max [deq txn]"
-257,"M",3,3000000,0,3000000,0,0,300,1,300,TRUE,FALSE,FALSE,644,6,344,3,336,3,"300 bytes xid max + 300 bytes data max [deq txn]"
-258,"M",10,1600000,0,1600000,0,0,1000,1,1000,TRUE,FALSE,FALSE,2044,16,1044,9,1036,9,"1000 bytes xid max + 1000 bytes data max [deq txn]"
-259,"M",30,600000,0,600000,0,0,3000,1,3000,TRUE,FALSE,FALSE,6044,48,3044,24,3036,24,"3000 bytes xid max + 3000 bytes data max [deq txn]"
-260,"M",100,200000,0,200000,0,0,10000,1,10000,TRUE,FALSE,FALSE,20044,157,10044,79,10036,79,"10000 bytes xid max + 10000 bytes data max [deq txn]"
-261,"M",300,60000,0,60000,0,0,30000,1,30000,TRUE,FALSE,FALSE,60044,470,30044,235,30036,235,"30000 bytes xid max + 30000 bytes data max [deq txn]"
-262,"M",1000,20000,0,20000,0,0,100000,1,100000,TRUE,FALSE,FALSE,200044,1563,100044,782,100036,782,"100000 bytes xid max + 100000 bytes data max [deq txn]"
-,,,,,,,,,,,,,,,,,,,,
-"STANDARD PERFORMANCE BENCHMARK: 10,000,000 writes, data=212b (2 dblks)",,,,,,,,,,,,,,,,,,,,
-263,"M",1,10000000,0,10000000,0,212,212,0,0,FALSE,FALSE,FALSE,256,2,0,0,0,0,"212 bytes data (2 dblks enq)"
-264,"M",1,10000000,0,10000000,0,148,148,64,64,FALSE,FALSE,FALSE,256,2,0,0,0,0,"148 bytes data + 64 bytes xid (2 dblks enq)"
-265,"M",1,10000000,0,10000000,0,212,212,0,0,TRUE,FALSE,FALSE,256,2,32,1,0,0,"212 bytes data (2 dblks enq + 1 dblk deq)"
-266,"M",1,10000000,0,10000000,0,148,148,64,64,TRUE,FALSE,FALSE,256,2,108,1,100,1,"148 bytes data + 64 bytes xid (2 dblks enq + 1 dblks deq + 1 dblks txn)"
17 years, 7 months
rhmessaging commits: r2433 - in store/trunk/cpp: lib and 1 other directories.
by rhmessaging-commits@lists.jboss.org
Author: kpvdr
Date: 2008-09-09 15:25:47 -0400 (Tue, 09 Sep 2008)
New Revision: 2433
Added:
store/trunk/cpp/lib/MessageStoreImpl.cpp
store/trunk/cpp/lib/MessageStoreImpl.h
Removed:
store/trunk/cpp/lib/BdbMessageStore.cpp
store/trunk/cpp/lib/BdbMessageStore.h
Modified:
store/trunk/cpp/configure.ac
store/trunk/cpp/lib/Makefile.am
store/trunk/cpp/lib/StorePlugin.cpp
store/trunk/cpp/tests/OrderingTest.cpp
store/trunk/cpp/tests/SimpleTest.cpp
store/trunk/cpp/tests/TransactionalTest.cpp
store/trunk/cpp/tests/TwoPhaseCommitTest.cpp
Log:
Changed name of class "BdbMessageStore" to class "MessageStoreImpl". This reflects the recent changes which remove BDB from the journal message path, and the goal of eventually removing BDB from the store altogether.
Modified: store/trunk/cpp/configure.ac
===================================================================
--- store/trunk/cpp/configure.ac 2008-09-09 13:39:28 UTC (rev 2432)
+++ store/trunk/cpp/configure.ac 2008-09-09 19:25:47 UTC (rev 2433)
@@ -29,7 +29,7 @@
AC_PREREQ(2.59)
AC_CONFIG_HEADERS([config.h:config.in])
-AC_CONFIG_SRCDIR([lib/BdbMessageStore.cpp])
+AC_CONFIG_SRCDIR([lib/MessageStoreImpl.cpp])
AC_PROG_CC_STDC
AM_PROG_CC_C_O
Deleted: store/trunk/cpp/lib/BdbMessageStore.cpp
===================================================================
--- store/trunk/cpp/lib/BdbMessageStore.cpp 2008-09-09 13:39:28 UTC (rev 2432)
+++ store/trunk/cpp/lib/BdbMessageStore.cpp 2008-09-09 19:25:47 UTC (rev 2433)
@@ -1,1693 +0,0 @@
-/*
- Copyright (C) 2007 Red Hat Software
-
- 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 "BdbMessageStore.h"
-
-#include "BindingDbt.h"
-#include "BufferValue.h"
-#include "IdPairDbt.h"
-#include "jrnl/txn_map.hpp"
-#include "qpid/log/Statement.h"
-#include "PackageMrgstore.h"
-
-#define MAX_AIO_SLEEPS 1000 // ~1 second
-#define AIO_SLEEP_TIME 1000 // 1 milisecond
-
-using namespace rhm::bdbstore;
-using namespace qpid::broker;
-using boost::static_pointer_cast;
-using boost::intrusive_ptr;
-
-using std::auto_ptr;
-using std::max;
-using qpid::framing::Buffer;
-using qpid::framing::FieldTable;
-using qpid::management::ManagementAgent;
-
-static const u_int8_t MESSAGE_MESSAGE = 1;
-static const u_int8_t BASIC_MESSAGE = 2;
-qpid::sys::Duration BdbMessageStore::defJournalGetEventsTimeout(10 * qpid::sys::TIME_MSEC); // 10ms
-qpid::sys::Duration BdbMessageStore::defJournalFlushTimeout(500 * qpid::sys::TIME_MSEC); // 0.5s
-qpid::sys::Mutex TxnCtxt::globalSerialiser;
-
-BdbMessageStore::TplRecoverStruct::TplRecoverStruct(const u_int64_t _rid,
- const bool _deq_flag,
- const bool _commit_flag,
- const bool _tpc_flag) :
- rid(_rid),
- deq_flag(_deq_flag),
- commit_flag(_commit_flag),
- tpc_flag(_tpc_flag)
-{}
-
-BdbMessageStore::BdbMessageStore(const char* envpath) :
- env(0),
- queueDb(&env, 0),
- configDb(&env, 0),
- exchangeDb(&env, 0),
- messageDb(&env, 0),
- mappingDb(&env, 0),
- bindingDb(&env, 0),
- generalDb(&env, 0),
- numJrnlFiles(0),
- jrnlFsizeSblks(0),
- wCachePgSizeSblks(0),
- wCacheNumPages(0),
- tplNumJrnlFiles(0),
- tplJrnlFsizeSblks(0),
- tplWCachePgSizeSblks(0),
- tplWCacheNumPages(0),
- highestRid(0),
- isInit(false),
- envPath(envpath),
- mgmtObject(0)
-{}
-
-u_int16_t BdbMessageStore::chkJrnlNumFilesParam(const u_int16_t param, const std::string paramName)
-{
- u_int16_t p = param;
- if (p < JRNL_MIN_NUM_FILES) {
- p = JRNL_MIN_NUM_FILES;
- QPID_LOG(warning, "parameter " << paramName << " (" << param << ") is below allowable minimum (" << JRNL_MIN_NUM_FILES << "); changing this parameter to minimum value.");
- } else if (p > JRNL_MAX_NUM_FILES) {
- p = JRNL_MAX_NUM_FILES;
- QPID_LOG(warning, "parameter " << paramName << " (" << param << ") is above allowable maximum (" << JRNL_MAX_NUM_FILES << "); changing this parameter to maximum value.");
- }
- return p;
-}
-
-u_int32_t BdbMessageStore::chkJrnlFileSizeParam(const u_int32_t param, const std::string paramName)
-{
- u_int32_t p = param;
- u_int32_t min = JRNL_MIN_FILE_SIZE / JRNL_RMGR_PAGE_SIZE;
- u_int32_t max = JRNL_MAX_FILE_SIZE / JRNL_RMGR_PAGE_SIZE;
- if (p < min) {
- p = min;
- QPID_LOG(warning, "parameter " << paramName << " (" << param << ") is below allowable minimum (" << min << "); changing this parameter to minimum value.");
- } else if (p > max) {
- p = max;
- QPID_LOG(warning, "parameter " << paramName << " (" << param << ") is above allowable maximum (" << max << "); changing this parameter to maximum value.");
- }
- return p;
-}
-
-u_int32_t BdbMessageStore::chkJrnlWrPageCacheSize(const u_int32_t param, const std::string paramName)
-{
- u_int32_t p = param;
- switch (p)
- {
- case 1:
- case 2:
- case 4:
- case 8:
- case 16:
- case 32:
- case 64:
- case 128:
- break;
- default:
- if (p == 0) {
- // For zero value, use default
- p = JRNL_WMGR_DEF_PAGE_SIZE * JRNL_DBLK_SIZE * JRNL_SBLK_SIZE / 1024;
- QPID_LOG(warning, "parameter " << paramName << " (" << param << ") must be a power of 2 between 1 and 128; changing this parameter to default value (" << p << ")");
- } else {
- // For any positive value, use closest value
- if (p < 6) p = 4;
- else if (p < 12) p = 8;
- else if (p < 24) p = 16;
- else if (p < 48) p = 32;
- else if (p < 96) p = 64;
- else if (p > 128) p = 128;
- QPID_LOG(warning, "parameter " << paramName << " (" << param << ") must be a power of 2 between 1 and 128; changing this parameter to closest allowable value (" << p << ")");
- }
- }
- return p;
-}
-
-u_int16_t BdbMessageStore::getJrnlWrNumPages(const u_int32_t wrPageSizeKib)
-{
- u_int32_t wrPageSizeSblks = wrPageSizeKib * 1024 / JRNL_DBLK_SIZE / JRNL_SBLK_SIZE; // convert from KiB to number sblks
- u_int32_t defTotWCacheSize = JRNL_WMGR_DEF_PAGE_SIZE * JRNL_WMGR_DEF_PAGES; // in sblks. Currently 2014 sblks (1 MiB).
- switch (wrPageSizeKib)
- {
- case 1:
- case 2:
- case 4:
- // 256 KiB total cache
- return defTotWCacheSize / wrPageSizeSblks / 4;
- case 8:
- case 16:
- // 512 KiB total cache
- return defTotWCacheSize / wrPageSizeSblks / 2;
- default: // 32, 64, 128
- // 1 MiB total cache
- return defTotWCacheSize / wrPageSizeSblks;
- }
-}
-
-void BdbMessageStore::initManagement (Broker* broker)
-{
- if (broker != 0) {
- ManagementAgent* agent = ManagementAgent::Singleton::getInstance();
- if (agent != 0) {
- qpid::management::PackageMrgstore packageInitializer(agent);
- mgmtObject = new qpid::management::Store(agent, this, broker);
-
- mgmtObject->set_location(storeDir);
- mgmtObject->set_defaultInitialFileCount(numJrnlFiles);
- mgmtObject->set_defaultDataFileSize(jrnlFsizeSblks / JRNL_RMGR_PAGE_SIZE);
- mgmtObject->set_tplIsInitialized(false);
- mgmtObject->set_tplDirectory(getTplBaseDir());
- mgmtObject->set_tplWritePageSize(tplWCachePgSizeSblks * JRNL_SBLK_SIZE * JRNL_DBLK_SIZE);
- mgmtObject->set_tplWritePages(tplWCacheNumPages);
- mgmtObject->set_tplInitialFileCount(tplNumJrnlFiles);
- mgmtObject->set_tplDataFileSize(tplJrnlFsizeSblks * JRNL_SBLK_SIZE * JRNL_DBLK_SIZE);
- mgmtObject->set_tplCurrentFileCount(tplNumJrnlFiles);
-
- agent->addObject(mgmtObject, 0x1000000000000050LL);
- }
- }
-}
-
-bool BdbMessageStore::init(const qpid::Options* options)
-{
- // Extract and check options
- const Options* opts = static_cast<const Options*>(options);
- u_int16_t numJrnlFiles = chkJrnlNumFilesParam(opts->numJrnlFiles, "num-jfiles");
- u_int32_t jrnlFsizePgs = chkJrnlFileSizeParam(opts->jrnlFsizePgs, "jfile-size-pgs");
- u_int32_t jrnlWrCachePageSizeKib = chkJrnlWrPageCacheSize(opts->wCachePageSizeKib, "wcache-page-size");
- u_int16_t tplNumJrnlFiles = chkJrnlNumFilesParam(opts->tplNumJrnlFiles, "tpl-num-jfiles");
- u_int32_t tplJrnlFSizePgs = chkJrnlFileSizeParam(opts->tplJrnlFsizePgs, "tpl-jfile-size-pgs");
- u_int32_t tplJrnlWrCachePageSizeKib = chkJrnlWrPageCacheSize(opts->tplWCachePageSizeKib, "tpl-wcache-page-size");
-
- // Pass option values to init(...)
- return init(opts->storeDir, numJrnlFiles, jrnlFsizePgs, jrnlWrCachePageSizeKib, tplNumJrnlFiles, tplJrnlFSizePgs, tplJrnlWrCachePageSizeKib);
-}
-
-// These params, taken from options, are assumed to be correct and verified
-bool BdbMessageStore::init(const std::string& dir,
- u_int16_t jfiles,
- u_int32_t jfileSizePgs,
- u_int32_t wCachePageSizeKib,
- u_int16_t tplJfiles,
- u_int32_t tplJfileSizePgs,
- u_int32_t tplWCachePageSizeKib)
-{
- if (isInit) return true;
-
- // Set geometry members (converting to correct units where req'd)
- numJrnlFiles = jfiles;
- jrnlFsizeSblks = jfileSizePgs * JRNL_RMGR_PAGE_SIZE;
- wCachePgSizeSblks = wCachePageSizeKib * 1024 / JRNL_DBLK_SIZE / JRNL_SBLK_SIZE; // convert from KiB to number sblks
- wCacheNumPages = getJrnlWrNumPages(wCachePageSizeKib);
- tplNumJrnlFiles = tplJfiles;
- tplJrnlFsizeSblks = tplJfileSizePgs * JRNL_RMGR_PAGE_SIZE;
- tplWCachePgSizeSblks = tplWCachePageSizeKib * 1024 / JRNL_DBLK_SIZE / JRNL_SBLK_SIZE; // convert from KiB to number sblks
- tplWCacheNumPages = getJrnlWrNumPages(tplWCachePageSizeKib);
-
- if (dir.size()>0) storeDir = dir;
-
- journal::jdir::create_dir(getBdbBaseDir());
-
- try {
- env.open(getBdbBaseDir().c_str(), DB_THREAD | DB_CREATE | DB_INIT_TXN | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_USE_ENVIRON, 0);
- } catch (const DbException& e) {
- if (e.get_errno() == DB_VERSION_MISMATCH)
- THROW_STORE_EXCEPTION_2("Database environment mismatch: This version of bd4 does not match that which created the store database. "
- "(If recovery is not important, delete the contents of the store directory. Otherwise, try upgrading the database using "
- "db_upgrade or using db_recover - but the db4-utils package must also be installed to use these utilities.)", e);
- THROW_STORE_EXCEPTION_2("Error opening environment", e);
- }
-
- TxnCtxt txn;
- try {
- txn.begin(env, false);
- open(queueDb, txn.get(), "queues.db", false);
- open(configDb, txn.get(), "config.db", false);
- open(exchangeDb, txn.get(), "exchanges.db", false);
- open(messageDb, txn.get(), "messages.db", false);
- open(mappingDb, txn.get(), "mappings.db", true);
- open(bindingDb, txn.get(), "bindings.db", true);
- open(generalDb, txn.get(), "general.db", false);
- tplStorePtr.reset(new TplJournalImpl("TplStore", getTplBaseDir(), "tpl", defJournalGetEventsTimeout, defJournalFlushTimeout));
- txn.commit();
- } catch (const journal::jexception& e) {
- txn.abort();
- THROW_STORE_EXCEPTION_2("Error opening tplStore instance", e.what());
- } catch (const DbException& e) {
- txn.abort();
- THROW_STORE_EXCEPTION_2("Error opening databases", e);
- } catch (...) {
- txn.abort();
- throw;
- }
-
- isInit = true;
- QPID_LOG(notice, "Store module initialized; dir=" << dir);
- QPID_LOG(info, "> Default files per journal: " << jfiles);
- QPID_LOG(info, "> Default jrournal file size: " << jfileSizePgs << " (wpgs)");
- QPID_LOG(info, "> Default write cache page size: " << wCachePageSizeKib << " (Kib)");
- QPID_LOG(info, "> Default number of write cache pages: " << wCacheNumPages);
- QPID_LOG(info, "> TPL files per journal: " << tplNumJrnlFiles);
- QPID_LOG(info, "> TPL jrournal file size: " << tplJfileSizePgs << " (wpgs)");
- QPID_LOG(info, "> TPL write cache page size: " << tplWCachePageSizeKib << " (Kib)");
- QPID_LOG(info, "> TPL number of write cache pages: " << tplWCacheNumPages);
- return true;
-}
-
-void BdbMessageStore::chkTplStoreInit()
-{
- if (!tplStorePtr->is_ready()) {
- qpid::sys::Mutex::ScopedLock sl(jrnlCreateLock);
- if (!tplStorePtr->is_ready()) {
- journal::jdir::create_dir(getTplBaseDir());
- tplStorePtr->initialize(tplNumJrnlFiles, tplJrnlFsizeSblks, tplWCacheNumPages, tplWCachePgSizeSblks);
- if (mgmtObject != 0) mgmtObject->set_tplIsInitialized(true);
- }
- }
-}
-
-void BdbMessageStore::open(Db& db,
- DbTxn* txn,
- const char* file,
- bool dupKey)
-{
- if(dupKey) db.set_flags(DB_DUPSORT);
- db.open(txn, file, 0, DB_BTREE, DB_CREATE | DB_THREAD, 0);
- dbs.push_back(&db);
-}
-
-BdbMessageStore::~BdbMessageStore()
-{
- try {
- for (std::list<Db*>::iterator i = dbs.begin(); i != dbs.end(); i++) {
- (*i)->close(0);
- }
- if (tplStorePtr->is_ready()) tplStorePtr->stop(true);
- } catch (const DbException& e) {
- QPID_LOG(error, "Error closing BDB databases: " << e.what());
- } catch (const journal::jexception& e) {
- QPID_LOG(error, "Error: " << e.what());
- } catch (const std::exception& e) {
- QPID_LOG(error, "Error: " << e.what());
- } catch (...) {
- QPID_LOG(error, "Unknown error in BdbMessageStore::~BdbMessageStore()");
- }
-
- if (mgmtObject != 0)
- mgmtObject->resourceDestroy();
-}
-
-void BdbMessageStore::truncate()
-{
- DbTxn* txn;
- env.txn_begin(0, &txn, 0);
- u_int32_t count;
-
- for (std::list<Db*>::iterator i = dbs.begin(); i != dbs.end(); i++) {
- (*i)->truncate(txn, &count, 0);
- }
-
- txn->commit(0);
- try {
- journal::jdir::delete_dir(getJrnlBaseDir(),true);
- journal::jdir::delete_dir(getTplBaseDir(),true);
- }
- catch (const journal::jexception& e) {
- THROW_STORE_EXCEPTION(std::string("truncate() failed: ") + e.what() );
- }
-}
-
-void BdbMessageStore::create(PersistableQueue& queue,
- const FieldTable& args)
-{
- checkInit();
- if (queue.getPersistenceId()) {
- THROW_STORE_EXCEPTION("Queue already created: " + queue.getName());
- }
- JournalImpl* jQueue = 0;
- FieldTable::ValuePtr value;
-
- u_int16_t localFileCount = numJrnlFiles;
- u_int32_t localFileSizeSblks = jrnlFsizeSblks;
-
- value = args.get ("qpid.file_count");
- if (value.get() != 0 && !value->empty() && value->convertsTo<int>())
- localFileCount = (u_int16_t) value->get<int>();
-
- value = args.get ("qpid.file_size");
- if (value.get() != 0 && !value->empty() && value->convertsTo<int>())
- localFileSizeSblks = (u_int32_t) value->get<int>() * JRNL_RMGR_PAGE_SIZE;
-
- {
- // TODO: Is this mutex necessary?
- qpid::sys::Mutex::ScopedLock sl(jrnlCreateLock);
- jQueue = new JournalImpl(queue.getName(), getJrnlDir(queue),
- std::string("JournalData"), defJournalGetEventsTimeout,
- defJournalFlushTimeout);
- }
-
- queue.setExternalQueueStore(dynamic_cast<ExternalQueueStore*>(jQueue));
- try {
- // init will create the deque's for the init...
- jQueue->initialize(localFileCount, localFileSizeSblks, wCacheNumPages, wCachePgSizeSblks);
- } catch (const journal::jexception& e) {
- THROW_STORE_EXCEPTION(std::string("Queue ") + queue.getName() + ": create() failed: " + e.what());
- }
- try {
- if (!create(queueDb, queueIdSequence, queue)) {
- THROW_STORE_EXCEPTION("Queue already exists: " + queue.getName());
- }
- } catch (const DbException& e) {
- THROW_STORE_EXCEPTION_2("Error creating queue named " + queue.getName(), e);
- }
-}
-
-void BdbMessageStore::destroy(PersistableQueue& queue)
-{
- checkInit();
- destroy(queueDb, queue);
- deleteBindingsForQueue(queue);
- qpid::broker::ExternalQueueStore* eqs = queue.getExternalQueueStore();
- if (eqs) {
- JournalImpl* jQueue = static_cast<JournalImpl*>(eqs);
- jQueue->delete_jrnl_files();
- queue.setExternalQueueStore(0); // will delete the journal if exists
- }
-}
-
-void BdbMessageStore::create(const PersistableExchange& exchange,
- const FieldTable& /*args*/)
-{
- checkInit();
- if (exchange.getPersistenceId()) {
- THROW_STORE_EXCEPTION("Exchange already created: " + exchange.getName());
- }
- try {
- if (!create(exchangeDb, exchangeIdSequence, exchange)) {
- THROW_STORE_EXCEPTION("Exchange already exists: " + exchange.getName());
- }
- } catch (const DbException& e) {
- THROW_STORE_EXCEPTION_2("Error creating exchange named " + exchange.getName(), e);
- }
-}
-
-void BdbMessageStore::destroy(const PersistableExchange& exchange)
-{
- checkInit();
- destroy(exchangeDb, exchange);
- //need to also delete bindings
- IdDbt key(exchange.getPersistenceId());
- bindingDb.del(0, &key, DB_AUTO_COMMIT);
-}
-
-void BdbMessageStore::create(const PersistableConfig& general)
-{
- checkInit();
- if (general.getPersistenceId()) {
- THROW_STORE_EXCEPTION("General configuration item already created");
- }
- try {
- if (!create(generalDb, generalIdSequence, general)) {
- THROW_STORE_EXCEPTION("General configuration already exists");
- }
- } catch (const DbException& e) {
- THROW_STORE_EXCEPTION_2("Error creating general configuration", e);
- }
-}
-
-void BdbMessageStore::destroy(const PersistableConfig& general)
-{
- checkInit();
- destroy(generalDb, general);
-}
-
-bool BdbMessageStore::create(Db& db,
- IdSequence& seq,
- const Persistable& p)
-{
- u_int64_t id (seq.next());
- Dbt key(&id, sizeof(id));
- BufferValue value (p);
-
- int status;
- TxnCtxt txn;
- txn.begin(env, true);
- try {
- status = db.put(txn.get(), &key, &value, DB_NOOVERWRITE);
- txn.commit();
- } catch (...) {
- txn.abort();
- throw;
- }
- if (status == DB_KEYEXIST) {
- return false;
- } else {
- p.setPersistenceId(id);
- return true;
- }
-}
-
-void BdbMessageStore::destroy(Db& db, const Persistable& p)
-{
- IdDbt key(p.getPersistenceId());
- db.del(0, &key, DB_AUTO_COMMIT);
-}
-
-
-void BdbMessageStore::bind(const PersistableExchange& e,
- const PersistableQueue& q,
- const std::string& k,
- const FieldTable& a)
-{
- checkInit();
- IdDbt key(e.getPersistenceId());
- BindingDbt value(e, q, k, a);
- TxnCtxt txn;
- txn.begin(env, true);
- try {
- put(bindingDb, txn.get(), key, value);
- txn.commit();
- } catch (...) {
- txn.abort();
- throw;
- }
-}
-
-void BdbMessageStore::unbind(const PersistableExchange& e,
- const PersistableQueue& q,
- const std::string& k,
- const FieldTable&)
-{
- checkInit();
- deleteBinding(e, q, k);
-}
-
-void BdbMessageStore::recover(RecoveryManager& registry)
-{
- checkInit();
- txn_list prepared;
- recoverLockedMappings(prepared);
-
- queue_index queues;//id->queue
- exchange_index exchanges;//id->exchange
- message_index messages;//id->message
-
- TxnCtxt txn;
- txn.begin(env, false);
- try {
- //read all queues, calls recoversMessages
- recoverQueues(txn, registry, queues, prepared, messages);
-
- //recover exchange & bindings:
- recoverExchanges(txn, registry, exchanges);
- recoverBindings(txn, exchanges, queues);
-
- //recover general-purpose configuration
- recoverGeneral(txn, registry);
-
- txn.commit();
- } catch (const DbException& e) {
- txn.abort();
- THROW_STORE_EXCEPTION_2("Error on recovery", e);
- } catch (...) {
- txn.abort();
- throw;
- }
-
- //recover transactions:
- for (txn_list::iterator i = prepared.begin(); i != prepared.end(); i++) {
- if (mgmtObject != 0) {
- mgmtObject->inc_tplTransactionDepth();
- mgmtObject->inc_tplTxnPrepares();
- }
-
- std::string xid = i->xid;
-
- // Restore data token state in TxnCtxt
- TplRecoverMapCitr citr = tplRecoverMap.find(xid);
- if (citr == tplRecoverMap.end()) THROW_STORE_EXCEPTION("XID not found in tplRecoverMap");
-
- // If a record is found that is dequeued but not committed/aborted from tplStore, then a complete() call
- // was interrupted part way through committing/aborting the impacted queues. Complete this process.
- bool incomplTplTxnFlag = citr->second.deq_flag;
-
- if (citr->second.tpc_flag) {
- // Dtx (2PC) transaction
- TPCTxnCtxt* tpcc = new TPCTxnCtxt(xid, &messageIdSequence);
- std::auto_ptr<TPCTransactionContext> txn(tpcc);
- tpcc->recoverDtok(citr->second.rid, xid);
- tpcc->prepare(tplStorePtr.get());
-
- RecoverableTransaction::shared_ptr dtx;
- if (!incomplTplTxnFlag) dtx = registry.recoverTransaction(xid, txn);
- if (i->enqueues.get()) {
- for (LockedMappings::iterator j = i->enqueues->begin(); j != i->enqueues->end(); j++) {
- tpcc->addXidRecord(queues[j->first]->getExternalQueueStore());
- if (!incomplTplTxnFlag) dtx->enqueue(queues[j->first], messages[j->second]);
- }
- }
- if (i->dequeues.get()) {
- for (LockedMappings::iterator j = i->dequeues->begin(); j != i->dequeues->end(); j++) {
- tpcc->addXidRecord(queues[j->first]->getExternalQueueStore());
- if (!incomplTplTxnFlag) dtx->dequeue(queues[j->first], messages[j->second]);
- }
- }
-
- if (incomplTplTxnFlag) {
- tpcc->complete(citr->second.commit_flag);
- }
- } else {
- // Local (1PC) transaction
- boost::shared_ptr<TxnCtxt> opcc(new TxnCtxt(xid, &messageIdSequence));
- opcc->recoverDtok(citr->second.rid, xid);
- opcc->prepare(tplStorePtr.get());
-
- if (i->enqueues.get()) {
- for (LockedMappings::iterator j = i->enqueues->begin(); j != i->enqueues->end(); j++) {
- opcc->addXidRecord(queues[j->first]->getExternalQueueStore());
- }
- }
- if (i->dequeues.get()) {
- for (LockedMappings::iterator j = i->dequeues->begin(); j != i->dequeues->end(); j++) {
- opcc->addXidRecord(queues[j->first]->getExternalQueueStore());
- }
- }
- if (incomplTplTxnFlag) {
- opcc->complete(citr->second.commit_flag);
- } else {
- completed(*opcc.get(), citr->second.commit_flag);
- }
- }
- }
- registry.recoveryComplete();
-}
-
-void BdbMessageStore::recoverQueues(TxnCtxt& txn,
- RecoveryManager& registry,
- queue_index& queue_index,
- txn_list& prepared,
- message_index& messages)
-{
- Cursor queues;
- queues.open(queueDb, txn.get());
-
- u_int64_t maxQueueId(1);
-
- IdDbt key;
- Dbt value;
- //read all queues
- while (queues.next(key, value)) {
- Buffer buffer(reinterpret_cast<char*>(value.get_data()), value.get_size());
- //create a Queue instance
- RecoverableQueue::shared_ptr queue = registry.recoverQueue(buffer);
- //set the persistenceId and update max as required
- queue->setPersistenceId(key.id);
-
- const char* queueName = queue->getName().c_str();
- JournalImpl* jQueue = 0;
- {
- qpid::sys::Mutex::ScopedLock sl(jrnlCreateLock);
- jQueue = new JournalImpl(queueName, getJrnlDir(queueName), std::string("JournalData"), defJournalGetEventsTimeout, defJournalFlushTimeout);
- }
- queue->setExternalQueueStore(dynamic_cast<ExternalQueueStore*>(jQueue));
-
- try
- {
- u_int64_t thisHighestRid = 0;
- jQueue->recover(numJrnlFiles, jrnlFsizeSblks, wCacheNumPages, wCachePgSizeSblks, &prepared, thisHighestRid, key.id); // start recovery
- if (thisHighestRid > highestRid)
- highestRid = thisHighestRid;
- recoverMessages(txn, registry, queue, prepared, messages);
- jQueue->recover_complete(); // start journal.
- } catch (const journal::jexception& e) {
- THROW_STORE_EXCEPTION(std::string("Queue ") + queueName + ": recoverQueues() failed: " + e.what());
- }
- //read all messages: done on a per queue basis if using Journal
-
- queue_index[key.id] = queue;
- maxQueueId = max(key.id, maxQueueId);
- }
-
- // NOTE: highestRid is set by both recoverQueues() and recoverTplStore() as
- // the messageIdSequence is used for both queue journals and the tpl journal.
- messageIdSequence.reset(highestRid + 1);
-
- queueIdSequence.reset(maxQueueId + 1);
-}
-
-
-void BdbMessageStore::recoverExchanges(TxnCtxt& txn,
- RecoveryManager& registry,
- exchange_index& index)
-{
- //TODO: this is a copy&paste from recoverQueues - refactor!
- Cursor exchanges;
- exchanges.open(exchangeDb, txn.get());
-
- u_int64_t maxExchangeId(1);
- IdDbt key;
- Dbt value;
- //read all exchanges
- while (exchanges.next(key, value)) {
- Buffer buffer(reinterpret_cast<char*>(value.get_data()), value.get_size());
- //create a Exchange instance
- RecoverableExchange::shared_ptr exchange = registry.recoverExchange(buffer);
- //set the persistenceId and update max as required
- exchange->setPersistenceId(key.id);
- index[key.id] = exchange;
- maxExchangeId = max(key.id, maxExchangeId);
- }
- exchangeIdSequence.reset(maxExchangeId + 1);
-}
-
-void BdbMessageStore::recoverBindings(TxnCtxt& txn,
- exchange_index& exchanges,
- queue_index& queues)
-{
- Cursor bindings;
- bindings.open(bindingDb, txn.get());
-
- IdDbt key;
- Dbt value;
- while (bindings.next(key, value)) {
- Buffer buffer(reinterpret_cast<char*>(value.get_data()), value.get_size());
- if (buffer.available() < 8) {
- QPID_LOG(error, "Not enough data for binding: " << buffer.available());
- THROW_STORE_EXCEPTION("Not enough data for binding");
- }
- uint64_t queueId = buffer.getLongLong();
- std::string queueName;
- std::string routingkey;
- FieldTable args;
- buffer.getShortString(queueName);
- buffer.getShortString(routingkey);
- buffer.get(args);
- exchange_index::iterator exchange = exchanges.find(key.id);
- queue_index::iterator queue = queues.find(queueId);
- if (exchange != exchanges.end() && queue != queues.end()) {
- //could use the recoverable queue here rather than the name...
- exchange->second->bind(queueName, routingkey, args);
- } else {
- //stale binding, delete it
- QPID_LOG(warning, "Deleting stale binding");
- bindings->del(0);
- }
- }
-}
-
-void BdbMessageStore::recoverGeneral(TxnCtxt& txn,
- RecoveryManager& registry)
-{
- Cursor items;
- items.open(generalDb, txn.get());
-
- u_int64_t maxGeneralId(1);
- IdDbt key;
- Dbt value;
- //read all items
- while (items.next(key, value)) {
- Buffer buffer(reinterpret_cast<char*>(value.get_data()), value.get_size());
- //create instance
- RecoverableConfig::shared_ptr config = registry.recoverConfig(buffer);
- //set the persistenceId and update max as required
- config->setPersistenceId(key.id);
- maxGeneralId = max(key.id, maxGeneralId);
- }
- generalIdSequence.reset(maxGeneralId + 1);
-}
-
-void BdbMessageStore::recoverMessages(TxnCtxt& /*txn*/,
- qpid::broker::RecoveryManager& recovery,
- qpid::broker::RecoverableQueue::shared_ptr& queue,
- txn_list& prepared,
- message_index& messages)
-{
- size_t preambleLength = sizeof(u_int32_t)/*header size*/;
-
- JournalImpl* jc = static_cast<JournalImpl*>(queue->getExternalQueueStore());
- DataTokenImpl dtok;
- size_t readSize = 0;
- unsigned msg_count = 0;
-
- // TODO: This optimization to skip reading if there are no enqueued messages to read
- // breaks the python system test in phase 6 with "Exception: Cannot write lock file"
- // Figure out what is breaking.
- //bool read = jc->get_enq_cnt() > 0;
- bool read = true;
-
- void* dbuff = NULL; size_t dbuffSize = 0;
- void* xidbuff = NULL; size_t xidbuffSize = 0;
- bool transientFlag = false;
- bool externalFlag = false;
-
- dtok.set_wstate(DataTokenImpl::ENQ);
-
- // Read the message from the Journal.
- try {
- unsigned aio_sleep_cnt = 0;
- while (read) {
- rhm::journal::iores res = jc->read_data_record(&dbuff, dbuffSize, &xidbuff, xidbuffSize, transientFlag, externalFlag, &dtok);
- readSize = dtok.dsize();
-
- switch (res)
- {
- case rhm::journal::RHM_IORES_SUCCESS: {
- msg_count++;
- RecoverableMessage::shared_ptr msg;
- char* data = (char*)dbuff;
-
- unsigned headerSize;
- if (externalFlag) {
- msg = getExternMessage(recovery, dtok.rid(), headerSize); // large message external to jrnl
- } else {
- headerSize = Buffer(data, preambleLength).getLong();
- Buffer headerBuff(data+ preambleLength, headerSize); /// do we want read size or header size ????
- msg = recovery.recoverMessage(headerBuff);
- }
- msg->setPersistenceId(dtok.rid());
-
- u_int32_t contentOffset = headerSize + preambleLength;
- u_int64_t contentSize = readSize - contentOffset;
- if (msg->loadContent(contentSize) && !externalFlag) {
- //now read the content
- Buffer contentBuff(data + contentOffset, contentSize);
- msg->decodeContent(contentBuff);
- }
-
- PreparedTransaction::list::iterator i = PreparedTransaction::getLockedPreparedTransaction(prepared, queue->getPersistenceId(), dtok.rid());
- if (i == prepared.end()) { // not in prepared list
- queue->recover(msg);
- } else {
- u_int64_t rid = dtok.rid();
- std::string xid(i->xid);
- TplRecoverMapCitr citr = tplRecoverMap.find(xid);
- if (citr == tplRecoverMap.end()) THROW_STORE_EXCEPTION("XID not found in tplRecoverMap");
-
- // deq present in prepared list, this xid is part of incomplete txn commit/abort
- // or this is a 1PC txn that must be rolled forward
- if (citr->second.deq_flag || !citr->second.tpc_flag) {
- if (jc->is_enqueued(rid, true)) {
- // Enqueue is non-tx, dequeue tx
- assert(jc->is_locked(rid)); // This record MUST be locked by a txn dequeue
- if (!citr->second.commit_flag) {
- queue->recover(msg); // recover message in abort case only
- }
- } else {
- // Enqueue and/or dequeue tx
- journal::txn_map& tmap = jc->get_txn_map();
- journal::txn_data_list txnList = tmap.get_tdata_list(xid);
- bool enq = false;
- bool deq = false;
- for (journal::tdl_itr j = txnList.begin(); j<txnList.end(); j++) {
- if (j->_enq_flag && j->_rid == rid) enq = true;
- else if (!j->_enq_flag && j->_drid == rid) deq = true;
- }
- if (enq && !deq && citr->second.commit_flag) {
- queue->recover(msg); // recover txn message in commit case only
- }
- }
- } else {
- messages[rid] = msg;
- }
- }
-
- dtok.reset();
- dtok.set_wstate(DataTokenImpl::ENQ);
-
- if (xidbuff)
- ::free(xidbuff);
- else if (dbuff)
- ::free(dbuff);
- aio_sleep_cnt = 0;
- break;
- }
- case rhm::journal::RHM_IORES_PAGE_AIOWAIT:
- if (++aio_sleep_cnt > MAX_AIO_SLEEPS)
- THROW_STORE_EXCEPTION("Timeout waiting for AIO in BdbMessageStore::recoverMessages()");
- ::usleep(AIO_SLEEP_TIME);
- break;
- case rhm::journal::RHM_IORES_EMPTY:
- read = false;
- break; // done with all messages. (add call in jrnl to test that _emap is empty.)
- default:
- assert("Store Error: Unexpected msg state");
- } // switch
- } // while
- } catch (const journal::jexception& e) {
- THROW_STORE_EXCEPTION(std::string("Queue ") + queue->getName() +
- ": recoverMessages() failed: " + e.what());
- }
-}
-
-RecoverableMessage::shared_ptr BdbMessageStore::getExternMessage(qpid::broker::RecoveryManager& recovery,
- uint64_t messageId,
- unsigned& headerSize)
-{
- RecoverableMessage::shared_ptr ret;
- Dbt key (&messageId, sizeof(messageId));
- size_t preamble_length = sizeof(u_int32_t); /*header size*/
-
- BufferValue value(preamble_length, 0);
- value.buffer.record();
-
- TxnCtxt txn;
- txn.begin(env, true);
- try {
- if (messageDb.get(txn.get(), &key, &value, 0) == DB_NOTFOUND) {
- txn.abort();
- THROW_STORE_EXCEPTION("Cannot load content. Message not known to store!");
- }
-
- //read header only to begin with
- headerSize = value.buffer.getLong();
-
- BufferValue header(headerSize, preamble_length);
- if (messageDb.get(txn.get(), &key, &header, 0) == DB_NOTFOUND) {
- txn.abort();
- THROW_STORE_EXCEPTION("Cannot load content. Message not known to store!");
- }
- ret = recovery.recoverMessage(header.buffer);
- txn.commit();
- } catch (const DbException& e) {
- txn.abort();
- THROW_STORE_EXCEPTION("Unexpected BDB error in BdbMessageStore::getExternMessage(): " + std::string(e.what()));
- } catch (...) {
- txn.abort();
- throw;
- }
- return ret;
-}
-
-int BdbMessageStore::enqueueMessage(TxnCtxt& txn,
- IdDbt& msgId,
- RecoverableMessage::shared_ptr& msg,
- queue_index& index,
- txn_list& prepared,
- message_index& messages)
-{
- Cursor mappings;
- mappings.open(mappingDb, txn.get());
-
- IdDbt value;
-
- int count(0);
- for (int status = mappings->get(&msgId, &value, DB_SET); status == 0; status = mappings->get(&msgId, &value, DB_NEXT_DUP)) {
- if (index.find(value.id) == index.end()) {
- QPID_LOG(warning, "Recovered message for queue that no longer exists");
- mappings->del(0);
- } else {
- RecoverableQueue::shared_ptr queue = index[value.id];
- if (PreparedTransaction::isLocked(prepared, value.id, msgId.id)) {
- messages[msgId.id] = msg;
- } else {
- queue->recover(msg);
- }
- count++;
- }
- }
- mappings.close();
- return count;
-}
-
-void BdbMessageStore::readTplStore()
-{
- tplRecoverMap.clear();
- journal::txn_map& tmap = tplStorePtr->get_txn_map();
- DataTokenImpl dtok;
- void* dbuff = NULL; size_t dbuffSize = 0;
- void* xidbuff = NULL; size_t xidbuffSize = 0;
- bool transientFlag = false;
- bool externalFlag = false;
- bool done = false;
- try {
- unsigned aio_sleep_cnt = 0;
- while (!done) {
- dtok.reset();
- dtok.set_wstate(DataTokenImpl::ENQ);
- switch (tplStorePtr->read_data_record(&dbuff, dbuffSize, &xidbuff, xidbuffSize, transientFlag, externalFlag, &dtok)) {
- case rhm::journal::RHM_IORES_SUCCESS: {
- // Every TPL record contains both data and an XID
- assert(dbuffSize>0);
- assert(xidbuffSize>0);
- std::string xid(static_cast<const char*>(xidbuff), xidbuffSize);
- bool is2PC = *(static_cast<char*>(dbuff)) != 0;
-
- // Check transaction details; add to recover map
- journal::txn_data_list txnList = tmap.get_tdata_list(xid);
- unsigned enqCnt = 0;
- unsigned deqCnt = 0;
- u_int64_t rid = 0;
-
- // Assume commit (roll forward) in cases where only prepare has been called - ie only enqueue record exists.
- // Note: will apply to both 1PC and 2PC transactions.
- bool commitFlag = true;
-
- for (journal::tdl_itr j = txnList.begin(); j<txnList.end(); j++) {
- if (j->_enq_flag) {
- rid = j->_rid;
- enqCnt++;
- } else {
- commitFlag = j->_commit_flag;
- deqCnt++;
- }
- }
- assert(enqCnt == 1);
- assert(deqCnt <= 1);
- tplRecoverMap.insert(TplRecoverMapPair(xid, TplRecoverStruct(rid, deqCnt == 1, commitFlag, is2PC)));
-
- ::free(xidbuff);
- aio_sleep_cnt = 0;
- break;
- }
- case rhm::journal::RHM_IORES_PAGE_AIOWAIT:
- if (++aio_sleep_cnt > MAX_AIO_SLEEPS)
- THROW_STORE_EXCEPTION("Timeout waiting for AIO in BdbMessageStore::recoverTplStore()");
- ::usleep(AIO_SLEEP_TIME);
- break;
- case rhm::journal::RHM_IORES_EMPTY:
- done = true;
- break; // done with all messages. (add call in jrnl to test that _emap is empty.)
- default:
- assert("Store Error: Unexpected msg state");
- } // switch
- }
- } catch (const journal::jexception& e) {
- THROW_STORE_EXCEPTION(std::string("TPL recoverTplStore() failed: ") + e.what());
- }
-}
-
-void BdbMessageStore::recoverTplStore()
-{
- if (journal::jdir::exists(tplStorePtr->jrnl_dir() + tplStorePtr->base_filename() + ".jinf")) {
- u_int64_t thisHighestRid;
- tplStorePtr->recover(tplNumJrnlFiles, tplJrnlFsizeSblks, tplWCachePgSizeSblks, tplWCacheNumPages, 0, thisHighestRid, 0);
- if (thisHighestRid > highestRid)
- highestRid = thisHighestRid;
-
- // Load tplRecoverMap by reading the TPL store
- readTplStore();
-
- tplStorePtr->recover_complete(); // start journal.
- }
-}
-
-void BdbMessageStore::recoverLockedMappings(txn_list& txns)
-{
- if (!tplStorePtr->is_ready())
- recoverTplStore();
-
- // Abort unprepaired xids and populate the locked maps
- for (TplRecoverMapCitr i = tplRecoverMap.begin(); i != tplRecoverMap.end(); i++) {
- LockedMappings::shared_ptr enq_ptr;
- enq_ptr.reset(new LockedMappings);
- LockedMappings::shared_ptr deq_ptr;
- deq_ptr.reset(new LockedMappings);
- txns.push_back(new PreparedTransaction(i->first, enq_ptr, deq_ptr));
- }
-}
-
-void BdbMessageStore::collectPreparedXids(std::set<std::string>& xids)
-{
- if (tplStorePtr->is_ready()) {
- tplStorePtr->read_reset();
- readTplStore();
- } else {
- recoverTplStore();
- }
- for (TplRecoverMapCitr i = tplRecoverMap.begin(); i != tplRecoverMap.end(); i++) {
- // Discard all txns that are to be rolled forward/back and 1PC transactions
- if (!i->second.deq_flag && i->second.tpc_flag)
- xids.insert(i->first);
- }
-}
-
-void BdbMessageStore::stage(const intrusive_ptr<PersistableMessage>& msg)
-{
- checkInit();
- TxnCtxt txn;
- txn.begin(env, true);
-
- u_int64_t messageId (msg->getPersistenceId());
- if (messageId == 0 || !msg->isContentReleased()) {
- try {
- Dbt key (&messageId, sizeof(messageId));
- messageId = messageIdSequence.next();
- store(NULL, &txn, key, msg, true);
- msg->setPersistenceId(messageId);
- txn.commit();
- } catch (...) {
- txn.abort();
- throw;
- }
- }
-}
-
-void BdbMessageStore::destroy(PersistableMessage& msg)
-{
- checkInit();
- u_int64_t messageId (msg.getPersistenceId());
- if (messageId) {
- Dbt key (&messageId, sizeof(messageId));
- TxnCtxt txn;
- txn.begin(env, true);
- try {
- deleteIfUnused(txn.get(), key);
- txn.commit();
- } catch (const DbException& e) {
- txn.abort();
- THROW_STORE_EXCEPTION_2("Error destroying message", e);
- } catch (...) {
- txn.abort();
- throw;
- }
- }
-}
-
-u_int64_t BdbMessageStore::getRecordSize(Db& db,
- Dbt& key)
-{
- u_int64_t ret = 0;
- TxnCtxt txn;
- txn.begin(env, true);
- try {
- ret = getRecordSize(txn.get(), db, key);
- txn.commit();
- } catch (...) {
- txn.abort();
- throw;
- }
- return ret;
-}
-
-u_int64_t BdbMessageStore::getRecordSize(DbTxn* txn,
- Db& db,
- Dbt& key)
-{
- Dbt peek;
- peek.set_flags(DB_DBT_USERMEM);
- peek.set_ulen(0);
- try {
- int status = db.get(txn, &key, &peek, 0);
- if (status != DB_BUFFER_SMALL) {
- THROW_STORE_EXCEPTION("Unexpected status code when determining record length: " + std::string(DbEnv::strerror(status)));
- }
- } catch (const DbMemoryException& expected) {
- //api doc indicates may throw exception instead of status = DB_BUFFER_SMALL;
- }
- return peek.get_size();
-}
-
-void BdbMessageStore::appendContent(const intrusive_ptr<const PersistableMessage>& msg,
- const std::string& data)
-{
- checkInit();
- u_int64_t messageId (msg->getPersistenceId());
- if (messageId != 0) {
- TxnCtxt txn;
- txn.begin(env, true);
- try {
- Dbt key (&messageId, sizeof(messageId));
- u_int64_t offset = getRecordSize(messageDb, key);
- const int size(data.length());
-
- //don't want to have to copy this and shouldn't need to as
- //it will be used for reading only. but have to cast away
- //the const-ness, which is nasty...
- //alternative involves copying:
- //char buffer[size];
- //data.copy(buffer, size);
- Dbt value((void*) data.data(), size);
- value.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);
- value.set_doff(offset);
- value.set_dlen(size);
- messageDb.put(txn.get(), &key, &value, 0);
- txn.commit();
- } catch (const DbException& e) {
- txn.abort();
- THROW_STORE_EXCEPTION_2("Error appending content", e);
- } catch (...) {
- txn.abort();
- throw;
- }
- } else {
- THROW_STORE_EXCEPTION("Cannot append content. Message not known to store!");
- }
-}
-
-void BdbMessageStore::loadContent(const qpid::broker::PersistableQueue& queue,
- const intrusive_ptr<const PersistableMessage>& msg,
- std::string& data,
- u_int64_t offset,
- u_int32_t length)
-{
- checkInit();
- u_int64_t realOffset = offset + sizeof(u_int32_t)/*header length*/ + msg->encodedHeaderSize();
- u_int64_t messageId (msg->getPersistenceId());
-
- if (messageId != 0) {
- try {
- JournalImpl* jc = static_cast<JournalImpl*>(queue.getExternalQueueStore());
- if (jc && jc->is_enqueued(messageId) ) {
- if (jc->loadMsgContent(messageId, data, realOffset, length)) {
- return;
- }
- }
- } catch (const journal::jexception& e) {
- THROW_STORE_EXCEPTION(std::string("Queue ") + queue.getName() +
- ": loadContent() failed: " + e.what());
- }
- TxnCtxt txn;
- txn.begin(env, true);
- try {
- Dbt key (&messageId, sizeof(messageId));
- char *buffer = new char[length];
- Dbt value(buffer, length);
- value.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);
- value.set_ulen(length);
- value.set_doff(realOffset);
- value.set_dlen(length);
- int status = messageDb.get(txn.get(), &key, &value, 0);
- if (status == DB_NOTFOUND) {
- delete [] buffer;
- THROW_STORE_EXCEPTION("Cannot load content. Message not known to store!");
- }
- data.assign(buffer, value.get_size());
- delete [] buffer;
- txn.commit();
- } catch (const DbException& e) {
- txn.abort();
- THROW_STORE_EXCEPTION_2("Error loading content", e);
- } catch (...) {
- txn.abort();
- throw;
- }
- } else {
- THROW_STORE_EXCEPTION("Cannot load content. Message not known to store!");
- }
-}
-
-void BdbMessageStore::flush(const qpid::broker::PersistableQueue& queue)
-{
- if (queue.getExternalQueueStore() == 0) return;
- checkInit();
- std::string qn = queue.getName();
- try {
- JournalImpl* jc = static_cast<JournalImpl*>(queue.getExternalQueueStore());
- if (jc) {
- // TODO: check if this result should be used...
- /*rhm::journal::iores res =*/ jc->flush();
- }
- } catch (const journal::jexception& e) {
- THROW_STORE_EXCEPTION(std::string("Queue ") + qn + ": flush() failed: " + e.what() );
- }
-}
-
-void BdbMessageStore::enqueue(TransactionContext* ctxt,
- const intrusive_ptr<PersistableMessage>& msg,
- const PersistableQueue& queue)
-{
- checkInit();
- u_int64_t queueId (queue.getPersistenceId());
- u_int64_t messageId (msg->getPersistenceId());
- if (queueId == 0) {
- THROW_STORE_EXCEPTION("Queue not created: " + queue.getName());
- }
- Dbt key (&messageId, sizeof(messageId));
-
- TxnCtxt implicit;
- TxnCtxt* txn = 0;
- if (ctxt) {
- txn = check(ctxt);
- } else {
- txn = &implicit;
- }
-
- bool newId = false;
- if (messageId == 0) {
- messageId = messageIdSequence.next();
- msg->setPersistenceId(messageId);
- newId = true;
- }
- store(&queue, txn, key, msg, newId);
-
- // add queue* to the txn map..
- if (ctxt) txn->addXidRecord(queue.getExternalQueueStore());
-}
-
-void BdbMessageStore::store(const PersistableQueue* queue,
- TxnCtxt* txn, Dbt& messageId,
- const intrusive_ptr<PersistableMessage>& message,
- bool newId)
-{
- u_int32_t headerSize = message->encodedHeaderSize();
- u_int64_t size = message->encodedSize() + sizeof(u_int32_t);
- char* buff = 0;
- if (!message->isContentReleased() )
- {
- buff = static_cast<char*>(::alloca(size)); // long + headers + content
- Buffer buffer(buff,size);
- buffer.putLong(headerSize);
- message->encode(buffer);
- }
-
- try {
- if (queue) {
- boost::intrusive_ptr<DataTokenImpl> dtokp(new DataTokenImpl);
- dtokp->addRef();
- dtokp->setSourceMessage(message);
- dtokp->set_external_rid(true);
- dtokp->set_rid(message->getPersistenceId()); // set the messageID into the Journal header (record-id)
-
- JournalImpl* jc = static_cast<JournalImpl*>(queue->getExternalQueueStore());
- if (txn->getXid().empty()) {
- if (message->isContentReleased()) {
- jc->enqueue_extern_data_record(size, dtokp.get(), false);
- } else {
- jc->enqueue_data_record(buff, size, size, dtokp.get(), false);
- }
- } else {
- if (message->isContentReleased()) {
- jc->enqueue_extern_txn_data_record(size, dtokp.get(), txn->getXid(), false);
- } else {
- jc->enqueue_txn_data_record(buff, size, size, dtokp.get(), txn->getXid(), false);
- }
- }
- } else {
- /// cct message db
- if (newId) { // only store in Bd if first time message is stored
- Dbt data(buff,size);
- messageDb.put(txn->get(), &messageId, &data, DB_NOOVERWRITE);
- }
- }
- } catch (const journal::jexception& e) {
- THROW_STORE_EXCEPTION(std::string("Queue ") + queue->getName() + ": store() failed: " +
- e.what());
- }
-}
-
-void BdbMessageStore::dequeue(TransactionContext* ctxt,
- const intrusive_ptr<PersistableMessage>& msg,
- const PersistableQueue& queue)
-{
- checkInit();
- u_int64_t queueId (queue.getPersistenceId());
- u_int64_t messageId (msg->getPersistenceId());
- if (messageId == 0) {
- THROW_STORE_EXCEPTION("Error dequeing message, persistence id not set");
- }
- if (queueId == 0) {
- THROW_STORE_EXCEPTION("Queue not created: " + queue.getName());
- }
-
- TxnCtxt implicit;
- TxnCtxt* txn = 0;
- if (ctxt) {
- txn = check(ctxt);
- } else {
- txn = &implicit;
- }
-
- // add queue* to the txn map..
- if (ctxt) txn->addXidRecord(queue.getExternalQueueStore());
- async_dequeue(ctxt, msg, queue);
-
- msg->dequeueComplete();
-}
-
-void BdbMessageStore::async_dequeue(TransactionContext* ctxt,
- const intrusive_ptr<PersistableMessage>& msg,
- const PersistableQueue& queue)
-{
- boost::intrusive_ptr<DataTokenImpl> ddtokp(new DataTokenImpl);
- ddtokp->addRef();
- ddtokp->setSourceMessage(msg);
- ddtokp->set_external_rid(true);
- ddtokp->set_rid(messageIdSequence.next());
- ddtokp->set_dequeue_rid(msg->getPersistenceId());
- ddtokp->set_wstate(DataTokenImpl::ENQ);
- std::string tid;
- if (ctxt) {
- TxnCtxt* txn = check(ctxt);
- tid = txn->getXid();
- }
- try {
- JournalImpl* jc = static_cast<JournalImpl*>(queue.getExternalQueueStore());
- if (tid.empty()) {
- jc->dequeue_data_record(ddtokp.get());
- } else {
- jc->dequeue_txn_data_record(ddtokp.get(), tid);
- }
- } catch (const journal::jexception& e) {
- THROW_STORE_EXCEPTION(std::string("Queue ") + queue.getName() + ": async_dequeue() failed: " + e.what());
- }
-}
-
-u_int32_t BdbMessageStore::outstandingQueueAIO(const qpid::broker::PersistableQueue& /*queue*/)
-{
- checkInit();
- return 0;
-}
-
-bool BdbMessageStore::deleteIfUnused(DbTxn* txn,
- Dbt& messageId)
-{
- Cursor cursor;
- cursor.open(mappingDb, txn);
- return deleteIfUnused(cursor, txn, messageId);
-}
-
-bool BdbMessageStore::deleteIfUnused(Cursor& cursor,
- DbTxn* txn,
- Dbt& messageId)
-{
- if (isUnused(cursor, messageId)) {
- messageDb.del(txn, &messageId, 0);
- return true;
- } else {
- return false;
- }
-}
-
-bool BdbMessageStore::isUnused(Cursor& cursor, Dbt& messageId)
-{
- Dbt empty;
- int status = cursor->get(&messageId, &empty, DB_SET);
- if (status == DB_NOTFOUND) {
- return true;
- } else if (status == 0) {
- return false;
- } else {
- THROW_STORE_EXCEPTION("Dequeue failed (in isUnused()) with status = " + status);
- }
-}
-
-void BdbMessageStore::completed(TxnCtxt& txn,
- bool commit)
-{
- try {
- chkTplStoreInit(); // Late initialize (if needed)
-
- // Nothing to do if not prepared
- if (txn.getDtok()->is_enqueued()) {
- txn.incrDtokRef();
- DataTokenImpl* dtokp = txn.getDtok();
- dtokp->set_dequeue_rid(dtokp->rid());
- dtokp->set_rid(messageIdSequence.next());
- tplStorePtr->dequeue_txn_data_record(txn.getDtok(), txn.getXid(), commit);
- }
- txn.complete(commit);
- if (mgmtObject != 0) {
- mgmtObject->dec_tplTransactionDepth();
- if (commit)
- mgmtObject->inc_tplTxnCommits();
- else
- mgmtObject->inc_tplTxnAborts();
- }
- } catch (const std::exception& e) {
- QPID_LOG(error, "Error completing xid " << txn.getXid() << ": " << e.what());
- throw;
- }
-}
-
-auto_ptr<TransactionContext> BdbMessageStore::begin()
-{
- checkInit();
- // pass sequence number for c/a
- return auto_ptr<TransactionContext>(new TxnCtxt(&messageIdSequence));
-}
-
-std::auto_ptr<qpid::broker::TPCTransactionContext> BdbMessageStore::begin(const std::string& xid)
-{
- checkInit();
- IdSequence* jtx = &messageIdSequence;
- // pass sequence number for c/a
- return auto_ptr<TPCTransactionContext>(new TPCTxnCtxt(xid, jtx));
-}
-
-void BdbMessageStore::prepare(qpid::broker::TPCTransactionContext& ctxt)
-{
- checkInit();
- TxnCtxt* txn = dynamic_cast<TxnCtxt*>(&ctxt);
- if(!txn) throw InvalidTransactionContextException();
- localPrepare(txn);
-}
-
-void BdbMessageStore::localPrepare(TxnCtxt* ctxt)
-{
- try {
- chkTplStoreInit(); // Late initialize (if needed)
-
- // This sync is requred to ensure multi-queue atomicity - ie all txn data
- // must hit the disk on *all* queues before the TPL prepare (enq) is written.
- ctxt->sync();
-
- ctxt->incrDtokRef();
- DataTokenImpl* dtokp = ctxt->getDtok();
- dtokp->set_external_rid(true);
- dtokp->set_rid(messageIdSequence.next());
- char tpcFlag = static_cast<char>(ctxt->isTPC());
- tplStorePtr->enqueue_txn_data_record(&tpcFlag, sizeof(char), sizeof(char), dtokp, ctxt->getXid(), false);
- ctxt->prepare(tplStorePtr.get());
- // make sure all the data is written to disk before returning
- ctxt->sync();
- if (mgmtObject != 0) {
- mgmtObject->inc_tplTransactionDepth();
- mgmtObject->inc_tplTxnPrepares();
- }
- } catch (const std::exception& e) {
- QPID_LOG(error, "Error preparing xid " << ctxt->getXid() << ": " << e.what());
- throw;
- }
-}
-
-void BdbMessageStore::commit(TransactionContext& ctxt)
-{
- checkInit();
- TxnCtxt* txn(check(&ctxt));
- if (!txn->isTPC()) {
- if (txn->impactedQueuesEmpty()) return;
- localPrepare(dynamic_cast<TxnCtxt*>(txn));
- }
- completed(*dynamic_cast<TxnCtxt*>(txn), true);
-}
-
-void BdbMessageStore::abort(TransactionContext& ctxt)
-{
- checkInit();
- TxnCtxt* txn(check(&ctxt));
- if (!txn->isTPC()) {
- if (txn->impactedQueuesEmpty()) return;
- localPrepare(dynamic_cast<TxnCtxt*>(txn));
- }
- completed(*dynamic_cast<TxnCtxt*>(txn), false);
-}
-
-TxnCtxt* BdbMessageStore::check(TransactionContext* ctxt)
-{
- TxnCtxt* txn = dynamic_cast<TxnCtxt*>(ctxt);
- if(!txn) throw InvalidTransactionContextException();
- return txn;
-}
-
-void BdbMessageStore::put(Db& db,
- DbTxn* txn,
- Dbt& key,
- Dbt& value)
-{
- try {
- int status = db.put(txn, &key, &value, DB_NODUPDATA);
- if (status == DB_KEYEXIST) {
- THROW_STORE_EXCEPTION("duplicate data");
- } else if (status) {
- THROW_STORE_EXCEPTION(DbEnv::strerror(status));
- }
- } catch (const DbException& e) {
- THROW_STORE_EXCEPTION(e.what());
- }
-}
-
-bool BdbMessageStore::deleteKeyValuePair(Db& db,
- DbTxn* txn,
- Dbt& key,
- Dbt& value)
-{
- Cursor cursor;
- cursor.open(db, txn);
- int status = cursor->get(&key, &value, DB_GET_BOTH | DB_RMW);
- if (status == 0) {
- cursor->del(0);
- return true;
- } else if (status == DB_NOTFOUND) {
- return false;
- } else {
- THROW_STORE_EXCEPTION("Deletion failed: " + std::string(DbEnv::strerror(status)));
- }
-}
-
-void BdbMessageStore::deleteBindingsForQueue(const PersistableQueue& queue)
-{
- TxnCtxt txn;
- txn.begin(env, true);
- try {
- {
- Cursor bindings;
- bindings.open(bindingDb, txn.get());
-
- IdDbt key;
- Dbt value;
- while (bindings.next(key, value)) {
- Buffer buffer(reinterpret_cast<char*>(value.get_data()), value.get_size());
- if (buffer.available() < 8) {
- THROW_STORE_EXCEPTION("Not enough data for binding");
- }
- uint64_t queueId = buffer.getLongLong();
- if (queue.getPersistenceId() == queueId) {
- bindings->del(0);
- QPID_LOG(debug, "Deleting binding for " << queue.getName() << " " << key.id << "->" << queueId);
- }
- }
- }
- txn.commit();
- } catch (const std::exception& e) {
- txn.abort();
- THROW_STORE_EXCEPTION_2("Error deleting bindings", e.what());
- } catch (...) {
- txn.abort();
- throw;
- }
- QPID_LOG(debug, "Deleted all bindings for " << queue.getName() << ":" << queue.getPersistenceId());
-}
-
-void BdbMessageStore::deleteBinding(const PersistableExchange& exchange,
- const PersistableQueue& queue,
- const std::string& bkey)
-{
- TxnCtxt txn;
- txn.begin(env, true);
- try {
- {
- Cursor bindings;
- bindings.open(bindingDb, txn.get());
-
- IdDbt key(exchange.getPersistenceId());
- Dbt value;
-
- for (int status = bindings->get(&key, &value, DB_SET); status == 0; status = bindings->get(&key, &value, DB_NEXT_DUP)) {
- Buffer buffer(reinterpret_cast<char*>(value.get_data()), value.get_size());
- if (buffer.available() < 8) {
- THROW_STORE_EXCEPTION("Not enough data for binding");
- }
- uint64_t queueId = buffer.getLongLong();
- if (queue.getPersistenceId() == queueId) {
- std::string q;
- std::string k;
- buffer.getShortString(q);
- buffer.getShortString(k);
- if (bkey == k) {
- bindings->del(0);
- QPID_LOG(debug, "Deleting binding for " << queue.getName() << " " << key.id << "->" << queueId);
- }
- }
- }
- }
- txn.commit();
- } catch (const std::exception& e) {
- txn.abort();
- THROW_STORE_EXCEPTION_2("Error deleting bindings", e.what());
- } catch (...) {
- txn.abort();
- throw;
- }
-}
-
-std::string BdbMessageStore::getJrnlBaseDir()
-{
- std::stringstream dir;
- dir << storeDir << "/rhm/jrnl/" ;
- return dir.str();
-}
-
-std::string BdbMessageStore::getBdbBaseDir()
-{
- std::stringstream dir;
- dir << storeDir << "/rhm/dat/" ;
- return dir.str();
-}
-
-std::string BdbMessageStore::getTplBaseDir()
-{
- std::stringstream dir;
- dir << storeDir << "/rhm/tpl/" ;
- return dir.str();
-}
-
-std::string BdbMessageStore::getJrnlDir(const qpid::broker::PersistableQueue& queue) //for exmaple /var/rhm/ + queueDir/
-{
- return getJrnlDir(queue.getName().c_str());
-}
-
-std::string BdbMessageStore::getJrnlDir(const char* queueName) //for exmaple /var/rhm/ + queueDir/
-{
- std::stringstream dir;
- dir << getJrnlBaseDir() << std::hex << std::setfill('0') << std::setw(4);
- u_int32_t count = 0;
- for (u_int32_t i = 0; i < strlen(queueName); i++) {
- count += queueName[i];
- }
- dir << (count % 29); // Use a prime number for better distribution across dirs
- dir << "/" << queueName << "/";
- return dir.str();
-}
-
-BdbMessageStore::Options::Options(const std::string& name) :
- qpid::Options(name),
- numJrnlFiles(defNumJrnlFiles),
- jrnlFsizePgs(defJrnlFileSizePgs),
- wCachePageSizeKib(defWCachePageSize),
- tplNumJrnlFiles(defTplNumJrnlFiles),
- tplJrnlFsizePgs(defTplJrnlFileSizePgs),
- tplWCachePageSizeKib(defTplWCachePageSize)
-{
- addOptions()
- ("store-dir", qpid::optValue(storeDir, "DIR"),
- "Store directory location for persistence (instead of using --data-dir value). "
- "Must be supplied if --no-data-dir is also used.")
- ("num-jfiles", qpid::optValue(numJrnlFiles, "N"),
- "Default number of files for each journal instance")
- ("jfile-size-pgs", qpid::optValue(jrnlFsizePgs, "N"),
- "Default size for each journal file in multiples of read pages (1 read page = 64kiB)")
- ("wcache-page-size", qpid::optValue(wCachePageSizeKib, "N"),
- "Size of the pages in the write page cache in KiB. "
- "Allowable values - powers of 2: 1, 2, 4, ... , 128. "
- "Lower values decrease latency at the expense of throughput.")
- ("tpl-num-jfiles", qpid::optValue(tplNumJrnlFiles, "N"),
- "Number of files for transaction prepared list journal instance")
- ("tpl-jfile-size-pgs", qpid::optValue(tplJrnlFsizePgs, "N"),
- "Size of each transaction prepared list journal file in multiples of read pages (1 read page = 64kiB)")
- ("tpl-wcache-page-size", qpid::optValue(tplWCachePageSizeKib, "N"),
- "Size of the pages in the transaction prepared list write page cache in KiB. "
- "Allowable values - powers of 2: 1, 2, 4, ... , 128. "
- "Lower values decrease latency at the expense of throughput.")
- ;
-}
Deleted: store/trunk/cpp/lib/BdbMessageStore.h
===================================================================
--- store/trunk/cpp/lib/BdbMessageStore.h 2008-09-09 13:39:28 UTC (rev 2432)
+++ store/trunk/cpp/lib/BdbMessageStore.h 2008-09-09 19:25:47 UTC (rev 2433)
@@ -1,348 +0,0 @@
-/*
- Copyright (C) 2007 Red Hat Software
-
- 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 _BdbMessageStore_
-#define _BdbMessageStore_
-
-#include <string>
-
-#include "db-inc.h"
-#include "Cursor.h"
-#include "IdDbt.h"
-#include "IdSequence.h"
-#include "JournalImpl.h"
-#include "jrnl/jcfg.hpp"
-#include "PreparedTransaction.h"
-#include "qpid/broker/Broker.h"
-#include "qpid/broker/MessageStore.h"
-#include "qpid/management/Manageable.h"
-#include "Store.h"
-#include "TxnCtxt.h"
-
-// Assume DB_VERSION_MAJOR == 4
-#if (DB_VERSION_MINOR == 2)
-#include <errno.h>
-#define DB_BUFFER_SMALL ENOMEM
-#endif
-
-namespace rhm {
-namespace bdbstore {
-
-/**
- * An implementation of the MessageStore interface based on Berkeley DB
- */
-class BdbMessageStore : public qpid::broker::MessageStore, public qpid::management::Manageable
-{
- protected:
- typedef std::map<u_int64_t, qpid::broker::RecoverableQueue::shared_ptr> queue_index;
- typedef std::map<u_int64_t, qpid::broker::RecoverableExchange::shared_ptr> exchange_index;
- typedef std::map<u_int64_t, qpid::broker::RecoverableMessage::shared_ptr> message_index;
-
- typedef LockedMappings::map txn_lock_map;
- typedef boost::ptr_list<PreparedTransaction> txn_list;
-
- // Structs for Transaction Recover List (TPL) recover state
- struct TplRecoverStruct {
- u_int64_t rid; // rid of TPL record
- bool deq_flag;
- bool commit_flag;
- bool tpc_flag;
- TplRecoverStruct(const u_int64_t _rid, const bool _deq_flag, const bool _commit_flag, const bool _tpc_flag);
- };
- typedef TplRecoverStruct TplRecover;
- typedef std::pair<std::string, TplRecover> TplRecoverMapPair;
- typedef std::map<std::string, TplRecover> TplRecoverMap;
- typedef TplRecoverMap::const_iterator TplRecoverMapCitr;
-
- // Default store settings
- static const u_int16_t defNumJrnlFiles = 8;
- static const u_int32_t defJrnlFileSizePgs = 24;
- static const u_int32_t defWCachePageSize = JRNL_WMGR_DEF_PAGE_SIZE * JRNL_DBLK_SIZE * JRNL_SBLK_SIZE / 1024;
- static const u_int16_t defTplNumJrnlFiles = 8;
- static const u_int32_t defTplJrnlFileSizePgs = 24;
- static const u_int32_t defTplWCachePageSize = defWCachePageSize / 8;
-
- std::list<Db*> dbs;
- DbEnv env;
- Db queueDb;
- Db configDb;
- Db exchangeDb;
- Db messageDb;
- Db mappingDb;
- Db bindingDb;
- Db generalDb;
-
- // Pointer to Transaction Prepared List (TPL) journal instance
- boost::shared_ptr<TplJournalImpl> tplStorePtr;
- TplRecoverMap tplRecoverMap;
-
- IdSequence queueIdSequence;
- IdSequence exchangeIdSequence;
- IdSequence generalIdSequence;
- IdSequence messageIdSequence;
- std::string storeDir;
- u_int16_t numJrnlFiles;
- u_int32_t jrnlFsizeSblks;
- u_int32_t wCachePgSizeSblks;
- u_int16_t wCacheNumPages;
- u_int16_t tplNumJrnlFiles;
- u_int32_t tplJrnlFsizeSblks;
- u_int32_t tplWCachePgSizeSblks;
- u_int16_t tplWCacheNumPages;
- u_int64_t highestRid;
- bool isInit;
- const char* envPath;
- static qpid::sys::Duration defJournalGetEventsTimeout;
- static qpid::sys::Duration defJournalFlushTimeout;
- qpid::management::Store* mgmtObject;
- qpid::sys::Mutex jrnlCreateLock;
-
- // Parameter validation and calculation
- static u_int16_t chkJrnlNumFilesParam(const u_int16_t param,
- const std::string paramName);
- static u_int32_t chkJrnlFileSizeParam(const u_int32_t param,
- const std::string paramName);
- static u_int32_t chkJrnlWrPageCacheSize(const u_int32_t param,
- const std::string paramName);
- static u_int16_t getJrnlWrNumPages(const u_int32_t wrPageSizeKib);
-
- void recoverQueues(TxnCtxt& txn,
- qpid::broker::RecoveryManager& recovery,
- queue_index& index,
- txn_list& locked,
- message_index& messages);
- void recoverMessages(TxnCtxt& txn,
- qpid::broker::RecoveryManager& recovery,
- queue_index& index,
- txn_list& locked,
- message_index& prepared);
- void recoverMessages(TxnCtxt& txn,
- qpid::broker::RecoveryManager& recovery,
- qpid::broker::RecoverableQueue::shared_ptr& queue,
- txn_list& locked,
- message_index& prepared);
- qpid::broker::RecoverableMessage::shared_ptr getExternMessage(qpid::broker::RecoveryManager& recovery,
- uint64_t mId,
- unsigned& headerSize);
- void recoverExchanges(TxnCtxt& txn,
- qpid::broker::RecoveryManager& recovery,
- exchange_index& index);
- void recoverBindings(TxnCtxt& txn,
- exchange_index& exchanges,
- queue_index& queues);
- void recoverGeneral(TxnCtxt& txn,
- qpid::broker::RecoveryManager& recovery);
- int enqueueMessage(TxnCtxt& txn,
- IdDbt& msgId,
- qpid::broker::RecoverableMessage::shared_ptr& msg,
- queue_index& index,
- txn_list& locked,
- message_index& prepared);
- void readTplStore();
- void recoverTplStore();
- void recoverLockedMappings(txn_list& txns);
- TxnCtxt* check(qpid::broker::TransactionContext* ctxt);
- void store(const qpid::broker::PersistableQueue* queue,
- TxnCtxt* txn,
- Dbt& messageId,
- const boost::intrusive_ptr<qpid::broker::PersistableMessage>& message,
- bool newId);
- void async_dequeue(qpid::broker::TransactionContext* ctxt,
- const boost::intrusive_ptr<qpid::broker::PersistableMessage>& msg,
- const qpid::broker::PersistableQueue& queue);
- bool deleteIfUnused(Cursor& cursor,
- DbTxn* txn,
- Dbt& messageId);
- bool deleteIfUnused(DbTxn* txn,
- Dbt& messageId);
- bool isUnused(Cursor& cursor,
- Dbt& messageId);
- void destroy(Db& db,
- const qpid::broker::Persistable& p);
- bool create(Db& db,
- IdSequence& seq,
- const qpid::broker::Persistable& p);
- void completed(TxnCtxt& txn,
- bool commit);
- void record2pcOp(Db& db,
- TPCTxnCtxt& txn,
- u_int64_t messageId,
- u_int64_t queueId);
- void deleteBindingsForQueue(const qpid::broker::PersistableQueue& queue);
- void deleteBinding(const qpid::broker::PersistableExchange& exchange,
- const qpid::broker::PersistableQueue& queue,
- const std::string& key);
-
- u_int64_t getRecordSize(Db& db,
- Dbt& key);
- u_int64_t getRecordSize(DbTxn* txn,
- Db& db,
- Dbt& key);
- void put(Db& db,
- DbTxn* txn,
- Dbt& key,
- Dbt& value);
- bool deleteKeyValuePair(Db& db,
- DbTxn* txn,
- Dbt& key,
- Dbt& value);
- void open(Db& db,
- DbTxn* txn,
- const char* file,
- bool dupKey);
-
- // journal functions
- void createJrnlQueue(const qpid::broker::PersistableQueue& queue);
- std::string getJrnlDir(const qpid::broker::PersistableQueue& queue); //for exmaple /var/rhm/ + queueDir/
- std::string getJrnlDir(const char* queueName);
- std::string getJrnlBaseDir();
- std::string getBdbBaseDir();
- std::string getTplBaseDir();
- inline void checkInit() {
- // TODO: change the default dir to ~/.qpidd
- if (!isInit) init("/tmp", defNumJrnlFiles, defJrnlFileSizePgs, defWCachePageSize); isInit = true;
- }
- void chkTplStoreInit();
-
- // debug aid for printing XIDs that may contain non-printable chars
- static std::string xid2str(const std::string xid) {
- std::ostringstream oss;
- oss << std::hex << std::setfill('0');
- for (unsigned i=0; i<xid.size(); i++) {
- if (isprint(xid[i]))
- oss << xid[i];
- else
- oss << "/" << std::setw(2) << (int)((char)xid[i]);
- }
- return oss.str();
- }
-
- public:
- struct Options : public qpid::Options {
- Options(const std::string& name="Store Options");
- std::string clusterName;
- std::string storeDir;
- u_int16_t numJrnlFiles;
- u_int32_t jrnlFsizePgs;
- u_int32_t wCachePageSizeKib;
- u_int16_t tplNumJrnlFiles;
- u_int32_t tplJrnlFsizePgs;
- u_int32_t tplWCachePageSizeKib;
- };
-
- typedef boost::shared_ptr<BdbMessageStore> shared_ptr;
-
- BdbMessageStore(const char* envpath = 0);
-
- virtual ~BdbMessageStore();
-
- bool init(const qpid::Options* options);
-
- bool init(const std::string& dir,
- u_int16_t jfiles = defNumJrnlFiles,
- u_int32_t jfileSizePgs = defJrnlFileSizePgs,
- u_int32_t wCachePageSize = defWCachePageSize,
- u_int16_t tplJfiles = defTplNumJrnlFiles,
- u_int32_t tplJfileSizePgs = defTplJrnlFileSizePgs,
- u_int32_t tplWCachePageSize = defTplWCachePageSize);
-
- void initManagement (qpid::broker::Broker* broker);
-
- void truncate();
-
- void create(qpid::broker::PersistableQueue& queue,
- const qpid::framing::FieldTable& args);
-
- void destroy(qpid::broker::PersistableQueue& queue);
-
- void create(const qpid::broker::PersistableExchange& queue,
- const qpid::framing::FieldTable& args);
-
- void destroy(const qpid::broker::PersistableExchange& queue);
-
- void bind(const qpid::broker::PersistableExchange& exchange,
- const qpid::broker::PersistableQueue& queue,
- const std::string& key,
- const qpid::framing::FieldTable& args);
-
- void unbind(const qpid::broker::PersistableExchange& exchange,
- const qpid::broker::PersistableQueue& queue,
- const std::string& key,
- const qpid::framing::FieldTable& args);
-
- void create(const qpid::broker::PersistableConfig& config);
-
- void destroy(const qpid::broker::PersistableConfig& config);
-
- void recover(qpid::broker::RecoveryManager& queues);
-
- void stage(const boost::intrusive_ptr<qpid::broker::PersistableMessage>& msg);
-
- void destroy(qpid::broker::PersistableMessage& msg);
-
- void appendContent(const boost::intrusive_ptr<const qpid::broker::PersistableMessage>& msg,
- const std::string& data);
-
- void loadContent(const qpid::broker::PersistableQueue& queue,
- const boost::intrusive_ptr<const qpid::broker::PersistableMessage>& msg,
- std::string& data,
- u_int64_t offset,
- u_int32_t length);
-
- void enqueue(qpid::broker::TransactionContext* ctxt,
- const boost::intrusive_ptr<qpid::broker::PersistableMessage>& msg,
- const qpid::broker::PersistableQueue& queue);
-
- void dequeue(qpid::broker::TransactionContext* ctxt,
- const boost::intrusive_ptr<qpid::broker::PersistableMessage>& msg,
- const qpid::broker::PersistableQueue& queue);
-
- void flush(const qpid::broker::PersistableQueue& queue);
-
- u_int32_t outstandingQueueAIO(const qpid::broker::PersistableQueue& queue);
-
- void collectPreparedXids(std::set<std::string>& xids);
-
- std::auto_ptr<qpid::broker::TransactionContext> begin();
-
- std::auto_ptr<qpid::broker::TPCTransactionContext> begin(const std::string& xid);
-
- void prepare(qpid::broker::TPCTransactionContext& ctxt);
-
- void localPrepare(TxnCtxt* ctxt);
-
- void commit(qpid::broker::TransactionContext& ctxt);
-
- void abort(qpid::broker::TransactionContext& ctxt);
-
- qpid::management::ManagementObject* GetManagementObject (void) const
- { return mgmtObject; }
-
- inline qpid::management::Manageable::status_t ManagementMethod (u_int32_t, qpid::management::Args&)
- { return qpid::management::Manageable::STATUS_OK; }
-}; // class BdbMessageStore
-
-} // namespace bdbstore
-} // namespace rhm
-
-#endif
Modified: store/trunk/cpp/lib/Makefile.am
===================================================================
--- store/trunk/cpp/lib/Makefile.am 2008-09-09 13:39:28 UTC (rev 2432)
+++ store/trunk/cpp/lib/Makefile.am 2008-09-09 19:25:47 UTC (rev 2433)
@@ -16,7 +16,6 @@
libbdbstore_la_SOURCES = \
StorePlugin.cpp \
- BdbMessageStore.cpp \
BindingDbt.cpp \
BufferValue.cpp \
DataTokenImpl.cpp \
@@ -24,9 +23,9 @@
IdPairDbt.cpp \
IdSequence.cpp \
JournalImpl.cpp \
+ MessageStoreImpl.cpp \
PreparedTransaction.cpp \
StringDbt.cpp \
- BdbMessageStore.h \
BindingDbt.h \
BufferValue.h \
Cursor.h \
@@ -35,6 +34,7 @@
IdPairDbt.h \
IdSequence.h \
JournalImpl.h \
+ MessageStoreImpl.h \
PreparedTransaction.h \
StoreException.h \
StringDbt.h \
Copied: store/trunk/cpp/lib/MessageStoreImpl.cpp (from rev 2432, store/trunk/cpp/lib/BdbMessageStore.cpp)
===================================================================
--- store/trunk/cpp/lib/MessageStoreImpl.cpp (rev 0)
+++ store/trunk/cpp/lib/MessageStoreImpl.cpp 2008-09-09 19:25:47 UTC (rev 2433)
@@ -0,0 +1,1693 @@
+/*
+ Copyright (C) 2007 Red Hat Software
+
+ 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 "MessageStoreImpl.h"
+
+#include "BindingDbt.h"
+#include "BufferValue.h"
+#include "IdPairDbt.h"
+#include "jrnl/txn_map.hpp"
+#include "qpid/log/Statement.h"
+#include "PackageMrgstore.h"
+
+#define MAX_AIO_SLEEPS 1000 // ~1 second
+#define AIO_SLEEP_TIME 1000 // 1 milisecond
+
+using namespace rhm::bdbstore;
+using namespace qpid::broker;
+using boost::static_pointer_cast;
+using boost::intrusive_ptr;
+
+using std::auto_ptr;
+using std::max;
+using qpid::framing::Buffer;
+using qpid::framing::FieldTable;
+using qpid::management::ManagementAgent;
+
+static const u_int8_t MESSAGE_MESSAGE = 1;
+static const u_int8_t BASIC_MESSAGE = 2;
+qpid::sys::Duration MessageStoreImpl::defJournalGetEventsTimeout(10 * qpid::sys::TIME_MSEC); // 10ms
+qpid::sys::Duration MessageStoreImpl::defJournalFlushTimeout(500 * qpid::sys::TIME_MSEC); // 0.5s
+qpid::sys::Mutex TxnCtxt::globalSerialiser;
+
+MessageStoreImpl::TplRecoverStruct::TplRecoverStruct(const u_int64_t _rid,
+ const bool _deq_flag,
+ const bool _commit_flag,
+ const bool _tpc_flag) :
+ rid(_rid),
+ deq_flag(_deq_flag),
+ commit_flag(_commit_flag),
+ tpc_flag(_tpc_flag)
+{}
+
+MessageStoreImpl::MessageStoreImpl(const char* envpath) :
+ env(0),
+ queueDb(&env, 0),
+ configDb(&env, 0),
+ exchangeDb(&env, 0),
+ messageDb(&env, 0),
+ mappingDb(&env, 0),
+ bindingDb(&env, 0),
+ generalDb(&env, 0),
+ numJrnlFiles(0),
+ jrnlFsizeSblks(0),
+ wCachePgSizeSblks(0),
+ wCacheNumPages(0),
+ tplNumJrnlFiles(0),
+ tplJrnlFsizeSblks(0),
+ tplWCachePgSizeSblks(0),
+ tplWCacheNumPages(0),
+ highestRid(0),
+ isInit(false),
+ envPath(envpath),
+ mgmtObject(0)
+{}
+
+u_int16_t MessageStoreImpl::chkJrnlNumFilesParam(const u_int16_t param, const std::string paramName)
+{
+ u_int16_t p = param;
+ if (p < JRNL_MIN_NUM_FILES) {
+ p = JRNL_MIN_NUM_FILES;
+ QPID_LOG(warning, "parameter " << paramName << " (" << param << ") is below allowable minimum (" << JRNL_MIN_NUM_FILES << "); changing this parameter to minimum value.");
+ } else if (p > JRNL_MAX_NUM_FILES) {
+ p = JRNL_MAX_NUM_FILES;
+ QPID_LOG(warning, "parameter " << paramName << " (" << param << ") is above allowable maximum (" << JRNL_MAX_NUM_FILES << "); changing this parameter to maximum value.");
+ }
+ return p;
+}
+
+u_int32_t MessageStoreImpl::chkJrnlFileSizeParam(const u_int32_t param, const std::string paramName)
+{
+ u_int32_t p = param;
+ u_int32_t min = JRNL_MIN_FILE_SIZE / JRNL_RMGR_PAGE_SIZE;
+ u_int32_t max = JRNL_MAX_FILE_SIZE / JRNL_RMGR_PAGE_SIZE;
+ if (p < min) {
+ p = min;
+ QPID_LOG(warning, "parameter " << paramName << " (" << param << ") is below allowable minimum (" << min << "); changing this parameter to minimum value.");
+ } else if (p > max) {
+ p = max;
+ QPID_LOG(warning, "parameter " << paramName << " (" << param << ") is above allowable maximum (" << max << "); changing this parameter to maximum value.");
+ }
+ return p;
+}
+
+u_int32_t MessageStoreImpl::chkJrnlWrPageCacheSize(const u_int32_t param, const std::string paramName)
+{
+ u_int32_t p = param;
+ switch (p)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+ case 32:
+ case 64:
+ case 128:
+ break;
+ default:
+ if (p == 0) {
+ // For zero value, use default
+ p = JRNL_WMGR_DEF_PAGE_SIZE * JRNL_DBLK_SIZE * JRNL_SBLK_SIZE / 1024;
+ QPID_LOG(warning, "parameter " << paramName << " (" << param << ") must be a power of 2 between 1 and 128; changing this parameter to default value (" << p << ")");
+ } else {
+ // For any positive value, use closest value
+ if (p < 6) p = 4;
+ else if (p < 12) p = 8;
+ else if (p < 24) p = 16;
+ else if (p < 48) p = 32;
+ else if (p < 96) p = 64;
+ else if (p > 128) p = 128;
+ QPID_LOG(warning, "parameter " << paramName << " (" << param << ") must be a power of 2 between 1 and 128; changing this parameter to closest allowable value (" << p << ")");
+ }
+ }
+ return p;
+}
+
+u_int16_t MessageStoreImpl::getJrnlWrNumPages(const u_int32_t wrPageSizeKib)
+{
+ u_int32_t wrPageSizeSblks = wrPageSizeKib * 1024 / JRNL_DBLK_SIZE / JRNL_SBLK_SIZE; // convert from KiB to number sblks
+ u_int32_t defTotWCacheSize = JRNL_WMGR_DEF_PAGE_SIZE * JRNL_WMGR_DEF_PAGES; // in sblks. Currently 2014 sblks (1 MiB).
+ switch (wrPageSizeKib)
+ {
+ case 1:
+ case 2:
+ case 4:
+ // 256 KiB total cache
+ return defTotWCacheSize / wrPageSizeSblks / 4;
+ case 8:
+ case 16:
+ // 512 KiB total cache
+ return defTotWCacheSize / wrPageSizeSblks / 2;
+ default: // 32, 64, 128
+ // 1 MiB total cache
+ return defTotWCacheSize / wrPageSizeSblks;
+ }
+}
+
+void MessageStoreImpl::initManagement (Broker* broker)
+{
+ if (broker != 0) {
+ ManagementAgent* agent = ManagementAgent::Singleton::getInstance();
+ if (agent != 0) {
+ qpid::management::PackageMrgstore packageInitializer(agent);
+ mgmtObject = new qpid::management::Store(agent, this, broker);
+
+ mgmtObject->set_location(storeDir);
+ mgmtObject->set_defaultInitialFileCount(numJrnlFiles);
+ mgmtObject->set_defaultDataFileSize(jrnlFsizeSblks / JRNL_RMGR_PAGE_SIZE);
+ mgmtObject->set_tplIsInitialized(false);
+ mgmtObject->set_tplDirectory(getTplBaseDir());
+ mgmtObject->set_tplWritePageSize(tplWCachePgSizeSblks * JRNL_SBLK_SIZE * JRNL_DBLK_SIZE);
+ mgmtObject->set_tplWritePages(tplWCacheNumPages);
+ mgmtObject->set_tplInitialFileCount(tplNumJrnlFiles);
+ mgmtObject->set_tplDataFileSize(tplJrnlFsizeSblks * JRNL_SBLK_SIZE * JRNL_DBLK_SIZE);
+ mgmtObject->set_tplCurrentFileCount(tplNumJrnlFiles);
+
+ agent->addObject(mgmtObject, 0x1000000000000050LL);
+ }
+ }
+}
+
+bool MessageStoreImpl::init(const qpid::Options* options)
+{
+ // Extract and check options
+ const Options* opts = static_cast<const Options*>(options);
+ u_int16_t numJrnlFiles = chkJrnlNumFilesParam(opts->numJrnlFiles, "num-jfiles");
+ u_int32_t jrnlFsizePgs = chkJrnlFileSizeParam(opts->jrnlFsizePgs, "jfile-size-pgs");
+ u_int32_t jrnlWrCachePageSizeKib = chkJrnlWrPageCacheSize(opts->wCachePageSizeKib, "wcache-page-size");
+ u_int16_t tplNumJrnlFiles = chkJrnlNumFilesParam(opts->tplNumJrnlFiles, "tpl-num-jfiles");
+ u_int32_t tplJrnlFSizePgs = chkJrnlFileSizeParam(opts->tplJrnlFsizePgs, "tpl-jfile-size-pgs");
+ u_int32_t tplJrnlWrCachePageSizeKib = chkJrnlWrPageCacheSize(opts->tplWCachePageSizeKib, "tpl-wcache-page-size");
+
+ // Pass option values to init(...)
+ return init(opts->storeDir, numJrnlFiles, jrnlFsizePgs, jrnlWrCachePageSizeKib, tplNumJrnlFiles, tplJrnlFSizePgs, tplJrnlWrCachePageSizeKib);
+}
+
+// These params, taken from options, are assumed to be correct and verified
+bool MessageStoreImpl::init(const std::string& dir,
+ u_int16_t jfiles,
+ u_int32_t jfileSizePgs,
+ u_int32_t wCachePageSizeKib,
+ u_int16_t tplJfiles,
+ u_int32_t tplJfileSizePgs,
+ u_int32_t tplWCachePageSizeKib)
+{
+ if (isInit) return true;
+
+ // Set geometry members (converting to correct units where req'd)
+ numJrnlFiles = jfiles;
+ jrnlFsizeSblks = jfileSizePgs * JRNL_RMGR_PAGE_SIZE;
+ wCachePgSizeSblks = wCachePageSizeKib * 1024 / JRNL_DBLK_SIZE / JRNL_SBLK_SIZE; // convert from KiB to number sblks
+ wCacheNumPages = getJrnlWrNumPages(wCachePageSizeKib);
+ tplNumJrnlFiles = tplJfiles;
+ tplJrnlFsizeSblks = tplJfileSizePgs * JRNL_RMGR_PAGE_SIZE;
+ tplWCachePgSizeSblks = tplWCachePageSizeKib * 1024 / JRNL_DBLK_SIZE / JRNL_SBLK_SIZE; // convert from KiB to number sblks
+ tplWCacheNumPages = getJrnlWrNumPages(tplWCachePageSizeKib);
+
+ if (dir.size()>0) storeDir = dir;
+
+ journal::jdir::create_dir(getBdbBaseDir());
+
+ try {
+ env.open(getBdbBaseDir().c_str(), DB_THREAD | DB_CREATE | DB_INIT_TXN | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_USE_ENVIRON, 0);
+ } catch (const DbException& e) {
+ if (e.get_errno() == DB_VERSION_MISMATCH)
+ THROW_STORE_EXCEPTION_2("Database environment mismatch: This version of bd4 does not match that which created the store database. "
+ "(If recovery is not important, delete the contents of the store directory. Otherwise, try upgrading the database using "
+ "db_upgrade or using db_recover - but the db4-utils package must also be installed to use these utilities.)", e);
+ THROW_STORE_EXCEPTION_2("Error opening environment", e);
+ }
+
+ TxnCtxt txn;
+ try {
+ txn.begin(env, false);
+ open(queueDb, txn.get(), "queues.db", false);
+ open(configDb, txn.get(), "config.db", false);
+ open(exchangeDb, txn.get(), "exchanges.db", false);
+ open(messageDb, txn.get(), "messages.db", false);
+ open(mappingDb, txn.get(), "mappings.db", true);
+ open(bindingDb, txn.get(), "bindings.db", true);
+ open(generalDb, txn.get(), "general.db", false);
+ tplStorePtr.reset(new TplJournalImpl("TplStore", getTplBaseDir(), "tpl", defJournalGetEventsTimeout, defJournalFlushTimeout));
+ txn.commit();
+ } catch (const journal::jexception& e) {
+ txn.abort();
+ THROW_STORE_EXCEPTION_2("Error opening tplStore instance", e.what());
+ } catch (const DbException& e) {
+ txn.abort();
+ THROW_STORE_EXCEPTION_2("Error opening databases", e);
+ } catch (...) {
+ txn.abort();
+ throw;
+ }
+
+ isInit = true;
+ QPID_LOG(notice, "Store module initialized; dir=" << dir);
+ QPID_LOG(info, "> Default files per journal: " << jfiles);
+ QPID_LOG(info, "> Default jrournal file size: " << jfileSizePgs << " (wpgs)");
+ QPID_LOG(info, "> Default write cache page size: " << wCachePageSizeKib << " (Kib)");
+ QPID_LOG(info, "> Default number of write cache pages: " << wCacheNumPages);
+ QPID_LOG(info, "> TPL files per journal: " << tplNumJrnlFiles);
+ QPID_LOG(info, "> TPL jrournal file size: " << tplJfileSizePgs << " (wpgs)");
+ QPID_LOG(info, "> TPL write cache page size: " << tplWCachePageSizeKib << " (Kib)");
+ QPID_LOG(info, "> TPL number of write cache pages: " << tplWCacheNumPages);
+ return true;
+}
+
+void MessageStoreImpl::chkTplStoreInit()
+{
+ if (!tplStorePtr->is_ready()) {
+ qpid::sys::Mutex::ScopedLock sl(jrnlCreateLock);
+ if (!tplStorePtr->is_ready()) {
+ journal::jdir::create_dir(getTplBaseDir());
+ tplStorePtr->initialize(tplNumJrnlFiles, tplJrnlFsizeSblks, tplWCacheNumPages, tplWCachePgSizeSblks);
+ if (mgmtObject != 0) mgmtObject->set_tplIsInitialized(true);
+ }
+ }
+}
+
+void MessageStoreImpl::open(Db& db,
+ DbTxn* txn,
+ const char* file,
+ bool dupKey)
+{
+ if(dupKey) db.set_flags(DB_DUPSORT);
+ db.open(txn, file, 0, DB_BTREE, DB_CREATE | DB_THREAD, 0);
+ dbs.push_back(&db);
+}
+
+MessageStoreImpl::~MessageStoreImpl()
+{
+ try {
+ for (std::list<Db*>::iterator i = dbs.begin(); i != dbs.end(); i++) {
+ (*i)->close(0);
+ }
+ if (tplStorePtr->is_ready()) tplStorePtr->stop(true);
+ } catch (const DbException& e) {
+ QPID_LOG(error, "Error closing BDB databases: " << e.what());
+ } catch (const journal::jexception& e) {
+ QPID_LOG(error, "Error: " << e.what());
+ } catch (const std::exception& e) {
+ QPID_LOG(error, "Error: " << e.what());
+ } catch (...) {
+ QPID_LOG(error, "Unknown error in MessageStoreImpl::~MessageStoreImpl()");
+ }
+
+ if (mgmtObject != 0)
+ mgmtObject->resourceDestroy();
+}
+
+void MessageStoreImpl::truncate()
+{
+ DbTxn* txn;
+ env.txn_begin(0, &txn, 0);
+ u_int32_t count;
+
+ for (std::list<Db*>::iterator i = dbs.begin(); i != dbs.end(); i++) {
+ (*i)->truncate(txn, &count, 0);
+ }
+
+ txn->commit(0);
+ try {
+ journal::jdir::delete_dir(getJrnlBaseDir(),true);
+ journal::jdir::delete_dir(getTplBaseDir(),true);
+ }
+ catch (const journal::jexception& e) {
+ THROW_STORE_EXCEPTION(std::string("truncate() failed: ") + e.what() );
+ }
+}
+
+void MessageStoreImpl::create(PersistableQueue& queue,
+ const FieldTable& args)
+{
+ checkInit();
+ if (queue.getPersistenceId()) {
+ THROW_STORE_EXCEPTION("Queue already created: " + queue.getName());
+ }
+ JournalImpl* jQueue = 0;
+ FieldTable::ValuePtr value;
+
+ u_int16_t localFileCount = numJrnlFiles;
+ u_int32_t localFileSizeSblks = jrnlFsizeSblks;
+
+ value = args.get ("qpid.file_count");
+ if (value.get() != 0 && !value->empty() && value->convertsTo<int>())
+ localFileCount = (u_int16_t) value->get<int>();
+
+ value = args.get ("qpid.file_size");
+ if (value.get() != 0 && !value->empty() && value->convertsTo<int>())
+ localFileSizeSblks = (u_int32_t) value->get<int>() * JRNL_RMGR_PAGE_SIZE;
+
+ {
+ // TODO: Is this mutex necessary?
+ qpid::sys::Mutex::ScopedLock sl(jrnlCreateLock);
+ jQueue = new JournalImpl(queue.getName(), getJrnlDir(queue),
+ std::string("JournalData"), defJournalGetEventsTimeout,
+ defJournalFlushTimeout);
+ }
+
+ queue.setExternalQueueStore(dynamic_cast<ExternalQueueStore*>(jQueue));
+ try {
+ // init will create the deque's for the init...
+ jQueue->initialize(localFileCount, localFileSizeSblks, wCacheNumPages, wCachePgSizeSblks);
+ } catch (const journal::jexception& e) {
+ THROW_STORE_EXCEPTION(std::string("Queue ") + queue.getName() + ": create() failed: " + e.what());
+ }
+ try {
+ if (!create(queueDb, queueIdSequence, queue)) {
+ THROW_STORE_EXCEPTION("Queue already exists: " + queue.getName());
+ }
+ } catch (const DbException& e) {
+ THROW_STORE_EXCEPTION_2("Error creating queue named " + queue.getName(), e);
+ }
+}
+
+void MessageStoreImpl::destroy(PersistableQueue& queue)
+{
+ checkInit();
+ destroy(queueDb, queue);
+ deleteBindingsForQueue(queue);
+ qpid::broker::ExternalQueueStore* eqs = queue.getExternalQueueStore();
+ if (eqs) {
+ JournalImpl* jQueue = static_cast<JournalImpl*>(eqs);
+ jQueue->delete_jrnl_files();
+ queue.setExternalQueueStore(0); // will delete the journal if exists
+ }
+}
+
+void MessageStoreImpl::create(const PersistableExchange& exchange,
+ const FieldTable& /*args*/)
+{
+ checkInit();
+ if (exchange.getPersistenceId()) {
+ THROW_STORE_EXCEPTION("Exchange already created: " + exchange.getName());
+ }
+ try {
+ if (!create(exchangeDb, exchangeIdSequence, exchange)) {
+ THROW_STORE_EXCEPTION("Exchange already exists: " + exchange.getName());
+ }
+ } catch (const DbException& e) {
+ THROW_STORE_EXCEPTION_2("Error creating exchange named " + exchange.getName(), e);
+ }
+}
+
+void MessageStoreImpl::destroy(const PersistableExchange& exchange)
+{
+ checkInit();
+ destroy(exchangeDb, exchange);
+ //need to also delete bindings
+ IdDbt key(exchange.getPersistenceId());
+ bindingDb.del(0, &key, DB_AUTO_COMMIT);
+}
+
+void MessageStoreImpl::create(const PersistableConfig& general)
+{
+ checkInit();
+ if (general.getPersistenceId()) {
+ THROW_STORE_EXCEPTION("General configuration item already created");
+ }
+ try {
+ if (!create(generalDb, generalIdSequence, general)) {
+ THROW_STORE_EXCEPTION("General configuration already exists");
+ }
+ } catch (const DbException& e) {
+ THROW_STORE_EXCEPTION_2("Error creating general configuration", e);
+ }
+}
+
+void MessageStoreImpl::destroy(const PersistableConfig& general)
+{
+ checkInit();
+ destroy(generalDb, general);
+}
+
+bool MessageStoreImpl::create(Db& db,
+ IdSequence& seq,
+ const Persistable& p)
+{
+ u_int64_t id (seq.next());
+ Dbt key(&id, sizeof(id));
+ BufferValue value (p);
+
+ int status;
+ TxnCtxt txn;
+ txn.begin(env, true);
+ try {
+ status = db.put(txn.get(), &key, &value, DB_NOOVERWRITE);
+ txn.commit();
+ } catch (...) {
+ txn.abort();
+ throw;
+ }
+ if (status == DB_KEYEXIST) {
+ return false;
+ } else {
+ p.setPersistenceId(id);
+ return true;
+ }
+}
+
+void MessageStoreImpl::destroy(Db& db, const Persistable& p)
+{
+ IdDbt key(p.getPersistenceId());
+ db.del(0, &key, DB_AUTO_COMMIT);
+}
+
+
+void MessageStoreImpl::bind(const PersistableExchange& e,
+ const PersistableQueue& q,
+ const std::string& k,
+ const FieldTable& a)
+{
+ checkInit();
+ IdDbt key(e.getPersistenceId());
+ BindingDbt value(e, q, k, a);
+ TxnCtxt txn;
+ txn.begin(env, true);
+ try {
+ put(bindingDb, txn.get(), key, value);
+ txn.commit();
+ } catch (...) {
+ txn.abort();
+ throw;
+ }
+}
+
+void MessageStoreImpl::unbind(const PersistableExchange& e,
+ const PersistableQueue& q,
+ const std::string& k,
+ const FieldTable&)
+{
+ checkInit();
+ deleteBinding(e, q, k);
+}
+
+void MessageStoreImpl::recover(RecoveryManager& registry)
+{
+ checkInit();
+ txn_list prepared;
+ recoverLockedMappings(prepared);
+
+ queue_index queues;//id->queue
+ exchange_index exchanges;//id->exchange
+ message_index messages;//id->message
+
+ TxnCtxt txn;
+ txn.begin(env, false);
+ try {
+ //read all queues, calls recoversMessages
+ recoverQueues(txn, registry, queues, prepared, messages);
+
+ //recover exchange & bindings:
+ recoverExchanges(txn, registry, exchanges);
+ recoverBindings(txn, exchanges, queues);
+
+ //recover general-purpose configuration
+ recoverGeneral(txn, registry);
+
+ txn.commit();
+ } catch (const DbException& e) {
+ txn.abort();
+ THROW_STORE_EXCEPTION_2("Error on recovery", e);
+ } catch (...) {
+ txn.abort();
+ throw;
+ }
+
+ //recover transactions:
+ for (txn_list::iterator i = prepared.begin(); i != prepared.end(); i++) {
+ if (mgmtObject != 0) {
+ mgmtObject->inc_tplTransactionDepth();
+ mgmtObject->inc_tplTxnPrepares();
+ }
+
+ std::string xid = i->xid;
+
+ // Restore data token state in TxnCtxt
+ TplRecoverMapCitr citr = tplRecoverMap.find(xid);
+ if (citr == tplRecoverMap.end()) THROW_STORE_EXCEPTION("XID not found in tplRecoverMap");
+
+ // If a record is found that is dequeued but not committed/aborted from tplStore, then a complete() call
+ // was interrupted part way through committing/aborting the impacted queues. Complete this process.
+ bool incomplTplTxnFlag = citr->second.deq_flag;
+
+ if (citr->second.tpc_flag) {
+ // Dtx (2PC) transaction
+ TPCTxnCtxt* tpcc = new TPCTxnCtxt(xid, &messageIdSequence);
+ std::auto_ptr<TPCTransactionContext> txn(tpcc);
+ tpcc->recoverDtok(citr->second.rid, xid);
+ tpcc->prepare(tplStorePtr.get());
+
+ RecoverableTransaction::shared_ptr dtx;
+ if (!incomplTplTxnFlag) dtx = registry.recoverTransaction(xid, txn);
+ if (i->enqueues.get()) {
+ for (LockedMappings::iterator j = i->enqueues->begin(); j != i->enqueues->end(); j++) {
+ tpcc->addXidRecord(queues[j->first]->getExternalQueueStore());
+ if (!incomplTplTxnFlag) dtx->enqueue(queues[j->first], messages[j->second]);
+ }
+ }
+ if (i->dequeues.get()) {
+ for (LockedMappings::iterator j = i->dequeues->begin(); j != i->dequeues->end(); j++) {
+ tpcc->addXidRecord(queues[j->first]->getExternalQueueStore());
+ if (!incomplTplTxnFlag) dtx->dequeue(queues[j->first], messages[j->second]);
+ }
+ }
+
+ if (incomplTplTxnFlag) {
+ tpcc->complete(citr->second.commit_flag);
+ }
+ } else {
+ // Local (1PC) transaction
+ boost::shared_ptr<TxnCtxt> opcc(new TxnCtxt(xid, &messageIdSequence));
+ opcc->recoverDtok(citr->second.rid, xid);
+ opcc->prepare(tplStorePtr.get());
+
+ if (i->enqueues.get()) {
+ for (LockedMappings::iterator j = i->enqueues->begin(); j != i->enqueues->end(); j++) {
+ opcc->addXidRecord(queues[j->first]->getExternalQueueStore());
+ }
+ }
+ if (i->dequeues.get()) {
+ for (LockedMappings::iterator j = i->dequeues->begin(); j != i->dequeues->end(); j++) {
+ opcc->addXidRecord(queues[j->first]->getExternalQueueStore());
+ }
+ }
+ if (incomplTplTxnFlag) {
+ opcc->complete(citr->second.commit_flag);
+ } else {
+ completed(*opcc.get(), citr->second.commit_flag);
+ }
+ }
+ }
+ registry.recoveryComplete();
+}
+
+void MessageStoreImpl::recoverQueues(TxnCtxt& txn,
+ RecoveryManager& registry,
+ queue_index& queue_index,
+ txn_list& prepared,
+ message_index& messages)
+{
+ Cursor queues;
+ queues.open(queueDb, txn.get());
+
+ u_int64_t maxQueueId(1);
+
+ IdDbt key;
+ Dbt value;
+ //read all queues
+ while (queues.next(key, value)) {
+ Buffer buffer(reinterpret_cast<char*>(value.get_data()), value.get_size());
+ //create a Queue instance
+ RecoverableQueue::shared_ptr queue = registry.recoverQueue(buffer);
+ //set the persistenceId and update max as required
+ queue->setPersistenceId(key.id);
+
+ const char* queueName = queue->getName().c_str();
+ JournalImpl* jQueue = 0;
+ {
+ qpid::sys::Mutex::ScopedLock sl(jrnlCreateLock);
+ jQueue = new JournalImpl(queueName, getJrnlDir(queueName), std::string("JournalData"), defJournalGetEventsTimeout, defJournalFlushTimeout);
+ }
+ queue->setExternalQueueStore(dynamic_cast<ExternalQueueStore*>(jQueue));
+
+ try
+ {
+ u_int64_t thisHighestRid = 0;
+ jQueue->recover(numJrnlFiles, jrnlFsizeSblks, wCacheNumPages, wCachePgSizeSblks, &prepared, thisHighestRid, key.id); // start recovery
+ if (thisHighestRid > highestRid)
+ highestRid = thisHighestRid;
+ recoverMessages(txn, registry, queue, prepared, messages);
+ jQueue->recover_complete(); // start journal.
+ } catch (const journal::jexception& e) {
+ THROW_STORE_EXCEPTION(std::string("Queue ") + queueName + ": recoverQueues() failed: " + e.what());
+ }
+ //read all messages: done on a per queue basis if using Journal
+
+ queue_index[key.id] = queue;
+ maxQueueId = max(key.id, maxQueueId);
+ }
+
+ // NOTE: highestRid is set by both recoverQueues() and recoverTplStore() as
+ // the messageIdSequence is used for both queue journals and the tpl journal.
+ messageIdSequence.reset(highestRid + 1);
+
+ queueIdSequence.reset(maxQueueId + 1);
+}
+
+
+void MessageStoreImpl::recoverExchanges(TxnCtxt& txn,
+ RecoveryManager& registry,
+ exchange_index& index)
+{
+ //TODO: this is a copy&paste from recoverQueues - refactor!
+ Cursor exchanges;
+ exchanges.open(exchangeDb, txn.get());
+
+ u_int64_t maxExchangeId(1);
+ IdDbt key;
+ Dbt value;
+ //read all exchanges
+ while (exchanges.next(key, value)) {
+ Buffer buffer(reinterpret_cast<char*>(value.get_data()), value.get_size());
+ //create a Exchange instance
+ RecoverableExchange::shared_ptr exchange = registry.recoverExchange(buffer);
+ //set the persistenceId and update max as required
+ exchange->setPersistenceId(key.id);
+ index[key.id] = exchange;
+ maxExchangeId = max(key.id, maxExchangeId);
+ }
+ exchangeIdSequence.reset(maxExchangeId + 1);
+}
+
+void MessageStoreImpl::recoverBindings(TxnCtxt& txn,
+ exchange_index& exchanges,
+ queue_index& queues)
+{
+ Cursor bindings;
+ bindings.open(bindingDb, txn.get());
+
+ IdDbt key;
+ Dbt value;
+ while (bindings.next(key, value)) {
+ Buffer buffer(reinterpret_cast<char*>(value.get_data()), value.get_size());
+ if (buffer.available() < 8) {
+ QPID_LOG(error, "Not enough data for binding: " << buffer.available());
+ THROW_STORE_EXCEPTION("Not enough data for binding");
+ }
+ uint64_t queueId = buffer.getLongLong();
+ std::string queueName;
+ std::string routingkey;
+ FieldTable args;
+ buffer.getShortString(queueName);
+ buffer.getShortString(routingkey);
+ buffer.get(args);
+ exchange_index::iterator exchange = exchanges.find(key.id);
+ queue_index::iterator queue = queues.find(queueId);
+ if (exchange != exchanges.end() && queue != queues.end()) {
+ //could use the recoverable queue here rather than the name...
+ exchange->second->bind(queueName, routingkey, args);
+ } else {
+ //stale binding, delete it
+ QPID_LOG(warning, "Deleting stale binding");
+ bindings->del(0);
+ }
+ }
+}
+
+void MessageStoreImpl::recoverGeneral(TxnCtxt& txn,
+ RecoveryManager& registry)
+{
+ Cursor items;
+ items.open(generalDb, txn.get());
+
+ u_int64_t maxGeneralId(1);
+ IdDbt key;
+ Dbt value;
+ //read all items
+ while (items.next(key, value)) {
+ Buffer buffer(reinterpret_cast<char*>(value.get_data()), value.get_size());
+ //create instance
+ RecoverableConfig::shared_ptr config = registry.recoverConfig(buffer);
+ //set the persistenceId and update max as required
+ config->setPersistenceId(key.id);
+ maxGeneralId = max(key.id, maxGeneralId);
+ }
+ generalIdSequence.reset(maxGeneralId + 1);
+}
+
+void MessageStoreImpl::recoverMessages(TxnCtxt& /*txn*/,
+ qpid::broker::RecoveryManager& recovery,
+ qpid::broker::RecoverableQueue::shared_ptr& queue,
+ txn_list& prepared,
+ message_index& messages)
+{
+ size_t preambleLength = sizeof(u_int32_t)/*header size*/;
+
+ JournalImpl* jc = static_cast<JournalImpl*>(queue->getExternalQueueStore());
+ DataTokenImpl dtok;
+ size_t readSize = 0;
+ unsigned msg_count = 0;
+
+ // TODO: This optimization to skip reading if there are no enqueued messages to read
+ // breaks the python system test in phase 6 with "Exception: Cannot write lock file"
+ // Figure out what is breaking.
+ //bool read = jc->get_enq_cnt() > 0;
+ bool read = true;
+
+ void* dbuff = NULL; size_t dbuffSize = 0;
+ void* xidbuff = NULL; size_t xidbuffSize = 0;
+ bool transientFlag = false;
+ bool externalFlag = false;
+
+ dtok.set_wstate(DataTokenImpl::ENQ);
+
+ // Read the message from the Journal.
+ try {
+ unsigned aio_sleep_cnt = 0;
+ while (read) {
+ rhm::journal::iores res = jc->read_data_record(&dbuff, dbuffSize, &xidbuff, xidbuffSize, transientFlag, externalFlag, &dtok);
+ readSize = dtok.dsize();
+
+ switch (res)
+ {
+ case rhm::journal::RHM_IORES_SUCCESS: {
+ msg_count++;
+ RecoverableMessage::shared_ptr msg;
+ char* data = (char*)dbuff;
+
+ unsigned headerSize;
+ if (externalFlag) {
+ msg = getExternMessage(recovery, dtok.rid(), headerSize); // large message external to jrnl
+ } else {
+ headerSize = Buffer(data, preambleLength).getLong();
+ Buffer headerBuff(data+ preambleLength, headerSize); /// do we want read size or header size ????
+ msg = recovery.recoverMessage(headerBuff);
+ }
+ msg->setPersistenceId(dtok.rid());
+
+ u_int32_t contentOffset = headerSize + preambleLength;
+ u_int64_t contentSize = readSize - contentOffset;
+ if (msg->loadContent(contentSize) && !externalFlag) {
+ //now read the content
+ Buffer contentBuff(data + contentOffset, contentSize);
+ msg->decodeContent(contentBuff);
+ }
+
+ PreparedTransaction::list::iterator i = PreparedTransaction::getLockedPreparedTransaction(prepared, queue->getPersistenceId(), dtok.rid());
+ if (i == prepared.end()) { // not in prepared list
+ queue->recover(msg);
+ } else {
+ u_int64_t rid = dtok.rid();
+ std::string xid(i->xid);
+ TplRecoverMapCitr citr = tplRecoverMap.find(xid);
+ if (citr == tplRecoverMap.end()) THROW_STORE_EXCEPTION("XID not found in tplRecoverMap");
+
+ // deq present in prepared list, this xid is part of incomplete txn commit/abort
+ // or this is a 1PC txn that must be rolled forward
+ if (citr->second.deq_flag || !citr->second.tpc_flag) {
+ if (jc->is_enqueued(rid, true)) {
+ // Enqueue is non-tx, dequeue tx
+ assert(jc->is_locked(rid)); // This record MUST be locked by a txn dequeue
+ if (!citr->second.commit_flag) {
+ queue->recover(msg); // recover message in abort case only
+ }
+ } else {
+ // Enqueue and/or dequeue tx
+ journal::txn_map& tmap = jc->get_txn_map();
+ journal::txn_data_list txnList = tmap.get_tdata_list(xid);
+ bool enq = false;
+ bool deq = false;
+ for (journal::tdl_itr j = txnList.begin(); j<txnList.end(); j++) {
+ if (j->_enq_flag && j->_rid == rid) enq = true;
+ else if (!j->_enq_flag && j->_drid == rid) deq = true;
+ }
+ if (enq && !deq && citr->second.commit_flag) {
+ queue->recover(msg); // recover txn message in commit case only
+ }
+ }
+ } else {
+ messages[rid] = msg;
+ }
+ }
+
+ dtok.reset();
+ dtok.set_wstate(DataTokenImpl::ENQ);
+
+ if (xidbuff)
+ ::free(xidbuff);
+ else if (dbuff)
+ ::free(dbuff);
+ aio_sleep_cnt = 0;
+ break;
+ }
+ case rhm::journal::RHM_IORES_PAGE_AIOWAIT:
+ if (++aio_sleep_cnt > MAX_AIO_SLEEPS)
+ THROW_STORE_EXCEPTION("Timeout waiting for AIO in MessageStoreImpl::recoverMessages()");
+ ::usleep(AIO_SLEEP_TIME);
+ break;
+ case rhm::journal::RHM_IORES_EMPTY:
+ read = false;
+ break; // done with all messages. (add call in jrnl to test that _emap is empty.)
+ default:
+ assert("Store Error: Unexpected msg state");
+ } // switch
+ } // while
+ } catch (const journal::jexception& e) {
+ THROW_STORE_EXCEPTION(std::string("Queue ") + queue->getName() +
+ ": recoverMessages() failed: " + e.what());
+ }
+}
+
+RecoverableMessage::shared_ptr MessageStoreImpl::getExternMessage(qpid::broker::RecoveryManager& recovery,
+ uint64_t messageId,
+ unsigned& headerSize)
+{
+ RecoverableMessage::shared_ptr ret;
+ Dbt key (&messageId, sizeof(messageId));
+ size_t preamble_length = sizeof(u_int32_t); /*header size*/
+
+ BufferValue value(preamble_length, 0);
+ value.buffer.record();
+
+ TxnCtxt txn;
+ txn.begin(env, true);
+ try {
+ if (messageDb.get(txn.get(), &key, &value, 0) == DB_NOTFOUND) {
+ txn.abort();
+ THROW_STORE_EXCEPTION("Cannot load content. Message not known to store!");
+ }
+
+ //read header only to begin with
+ headerSize = value.buffer.getLong();
+
+ BufferValue header(headerSize, preamble_length);
+ if (messageDb.get(txn.get(), &key, &header, 0) == DB_NOTFOUND) {
+ txn.abort();
+ THROW_STORE_EXCEPTION("Cannot load content. Message not known to store!");
+ }
+ ret = recovery.recoverMessage(header.buffer);
+ txn.commit();
+ } catch (const DbException& e) {
+ txn.abort();
+ THROW_STORE_EXCEPTION("Unexpected BDB error in MessageStoreImpl::getExternMessage(): " + std::string(e.what()));
+ } catch (...) {
+ txn.abort();
+ throw;
+ }
+ return ret;
+}
+
+int MessageStoreImpl::enqueueMessage(TxnCtxt& txn,
+ IdDbt& msgId,
+ RecoverableMessage::shared_ptr& msg,
+ queue_index& index,
+ txn_list& prepared,
+ message_index& messages)
+{
+ Cursor mappings;
+ mappings.open(mappingDb, txn.get());
+
+ IdDbt value;
+
+ int count(0);
+ for (int status = mappings->get(&msgId, &value, DB_SET); status == 0; status = mappings->get(&msgId, &value, DB_NEXT_DUP)) {
+ if (index.find(value.id) == index.end()) {
+ QPID_LOG(warning, "Recovered message for queue that no longer exists");
+ mappings->del(0);
+ } else {
+ RecoverableQueue::shared_ptr queue = index[value.id];
+ if (PreparedTransaction::isLocked(prepared, value.id, msgId.id)) {
+ messages[msgId.id] = msg;
+ } else {
+ queue->recover(msg);
+ }
+ count++;
+ }
+ }
+ mappings.close();
+ return count;
+}
+
+void MessageStoreImpl::readTplStore()
+{
+ tplRecoverMap.clear();
+ journal::txn_map& tmap = tplStorePtr->get_txn_map();
+ DataTokenImpl dtok;
+ void* dbuff = NULL; size_t dbuffSize = 0;
+ void* xidbuff = NULL; size_t xidbuffSize = 0;
+ bool transientFlag = false;
+ bool externalFlag = false;
+ bool done = false;
+ try {
+ unsigned aio_sleep_cnt = 0;
+ while (!done) {
+ dtok.reset();
+ dtok.set_wstate(DataTokenImpl::ENQ);
+ switch (tplStorePtr->read_data_record(&dbuff, dbuffSize, &xidbuff, xidbuffSize, transientFlag, externalFlag, &dtok)) {
+ case rhm::journal::RHM_IORES_SUCCESS: {
+ // Every TPL record contains both data and an XID
+ assert(dbuffSize>0);
+ assert(xidbuffSize>0);
+ std::string xid(static_cast<const char*>(xidbuff), xidbuffSize);
+ bool is2PC = *(static_cast<char*>(dbuff)) != 0;
+
+ // Check transaction details; add to recover map
+ journal::txn_data_list txnList = tmap.get_tdata_list(xid);
+ unsigned enqCnt = 0;
+ unsigned deqCnt = 0;
+ u_int64_t rid = 0;
+
+ // Assume commit (roll forward) in cases where only prepare has been called - ie only enqueue record exists.
+ // Note: will apply to both 1PC and 2PC transactions.
+ bool commitFlag = true;
+
+ for (journal::tdl_itr j = txnList.begin(); j<txnList.end(); j++) {
+ if (j->_enq_flag) {
+ rid = j->_rid;
+ enqCnt++;
+ } else {
+ commitFlag = j->_commit_flag;
+ deqCnt++;
+ }
+ }
+ assert(enqCnt == 1);
+ assert(deqCnt <= 1);
+ tplRecoverMap.insert(TplRecoverMapPair(xid, TplRecoverStruct(rid, deqCnt == 1, commitFlag, is2PC)));
+
+ ::free(xidbuff);
+ aio_sleep_cnt = 0;
+ break;
+ }
+ case rhm::journal::RHM_IORES_PAGE_AIOWAIT:
+ if (++aio_sleep_cnt > MAX_AIO_SLEEPS)
+ THROW_STORE_EXCEPTION("Timeout waiting for AIO in MessageStoreImpl::recoverTplStore()");
+ ::usleep(AIO_SLEEP_TIME);
+ break;
+ case rhm::journal::RHM_IORES_EMPTY:
+ done = true;
+ break; // done with all messages. (add call in jrnl to test that _emap is empty.)
+ default:
+ assert("Store Error: Unexpected msg state");
+ } // switch
+ }
+ } catch (const journal::jexception& e) {
+ THROW_STORE_EXCEPTION(std::string("TPL recoverTplStore() failed: ") + e.what());
+ }
+}
+
+void MessageStoreImpl::recoverTplStore()
+{
+ if (journal::jdir::exists(tplStorePtr->jrnl_dir() + tplStorePtr->base_filename() + ".jinf")) {
+ u_int64_t thisHighestRid;
+ tplStorePtr->recover(tplNumJrnlFiles, tplJrnlFsizeSblks, tplWCachePgSizeSblks, tplWCacheNumPages, 0, thisHighestRid, 0);
+ if (thisHighestRid > highestRid)
+ highestRid = thisHighestRid;
+
+ // Load tplRecoverMap by reading the TPL store
+ readTplStore();
+
+ tplStorePtr->recover_complete(); // start journal.
+ }
+}
+
+void MessageStoreImpl::recoverLockedMappings(txn_list& txns)
+{
+ if (!tplStorePtr->is_ready())
+ recoverTplStore();
+
+ // Abort unprepaired xids and populate the locked maps
+ for (TplRecoverMapCitr i = tplRecoverMap.begin(); i != tplRecoverMap.end(); i++) {
+ LockedMappings::shared_ptr enq_ptr;
+ enq_ptr.reset(new LockedMappings);
+ LockedMappings::shared_ptr deq_ptr;
+ deq_ptr.reset(new LockedMappings);
+ txns.push_back(new PreparedTransaction(i->first, enq_ptr, deq_ptr));
+ }
+}
+
+void MessageStoreImpl::collectPreparedXids(std::set<std::string>& xids)
+{
+ if (tplStorePtr->is_ready()) {
+ tplStorePtr->read_reset();
+ readTplStore();
+ } else {
+ recoverTplStore();
+ }
+ for (TplRecoverMapCitr i = tplRecoverMap.begin(); i != tplRecoverMap.end(); i++) {
+ // Discard all txns that are to be rolled forward/back and 1PC transactions
+ if (!i->second.deq_flag && i->second.tpc_flag)
+ xids.insert(i->first);
+ }
+}
+
+void MessageStoreImpl::stage(const intrusive_ptr<PersistableMessage>& msg)
+{
+ checkInit();
+ TxnCtxt txn;
+ txn.begin(env, true);
+
+ u_int64_t messageId (msg->getPersistenceId());
+ if (messageId == 0 || !msg->isContentReleased()) {
+ try {
+ Dbt key (&messageId, sizeof(messageId));
+ messageId = messageIdSequence.next();
+ store(NULL, &txn, key, msg, true);
+ msg->setPersistenceId(messageId);
+ txn.commit();
+ } catch (...) {
+ txn.abort();
+ throw;
+ }
+ }
+}
+
+void MessageStoreImpl::destroy(PersistableMessage& msg)
+{
+ checkInit();
+ u_int64_t messageId (msg.getPersistenceId());
+ if (messageId) {
+ Dbt key (&messageId, sizeof(messageId));
+ TxnCtxt txn;
+ txn.begin(env, true);
+ try {
+ deleteIfUnused(txn.get(), key);
+ txn.commit();
+ } catch (const DbException& e) {
+ txn.abort();
+ THROW_STORE_EXCEPTION_2("Error destroying message", e);
+ } catch (...) {
+ txn.abort();
+ throw;
+ }
+ }
+}
+
+u_int64_t MessageStoreImpl::getRecordSize(Db& db,
+ Dbt& key)
+{
+ u_int64_t ret = 0;
+ TxnCtxt txn;
+ txn.begin(env, true);
+ try {
+ ret = getRecordSize(txn.get(), db, key);
+ txn.commit();
+ } catch (...) {
+ txn.abort();
+ throw;
+ }
+ return ret;
+}
+
+u_int64_t MessageStoreImpl::getRecordSize(DbTxn* txn,
+ Db& db,
+ Dbt& key)
+{
+ Dbt peek;
+ peek.set_flags(DB_DBT_USERMEM);
+ peek.set_ulen(0);
+ try {
+ int status = db.get(txn, &key, &peek, 0);
+ if (status != DB_BUFFER_SMALL) {
+ THROW_STORE_EXCEPTION("Unexpected status code when determining record length: " + std::string(DbEnv::strerror(status)));
+ }
+ } catch (const DbMemoryException& expected) {
+ //api doc indicates may throw exception instead of status = DB_BUFFER_SMALL;
+ }
+ return peek.get_size();
+}
+
+void MessageStoreImpl::appendContent(const intrusive_ptr<const PersistableMessage>& msg,
+ const std::string& data)
+{
+ checkInit();
+ u_int64_t messageId (msg->getPersistenceId());
+ if (messageId != 0) {
+ TxnCtxt txn;
+ txn.begin(env, true);
+ try {
+ Dbt key (&messageId, sizeof(messageId));
+ u_int64_t offset = getRecordSize(messageDb, key);
+ const int size(data.length());
+
+ //don't want to have to copy this and shouldn't need to as
+ //it will be used for reading only. but have to cast away
+ //the const-ness, which is nasty...
+ //alternative involves copying:
+ //char buffer[size];
+ //data.copy(buffer, size);
+ Dbt value((void*) data.data(), size);
+ value.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);
+ value.set_doff(offset);
+ value.set_dlen(size);
+ messageDb.put(txn.get(), &key, &value, 0);
+ txn.commit();
+ } catch (const DbException& e) {
+ txn.abort();
+ THROW_STORE_EXCEPTION_2("Error appending content", e);
+ } catch (...) {
+ txn.abort();
+ throw;
+ }
+ } else {
+ THROW_STORE_EXCEPTION("Cannot append content. Message not known to store!");
+ }
+}
+
+void MessageStoreImpl::loadContent(const qpid::broker::PersistableQueue& queue,
+ const intrusive_ptr<const PersistableMessage>& msg,
+ std::string& data,
+ u_int64_t offset,
+ u_int32_t length)
+{
+ checkInit();
+ u_int64_t realOffset = offset + sizeof(u_int32_t)/*header length*/ + msg->encodedHeaderSize();
+ u_int64_t messageId (msg->getPersistenceId());
+
+ if (messageId != 0) {
+ try {
+ JournalImpl* jc = static_cast<JournalImpl*>(queue.getExternalQueueStore());
+ if (jc && jc->is_enqueued(messageId) ) {
+ if (jc->loadMsgContent(messageId, data, realOffset, length)) {
+ return;
+ }
+ }
+ } catch (const journal::jexception& e) {
+ THROW_STORE_EXCEPTION(std::string("Queue ") + queue.getName() +
+ ": loadContent() failed: " + e.what());
+ }
+ TxnCtxt txn;
+ txn.begin(env, true);
+ try {
+ Dbt key (&messageId, sizeof(messageId));
+ char *buffer = new char[length];
+ Dbt value(buffer, length);
+ value.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);
+ value.set_ulen(length);
+ value.set_doff(realOffset);
+ value.set_dlen(length);
+ int status = messageDb.get(txn.get(), &key, &value, 0);
+ if (status == DB_NOTFOUND) {
+ delete [] buffer;
+ THROW_STORE_EXCEPTION("Cannot load content. Message not known to store!");
+ }
+ data.assign(buffer, value.get_size());
+ delete [] buffer;
+ txn.commit();
+ } catch (const DbException& e) {
+ txn.abort();
+ THROW_STORE_EXCEPTION_2("Error loading content", e);
+ } catch (...) {
+ txn.abort();
+ throw;
+ }
+ } else {
+ THROW_STORE_EXCEPTION("Cannot load content. Message not known to store!");
+ }
+}
+
+void MessageStoreImpl::flush(const qpid::broker::PersistableQueue& queue)
+{
+ if (queue.getExternalQueueStore() == 0) return;
+ checkInit();
+ std::string qn = queue.getName();
+ try {
+ JournalImpl* jc = static_cast<JournalImpl*>(queue.getExternalQueueStore());
+ if (jc) {
+ // TODO: check if this result should be used...
+ /*rhm::journal::iores res =*/ jc->flush();
+ }
+ } catch (const journal::jexception& e) {
+ THROW_STORE_EXCEPTION(std::string("Queue ") + qn + ": flush() failed: " + e.what() );
+ }
+}
+
+void MessageStoreImpl::enqueue(TransactionContext* ctxt,
+ const intrusive_ptr<PersistableMessage>& msg,
+ const PersistableQueue& queue)
+{
+ checkInit();
+ u_int64_t queueId (queue.getPersistenceId());
+ u_int64_t messageId (msg->getPersistenceId());
+ if (queueId == 0) {
+ THROW_STORE_EXCEPTION("Queue not created: " + queue.getName());
+ }
+ Dbt key (&messageId, sizeof(messageId));
+
+ TxnCtxt implicit;
+ TxnCtxt* txn = 0;
+ if (ctxt) {
+ txn = check(ctxt);
+ } else {
+ txn = &implicit;
+ }
+
+ bool newId = false;
+ if (messageId == 0) {
+ messageId = messageIdSequence.next();
+ msg->setPersistenceId(messageId);
+ newId = true;
+ }
+ store(&queue, txn, key, msg, newId);
+
+ // add queue* to the txn map..
+ if (ctxt) txn->addXidRecord(queue.getExternalQueueStore());
+}
+
+void MessageStoreImpl::store(const PersistableQueue* queue,
+ TxnCtxt* txn, Dbt& messageId,
+ const intrusive_ptr<PersistableMessage>& message,
+ bool newId)
+{
+ u_int32_t headerSize = message->encodedHeaderSize();
+ u_int64_t size = message->encodedSize() + sizeof(u_int32_t);
+ char* buff = 0;
+ if (!message->isContentReleased() )
+ {
+ buff = static_cast<char*>(::alloca(size)); // long + headers + content
+ Buffer buffer(buff,size);
+ buffer.putLong(headerSize);
+ message->encode(buffer);
+ }
+
+ try {
+ if (queue) {
+ boost::intrusive_ptr<DataTokenImpl> dtokp(new DataTokenImpl);
+ dtokp->addRef();
+ dtokp->setSourceMessage(message);
+ dtokp->set_external_rid(true);
+ dtokp->set_rid(message->getPersistenceId()); // set the messageID into the Journal header (record-id)
+
+ JournalImpl* jc = static_cast<JournalImpl*>(queue->getExternalQueueStore());
+ if (txn->getXid().empty()) {
+ if (message->isContentReleased()) {
+ jc->enqueue_extern_data_record(size, dtokp.get(), false);
+ } else {
+ jc->enqueue_data_record(buff, size, size, dtokp.get(), false);
+ }
+ } else {
+ if (message->isContentReleased()) {
+ jc->enqueue_extern_txn_data_record(size, dtokp.get(), txn->getXid(), false);
+ } else {
+ jc->enqueue_txn_data_record(buff, size, size, dtokp.get(), txn->getXid(), false);
+ }
+ }
+ } else {
+ /// cct message db
+ if (newId) { // only store in Bd if first time message is stored
+ Dbt data(buff,size);
+ messageDb.put(txn->get(), &messageId, &data, DB_NOOVERWRITE);
+ }
+ }
+ } catch (const journal::jexception& e) {
+ THROW_STORE_EXCEPTION(std::string("Queue ") + queue->getName() + ": store() failed: " +
+ e.what());
+ }
+}
+
+void MessageStoreImpl::dequeue(TransactionContext* ctxt,
+ const intrusive_ptr<PersistableMessage>& msg,
+ const PersistableQueue& queue)
+{
+ checkInit();
+ u_int64_t queueId (queue.getPersistenceId());
+ u_int64_t messageId (msg->getPersistenceId());
+ if (messageId == 0) {
+ THROW_STORE_EXCEPTION("Error dequeing message, persistence id not set");
+ }
+ if (queueId == 0) {
+ THROW_STORE_EXCEPTION("Queue not created: " + queue.getName());
+ }
+
+ TxnCtxt implicit;
+ TxnCtxt* txn = 0;
+ if (ctxt) {
+ txn = check(ctxt);
+ } else {
+ txn = &implicit;
+ }
+
+ // add queue* to the txn map..
+ if (ctxt) txn->addXidRecord(queue.getExternalQueueStore());
+ async_dequeue(ctxt, msg, queue);
+
+ msg->dequeueComplete();
+}
+
+void MessageStoreImpl::async_dequeue(TransactionContext* ctxt,
+ const intrusive_ptr<PersistableMessage>& msg,
+ const PersistableQueue& queue)
+{
+ boost::intrusive_ptr<DataTokenImpl> ddtokp(new DataTokenImpl);
+ ddtokp->addRef();
+ ddtokp->setSourceMessage(msg);
+ ddtokp->set_external_rid(true);
+ ddtokp->set_rid(messageIdSequence.next());
+ ddtokp->set_dequeue_rid(msg->getPersistenceId());
+ ddtokp->set_wstate(DataTokenImpl::ENQ);
+ std::string tid;
+ if (ctxt) {
+ TxnCtxt* txn = check(ctxt);
+ tid = txn->getXid();
+ }
+ try {
+ JournalImpl* jc = static_cast<JournalImpl*>(queue.getExternalQueueStore());
+ if (tid.empty()) {
+ jc->dequeue_data_record(ddtokp.get());
+ } else {
+ jc->dequeue_txn_data_record(ddtokp.get(), tid);
+ }
+ } catch (const journal::jexception& e) {
+ THROW_STORE_EXCEPTION(std::string("Queue ") + queue.getName() + ": async_dequeue() failed: " + e.what());
+ }
+}
+
+u_int32_t MessageStoreImpl::outstandingQueueAIO(const qpid::broker::PersistableQueue& /*queue*/)
+{
+ checkInit();
+ return 0;
+}
+
+bool MessageStoreImpl::deleteIfUnused(DbTxn* txn,
+ Dbt& messageId)
+{
+ Cursor cursor;
+ cursor.open(mappingDb, txn);
+ return deleteIfUnused(cursor, txn, messageId);
+}
+
+bool MessageStoreImpl::deleteIfUnused(Cursor& cursor,
+ DbTxn* txn,
+ Dbt& messageId)
+{
+ if (isUnused(cursor, messageId)) {
+ messageDb.del(txn, &messageId, 0);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool MessageStoreImpl::isUnused(Cursor& cursor, Dbt& messageId)
+{
+ Dbt empty;
+ int status = cursor->get(&messageId, &empty, DB_SET);
+ if (status == DB_NOTFOUND) {
+ return true;
+ } else if (status == 0) {
+ return false;
+ } else {
+ THROW_STORE_EXCEPTION("Dequeue failed (in isUnused()) with status = " + status);
+ }
+}
+
+void MessageStoreImpl::completed(TxnCtxt& txn,
+ bool commit)
+{
+ try {
+ chkTplStoreInit(); // Late initialize (if needed)
+
+ // Nothing to do if not prepared
+ if (txn.getDtok()->is_enqueued()) {
+ txn.incrDtokRef();
+ DataTokenImpl* dtokp = txn.getDtok();
+ dtokp->set_dequeue_rid(dtokp->rid());
+ dtokp->set_rid(messageIdSequence.next());
+ tplStorePtr->dequeue_txn_data_record(txn.getDtok(), txn.getXid(), commit);
+ }
+ txn.complete(commit);
+ if (mgmtObject != 0) {
+ mgmtObject->dec_tplTransactionDepth();
+ if (commit)
+ mgmtObject->inc_tplTxnCommits();
+ else
+ mgmtObject->inc_tplTxnAborts();
+ }
+ } catch (const std::exception& e) {
+ QPID_LOG(error, "Error completing xid " << txn.getXid() << ": " << e.what());
+ throw;
+ }
+}
+
+auto_ptr<TransactionContext> MessageStoreImpl::begin()
+{
+ checkInit();
+ // pass sequence number for c/a
+ return auto_ptr<TransactionContext>(new TxnCtxt(&messageIdSequence));
+}
+
+std::auto_ptr<qpid::broker::TPCTransactionContext> MessageStoreImpl::begin(const std::string& xid)
+{
+ checkInit();
+ IdSequence* jtx = &messageIdSequence;
+ // pass sequence number for c/a
+ return auto_ptr<TPCTransactionContext>(new TPCTxnCtxt(xid, jtx));
+}
+
+void MessageStoreImpl::prepare(qpid::broker::TPCTransactionContext& ctxt)
+{
+ checkInit();
+ TxnCtxt* txn = dynamic_cast<TxnCtxt*>(&ctxt);
+ if(!txn) throw InvalidTransactionContextException();
+ localPrepare(txn);
+}
+
+void MessageStoreImpl::localPrepare(TxnCtxt* ctxt)
+{
+ try {
+ chkTplStoreInit(); // Late initialize (if needed)
+
+ // This sync is requred to ensure multi-queue atomicity - ie all txn data
+ // must hit the disk on *all* queues before the TPL prepare (enq) is written.
+ ctxt->sync();
+
+ ctxt->incrDtokRef();
+ DataTokenImpl* dtokp = ctxt->getDtok();
+ dtokp->set_external_rid(true);
+ dtokp->set_rid(messageIdSequence.next());
+ char tpcFlag = static_cast<char>(ctxt->isTPC());
+ tplStorePtr->enqueue_txn_data_record(&tpcFlag, sizeof(char), sizeof(char), dtokp, ctxt->getXid(), false);
+ ctxt->prepare(tplStorePtr.get());
+ // make sure all the data is written to disk before returning
+ ctxt->sync();
+ if (mgmtObject != 0) {
+ mgmtObject->inc_tplTransactionDepth();
+ mgmtObject->inc_tplTxnPrepares();
+ }
+ } catch (const std::exception& e) {
+ QPID_LOG(error, "Error preparing xid " << ctxt->getXid() << ": " << e.what());
+ throw;
+ }
+}
+
+void MessageStoreImpl::commit(TransactionContext& ctxt)
+{
+ checkInit();
+ TxnCtxt* txn(check(&ctxt));
+ if (!txn->isTPC()) {
+ if (txn->impactedQueuesEmpty()) return;
+ localPrepare(dynamic_cast<TxnCtxt*>(txn));
+ }
+ completed(*dynamic_cast<TxnCtxt*>(txn), true);
+}
+
+void MessageStoreImpl::abort(TransactionContext& ctxt)
+{
+ checkInit();
+ TxnCtxt* txn(check(&ctxt));
+ if (!txn->isTPC()) {
+ if (txn->impactedQueuesEmpty()) return;
+ localPrepare(dynamic_cast<TxnCtxt*>(txn));
+ }
+ completed(*dynamic_cast<TxnCtxt*>(txn), false);
+}
+
+TxnCtxt* MessageStoreImpl::check(TransactionContext* ctxt)
+{
+ TxnCtxt* txn = dynamic_cast<TxnCtxt*>(ctxt);
+ if(!txn) throw InvalidTransactionContextException();
+ return txn;
+}
+
+void MessageStoreImpl::put(Db& db,
+ DbTxn* txn,
+ Dbt& key,
+ Dbt& value)
+{
+ try {
+ int status = db.put(txn, &key, &value, DB_NODUPDATA);
+ if (status == DB_KEYEXIST) {
+ THROW_STORE_EXCEPTION("duplicate data");
+ } else if (status) {
+ THROW_STORE_EXCEPTION(DbEnv::strerror(status));
+ }
+ } catch (const DbException& e) {
+ THROW_STORE_EXCEPTION(e.what());
+ }
+}
+
+bool MessageStoreImpl::deleteKeyValuePair(Db& db,
+ DbTxn* txn,
+ Dbt& key,
+ Dbt& value)
+{
+ Cursor cursor;
+ cursor.open(db, txn);
+ int status = cursor->get(&key, &value, DB_GET_BOTH | DB_RMW);
+ if (status == 0) {
+ cursor->del(0);
+ return true;
+ } else if (status == DB_NOTFOUND) {
+ return false;
+ } else {
+ THROW_STORE_EXCEPTION("Deletion failed: " + std::string(DbEnv::strerror(status)));
+ }
+}
+
+void MessageStoreImpl::deleteBindingsForQueue(const PersistableQueue& queue)
+{
+ TxnCtxt txn;
+ txn.begin(env, true);
+ try {
+ {
+ Cursor bindings;
+ bindings.open(bindingDb, txn.get());
+
+ IdDbt key;
+ Dbt value;
+ while (bindings.next(key, value)) {
+ Buffer buffer(reinterpret_cast<char*>(value.get_data()), value.get_size());
+ if (buffer.available() < 8) {
+ THROW_STORE_EXCEPTION("Not enough data for binding");
+ }
+ uint64_t queueId = buffer.getLongLong();
+ if (queue.getPersistenceId() == queueId) {
+ bindings->del(0);
+ QPID_LOG(debug, "Deleting binding for " << queue.getName() << " " << key.id << "->" << queueId);
+ }
+ }
+ }
+ txn.commit();
+ } catch (const std::exception& e) {
+ txn.abort();
+ THROW_STORE_EXCEPTION_2("Error deleting bindings", e.what());
+ } catch (...) {
+ txn.abort();
+ throw;
+ }
+ QPID_LOG(debug, "Deleted all bindings for " << queue.getName() << ":" << queue.getPersistenceId());
+}
+
+void MessageStoreImpl::deleteBinding(const PersistableExchange& exchange,
+ const PersistableQueue& queue,
+ const std::string& bkey)
+{
+ TxnCtxt txn;
+ txn.begin(env, true);
+ try {
+ {
+ Cursor bindings;
+ bindings.open(bindingDb, txn.get());
+
+ IdDbt key(exchange.getPersistenceId());
+ Dbt value;
+
+ for (int status = bindings->get(&key, &value, DB_SET); status == 0; status = bindings->get(&key, &value, DB_NEXT_DUP)) {
+ Buffer buffer(reinterpret_cast<char*>(value.get_data()), value.get_size());
+ if (buffer.available() < 8) {
+ THROW_STORE_EXCEPTION("Not enough data for binding");
+ }
+ uint64_t queueId = buffer.getLongLong();
+ if (queue.getPersistenceId() == queueId) {
+ std::string q;
+ std::string k;
+ buffer.getShortString(q);
+ buffer.getShortString(k);
+ if (bkey == k) {
+ bindings->del(0);
+ QPID_LOG(debug, "Deleting binding for " << queue.getName() << " " << key.id << "->" << queueId);
+ }
+ }
+ }
+ }
+ txn.commit();
+ } catch (const std::exception& e) {
+ txn.abort();
+ THROW_STORE_EXCEPTION_2("Error deleting bindings", e.what());
+ } catch (...) {
+ txn.abort();
+ throw;
+ }
+}
+
+std::string MessageStoreImpl::getJrnlBaseDir()
+{
+ std::stringstream dir;
+ dir << storeDir << "/rhm/jrnl/" ;
+ return dir.str();
+}
+
+std::string MessageStoreImpl::getBdbBaseDir()
+{
+ std::stringstream dir;
+ dir << storeDir << "/rhm/dat/" ;
+ return dir.str();
+}
+
+std::string MessageStoreImpl::getTplBaseDir()
+{
+ std::stringstream dir;
+ dir << storeDir << "/rhm/tpl/" ;
+ return dir.str();
+}
+
+std::string MessageStoreImpl::getJrnlDir(const qpid::broker::PersistableQueue& queue) //for exmaple /var/rhm/ + queueDir/
+{
+ return getJrnlDir(queue.getName().c_str());
+}
+
+std::string MessageStoreImpl::getJrnlDir(const char* queueName) //for exmaple /var/rhm/ + queueDir/
+{
+ std::stringstream dir;
+ dir << getJrnlBaseDir() << std::hex << std::setfill('0') << std::setw(4);
+ u_int32_t count = 0;
+ for (u_int32_t i = 0; i < strlen(queueName); i++) {
+ count += queueName[i];
+ }
+ dir << (count % 29); // Use a prime number for better distribution across dirs
+ dir << "/" << queueName << "/";
+ return dir.str();
+}
+
+MessageStoreImpl::Options::Options(const std::string& name) :
+ qpid::Options(name),
+ numJrnlFiles(defNumJrnlFiles),
+ jrnlFsizePgs(defJrnlFileSizePgs),
+ wCachePageSizeKib(defWCachePageSize),
+ tplNumJrnlFiles(defTplNumJrnlFiles),
+ tplJrnlFsizePgs(defTplJrnlFileSizePgs),
+ tplWCachePageSizeKib(defTplWCachePageSize)
+{
+ addOptions()
+ ("store-dir", qpid::optValue(storeDir, "DIR"),
+ "Store directory location for persistence (instead of using --data-dir value). "
+ "Must be supplied if --no-data-dir is also used.")
+ ("num-jfiles", qpid::optValue(numJrnlFiles, "N"),
+ "Default number of files for each journal instance")
+ ("jfile-size-pgs", qpid::optValue(jrnlFsizePgs, "N"),
+ "Default size for each journal file in multiples of read pages (1 read page = 64kiB)")
+ ("wcache-page-size", qpid::optValue(wCachePageSizeKib, "N"),
+ "Size of the pages in the write page cache in KiB. "
+ "Allowable values - powers of 2: 1, 2, 4, ... , 128. "
+ "Lower values decrease latency at the expense of throughput.")
+ ("tpl-num-jfiles", qpid::optValue(tplNumJrnlFiles, "N"),
+ "Number of files for transaction prepared list journal instance")
+ ("tpl-jfile-size-pgs", qpid::optValue(tplJrnlFsizePgs, "N"),
+ "Size of each transaction prepared list journal file in multiples of read pages (1 read page = 64kiB)")
+ ("tpl-wcache-page-size", qpid::optValue(tplWCachePageSizeKib, "N"),
+ "Size of the pages in the transaction prepared list write page cache in KiB. "
+ "Allowable values - powers of 2: 1, 2, 4, ... , 128. "
+ "Lower values decrease latency at the expense of throughput.")
+ ;
+}
Copied: store/trunk/cpp/lib/MessageStoreImpl.h (from rev 2432, store/trunk/cpp/lib/BdbMessageStore.h)
===================================================================
--- store/trunk/cpp/lib/MessageStoreImpl.h (rev 0)
+++ store/trunk/cpp/lib/MessageStoreImpl.h 2008-09-09 19:25:47 UTC (rev 2433)
@@ -0,0 +1,348 @@
+/*
+ Copyright (C) 2007 Red Hat Software
+
+ 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 _MessageStoreImpl_
+#define _MessageStoreImpl_
+
+#include <string>
+
+#include "db-inc.h"
+#include "Cursor.h"
+#include "IdDbt.h"
+#include "IdSequence.h"
+#include "JournalImpl.h"
+#include "jrnl/jcfg.hpp"
+#include "PreparedTransaction.h"
+#include "qpid/broker/Broker.h"
+#include "qpid/broker/MessageStore.h"
+#include "qpid/management/Manageable.h"
+#include "Store.h"
+#include "TxnCtxt.h"
+
+// Assume DB_VERSION_MAJOR == 4
+#if (DB_VERSION_MINOR == 2)
+#include <errno.h>
+#define DB_BUFFER_SMALL ENOMEM
+#endif
+
+namespace rhm {
+namespace bdbstore {
+
+/**
+ * An implementation of the MessageStore interface based on Berkeley DB
+ */
+class MessageStoreImpl : public qpid::broker::MessageStore, public qpid::management::Manageable
+{
+ protected:
+ typedef std::map<u_int64_t, qpid::broker::RecoverableQueue::shared_ptr> queue_index;
+ typedef std::map<u_int64_t, qpid::broker::RecoverableExchange::shared_ptr> exchange_index;
+ typedef std::map<u_int64_t, qpid::broker::RecoverableMessage::shared_ptr> message_index;
+
+ typedef LockedMappings::map txn_lock_map;
+ typedef boost::ptr_list<PreparedTransaction> txn_list;
+
+ // Structs for Transaction Recover List (TPL) recover state
+ struct TplRecoverStruct {
+ u_int64_t rid; // rid of TPL record
+ bool deq_flag;
+ bool commit_flag;
+ bool tpc_flag;
+ TplRecoverStruct(const u_int64_t _rid, const bool _deq_flag, const bool _commit_flag, const bool _tpc_flag);
+ };
+ typedef TplRecoverStruct TplRecover;
+ typedef std::pair<std::string, TplRecover> TplRecoverMapPair;
+ typedef std::map<std::string, TplRecover> TplRecoverMap;
+ typedef TplRecoverMap::const_iterator TplRecoverMapCitr;
+
+ // Default store settings
+ static const u_int16_t defNumJrnlFiles = 8;
+ static const u_int32_t defJrnlFileSizePgs = 24;
+ static const u_int32_t defWCachePageSize = JRNL_WMGR_DEF_PAGE_SIZE * JRNL_DBLK_SIZE * JRNL_SBLK_SIZE / 1024;
+ static const u_int16_t defTplNumJrnlFiles = 8;
+ static const u_int32_t defTplJrnlFileSizePgs = 24;
+ static const u_int32_t defTplWCachePageSize = defWCachePageSize / 8;
+
+ std::list<Db*> dbs;
+ DbEnv env;
+ Db queueDb;
+ Db configDb;
+ Db exchangeDb;
+ Db messageDb;
+ Db mappingDb;
+ Db bindingDb;
+ Db generalDb;
+
+ // Pointer to Transaction Prepared List (TPL) journal instance
+ boost::shared_ptr<TplJournalImpl> tplStorePtr;
+ TplRecoverMap tplRecoverMap;
+
+ IdSequence queueIdSequence;
+ IdSequence exchangeIdSequence;
+ IdSequence generalIdSequence;
+ IdSequence messageIdSequence;
+ std::string storeDir;
+ u_int16_t numJrnlFiles;
+ u_int32_t jrnlFsizeSblks;
+ u_int32_t wCachePgSizeSblks;
+ u_int16_t wCacheNumPages;
+ u_int16_t tplNumJrnlFiles;
+ u_int32_t tplJrnlFsizeSblks;
+ u_int32_t tplWCachePgSizeSblks;
+ u_int16_t tplWCacheNumPages;
+ u_int64_t highestRid;
+ bool isInit;
+ const char* envPath;
+ static qpid::sys::Duration defJournalGetEventsTimeout;
+ static qpid::sys::Duration defJournalFlushTimeout;
+ qpid::management::Store* mgmtObject;
+ qpid::sys::Mutex jrnlCreateLock;
+
+ // Parameter validation and calculation
+ static u_int16_t chkJrnlNumFilesParam(const u_int16_t param,
+ const std::string paramName);
+ static u_int32_t chkJrnlFileSizeParam(const u_int32_t param,
+ const std::string paramName);
+ static u_int32_t chkJrnlWrPageCacheSize(const u_int32_t param,
+ const std::string paramName);
+ static u_int16_t getJrnlWrNumPages(const u_int32_t wrPageSizeKib);
+
+ void recoverQueues(TxnCtxt& txn,
+ qpid::broker::RecoveryManager& recovery,
+ queue_index& index,
+ txn_list& locked,
+ message_index& messages);
+ void recoverMessages(TxnCtxt& txn,
+ qpid::broker::RecoveryManager& recovery,
+ queue_index& index,
+ txn_list& locked,
+ message_index& prepared);
+ void recoverMessages(TxnCtxt& txn,
+ qpid::broker::RecoveryManager& recovery,
+ qpid::broker::RecoverableQueue::shared_ptr& queue,
+ txn_list& locked,
+ message_index& prepared);
+ qpid::broker::RecoverableMessage::shared_ptr getExternMessage(qpid::broker::RecoveryManager& recovery,
+ uint64_t mId,
+ unsigned& headerSize);
+ void recoverExchanges(TxnCtxt& txn,
+ qpid::broker::RecoveryManager& recovery,
+ exchange_index& index);
+ void recoverBindings(TxnCtxt& txn,
+ exchange_index& exchanges,
+ queue_index& queues);
+ void recoverGeneral(TxnCtxt& txn,
+ qpid::broker::RecoveryManager& recovery);
+ int enqueueMessage(TxnCtxt& txn,
+ IdDbt& msgId,
+ qpid::broker::RecoverableMessage::shared_ptr& msg,
+ queue_index& index,
+ txn_list& locked,
+ message_index& prepared);
+ void readTplStore();
+ void recoverTplStore();
+ void recoverLockedMappings(txn_list& txns);
+ TxnCtxt* check(qpid::broker::TransactionContext* ctxt);
+ void store(const qpid::broker::PersistableQueue* queue,
+ TxnCtxt* txn,
+ Dbt& messageId,
+ const boost::intrusive_ptr<qpid::broker::PersistableMessage>& message,
+ bool newId);
+ void async_dequeue(qpid::broker::TransactionContext* ctxt,
+ const boost::intrusive_ptr<qpid::broker::PersistableMessage>& msg,
+ const qpid::broker::PersistableQueue& queue);
+ bool deleteIfUnused(Cursor& cursor,
+ DbTxn* txn,
+ Dbt& messageId);
+ bool deleteIfUnused(DbTxn* txn,
+ Dbt& messageId);
+ bool isUnused(Cursor& cursor,
+ Dbt& messageId);
+ void destroy(Db& db,
+ const qpid::broker::Persistable& p);
+ bool create(Db& db,
+ IdSequence& seq,
+ const qpid::broker::Persistable& p);
+ void completed(TxnCtxt& txn,
+ bool commit);
+ void record2pcOp(Db& db,
+ TPCTxnCtxt& txn,
+ u_int64_t messageId,
+ u_int64_t queueId);
+ void deleteBindingsForQueue(const qpid::broker::PersistableQueue& queue);
+ void deleteBinding(const qpid::broker::PersistableExchange& exchange,
+ const qpid::broker::PersistableQueue& queue,
+ const std::string& key);
+
+ u_int64_t getRecordSize(Db& db,
+ Dbt& key);
+ u_int64_t getRecordSize(DbTxn* txn,
+ Db& db,
+ Dbt& key);
+ void put(Db& db,
+ DbTxn* txn,
+ Dbt& key,
+ Dbt& value);
+ bool deleteKeyValuePair(Db& db,
+ DbTxn* txn,
+ Dbt& key,
+ Dbt& value);
+ void open(Db& db,
+ DbTxn* txn,
+ const char* file,
+ bool dupKey);
+
+ // journal functions
+ void createJrnlQueue(const qpid::broker::PersistableQueue& queue);
+ std::string getJrnlDir(const qpid::broker::PersistableQueue& queue); //for exmaple /var/rhm/ + queueDir/
+ std::string getJrnlDir(const char* queueName);
+ std::string getJrnlBaseDir();
+ std::string getBdbBaseDir();
+ std::string getTplBaseDir();
+ inline void checkInit() {
+ // TODO: change the default dir to ~/.qpidd
+ if (!isInit) init("/tmp", defNumJrnlFiles, defJrnlFileSizePgs, defWCachePageSize); isInit = true;
+ }
+ void chkTplStoreInit();
+
+ // debug aid for printing XIDs that may contain non-printable chars
+ static std::string xid2str(const std::string xid) {
+ std::ostringstream oss;
+ oss << std::hex << std::setfill('0');
+ for (unsigned i=0; i<xid.size(); i++) {
+ if (isprint(xid[i]))
+ oss << xid[i];
+ else
+ oss << "/" << std::setw(2) << (int)((char)xid[i]);
+ }
+ return oss.str();
+ }
+
+ public:
+ struct Options : public qpid::Options {
+ Options(const std::string& name="Store Options");
+ std::string clusterName;
+ std::string storeDir;
+ u_int16_t numJrnlFiles;
+ u_int32_t jrnlFsizePgs;
+ u_int32_t wCachePageSizeKib;
+ u_int16_t tplNumJrnlFiles;
+ u_int32_t tplJrnlFsizePgs;
+ u_int32_t tplWCachePageSizeKib;
+ };
+
+ typedef boost::shared_ptr<MessageStoreImpl> shared_ptr;
+
+ MessageStoreImpl(const char* envpath = 0);
+
+ virtual ~MessageStoreImpl();
+
+ bool init(const qpid::Options* options);
+
+ bool init(const std::string& dir,
+ u_int16_t jfiles = defNumJrnlFiles,
+ u_int32_t jfileSizePgs = defJrnlFileSizePgs,
+ u_int32_t wCachePageSize = defWCachePageSize,
+ u_int16_t tplJfiles = defTplNumJrnlFiles,
+ u_int32_t tplJfileSizePgs = defTplJrnlFileSizePgs,
+ u_int32_t tplWCachePageSize = defTplWCachePageSize);
+
+ void initManagement (qpid::broker::Broker* broker);
+
+ void truncate();
+
+ void create(qpid::broker::PersistableQueue& queue,
+ const qpid::framing::FieldTable& args);
+
+ void destroy(qpid::broker::PersistableQueue& queue);
+
+ void create(const qpid::broker::PersistableExchange& queue,
+ const qpid::framing::FieldTable& args);
+
+ void destroy(const qpid::broker::PersistableExchange& queue);
+
+ void bind(const qpid::broker::PersistableExchange& exchange,
+ const qpid::broker::PersistableQueue& queue,
+ const std::string& key,
+ const qpid::framing::FieldTable& args);
+
+ void unbind(const qpid::broker::PersistableExchange& exchange,
+ const qpid::broker::PersistableQueue& queue,
+ const std::string& key,
+ const qpid::framing::FieldTable& args);
+
+ void create(const qpid::broker::PersistableConfig& config);
+
+ void destroy(const qpid::broker::PersistableConfig& config);
+
+ void recover(qpid::broker::RecoveryManager& queues);
+
+ void stage(const boost::intrusive_ptr<qpid::broker::PersistableMessage>& msg);
+
+ void destroy(qpid::broker::PersistableMessage& msg);
+
+ void appendContent(const boost::intrusive_ptr<const qpid::broker::PersistableMessage>& msg,
+ const std::string& data);
+
+ void loadContent(const qpid::broker::PersistableQueue& queue,
+ const boost::intrusive_ptr<const qpid::broker::PersistableMessage>& msg,
+ std::string& data,
+ u_int64_t offset,
+ u_int32_t length);
+
+ void enqueue(qpid::broker::TransactionContext* ctxt,
+ const boost::intrusive_ptr<qpid::broker::PersistableMessage>& msg,
+ const qpid::broker::PersistableQueue& queue);
+
+ void dequeue(qpid::broker::TransactionContext* ctxt,
+ const boost::intrusive_ptr<qpid::broker::PersistableMessage>& msg,
+ const qpid::broker::PersistableQueue& queue);
+
+ void flush(const qpid::broker::PersistableQueue& queue);
+
+ u_int32_t outstandingQueueAIO(const qpid::broker::PersistableQueue& queue);
+
+ void collectPreparedXids(std::set<std::string>& xids);
+
+ std::auto_ptr<qpid::broker::TransactionContext> begin();
+
+ std::auto_ptr<qpid::broker::TPCTransactionContext> begin(const std::string& xid);
+
+ void prepare(qpid::broker::TPCTransactionContext& ctxt);
+
+ void localPrepare(TxnCtxt* ctxt);
+
+ void commit(qpid::broker::TransactionContext& ctxt);
+
+ void abort(qpid::broker::TransactionContext& ctxt);
+
+ qpid::management::ManagementObject* GetManagementObject (void) const
+ { return mgmtObject; }
+
+ inline qpid::management::Manageable::status_t ManagementMethod (u_int32_t, qpid::management::Args&)
+ { return qpid::management::Manageable::STATUS_OK; }
+}; // class MessageStoreImpl
+
+} // namespace bdbstore
+} // namespace rhm
+
+#endif
Modified: store/trunk/cpp/lib/StorePlugin.cpp
===================================================================
--- store/trunk/cpp/lib/StorePlugin.cpp 2008-09-09 13:39:28 UTC (rev 2432)
+++ store/trunk/cpp/lib/StorePlugin.cpp 2008-09-09 19:25:47 UTC (rev 2433)
@@ -25,7 +25,7 @@
#include "qpid/Plugin.h"
#include "qpid/Options.h"
#include "qpid/DataDir.h"
-#include "BdbMessageStore.h"
+#include "MessageStoreImpl.h"
namespace qpid {
@@ -35,7 +35,7 @@
struct StorePlugin : public Plugin {
- rhm::bdbstore::BdbMessageStore::Options options;
+ rhm::bdbstore::MessageStoreImpl::Options options;
MessageStore *store;
Options* getOptions() { return &options; }
@@ -43,7 +43,7 @@
void earlyInitialize (Plugin::Target& target)
{
Broker* broker = dynamic_cast<Broker*>(&target);
- store = new rhm::bdbstore::BdbMessageStore ();
+ store = new rhm::bdbstore::MessageStoreImpl ();
DataDir& dataDir = broker->getDataDir ();
if (options.storeDir.empty ())
@@ -60,7 +60,7 @@
void initialize(Plugin::Target& target)
{
Broker* broker = dynamic_cast<Broker*>(&target);
- ((rhm::bdbstore::BdbMessageStore*) store)->initManagement (broker);
+ ((rhm::bdbstore::MessageStoreImpl*) store)->initManagement (broker);
}
};
Modified: store/trunk/cpp/tests/OrderingTest.cpp
===================================================================
--- store/trunk/cpp/tests/OrderingTest.cpp 2008-09-09 13:39:28 UTC (rev 2432)
+++ store/trunk/cpp/tests/OrderingTest.cpp 2008-09-09 19:25:47 UTC (rev 2433)
@@ -27,7 +27,7 @@
#include "unit_test.h"
-#include "BdbMessageStore.h"
+#include "MessageStoreImpl.h"
#include <iostream>
#include "MessageUtils.h"
#include <qpid/broker/Queue.h>
@@ -47,7 +47,7 @@
// === Helper fns ===
const string name("OrderingQueue");
-std::auto_ptr<BdbMessageStore> store;
+std::auto_ptr<MessageStoreImpl> store;
QueueRegistry queues;
Queue::shared_ptr queue;
std::queue<Uuid> ids;
@@ -55,7 +55,7 @@
void setup()
{
- store = std::auto_ptr<BdbMessageStore>(new BdbMessageStore());
+ store = std::auto_ptr<MessageStoreImpl>(new MessageStoreImpl());
store->init(test_dir, 4, 1, 8);
store->truncate();
@@ -93,7 +93,7 @@
queue.reset();
store.reset();
- store = std::auto_ptr<BdbMessageStore>(new BdbMessageStore());
+ store = std::auto_ptr<MessageStoreImpl>(new MessageStoreImpl());
store->init(test_dir, 4, 1, 8);
ExchangeRegistry exchanges;
LinkRegistry links(0);
Modified: store/trunk/cpp/tests/SimpleTest.cpp
===================================================================
--- store/trunk/cpp/tests/SimpleTest.cpp 2008-09-09 13:39:28 UTC (rev 2432)
+++ store/trunk/cpp/tests/SimpleTest.cpp 2008-09-09 19:25:47 UTC (rev 2433)
@@ -27,7 +27,7 @@
#include "unit_test.h"
-#include "BdbMessageStore.h"
+#include "MessageStoreImpl.h"
#include <iostream>
#include "MessageUtils.h"
#include <qpid/broker/Queue.h>
@@ -60,7 +60,7 @@
}
};
-void recover(BdbMessageStore& store, QueueRegistry& queues, ExchangeRegistry& exchanges, LinkRegistry& links)
+void recover(MessageStoreImpl& store, QueueRegistry& queues, ExchangeRegistry& exchanges, LinkRegistry& links)
{
DtxManager mgr;
mgr.setStore (&store);
@@ -68,14 +68,14 @@
store.recover(recovery);
}
-void recover(BdbMessageStore& store, ExchangeRegistry& exchanges)
+void recover(MessageStoreImpl& store, ExchangeRegistry& exchanges)
{
QueueRegistry queues;
LinkRegistry links(0);
recover(store, queues, exchanges, links);
}
-void recover(BdbMessageStore& store, QueueRegistry& queues)
+void recover(MessageStoreImpl& store, QueueRegistry& queues)
{
ExchangeRegistry exchanges;
LinkRegistry links(0);
@@ -86,7 +86,7 @@
const string& key, const FieldTable& args)
{
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
store.truncate();//make sure it is empty to begin with
Exchange::shared_ptr exchange(new DirectExchange(exchangeName, true, args));
@@ -97,7 +97,7 @@
store.bind(*exchange, *queue, key, args);
}//db will be closed
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
ExchangeRegistry exchanges;
QueueRegistry queues;
@@ -112,7 +112,7 @@
store.unbind(*exchange, *queue, key, args);
}
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
ExchangeRegistry exchanges;
QueueRegistry queues;
@@ -134,7 +134,7 @@
{
cout << test_filename << ".CreateDelete: " << flush;
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
store.truncate();//make sure it is empty to begin with
string name("CreateDeleteQueue");
@@ -152,7 +152,7 @@
{
cout << test_filename << ".EmptyRecover: " << flush;
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
store.truncate();//make sure it is empty to begin with
QueueRegistry registry;
@@ -170,7 +170,7 @@
uint64_t id(0);
string name("MyDurableQueue");
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
store.truncate();//make sure it is empty to begin with
Queue queue(name, 0, &store, 0);
@@ -179,7 +179,7 @@
id = queue.getPersistenceId();
}//db will be closed
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
QueueRegistry registry;
registry.setStore (&store);
@@ -199,7 +199,7 @@
QueuePolicy policy(101, 202);
string name("MyDurableQueue");
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
store.truncate();//make sure it is empty to begin with
Queue queue(name, 0, &store, 0);
@@ -209,7 +209,7 @@
BOOST_REQUIRE(queue.getPersistenceId());
}//db will be closed
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
QueueRegistry registry;
registry.setStore (&store);
@@ -230,7 +230,7 @@
string name("MyDurableQueue");
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
store.truncate();//make sure it is empty to begin with
Queue queue(name, 0, &store, 0);
@@ -238,7 +238,7 @@
store.destroy(queue);
}//db will be closed
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
QueueRegistry registry;
registry.setStore (&store);
@@ -264,7 +264,7 @@
string data1("abcdefg");
string data2("hijklmn");
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
store.truncate();//make sure it is empty to begin with
Queue::shared_ptr queue(new Queue(name, 0, &store, 0));
@@ -283,7 +283,7 @@
queue->enqueue(0, msg);
}//db will be closed
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
QueueRegistry registry;
registry.setStore (&store);
@@ -324,7 +324,7 @@
string routingKey("MyRoutingKey");
Uuid messageId(true);
string data("abcdefg");
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
store.truncate();//make sure it is empty to begin with
Queue::shared_ptr queue(new Queue(name, 0, &store, 0));
@@ -339,7 +339,7 @@
queue->dequeue(0, msg);
}//db will be closed
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
QueueRegistry registry;
registry.setStore (&store);
@@ -363,7 +363,7 @@
const string data1("abcdefghijklmnopqrstuvwxyz");
const string data2("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
store.truncate();//make sure it is empty to begin with
@@ -405,7 +405,7 @@
}//db will be closed
{
//recover
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
QueueRegistry registry;
registry.setStore (&store);
@@ -457,7 +457,7 @@
{
cout << test_filename << ".DestroyStagedMessage: " << flush;
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
store.truncate();//make sure it is empty to begin with
@@ -485,7 +485,7 @@
{
cout << test_filename << ".DestroyEnqueuedMessage: " << flush;
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
store.truncate();//make sure it is empty to begin with
@@ -521,7 +521,7 @@
FieldTable args;
args.setString("a", "A");
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
store.truncate();//make sure it is empty to begin with
ExchangeRegistry registry;
@@ -531,7 +531,7 @@
BOOST_REQUIRE(id);
}//db will be closed
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
ExchangeRegistry registry;
@@ -545,7 +545,7 @@
store.destroy(*exchange);
}
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
ExchangeRegistry registry;
@@ -593,7 +593,7 @@
string key("my-routing-key");
FieldTable args;
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
store.truncate();//make sure it is empty to begin with
Exchange::shared_ptr exchange(new DirectExchange(exchangeName, true, args));
@@ -608,7 +608,7 @@
store.destroy(*queue1);
}//db will be closed
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
ExchangeRegistry exchanges;
QueueRegistry queues;
@@ -625,7 +625,7 @@
store.destroy(*exchange);
}
{
- BdbMessageStore store;
+ MessageStoreImpl store;
store.init(test_dir, 4, 1, 8);
ExchangeRegistry exchanges;
QueueRegistry queues;
Modified: store/trunk/cpp/tests/TransactionalTest.cpp
===================================================================
--- store/trunk/cpp/tests/TransactionalTest.cpp 2008-09-09 13:39:28 UTC (rev 2432)
+++ store/trunk/cpp/tests/TransactionalTest.cpp 2008-09-09 19:25:47 UTC (rev 2433)
@@ -27,7 +27,7 @@
#include "unit_test.h"
-#include "BdbMessageStore.h"
+#include "MessageStoreImpl.h"
#include <iostream>
#include "MessageUtils.h"
#include "qpid/broker/Queue.h"
@@ -61,10 +61,10 @@
// Test store which has sepcial begin() which returns a TestTPCTxnCtxt, and a method to check for
// reamining open transactions
-class TestMessageStore: public BdbMessageStore
+class TestMessageStore: public MessageStoreImpl
{
public:
- TestMessageStore(const char* envpath = 0) : BdbMessageStore(envpath) {}
+ TestMessageStore(const char* envpath = 0) : MessageStoreImpl(envpath) {}
std::auto_ptr<qpid::broker::TransactionContext> begin() {
checkInit();
// pass sequence number for c/a
@@ -96,7 +96,7 @@
const string nameA("queueA");
const string nameB("queueB");
//const Uuid messageId(true);
-std::auto_ptr<BdbMessageStore> store;
+std::auto_ptr<MessageStoreImpl> store;
std::auto_ptr<QueueRegistry> queues;
Queue::shared_ptr queueA;
Queue::shared_ptr queueB;
@@ -159,7 +159,7 @@
void swap(bool commit)
{
- setup<BdbMessageStore>();
+ setup<MessageStoreImpl>();
//create message and enqueue it onto first queue:
boost::intrusive_ptr<Message> msgA = createMessage("Message", "exchange", "routing_key");
@@ -177,7 +177,7 @@
store->abort(*txn);
}
- restart<BdbMessageStore>();
+ restart<MessageStoreImpl>();
// Check outcome
BOOST_REQUIRE(queueA);
Modified: store/trunk/cpp/tests/TwoPhaseCommitTest.cpp
===================================================================
--- store/trunk/cpp/tests/TwoPhaseCommitTest.cpp 2008-09-09 13:39:28 UTC (rev 2432)
+++ store/trunk/cpp/tests/TwoPhaseCommitTest.cpp 2008-09-09 19:25:47 UTC (rev 2433)
@@ -27,7 +27,7 @@
#include "unit_test.h"
-#include "BdbMessageStore.h"
+#include "MessageStoreImpl.h"
#include <iostream>
#include "MessageUtils.h"
#include "qpid/broker/Queue.h"
@@ -175,10 +175,10 @@
// Test store which has sepcial begin() which returns a TestTPCTxnCtxt, and a method to check for
// reamining open transactions
- class TestMessageStore: public BdbMessageStore
+ class TestMessageStore: public MessageStoreImpl
{
public:
- TestMessageStore(const char* envpath = 0) : BdbMessageStore(envpath) {}
+ TestMessageStore(const char* envpath = 0) : MessageStoreImpl(envpath) {}
std::auto_ptr<qpid::broker::TPCTransactionContext> begin(const std::string& xid) {
checkInit();
IdSequence* jtx = &messageIdSequence;
@@ -195,7 +195,7 @@
const string nameA;
const string nameB;
- std::auto_ptr<BdbMessageStore> store;
+ std::auto_ptr<MessageStoreImpl> store;
std::auto_ptr<DtxManager> dtxmgr;
std::auto_ptr<QueueRegistry> queues;
std::auto_ptr<LinkRegistry> links;
@@ -207,14 +207,14 @@
void recoverPrepared(bool commit)
{
- setup<BdbMessageStore>();
+ setup<MessageStoreImpl>();
Swap swap(this, "RecoverPrepared");
swap.init();
std::auto_ptr<TPCTransactionContext> txn(store->begin("my-xid"));
swap.run(txn.get());
store->prepare(*txn);
- restart<BdbMessageStore>();
+ restart<MessageStoreImpl>();
//check that the message is not available from either queue
BOOST_CHECK_EQUAL((u_int32_t) 0, queueA->getMessageCount());
@@ -228,7 +228,7 @@
}
swap.check(commit);
- restart<BdbMessageStore>();
+ restart<MessageStoreImpl>();
swap.check(commit);
}
@@ -256,27 +256,27 @@
void commit(Strategy& strategy)
{
- setup<BdbMessageStore>();
+ setup<MessageStoreImpl>();
strategy.init();
std::auto_ptr<TPCTransactionContext> txn(store->begin("my-xid"));
strategy.run(txn.get());
store->prepare(*txn);
store->commit(*txn);
- restart<BdbMessageStore>();
+ restart<MessageStoreImpl>();
strategy.check(true);
}
void abort(Strategy& strategy, bool prepare)
{
- setup<BdbMessageStore>();
+ setup<MessageStoreImpl>();
strategy.init();
std::auto_ptr<TPCTransactionContext> txn(store->begin("my-xid"));
strategy.run(txn.get());
if (prepare) store->prepare(*txn);
store->abort(*txn);
- restart<BdbMessageStore>();
+ restart<MessageStoreImpl>();
strategy.check(false);
}
17 years, 7 months
rhmessaging commits: r2432 - store/trunk/cpp.
by rhmessaging-commits@lists.jboss.org
Author: kpvdr
Date: 2008-09-09 09:39:28 -0400 (Tue, 09 Sep 2008)
New Revision: 2432
Modified:
store/trunk/cpp/configure.ac
Log:
Added version 4.7 to list of BDB libs searched during configure for rawhide (F10)
Modified: store/trunk/cpp/configure.ac
===================================================================
--- store/trunk/cpp/configure.ac 2008-09-09 12:19:01 UTC (rev 2431)
+++ store/trunk/cpp/configure.ac 2008-09-09 13:39:28 UTC (rev 2432)
@@ -117,14 +117,14 @@
AC_SUBST([LIB_DLOPEN])
LIBS=$gl_saved_libs
-# Require libdb_cxx (any version between 4.2 and 4.6), for the library, and for db_cxx.h.
+# Require libdb_cxx (any version between 4.2 and 4.7), for the library, and for db_cxx.h.
db4_devel_fail=0
AC_CHECK_HEADER([db_cxx.h], ,[db4_devel_fail=1])
test $db4_devel_fail == 1 && \
AC_MSG_ERROR([db4-devel package missing. Please ensure both db4 and db4-devel are installed. (hint: "yum install db4-devel" should do it...)])
gl_saved_libs=$LIBS
-AC_SEARCH_LIBS([__db_open], [db_cxx-4.6 db_cxx-4.5 db_cxx-4.4 db_cxx-4.3 db_cxx-4.2],
+AC_SEARCH_LIBS([__db_open], [db_cxx-4.7 db_cxx-4.6 db_cxx-4.5 db_cxx-4.4 db_cxx-4.3 db_cxx-4.2],
[test "$ac_cv_search___db_open" = "none required" ||
LIB_BERKELEY_DB=$ac_cv_search___db_open],
AC_MSG_ERROR([Couldn't find required library in range db_cxx-4.2 through db_cxx-4.6]))
17 years, 7 months
rhmessaging commits: r2431 - in store/branches/java/broker-queue-refactor/java: bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb and 4 other directories.
by rhmessaging-commits@lists.jboss.org
Author: aidanskinner
Date: 2008-09-09 08:19:01 -0400 (Tue, 09 Sep 2008)
New Revision: 2431
Added:
store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/MessageReSendTest.java
store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/QueueDeleteWhilstRoutingTest.java
store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/StoreContextRaceConditionTest.java
store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/utils/BDBVMTestCase.java
store/branches/java/broker-queue-refactor/java/bdbstore/test-provider.properties
Removed:
store/branches/java/broker-queue-refactor/java/bdbstorebackup/ReadMe.txt
store/branches/java/broker-queue-refactor/java/bdbstorebackup/bin/bdbstorebackup.sh
store/branches/java/broker-queue-refactor/java/bdbstorebackup/pom.xml
store/branches/java/broker-queue-refactor/java/bdbstorebackup/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBBackup.java
Modified:
store/branches/java/broker-queue-refactor/java/bdbstore/build.xml
store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBStoreTest.java
Log:
Merge all changes from M2.x branch and remove common code from tests. Remove dead bdbstorebackup directory.
Modified: store/branches/java/broker-queue-refactor/java/bdbstore/build.xml
===================================================================
--- store/branches/java/broker-queue-refactor/java/bdbstore/build.xml 2008-09-08 17:09:10 UTC (rev 2430)
+++ store/branches/java/broker-queue-refactor/java/bdbstore/build.xml 2008-09-09 12:19:01 UTC (rev 2431)
@@ -111,10 +111,11 @@
<sysproperty key="example.plugin.target" value="${project.root}/build/lib/plugins"/>
<sysproperty key="QPID_HOME" value="${project.root}"/>
<sysproperty key="QPID_WORK" value="${project.root}/build/test-work"/>
+ <sysproperty key="BDB_WORK" value="${project.root}/build/test-work/bdbstore"/>
<sysproperty key="BDB_HOME" value="${project.root}"/>
+ <sysproperty key="test.excludes" value="false"/>
-
<formatter type="plain"/>
<formatter type="xml"/>
Modified: store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBStoreTest.java
===================================================================
--- store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBStoreTest.java 2008-09-08 17:09:10 UTC (rev 2430)
+++ store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBStoreTest.java 2008-09-09 12:19:01 UTC (rev 2431)
@@ -34,6 +34,7 @@
import org.apache.qpid.server.exchange.DirectExchange;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.store.StoreContext;
+import org.apache.qpid.server.store.berkeleydb.utils.BDBVMTestCase;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.MessageMetaData;
import org.apache.qpid.server.queue.AMQQueueFactory;
@@ -48,12 +49,13 @@
import java.util.LinkedList;
import java.util.List;
-public class BDBStoreTest extends TestCase
+public class BDBStoreTest extends BDBVMTestCase
{
private static final Logger _log = Logger.getLogger(BDBStoreTest.class);
private BDBMessageStore _store;
-
+ private String STORE_LOCATION = System.getProperty("BDB_WORK") + "/bdbTestEnv";
+
private StoreContext _storeContext = new StoreContext();
private VirtualHost _virtualHost;
@@ -67,8 +69,7 @@
private static final AMQShortString EXCHANGE1 = new AMQShortString("exchange1");
private static volatile int _loops;
- private String TEST_LOCATION = "bdbTestEnv";
- File BDB_DIR = new File(TEST_LOCATION);
+ File BDB_DIR = new File(STORE_LOCATION);
public void setUp() throws Exception
{
@@ -79,6 +80,8 @@
ApplicationRegistry.initialise(new NullApplicationRegistry());
+ File bdbDir = new File(STORE_LOCATION);
+ deleteDirectory(bdbDir);
BDB_DIR.mkdirs();
_store = new BDBMessageStore();
@@ -92,28 +95,13 @@
_txnContext = new NonTransactionalContext(_store, _storeContext, null, new LinkedList<RequiredDeliveryException>());
}
- private void deleteDirectory(File path) throws InterruptedException
- {
- if (path.isDirectory())
- {
- for (File file : path.listFiles())
- {
- deleteDirectory(file);
- }
- }
- else
- {
- path.delete();
- }
- }
-
private void reload() throws Exception
{
_virtualHost.close();
PropertiesConfiguration env = new PropertiesConfiguration();
- env.addProperty("store.environment-path", "bdbTestEnv");
+ env.addProperty("store.environment-path", STORE_LOCATION);
env.addProperty("store.class", "org.apache.qpid.server.store.berkeleydb.BDBMessageStore");
_virtualHost = new VirtualHost("test", env);
Added: store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/MessageReSendTest.java
===================================================================
--- store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/MessageReSendTest.java (rev 0)
+++ store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/MessageReSendTest.java 2008-09-09 12:19:01 UTC (rev 2431)
@@ -0,0 +1,112 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.server.store.berkeleydb;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.Queue;
+import javax.jms.Session;
+
+import org.apache.qpid.server.store.berkeleydb.utils.BDBVMTestCase;
+
+public class MessageReSendTest extends BDBVMTestCase
+{
+ protected static final String MESSAGE_ID_PROPERTY = "MessageIDProperty";
+
+ public void test() throws Exception
+ {
+
+ //Send Message
+ sendMessages(getConnection(), 1);
+ System.err.println("SEND");
+
+ //Create Connection
+ Connection connection = getConnection();
+ System.err.println("RECEIVE");
+
+ //Receive Message
+ checkMessagesOnQueue(connection, _queue, 1);
+ //Close connections
+ connection.close();
+ System.err.println("VALIDATE");
+
+ //Reconnect and ensure message is gone
+ connection = getConnection();
+ checkMessagesOnQueue(connection, _queue, 0);
+ connection.close();
+
+ try
+ {
+ //restart broker
+ stopBroker(1);
+ System.err.println("START");
+ startBroker(1);
+ }
+ catch (Exception e)
+ {
+ fail(e.getMessage());
+ }
+
+ //reconnect and ensure message is gone
+ connection = getConnection();
+ checkMessagesOnQueue(connection, _queue, 0);
+ connection.close();
+ }
+
+ private void checkMessagesOnQueue(Connection connection, Queue queue, int count)
+ {
+ try
+ {
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer consumer = session.createConsumer(queue);
+
+ connection.start();
+
+ Message msg = consumer.receive(1000);
+
+ if (count > 0)
+ {
+ int received = 1;
+ while (received < count)
+ {
+ assertNotNull(msg);
+ assertEquals(received, msg.getIntProperty(MESSAGE_ID_PROPERTY));
+
+ //get next message
+ msg = consumer.receive(1000);
+ }
+
+ }
+ else
+ {
+ assertNull("Received Message when none expected", msg);
+ }
+ }
+ catch (JMSException e)
+ {
+ fail(e.getMessage());
+ }
+ }
+
+}
Added: store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/QueueDeleteWhilstRoutingTest.java
===================================================================
--- store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/QueueDeleteWhilstRoutingTest.java (rev 0)
+++ store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/QueueDeleteWhilstRoutingTest.java 2008-09-09 12:19:01 UTC (rev 2431)
@@ -0,0 +1,204 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.store.berkeleydb;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.store.berkeleydb.utils.BDBVMTestCase;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.naming.NamingException;
+import java.io.File;
+
+public class QueueDeleteWhilstRoutingTest extends BDBVMTestCase
+{
+ private static final Logger _logger = Logger.getLogger(QueueDeleteWhilstRoutingTest.class);
+
+ MessageConsumer _consumer1, _consumer2;
+ Session _clientSession1;
+ Connection _producerConnection, _clientConnection1;
+
+ int brokerID = 2;
+
+ /**
+ * Issue analysis:
+ * When an Exclusive NonDurable queue is created a queueDelete task is added to the sessionCloseTaskList
+ * When the last consumer on an autodelete queue closes queueDelete is called.
+ *
+ * Hence the queue is delted twice. Which would hurt the ref counting of all messages in the consumers
+ * unacked map
+ *
+ * Test Plan:
+ *
+ * Create two subscribers same topic
+ *
+ * Send two messages
+ *
+ * consume one from each consumer to validate that all is good
+ *
+ * Shutdown persistent broker
+ *
+ * restart.
+ *
+ * Expecting failure in broker startup.
+ * @throws Exception
+ */
+ public void test() throws Exception
+ {
+ _logger.debug("Performing receives");
+
+ Message msg1 = _consumer1.receive(1000);
+
+ assertNotNull(msg1);
+
+ //Check message recevied ok
+ assertEquals("Message 1 not received on consumer 1", "Message: 1", ((TextMessage) msg1).getText());
+
+ _consumer1.close();
+
+ _clientConnection1.close();
+
+ _producerConnection.close();
+
+ try
+ {
+ _logger.debug("Shutdown broker in 1 second");
+ Thread.sleep(4000);
+ }
+ catch (InterruptedException e)
+ {
+ fail(e.getMessage());
+ }
+
+ //Stop the broker
+ stopBroker(brokerID);
+
+ try
+ {
+ _logger.debug("Restart broker in 2 second");
+ Thread.sleep(4000);
+ }
+ catch (InterruptedException e)
+ {
+ fail(e.getMessage());
+ }
+
+ //Start the broker
+ try
+ {
+ //FIXME startVMBroker(brokerID, _persistentConfigFile);
+ }
+ catch (Exception e)
+ {
+ fail(e.getMessage());
+ }
+
+ //Test Connection
+ _clientConnection1 = getConnection();
+
+ _clientConnection1.close();
+ }
+
+ public void setUp() throws Exception
+ {
+ super.setUp();
+
+ //FIXME startVMBroker(brokerID, _persistentConfigFile);
+
+ // Initialise ACLs.
+
+ //Create Consumers
+ //Create consumer on the temp queue
+ Queue requestQueue = (Queue) getInitialContext().lookup("queue");
+
+ _clientConnection1 = getConnection();
+ _clientSession1 = _clientConnection1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ _queue = _clientSession1.createTemporaryQueue();
+
+ _consumer1 = _clientSession1.createConsumer(_queue);
+
+ //Start the connection
+ _clientConnection1.start();
+
+ //Create Producer
+ _producerConnection = getConnection();
+ final Session producerSession = _producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ //Create a listener for the messages
+ producerSession.createConsumer(requestQueue).setMessageListener(new MessageListener()
+ {
+ public void onMessage(final Message message)
+ {
+ try
+ {
+ Destination responseQueue = message.getJMSReplyTo();
+
+ //Send a response to the message
+ producerSession.createProducer(responseQueue)
+ .send(producerSession.createTextMessage(((TextMessage) message).getText()));
+ }
+ catch (JMSException e)
+ {
+ fail(e.getMessage());
+ }
+ }
+ });
+ //Start the connection
+ _producerConnection.start();
+
+ //Send two messages
+
+ MessageProducer _clientProducer = _clientSession1.createProducer(requestQueue);
+ Message msg = _clientSession1.createTextMessage("Message: 1");
+ msg.setJMSReplyTo(_queue);
+ _clientProducer.send(msg);
+
+ msg = _clientSession1.createTextMessage("Message: 2");
+ msg.setJMSReplyTo(_queue);
+ _clientProducer.send(msg);
+ }
+
+ public void tearDown() throws Exception
+ {
+ //Stop the broker
+ try
+ {
+ stopBroker(brokerID);
+ }
+ catch (Exception e)
+ {
+ fail(e.getMessage());
+ }
+
+ super.tearDown();
+ }
+
+}
Added: store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/StoreContextRaceConditionTest.java
===================================================================
--- store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/StoreContextRaceConditionTest.java (rev 0)
+++ store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/StoreContextRaceConditionTest.java 2008-09-09 12:19:01 UTC (rev 2431)
@@ -0,0 +1,161 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.server.store.berkeleydb;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.MessageConsumer;
+import javax.jms.Session;
+import javax.naming.NamingException;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.store.berkeleydb.utils.BDBVMTestCase;
+
+public class StoreContextRaceConditionTest extends BDBVMTestCase
+{
+ private static final Logger _logger = Logger.getLogger(StoreContextRaceConditionTest.class);
+
+ public void test() throws InterruptedException, NamingException, JMSException
+ {
+ Runnable test = new Runnable()
+ {
+ public void run()
+ {
+
+ //Create Consumer
+ Connection connection = null;
+
+ Session session = null;
+ try
+ {
+ try
+ {
+ connection = getConnection();
+ }
+ catch (Exception e)
+ {
+ fail("Unable to obtain connection.");
+ }
+ session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ }
+ catch (JMSException e)
+ {
+ return;
+ }
+
+ try
+ {
+ int run = 0;
+ while (run < 1)
+ {
+ try
+ {
+ //Stop the connection to prevent flow
+ connection.stop();
+ //Create Consumer to receive msgs
+ MessageConsumer consumer = session.createConsumer(_queue);
+
+ //Send one message to hold up the Async Delivery from purging
+ _logger.info("***** CREATED Consumer");
+ _TimeToLive = 0L;
+ sendMessages(1);
+ _logger.info("***** SENT msg 1");
+ //Send 1000 msgs that will time out
+ _TimeToLive = 1000L;
+ sendMessages(50);
+ _logger.info("***** SENT TTL msgs");
+
+ //Timeout Messages - Note that we
+ Thread.sleep(1000);
+ _logger.info("***** SLEEP");
+
+ //Allw the messages to flow to us
+ connection.start();
+ _logger.info("***** START Consumer");
+ //*** Starts Async process
+
+ //Remove the first message so that the async will occcur and start purging.
+ consumer.receive(1000);
+ _logger.info("***** RECEIVE Consumer");
+
+ sendMessages(50);
+ _logger.info("***** SENT TTL msgs");
+
+ //Close the consumer freeing the QHK thread to doing work
+ consumer.close();
+ _logger.info("***** CLOSE Consumer");
+ //** Allows QueueHouskeeping to run.
+ sendMessages(50);
+ _logger.info("***** SENT TTL msgs");
+
+ run++;
+ }
+ catch (JMSException e)
+ {
+
+ }
+ catch (InterruptedException e)
+ {
+ }
+ }
+ }
+ finally
+ {
+ try
+ {
+ connection.close();
+ }
+ catch (JMSException e)
+ {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+ _logger.info("***** Test Done");
+ }
+ }
+ };
+
+ int MAX_THREADS = 1;
+
+ Thread[] threads = new Thread[MAX_THREADS];
+
+ for (int concurentClients = 0; concurentClients < MAX_THREADS; concurentClients++)
+ {
+ threads[concurentClients] = new Thread(test);
+ threads[concurentClients].start();
+ }
+
+ for (int concurentClients = 0; concurentClients < MAX_THREADS; concurentClients++)
+ {
+ threads[concurentClients].join();
+ }
+ }
+
+ public static void main(String[] args) throws Exception, InterruptedException
+ {
+ StoreContextRaceConditionTest scrc = new StoreContextRaceConditionTest();
+
+ scrc.setUp();
+ scrc.test();
+// scrc.tearDown();
+ }
+
+}
Added: store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/utils/BDBVMTestCase.java
===================================================================
--- store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/utils/BDBVMTestCase.java (rev 0)
+++ store/branches/java/broker-queue-refactor/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/utils/BDBVMTestCase.java 2008-09-09 12:19:01 UTC (rev 2431)
@@ -0,0 +1,170 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.store.berkeleydb.utils;
+
+import java.io.File;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.log4j.Level;
+import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class BDBVMTestCase extends QpidTestCase
+{
+ public static final String BDB_WORK = "BDB_WORK";
+ public static final String QPID_WORK = "QPID_WORK";
+
+ protected String testWork = null;
+
+ protected String BDB_WORK_PRE_TEST;
+ protected String QPID_WORK_PRE_TEST;
+
+ protected final String QpidHome = System.getProperty("QPID_HOME");
+ protected final File _persistentConfigFile = new File(QpidHome, "etc/persistent_config.xml");
+ protected Queue _queue;
+
+ protected long _TimeToLive = 0L;
+ public static final String MESSAGE_ID_PROPERTY = "MessageIDProperty";
+
+ public void setUp() throws Exception
+ {
+ setupWorkDirectory();
+
+ //Create the Broker
+ super.setUp();
+
+ _queue = new AMQQueue("amq.direct", "BDBTestQ");
+ }
+
+ public void tearDown() throws Exception
+ {
+ super.tearDown();
+
+ if (testWork != null)
+ {
+ // Clean up the BDB store
+ deleteDirectory(new File(testWork));
+ testWork = null;
+ }
+
+ //Reset BDB_WORK
+ System.setProperty(BDB_WORK, BDB_WORK_PRE_TEST == null ? "" : BDB_WORK_PRE_TEST);
+
+ //Reset QPID_WORK
+ System.setProperty(QPID_WORK, QPID_WORK_PRE_TEST == null ? "" : QPID_WORK_PRE_TEST);
+ }
+
+ public void setupWorkDirectory()
+ {
+ if (System.getProperty(BDB_WORK) == null)
+ {
+ fail("BDB_WORK required for BDB tests");
+ }
+
+ BDB_WORK_PRE_TEST = System.getProperty(BDB_WORK);
+ QPID_WORK_PRE_TEST = System.getProperty(QPID_WORK);
+
+ //IF BDB_WORK is set but not QPID_WORK then set QPID_WORK to BDB_WORK
+ if (QPID_WORK_PRE_TEST == null && BDB_WORK_PRE_TEST != null)
+ {
+ System.setProperty(QPID_WORK, BDB_WORK_PRE_TEST);
+ }
+ }
+
+ public void startVMBroker(int vmID, ConfigurationFileApplicationRegistry configFile) throws Exception
+ {
+ if (vmID != 1)
+ {
+ testWork = BDB_WORK_PRE_TEST + "-" + vmID;
+ }
+ else
+ {
+ testWork = BDB_WORK_PRE_TEST;
+ }
+ System.setProperty(BDB_WORK, testWork);
+ System.setProperty(QPID_WORK, testWork);
+
+ super.startBroker(vmID, configFile);
+ }
+
+ public boolean deleteDirectory(File dir)
+ {
+ if (dir.isDirectory())
+ {
+ String[] children = dir.list();
+ for (int i = 0; i < children.length; i++)
+ {
+ if (!deleteDirectory(new File(dir, children[i])))
+ {
+ return false;
+ }
+ }
+ }
+
+ return (dir.delete());
+ }
+
+ protected void sendMessages(int num) throws JMSException
+ {
+ Connection producerConnection = null;
+ try
+ {
+ producerConnection = getConnection();
+ }
+ catch (Exception e)
+ {
+ fail("Unable to lookup connection in JNDI.");
+ }
+
+ sendMessages(producerConnection, num);
+ }
+
+ protected void sendMessages(Connection producerConnection, int num) throws JMSException
+ {
+ Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ //Ensure _queue is created
+ producerSession.createConsumer(_queue).close();
+
+ MessageProducer producer = producerSession.createProducer(_queue);
+
+ producer.setTimeToLive(_TimeToLive);
+ producer.setDisableMessageTimestamp(false);
+
+ for (int messsageID = 0; messsageID < num; messsageID++)
+ {
+ TextMessage textMsg = producerSession.createTextMessage("Message " + messsageID);
+ textMsg.setIntProperty(MESSAGE_ID_PROPERTY, messsageID);
+ producer.send(textMsg);
+ }
+
+ producerConnection.close();
+ }
+}
Copied: store/branches/java/broker-queue-refactor/java/bdbstore/test-provider.properties (from rev 2429, store/branches/java/broker-queue-refactor/java/bdbstorebackup/bin/bdbstorebackup.sh)
===================================================================
--- store/branches/java/broker-queue-refactor/java/bdbstore/test-provider.properties (rev 0)
+++ store/branches/java/broker-queue-refactor/java/bdbstore/test-provider.properties 2008-09-09 12:19:01 UTC (rev 2431)
@@ -0,0 +1,34 @@
+#
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#
+
+connectionfactory.vm = amqp://username:password@clientid/test?brokerlist='vm://:1'
+
+connectionfactory.vmfailover = amqp://username:password@clientid/test?brokerlist='vm://:2;vm://:1'
+connectionfactory.connection1 = amqp://username:password@clientid/test?brokerlist='vm://:1'
+connectionfactory.connection2 = amqp://username:password@clientid/test?brokerlist='vm://:2'
+
+
+#queue.MyQueue = example.MyQueue
+queue.queue = example.queue
+#queue.xaQueue = xaQueue
+
+#topic.xaTopic = xaTopic
+#topic.durableSubscriberTopic = durableSubscriberTopic
Property changes on: store/branches/java/broker-queue-refactor/java/bdbstore/test-provider.properties
___________________________________________________________________
Name: svn:eol-style
+ native
Deleted: store/branches/java/broker-queue-refactor/java/bdbstorebackup/ReadMe.txt
===================================================================
--- store/branches/java/broker-queue-refactor/java/bdbstorebackup/ReadMe.txt 2008-09-08 17:09:10 UTC (rev 2430)
+++ store/branches/java/broker-queue-refactor/java/bdbstorebackup/ReadMe.txt 2008-09-09 12:19:01 UTC (rev 2431)
@@ -1,10 +0,0 @@
-Building with Maven
--------------------
-The BerkeleyDB jar will automatically be installed in to your local repository with maven from the
-local mvn-repo. This will occur when you first try and compile the BDB module.
-
-
-Using with Qpid
----------------
-This can be pluged into BDBMessageStore and also as a standalone utility to take a offline backup
-For a offline back up , run the bdbstorebackup.sh script
Deleted: store/branches/java/broker-queue-refactor/java/bdbstorebackup/bin/bdbstorebackup.sh
===================================================================
--- store/branches/java/broker-queue-refactor/java/bdbstorebackup/bin/bdbstorebackup.sh 2008-09-08 17:09:10 UTC (rev 2430)
+++ store/branches/java/broker-queue-refactor/java/bdbstorebackup/bin/bdbstorebackup.sh 2008-09-09 12:19:01 UTC (rev 2431)
@@ -1,44 +0,0 @@
-#!/bin/bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-if [ "$JAVA_HOME" == "" ]; then
- echo "The JAVA_HOME environment variable is not defined";
- exit 0;
-fi
-
-if [ $# -lt 2 ]; then
- echo "Usage: bdbstorebackup.sh -bdbpath <bdb env path> [-virtualhost <virtual host name>]"
- exit 1
-fi
-
-## Add these jars in the classpath
-## je-3.1.0.jar
-## qpid-bdbstorebackup-1.0-incubating-M2-SNAPSHOT.jar
-
-
-CP=../target/qpid-bdbstorebackup-1.0-incubating-M2-SNAPSHOT.jar:../target/je-3.1.0.jar
-
-if [ `uname -o` == "Cygwin" ] ; then
- CP=`cygpath --path --windows $CP`
-fi
-
-##echo $CP
-
-"$JAVA_HOME/bin/java" -cp $CP org.apache.qpid.server.store.berkeleydb.BDBBackup $@
Deleted: store/branches/java/broker-queue-refactor/java/bdbstorebackup/pom.xml
===================================================================
--- store/branches/java/broker-queue-refactor/java/bdbstorebackup/pom.xml 2008-09-08 17:09:10 UTC (rev 2430)
+++ store/branches/java/broker-queue-refactor/java/bdbstorebackup/pom.xml 2008-09-09 12:19:01 UTC (rev 2431)
@@ -1,57 +0,0 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>org.etp.qpid</groupId>
- <artifactId>qpid-bdbstorebackup</artifactId>
- <packaging>jar</packaging>
- <version>1.0-incubating-M2-SNAPSHOT</version>
- <name>Qpid BDB Store Backup</name>
- <url>http://cwiki.apache.org/confluence/display/qpid</url>
-
- <parent>
- <groupId>org.apache.qpid</groupId>
- <artifactId>qpid</artifactId>
- <version>1.0-incubating-M2-SNAPSHOT</version>
- </parent>
-
- <!-- Local repository for the BerkelyDB-je so we don't have to use the installer script -->
- <repositories>
- <repository>
- <id>berkley-je.local</id>
- <name>Local BerkelyDB JE Repository</name>
- <url>file://${basedir}/mvn-repo</url>
- </repository>
- </repositories>
-
- <dependencies>
- <dependency>
- <groupId>sleepycat</groupId>
- <artifactId>berkeleydb-je</artifactId>
- <version>3.1.0</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.1</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-</project>
Deleted: store/branches/java/broker-queue-refactor/java/bdbstorebackup/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBBackup.java
===================================================================
--- store/branches/java/broker-queue-refactor/java/bdbstorebackup/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBBackup.java 2008-09-08 17:09:10 UTC (rev 2430)
+++ store/branches/java/broker-queue-refactor/java/bdbstorebackup/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBBackup.java 2008-09-09 12:19:01 UTC (rev 2431)
@@ -1,199 +0,0 @@
-/*
- *
- * Copyright (c) 2006 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-package org.apache.qpid.server.store.berkeleydb;
-
-import com.sleepycat.je.util.DbBackup;
-import com.sleepycat.je.EnvironmentConfig;
-import com.sleepycat.je.Environment;
-import com.sleepycat.je.DatabaseException;
-
-import java.io.*;
-import java.util.Date;
-import java.text.SimpleDateFormat;
-
-/**
- * This class uses the DbBackup class to take a backup of bdb logfiles.
- */
-public class BDBBackup
-{
- private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");//("yyyyMMddHHmmss");
- //TODO : to be decided what should be the root dir. It can be another parameter in the broker config
- private static String _backupRootDir = System.getProperty("user.home") + File.separator + "BDBbackup";
- // Directory for a particular virtual host
- // It is of the form backupRootDir/time/envName
- private String _backupDir = null;
- // This is bdb env dir
- private String _envDir = null;
- // This file contains the information about the last logfile name in previous backup
- private String iniFile = "bdbbackup.ini";
- // bdb environment
- private Environment _env;
- // This represents the dir name specific to a virtual host. This is
- private String _envName = null;
- // helper class for backup
- private DbBackup _backupHelper;
-
- /**
- * Creates the backup utility instance for backup
- * @param env bdb environment for particular virtual host
- * @param virtualHostName
- * @throws Exception
- */
- public BDBBackup(Environment env, String virtualHostName) throws Exception
- {
- _env = env;
- _envDir = _env.getHome().getAbsolutePath();
- _envName = (virtualHostName != null) ? virtualHostName : _env.getHome().getName();
- _backupHelper = new DbBackup(_env);
- }
-
- public static void main(String[] args) throws Exception
- {
- if (args.length < 2 || (!args[0].equals("-bdbpath")) )
- {
- usage();
- System.exit(1);
- }
- String envName = null;
- if (args.length >= 4 && (args[2].equals("-virtualhost")))
- {
- envName = args[3];
- }
-
- File environmentPath = new File(args[1]);
- EnvironmentConfig envConfig = new EnvironmentConfig();
- Environment env = new Environment(environmentPath, envConfig);
-
- BDBBackup bdbBackup= new BDBBackup(env, envName);
- bdbBackup.takeBackup();
- }
-
- /**
- * It takes the backup by copying all the logfiles into the backup dir
- * @throws DatabaseException
- */
- public void takeBackup() throws DatabaseException
- {
- try
- {
- long lastFileCopiedInPrevBackup = getLastFileNoCopiedInPreviousBackup();
-
- _backupHelper.startBackup();
- String[] filesForBackup = _backupHelper.getLogFilesInBackupSet(lastFileCopiedInPrevBackup);
-
- // Inside the destination dir, a dir with current time will be created for this backup
- _backupDir = _backupRootDir + File.separator + sdf.format(new Date()) + File.separator + _envName;
- // Create the backup directories
- File destFile = new File(_backupDir);
- if (!(destFile.exists()))
- {
- destFile.mkdirs();
- }
-
- // Copy the files to archival storage.
- for (int i = 0; i < filesForBackup.length; i++)
- {
-
- File sourceFile = new File(_envDir + File.separator + filesForBackup[i]);
- destFile = new File(_backupDir + File.separator + filesForBackup[i]);
- copy(sourceFile, destFile);
- }
- // Update our knowlege of the last file saved in the backup set,
- // so we can copy less on the next backup
- long lastFileCopiedInBackup = _backupHelper.getLastFileInBackupSet();
- saveLastFileInformation(lastFileCopiedInBackup);
-
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- finally
- {
- // Remember to exit backup mode, or all log files won't be cleaned and disk usage will bloat.
- if (_backupHelper != null)
- {
- _backupHelper.endBackup();
- }
- }
- }
-
- /**
- * Copies src file to dst file. If the dst file does not exist, it is created
- * @param src file name
- * @param dst file name
- * @throws IOException
- */
- private synchronized static void copy(File src, File dst) throws IOException
- {
- InputStream in = new FileInputStream(src);
- if (!dst.exists())
- {
- dst.createNewFile();
- }
- OutputStream out = new FileOutputStream(dst);
-
- // Transfer bytes from in to out
- byte[] buf = new byte[1024];
- int len;
- while ((len = in.read(buf)) > 0)
- {
- out.write(buf, 0, len);
- }
- in.close();
- out.close();
- }
-
- private void saveLastFileInformation(long fileNo) throws IOException
- {
- File file = new File(_envDir + File.separator + iniFile);
- file.delete();
- file.createNewFile();
-
- BufferedWriter out = new BufferedWriter(new FileWriter(file, true));
- out.write(fileNo + "\n");
- out.close();
-
- // Copy the ini file in the destination dir also
- copy(file, new File(_backupDir + File.separator + iniFile));
- }
-
- private long getLastFileNoCopiedInPreviousBackup() throws IOException
- {
- File file = new File(_envDir + File.separator + iniFile);
- if (!file.exists())
- return -1;
-
- BufferedReader in = new BufferedReader(new FileReader(file));;
- String str = in.readLine();
- in.close();
-
- if (str != null)
- {
- return Long.parseLong(str);
- }
-
- return -1;
- }
-
- private static void usage()
- {
- System.out.println("bdb env path is not specified. \n -bdbpath <bdb env path> " +
- "\n [-virtualhost <virtual host name> ]");
- }
-}
17 years, 7 months
rhmessaging commits: r2430 - store/trunk/cpp/lib.
by rhmessaging-commits@lists.jboss.org
Author: tedross
Date: 2008-09-08 13:09:10 -0400 (Mon, 08 Sep 2008)
New Revision: 2430
Modified:
store/trunk/cpp/lib/Makefile.am
Log:
Removed reference to nonexistant file
Modified: store/trunk/cpp/lib/Makefile.am
===================================================================
--- store/trunk/cpp/lib/Makefile.am 2008-09-08 14:30:40 UTC (rev 2429)
+++ store/trunk/cpp/lib/Makefile.am 2008-09-08 17:09:10 UTC (rev 2430)
@@ -101,8 +101,7 @@
gen/Journal.h \
gen/Store.cpp \
gen/Store.h \
- gen/ArgsJournalExpand.h \
- gen/ArgsJournalReconfigure.h
+ gen/ArgsJournalExpand.h
BUILT_SOURCES = db-inc.h
17 years, 7 months
rhmessaging commits: r2429 - store/branches/java/broker-queue-refactor/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb.
by rhmessaging-commits@lists.jboss.org
Author: aidanskinner
Date: 2008-09-08 10:30:40 -0400 (Mon, 08 Sep 2008)
New Revision: 2429
Modified:
store/branches/java/broker-queue-refactor/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java
Log:
Use a cursor for deleting entries
Modified: store/branches/java/broker-queue-refactor/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java
===================================================================
--- store/branches/java/broker-queue-refactor/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java 2008-09-05 21:32:24 UTC (rev 2428)
+++ store/branches/java/broker-queue-refactor/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java 2008-09-08 14:30:40 UTC (rev 2429)
@@ -938,12 +938,16 @@
try
{
- OperationStatus status = _deliveryDb.delete(tx, key);
+ Cursor cursor = _deliveryDb.openCursor(tx, null);
+ DatabaseEntry data = new DatabaseEntry();
+ OperationStatus status = cursor.getSearchKey(key, data, null);
if (status == OperationStatus.NOTFOUND)
{
throw new AMQException("Unable to find message with id " + messageId + " on queue " + name);
}
- else if (status != OperationStatus.SUCCESS)
+ status = cursor.delete();
+ cursor.close();
+ if (status != OperationStatus.SUCCESS)
{
throw new AMQException("Unable to remove message with id " + messageId + " on queue " + name);
}
17 years, 7 months
rhmessaging commits: r2428 - mgmt/trunk/cumin/python/cumin.
by rhmessaging-commits@lists.jboss.org
Author: nunofsantos
Date: 2008-09-05 17:32:24 -0400 (Fri, 05 Sep 2008)
New Revision: 2428
Modified:
mgmt/trunk/cumin/python/cumin/job.py
mgmt/trunk/cumin/python/cumin/model.py
Log:
adapt Jobs to use sourceObjectId instead of idOriginal as id/name
Modified: mgmt/trunk/cumin/python/cumin/job.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/job.py 2008-09-05 21:07:03 UTC (rev 2427)
+++ mgmt/trunk/cumin/python/cumin/job.py 2008-09-05 21:32:24 UTC (rev 2428)
@@ -231,7 +231,7 @@
return self.frame.get_args(session)
def render_title(self, session, job):
- return "Hold Job '%d'" % job.idOriginal
+ return "Hold Job '%d'" % job.sourceObjectId
def process_submit(self, session, job):
action = self.app.model.job.hold
@@ -240,7 +240,7 @@
self.process_cancel(session, job)
def render_submit_content(self, session, job):
- return "Yes, Hold Job '%d'" % job.idOriginal
+ return "Yes, Hold Job '%d'" % job.sourceObjectId
def render_cancel_content(self, session, job):
return "No, Cancel"
@@ -250,7 +250,7 @@
return self.frame.get_args(session)
def render_title(self, session, job):
- return "Remove Job '%d'" % job.idOriginal
+ return "Remove Job '%d'" % job.sourceObjectId
def process_submit(self, session, job):
action = self.app.model.job.remove
@@ -259,7 +259,7 @@
self.process_cancel(session, job)
def render_submit_content(self, session, job):
- return "Yes, Remove Job '%d'" % job.idOriginal
+ return "Yes, Remove Job '%d'" % job.sourceObjectId
def render_cancel_content(self, session, job):
return "No, Cancel"
@@ -269,7 +269,7 @@
return self.frame.get_args(session)
def render_title(self, session, job):
- return "Release Job '%d'" % job.idOriginal
+ return "Release Job '%d'" % job.sourceObjectId
def process_submit(self, session, job):
action = self.app.model.job.release
@@ -278,7 +278,7 @@
self.process_cancel(session, job)
def render_submit_content(self, session, job):
- return "Yes, Release Job '%d'" % job.idOriginal
+ return "Yes, Release Job '%d'" % job.sourceObjectId
def render_cancel_content(self, session, job):
return "No, Cancel"
Modified: mgmt/trunk/cumin/python/cumin/model.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/model.py 2008-09-05 21:07:03 UTC (rev 2427)
+++ mgmt/trunk/cumin/python/cumin/model.py 2008-09-05 21:32:24 UTC (rev 2428)
@@ -438,7 +438,7 @@
self.mint_stats_class = mint_stats_class
- prop = CuminProperty(self, "idOriginal")
+ prop = CuminProperty(self, "sourceObjectId")
prop.title = "Management ID"
prop = CuminProperty(self, "creationTime")
17 years, 7 months
rhmessaging commits: r2427 - mgmt/trunk/cumin/python/cumin.
by rhmessaging-commits@lists.jboss.org
Author: justi9
Date: 2008-09-05 17:07:03 -0400 (Fri, 05 Sep 2008)
New Revision: 2427
Modified:
mgmt/trunk/cumin/python/cumin/model.py
Log:
Fix id ref
Modified: mgmt/trunk/cumin/python/cumin/model.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/model.py 2008-09-05 20:55:03 UTC (rev 2426)
+++ mgmt/trunk/cumin/python/cumin/model.py 2008-09-05 21:07:03 UTC (rev 2427)
@@ -1633,7 +1633,7 @@
return "Job"
def get_object_name(self, job):
- return str(job.idSourceObject)
+ return str(job.sourceObjectId)
def show_object(self, session, job):
17 years, 7 months
rhmessaging commits: r2426 - mgmt/trunk/cumin/python/cumin.
by rhmessaging-commits@lists.jboss.org
Author: eallen
Date: 2008-09-05 16:55:03 -0400 (Fri, 05 Sep 2008)
New Revision: 2426
Modified:
mgmt/trunk/cumin/python/cumin/model.py
Log:
Added some guesses at some Ad properties
Modified: mgmt/trunk/cumin/python/cumin/model.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/model.py 2008-09-05 20:53:56 UTC (rev 2425)
+++ mgmt/trunk/cumin/python/cumin/model.py 2008-09-05 20:55:03 UTC (rev 2426)
@@ -105,7 +105,7 @@
return self.app.main_page.show_main(session)
class AdProperty(object):
- groups = ["Main", "Condor Info", "Command Info", "Other"]
+ groups = ["Main", "Command Info", "Job Status Info", "Condor Info", "Other"]
def __init__(self, cls, name):
self.cumin_model = cls.cumin_model
@@ -1476,13 +1476,8 @@
super(CuminJob, self).__init__(model, "job", Job, JobStats)
### Main Group
- prop = self.JobStatusProperty(self, "JobStatus")
- prop.description = "The current job status"
- prop.renderer = prop.render_status
- prop.title = "Job Status"
- prop.writable = False
-
prop = AdProperty(self, "Owner")
+ prop.description = "The submitter of the job"
prop.writable = False
prop = AdProperty(self, "BufferBlockSize")
@@ -1508,7 +1503,7 @@
prop.title = "Command"
prop = AdProperty(self, "In")
- prop.description = "Command Input"
+ prop.description = "The file where the job's standard input is read"
prop.group = "Command Info"
prop = AdProperty(self, "Iwd")
@@ -1517,10 +1512,48 @@
prop.title = "Working Directory"
prop = AdProperty(self, "Out")
- prop.description = "Where the output will be stored"
+ prop.description = "The file where the job's standard output is written"
prop.example = "'/dev/null' or '~/logs/'"
prop.group = "Command Info"
+ ######## Job Status Info
+ prop = self.JobStatusProperty(self, "JobStatus")
+ prop.description = "The current job status"
+ prop.group = "Job Status Info"
+ prop.renderer = prop.render_status
+ prop.title = "Job Status"
+ prop.writable = False
+
+ prop = AdProperty(self, "HoldReasonCode")
+ prop.group = "Job Status Info"
+ prop.title = "Hold Reason Code"
+ prop.writable = False
+
+ prop = AdProperty(self, "ExitStatus")
+ prop.description = "Status when job completes"
+ prop.group = "Job Status Info"
+ prop.title = "Exit Status"
+ prop.writable = False
+
+ prop = AdProperty(self, "ProcId")
+ prop.description = "The id of the job within its cluster. Proc Ids are unique within a cluster."
+ prop.group = "Job Status Info"
+ prop.title = "Proc Id"
+ prop.writable = False
+
+ ######## Other
+ prop = AdProperty(self, "ClusterId")
+ prop.description = "The id of the cluster the job belongs to"
+ prop.group = "Other"
+ prop.title = "Cluster ID"
+ prop.writable = False
+
+ prop = AdProperty(self, "QDate")
+ prop.description = "The number of nanoseconds since epoch when the job was submitted"
+ prop.group = "Other"
+ prop.title = "QDate"
+ prop.writable = False
+
######## Properties
prop = CuminProperty(self, "AccountingGroup")
prop.summary = True
17 years, 7 months