rhmessaging commits: r967 - in mgmt: bin and 10 other directories.
by rhmessaging-commits@lists.jboss.org
Author: nunofsantos
Date: 2007-10-08 11:51:14 -0400 (Mon, 08 Oct 2007)
New Revision: 967
Added:
mgmt/COPYING
mgmt/LICENSE
mgmt/bin/
mgmt/bin/cumindev
mgmt/bin/cumindev-etags
mgmt/cumin-test-0/
mgmt/cumin-test-0/bin
mgmt/cumin-test-0/lib
mgmt/cumin-test-0/python
mgmt/cumin-test-0/resources
mgmt/cumin/
mgmt/cumin/bin/
mgmt/cumin/bin/cumin-test
mgmt/cumin/python/
mgmt/cumin/python/cumin/
mgmt/cumin/python/cumin/__init__.py
mgmt/cumin/python/cumin/…
[View More]cluster.py
mgmt/cumin/python/cumin/cluster.strings
mgmt/cumin/python/cumin/demo.py
mgmt/cumin/python/cumin/exchange.py
mgmt/cumin/python/cumin/exchange.strings
mgmt/cumin/python/cumin/model.py
mgmt/cumin/python/cumin/page.py
mgmt/cumin/python/cumin/page.strings
mgmt/cumin/python/cumin/queue.py
mgmt/cumin/python/cumin/queue.strings
mgmt/cumin/python/cumin/realm.py
mgmt/cumin/python/cumin/realm.strings
mgmt/cumin/python/cumin/server.py
mgmt/cumin/python/cumin/server.strings
mgmt/cumin/python/cumin/virtualhost.py
mgmt/cumin/python/cumin/virtualhost.strings
mgmt/cumin/python/cumin/widgets.py
mgmt/cumin/python/cumin/widgets.strings
mgmt/cumin/python/wooly/
mgmt/cumin/python/wooly/__init__.py
mgmt/cumin/python/wooly/debug.py
mgmt/cumin/python/wooly/devel.py
mgmt/cumin/python/wooly/forms.py
mgmt/cumin/python/wooly/forms.strings
mgmt/cumin/python/wooly/model.py
mgmt/cumin/python/wooly/pages.py
mgmt/cumin/python/wooly/parameters.py
mgmt/cumin/python/wooly/resources.py
mgmt/cumin/python/wooly/server.py
mgmt/cumin/python/wooly/widgets.py
mgmt/cumin/python/wooly/widgets.strings
mgmt/cumin/resources/
mgmt/cumin/resources/ajax-test.html
mgmt/cumin/resources/ajax.js
mgmt/cumin/resources/exchange-20.png
mgmt/cumin/resources/exchange-36.png
mgmt/cumin/resources/exchange.svg
mgmt/cumin/resources/logo.png
mgmt/cumin/resources/logo.svg
mgmt/cumin/resources/object-20.png
mgmt/cumin/resources/object-36.png
mgmt/cumin/resources/object.svg
mgmt/cumin/resources/purple.png
mgmt/cumin/resources/queue-20.png
mgmt/cumin/resources/queue-36.png
mgmt/cumin/resources/queue.svg
mgmt/cumin/resources/radio-button-checked.png
mgmt/cumin/resources/radio-button.png
mgmt/cumin/resources/radio-buttons.svg
mgmt/cumin/resources/wooly.js
mgmt/etc/
mgmt/etc/cumindev.el
mgmt/etc/cumindev.profile
mgmt/lib/
mgmt/misc/
mgmt/misc/templates.py
mgmt/notes/
mgmt/notes/Errors
mgmt/notes/InterfaceQuestions
mgmt/notes/ProtocolQuestions
mgmt/notes/Todo
mgmt/notes/WoolyOverview
mgmt/notes/firebug-exception-bug.js
mgmt/notes/firebug-swallows-exceptions.html
Log:
initial import of cumin code
Added: mgmt/COPYING
===================================================================
--- mgmt/COPYING (rev 0)
+++ mgmt/COPYING 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,15 @@
+Copyright (C) 2007 Red Hat Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Added: mgmt/LICENSE
===================================================================
--- mgmt/LICENSE (rev 0)
+++ mgmt/LICENSE 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,280 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
Added: mgmt/bin/cumindev
===================================================================
--- mgmt/bin/cumindev (rev 0)
+++ mgmt/bin/cumindev 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+if [ -z "$CUMINDEV_HOME" ]; then
+ export CUMINDEV_HOME="${HOME}/cumindev"
+fi
+
+echo "CUMINDEV_HOME is ${CUMINDEV_HOME}"
+
+source "${CUMINDEV_HOME}/etc/cumindev.profile"
+
+cumindev-etags
+
+exec emacs -nw -l "${CUMINDEV_HOME}/etc/cumindev.el"
Property changes on: mgmt/bin/cumindev
___________________________________________________________________
Name: svn:executable
+ *
Added: mgmt/bin/cumindev-etags
===================================================================
--- mgmt/bin/cumindev-etags (rev 0)
+++ mgmt/bin/cumindev-etags 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+output="${CUMINDEV_HOME}/etc/cumindev.tags"
+
+find "$CUMINDEV_HOME" -name \*.py -print | etags --output="$output" -
+find "$CUMINDEV_HOME" -name \*.strings -print \
+ | etags --append --output="$output" --regex='/^\[.*\][ \t]*$/\1/' -
Property changes on: mgmt/bin/cumindev-etags
___________________________________________________________________
Name: svn:executable
+ *
Added: mgmt/cumin/bin/cumin-test
===================================================================
--- mgmt/cumin/bin/cumin-test (rev 0)
+++ mgmt/cumin/bin/cumin-test 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+
+import sys
+from cumin import CuminServer
+
+def load_args(argv):
+ args = dict()
+ key = None
+
+ for arg in sys.argv:
+ if arg.startswith("--"):
+ key = arg[2:]
+ elif key:
+ args[key] = arg
+ key = None
+
+ if key:
+ args[key] = None
+
+ return args
+
+if __name__ == "__main__":
+ args = load_args(sys.argv)
+
+ port = int(args.get("port", 9090))
+
+ if "profile" in args:
+ import profile, pstats
+
+ try:
+ profile.run("CuminServer().run()", "cumin-test-stats")
+ raise KeyboardInterrupt()
+ except KeyboardInterrupt:
+ stats = pstats.Stats("cumin-test-stats")
+
+ stats.sort_stats("cumulative").print_stats(15)
+ stats.sort_stats("time").print_stats(15)
+
+ stats.strip_dirs()
+
+ #stats.print_callers("interpolate")
+ #stats.print_callees("interpolate")
+ else:
+ CuminServer(port).run()
Property changes on: mgmt/cumin/bin/cumin-test
___________________________________________________________________
Name: svn:executable
+ *
Added: mgmt/cumin/python/cumin/__init__.py
===================================================================
--- mgmt/cumin/python/cumin/__init__.py (rev 0)
+++ mgmt/cumin/python/cumin/__init__.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,78 @@
+import sys, os
+
+from random import randint
+from wooly import Application, Session, Page
+from wooly.pages import CssPage, ResourcePage
+from wooly.server import WebServer
+from wooly.devel import DevelPage
+from wooly.parameters import IntegerParameter
+
+from model import CuminModel
+from demo import DemoData
+from page import CuminPage
+from queue import QueueXmlPage
+
+class Cumin(Application):
+ def __init__(self, model):
+ super(Cumin, self).__init__()
+
+ try:
+ self.home = os.environ["CUMIN_HOME"]
+ except KeyError:
+ sys.exit(1)
+
+ self.add_resource_dir(os.path.join(self.home, "resources"))
+
+ self.model = model
+
+ self.cumin_page = CuminPage(self, "cumin.html")
+ self.set_default_page(self.cumin_page)
+
+ self.add_page(CssPage(self, "cumin.css"))
+ self.add_page(ResourcePage(self, "resource"))
+ self.add_page(CountPage(self, "count"))
+ self.add_page(RandomIntegerPage(self, "randint"))
+ self.add_page(DevelPage(self, "devel.html"))
+ self.add_page(QueueXmlPage(self, "queue.xml"))
+
+class RandomIntegerPage(Page):
+ def __init__(self, app, name):
+ super(RandomIntegerPage, self).__init__(app, name)
+
+ self.min = IntegerParameter(app, "min");
+ self.add_parameter(self.min);
+
+ self.max = IntegerParameter(app, "max");
+ self.add_parameter(self.max);
+
+ def get_content_type(self, session):
+ return Page.xml_content_type
+
+ def do_render(self, session, object):
+ int = randint(self.min.get(session), self.max.get(session))
+ return "%s<integer>%i</integer>" % (Page.xml_1_0_declaration, int)
+
+class CountPage(Page):
+ def __init__(self, app, name):
+ super(CountPage, self).__init__(app, name)
+
+ self.count = 0
+
+ def get_content_type(self, session):
+ return Page.xml_content_type
+
+ def do_render(self, session, object):
+ self.count += 1
+ return "<count>%i</count>" % self.count
+
+class CuminServer(WebServer):
+ def __init__(self, port=9090):
+ model = CuminModel()
+
+ data = DemoData(model)
+ data.load()
+ data.start_updates()
+
+ app = Cumin(model)
+
+ super(CuminServer, self).__init__(app, port)
Added: mgmt/cumin/python/cumin/cluster.py
===================================================================
--- mgmt/cumin/python/cumin/cluster.py (rev 0)
+++ mgmt/cumin/python/cumin/cluster.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,75 @@
+from wooly import *
+from wooly.widgets import *
+
+from server import *
+from queue import *
+from realm import *
+from exchange import *
+from widgets import *
+
+strings = StringCatalog(__file__)
+
+class ClusterSet(ItemSet):
+ def render_title(self, session, model):
+ return "Clusters (%i)" % len(model.get_clusters())
+
+ def get_items(self, session, model):
+ return sorted(model.get_clusters())
+
+ def render_item_href(self, session, cluster):
+ branch = session.branch()
+ self.page().show_cluster(branch, cluster).show_view(branch)
+ return branch.marshal()
+
+ def render_item_name(self, session, cluster):
+ return cluster.name
+
+class ClusterParameter(Parameter):
+ def do_unmarshal(self, string):
+ return self.app.model.get_cluster(int(string))
+
+ def do_marshal(self, cluster):
+ return str(cluster.id)
+
+class ClusterFrame(CuminFrame):
+ def __init__(self, app, name):
+ super(ClusterFrame, self).__init__(app, name)
+
+ self.param = ClusterParameter(app, "id")
+ self.add_parameter(self.param)
+ self.set_object_attribute(self.param)
+
+ self.view = ClusterView(app, "view")
+ self.add_child(self.view)
+
+ def set_cluster(self, session, cluster):
+ self.param.set(session, cluster)
+
+ def show_view(self, session):
+ return self.show_mode(session, self.view)
+
+ def render_href(self, session, cluster):
+ branch = session.branch()
+ return branch.marshal()
+
+ def render_title(self, session, cluster):
+ return "Cluster '%s'" % cluster.name
+
+class ClusterView(Widget):
+ def __init__(self, app, name):
+ super(ClusterView, self).__init__(app, name)
+
+ self.tabs = TabSet(app, "tabs")
+ self.add_child(self.tabs)
+
+ self.tabs.add_child(self.Servers(app, "servers"))
+
+ def render_title(self, session, cluster):
+ return "Cluster '%s'" % cluster.name
+
+ class Servers(ServerSet):
+ def render_title(self, session, cluster):
+ return "Servers (%i)" % len(cluster.server_items())
+
+ def get_items(self, session, cluster):
+ return sorted(cluster.server_items())
Added: mgmt/cumin/python/cumin/cluster.strings
===================================================================
--- mgmt/cumin/python/cumin/cluster.strings (rev 0)
+++ mgmt/cumin/python/cumin/cluster.strings 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,18 @@
+[ClusterSet.html]
+<table class="ClusterSet mobjects">
+ <tr>
+ <th>Name</th>
+ </tr>
+ {items}
+</table>
+
+[ClusterSet.item_html]
+<tr>
+ <td><a href="{item_href}">{item_name}</a></td>
+</tr>
+
+[ClusterView.html]
+<div class="oblock">
+ <h1>{title}</h1>
+ {tabs}
+</div>
Added: mgmt/cumin/python/cumin/demo.py
===================================================================
--- mgmt/cumin/python/cumin/demo.py (rev 0)
+++ mgmt/cumin/python/cumin/demo.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,115 @@
+from time import sleep
+from threading import Thread
+from random import sample, random, randint
+
+from model import *
+
+class DemoData(object):
+ def __init__(self, model):
+ self.model = model
+
+ def load(self):
+ # XXX need some locking in here
+
+ sgroups = dict()
+
+ for name in ("Geography", "Department"):
+ sgroup = ServerGroup(self.model)
+ sgroup.name = name
+ sgroups[name] = sgroup
+
+ for name in ("West Coast", "East Coast"):
+ sgroup = ServerGroup(self.model)
+ sgroup.name = name
+ sgroups["Geography"].add_child(sgroup)
+ sgroups[name] = sgroup
+
+ for name in ("Marketing", "Sales"):
+ sgroup = ServerGroup(self.model)
+ sgroup.name = name
+ sgroups["Department"].add_child(sgroup)
+ sgroups[name] = sgroup
+
+ clusters = list()
+
+ for cluster_count in range(3):
+ cluster = Cluster(self.model)
+ cluster.name = "cluster" + str(cluster_count)
+ clusters.append(cluster)
+
+ for server_count in range(12):
+ server = Server(self.model)
+ server.name = "server" + str(server_count)
+ server.set_cluster(clusters[server_count % 3])
+
+ vhost = VirtualHost(self.model)
+ vhost.name = "default"
+ server.add_virtual_host(vhost)
+ server.default_virtual_host = vhost
+
+ for name in ("test", "devel"):
+ vhost = VirtualHost(self.model)
+ vhost.name = name
+ server.add_virtual_host(vhost)
+
+ for vhost in server.virtual_host_items():
+ for name in ("realm0", "realm1", "realm2"):
+ realm = Realm(self.model)
+ realm.name = name
+ vhost.add_realm(realm)
+
+ for name in ("amq.direct", "amq.fanout",
+ "amq.topic", "amq.match"):
+ exchange = Exchange(self.model)
+ exchange.name = name
+ vhost.add_exchange(exchange)
+
+ for queue_count in range(10):
+ queue = Queue(self.model)
+ queue.name = "queue" + str(queue_count)
+ vhost.add_queue(queue)
+
+ def start_updates(self):
+ thread = UpdateThread(self.model)
+ thread.start()
+
+class UpdateThread(Thread):
+ def __init__(self, model):
+ super(UpdateThread, self).__init__()
+
+ self.model = model
+ self.setDaemon(True)
+
+ def run(self):
+ while True:
+ sleep(1)
+
+ for server in self.model.get_servers():
+ for vhost in server.virtual_host_items():
+ for queue in vhost.queue_items():
+ queue.lock()
+ try:
+ queue.message_count += 1
+
+ if random() < 0.01:
+ queue.error_count += 1
+
+ if random() < 0.01:
+ queue.warning_count += 1
+ finally:
+ queue.unlock()
+
+if __name__ == "__main__":
+ import sys
+
+ model = CuminModel()
+
+ data = DemoData(model)
+ data.load()
+
+ sys.stdout.write("<?xml version=\"1.0\"?><model>")
+
+ for server in model.get_servers():
+ server.write_xml(sys.stdout)
+
+ sys.stdout.write("</model>")
Added: mgmt/cumin/python/cumin/exchange.py
===================================================================
--- mgmt/cumin/python/cumin/exchange.py (rev 0)
+++ mgmt/cumin/python/cumin/exchange.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,277 @@
+from wooly import *
+from wooly.widgets import *
+from wooly.forms import *
+from wooly.resources import *
+
+from model import *
+from widgets import *
+
+strings = StringCatalog(__file__)
+
+class ExchangeParameter(Parameter):
+ def do_unmarshal(self, string):
+ return self.app.model.get_exchange(int(string))
+
+ def do_marshal(self, exchange):
+ return str(exchange.id)
+
+class ExchangeInputSet(RadioInputSet):
+ def __init__(self, app, name, form):
+ super(ExchangeInputSet, self).__init__(app, name, form)
+
+ param = ExchangeParameter(app, "param")
+ self.add_parameter(param)
+ self.set_parameter(param)
+
+ def get_items(self, session, vhost):
+ return sorted(vhost.exchange_items())
+
+ def render_item_value(self, session, exchange):
+ return exchange.id
+
+ def render_item_content(self, session, exchange):
+ return exchange.name
+
+ def render_item_checked_attr(self, session, exchange):
+ return exchange is self.param.get(session) and "checked=\"checked\""
+
+class ExchangeSet(ItemSet):
+ def render_title(self, session, vhost):
+ return "Exchanges (%s)" % len(vhost.exchange_items())
+
+ def get_items(self, session, vhost):
+ return sorted(vhost.exchange_items())
+
+ def render_item_href(self, session, exchange):
+ branch = session.branch()
+ self.page().show_exchange(branch, exchange).show_view(branch)
+ return branch.marshal()
+
+ def render_item_name(self, session, exchange):
+ return exchange.name
+
+ def render_item_flags(self, session, exchange):
+ flags = list()
+ return ", ".join(flags)
+
+ def render_item_config(self, session, exchange):
+ return "%i bindings" % len(exchange.binding_items())
+
+ def render_item_status(self, session, exchange):
+ return "2 errors"
+
+class ExchangeFrame(CuminFrame):
+ def __init__(self, app, name):
+ super(ExchangeFrame, self).__init__(app, name)
+
+ self.param = ExchangeParameter(app, "id")
+ self.add_parameter(self.param)
+ self.set_object_attribute(self.param)
+
+ self.view = ExchangeView(app, "view")
+ self.add_child(self.view)
+
+ self.edit = ExchangeEdit(app, "edit")
+ self.add_child(self.edit)
+
+ self.remove = ExchangeRemove(app, "remove")
+ self.add_child(self.remove)
+
+ def set_exchange(self, session, exchange):
+ return self.param.set(session, exchange)
+
+ def show_view(self, session):
+ return self.show_mode(session, self.view)
+
+ def show_edit(self, session):
+ return self.show_mode(session, self.edit)
+
+ def show_remove(self, session):
+ return self.show_mode(session, self.remove)
+
+ def render_href(self, session, exchange):
+ branch = session.branch()
+ self.show_view(branch)
+ return branch.marshal()
+
+ def render_title(self, session, exchange):
+ return "Exchange '%s'" % exchange.name
+
+class ExchangeView(Widget):
+ def __init__(self, app, name):
+ super(ExchangeView, self).__init__(app, name)
+
+ self.tabs = TabSet(app, "tabs")
+ self.add_child(self.tabs)
+
+ self.tabs.add_child(ExchangeBindingSet(app, "bindings"))
+ self.tabs.add_child(self.ExchangeLog(app, "log"))
+
+ class ExchangeLog(Widget):
+ def render_title(self, session, exchange):
+ return "Log Messages"
+
+ def render_title(self, session, exchange):
+ return "Exchange '%s'" % exchange.name
+
+ def render_exchange_name(self, session, exchange):
+ return exchange.name
+
+ def render_type(self, session, exchange):
+ if exchange.type == "direct":
+ return "Direct"
+ elif exchange.type == "topic":
+ return "Topic"
+ elif exchange.type == "fanout":
+ return "Fan Out"
+ else:
+ raise Exception()
+
+ def render_edit_exchange_href(self, session, exchange):
+ branch = session.branch()
+ self.page().show_exchange(branch, exchange).show_edit(branch)
+ return branch.marshal()
+
+ def render_remove_exchange_href(self, session, exchange):
+ branch = session.branch()
+ self.page().show_exchange(branch, exchange).show_remove(branch)
+ return branch.marshal()
+
+class ExchangeBindingSet(ItemSet):
+ def render_title(self, session, exchange):
+ return "Bindings (%i)" % len(exchange.binding_items())
+
+ def get_items(self, session, exchange):
+ return sorted(exchange.binding_items())
+
+ def render_item_href(self, session, binding):
+ branch = session.branch()
+ self.page().show_queue(branch, binding.queue)
+ return branch.marshal()
+
+ def render_item_name(self, session, binding):
+ return binding.get_queue().name
+
+ def render_item_routing_key(self, session, binding):
+ return binding.routing_key
+
+class ExchangeForm(CuminForm):
+ def __init__(self, app, name):
+ super(ExchangeForm, self).__init__(app, name)
+
+ self.exchange_name = TextInput(app, "exchange_name", self)
+ self.add_child(self.exchange_name)
+
+ self.type = Parameter(app, "type")
+ self.type.set_default("direct")
+ self.add_parameter(self.type)
+
+ self.direct = RadioInput(app, "direct", self)
+ self.direct.set_parameter(self.type)
+ self.direct.set_value("direct")
+ self.add_child(self.direct)
+
+ self.topic = RadioInput(app, "topic", self)
+ self.topic.set_parameter(self.type)
+ self.topic.set_value("topic")
+ self.add_child(self.topic)
+
+ self.fanout = RadioInput(app, "fanout", self)
+ self.fanout.set_parameter(self.type)
+ self.fanout.set_value("fanout")
+ self.add_child(self.fanout)
+
+ def validate(self, session):
+ valid = True
+
+ name = self.exchange_name.get(session)
+
+ if name == "":
+ valid = False
+ self.exchange_name.add_error(session, """
+ The exchange name is empty; it is required
+ """)
+ elif " " in name:
+ valid = False
+ self.exchange_name.add_error(session, """
+ The exchange name is invalid; allowed characters are
+ letters, digits, ".", and "_"
+ """)
+
+ return valid
+
+class ExchangeAdd(ExchangeForm):
+ def on_cancel(self, session, vhost):
+ branch = session.branch()
+ self.page().show_virtual_host(branch, vhost).show_view(branch)
+ session.set_redirect(branch.marshal())
+
+ def on_submit(self, session, vhost):
+ if self.validate(session):
+ exchange = Exchange(self.app.model)
+
+ exchange.lock()
+ try:
+ exchange.name = self.exchange_name.get(session)
+ exchange.type = self.type.get(session)
+ finally:
+ exchange.unlock()
+
+ vhost.add_exchange(exchange)
+
+ branch = session.branch()
+ self.page().show_exchange(branch, exchange).show_view(branch)
+ session.set_redirect(branch.marshal())
+
+ def render_title(self, session, vhost):
+ return "Add Exchange to Virtual Host '%s'" % vhost.name
+
+class ExchangeEdit(ExchangeForm):
+ def on_cancel(self, session, exchange):
+ branch = session.branch()
+ self.page().show_exchange(branch, exchange).show_view(branch)
+ session.set_redirect(branch.marshal())
+
+ def on_submit(self, session, exchange):
+ if self.validate(session):
+ exchange.lock()
+ try:
+ exchange.name = self.exchange_name.get(session)
+ exchange.type = self.type.get(session)
+ finally:
+ exchange.unlock()
+
+ branch = session.branch()
+ self.page().show_exchange(branch, exchange).show_view(branch)
+ session.set_redirect(branch.marshal())
+
+ def on_display(self, session, exchange):
+ self.exchange_name.set(session, exchange.name)
+ self.type.set(session, exchange.type)
+
+ def render_title(self, session, exchange):
+ return "Edit Exchange '%s'" % exchange.name
+
+class ExchangeRemove(CuminConfirmForm):
+ def on_confirm(self, session, exchange):
+ vhost = exchange.get_virtual_host()
+
+ exchange.remove()
+
+ branch = session.branch()
+ self.page().show_virtual_host(branch, vhost).show_view(branch)
+ session.set_redirect(branch.marshal())
+
+ def on_cancel(self, session, exchange):
+ branch = session.branch()
+ self.page().show_exchange(branch, exchange).show_view(branch)
+ session.set_redirect(branch.marshal())
+
+ def render_title(self, session, exchange):
+ return "Remove Exchange '%s'" % exchange.name
+
+ def render_confirm_content(self, session, exchange):
+ return "Yes, Remove Exchange '%s'" % exchange.name
+
+ def render_cancel_content(self, session, exchange):
+ return "No, Cancel"
Added: mgmt/cumin/python/cumin/exchange.strings
===================================================================
--- mgmt/cumin/python/cumin/exchange.strings (rev 0)
+++ mgmt/cumin/python/cumin/exchange.strings 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,105 @@
+[ExchangeInputSet.item_html]
+<div class="field">
+ <input type="radio" name="{name}" value="{item_value}" tabindex="{tabindex}" {item_checked_attr}/>
+ {item_content}
+</div>
+
+[ExchangeSet.css]
+ul.ExchangeSet li:before {
+ content: url(resource?name=exchange-20.png);
+ vertical-align: -30%;
+ padding: 0 0.25em;
+}
+
+[ExchangeSet.html]
+<table class="ExchangeSet mobjects">
+ <tr>
+ <th>Name</th>
+ <th>Configuration</th>
+ <th>Status</th>
+ </tr>
+{items}
+</table>
+
+[ExchangeSet.item_html]
+<tr>
+ <td><a href="{item_href}">{item_name}</a></td>
+ <td>{item_config}</td>
+ <td>{item_status}</td>
+</tr>
+
+[ExchangeForm.html]
+<form id="{id}" class="ExchangeForm mform" method="post" action="?">
+ <div class="head">
+ <h1>{title}</h1>
+ </div>
+ <div class="body">
+ <span class="legend">Name</span>
+ <fieldset>
+ <div class="field">{exchange_name}</div>
+ </fieldset>
+ <span class="legend">Type</span>
+ <fieldset>
+ <div class="field">
+ {direct}
+ <em>Direct:</em> Route messages to queues by queue name
+ </div>
+ <div class="field">
+ {topic}
+ <em>Topic:</em> Route messages to queues by topic keyword match
+ </div>
+ <div class="field">
+ {fanout}
+ <em>Fan Out:</em> Lorem ipsum gloria dei ipso facto ad nauseum
+ </div>
+ </fieldset>
+{hidden_inputs}
+ </div>
+ <div class="foot">
+ <div style="display: block; float: left;"><button>Help</help></div>
+{cancel}
+{submit}
+ </div>
+</form>
+<script defer="defer">
+(function() {
+ // elements[0] is a fieldset, at least in firefox
+ var elem = wooly.doc().elem("{id}").node.elements[1];
+ elem.focus();
+ elem.select();
+}())
+</script>
+
+[ExchangeView.html]
+<div class="ExchangeView oblock">
+ <h1><img src="resource?name=exchange-36.png"> {title}</h1>
+
+ <dl class="properties">
+ <dt>Exchange Name</dt><dd>{exchange_name}</dd>
+ <dt>Type</dt><dd>{type}</dd>
+ </dl>
+
+ <ul class="actions">
+ <li><a href="{edit_exchange_href}">Edit Exchange</a></li>
+ <li><a href="{remove_exchange_href}">Remove Exchange</a></li>
+ </ul>
+
+ {tabs}
+</div>
+
+[ExchangeBindingSet.html]
+<table class="ExchangeBindingSet mobjects">
+ <tr>
+ <th>Queue</th>
+ <th>Routing Key</th>
+ <th></th>
+ </tr>
+{items}
+</table>
+
+[ExchangeBindingSet.item_html]
+<tr>
+ <td><a href="{item_href}">{item_name}</a></td>
+ <td>{item_routing_key}</td>
+ <td><a class="action" href="">Remove</a></td>
+</tr>
Added: mgmt/cumin/python/cumin/model.py
===================================================================
--- mgmt/cumin/python/cumin/model.py (rev 0)
+++ mgmt/cumin/python/cumin/model.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,282 @@
+from wooly import *
+from wooly.model import *
+
+class CuminModel(Model):
+ def __init__(self):
+ super(CuminModel, self).__init__()
+
+ self.cluster = ModelClass(self, "cluster")
+ self.server = ModelClass(self, "server")
+ self.server_group = ModelClass(self, "server_group")
+ self.virtual_host = ModelClass(self, "virtual_host")
+ self.virtual_host_group = ModelClass(self, "virtual_host_group")
+ self.queue = ModelClass(self, "queue")
+ self.exchange = ModelClass(self, "exchange")
+ self.realm = ModelClass(self, "realm")
+ self.binding = ModelClass(self, "binding")
+
+ assoc = ModelAssociation(self, "cluster_to_servers")
+ assoc.add_endpoint(self.server, "cluster", "0..1")
+ assoc.add_endpoint(self.cluster, "server", "0..n")
+
+ assoc = ModelAssociation(self, "server_to_virtual_hosts")
+ assoc.add_endpoint(self.server, "virtual_host", "0..n")
+ assoc.add_endpoint(self.virtual_host, "server", "0..1")
+
+ assoc = ModelAssociation(self, "server_groups_to_servers")
+ assoc.add_endpoint(self.server, "server_group", "0..n")
+ assoc.add_endpoint(self.server_group, "server", "0..n")
+
+ assoc = ModelAssociation(self, "server_groups_to_server_groups")
+ assoc.add_endpoint(self.server_group, "parent", "0..n")
+ assoc.add_endpoint(self.server_group, "child", "0..n")
+
+ assoc = ModelAssociation(self, "virtual_host_groups_to_virtual_hosts")
+ assoc.add_endpoint(self.virtual_host, "virtual_host_group", "0..n")
+ assoc.add_endpoint(self.virtual_host_group, "virtual_host", "0..n")
+
+ assoc = ModelAssociation \
+ (self, "virtual_host_groups_to_virtual_host_groups")
+ assoc.add_endpoint(self.virtual_host_group, "parent", "0..n")
+ assoc.add_endpoint(self.virtual_host_group, "child", "0..n")
+
+ assoc = ModelAssociation(self, "virtual_host_to_queues")
+ assoc.add_endpoint(self.virtual_host, "queue", "0..n")
+ assoc.add_endpoint(self.queue, "virtual_host", "0..1")
+
+ assoc = ModelAssociation(self, "virtual_host_to_exchanges")
+ assoc.add_endpoint(self.virtual_host, "exchange", "0..n")
+ assoc.add_endpoint(self.exchange, "virtual_host", "0..1")
+
+ assoc = ModelAssociation(self, "virtual_host_to_realms")
+ assoc.add_endpoint(self.virtual_host, "realm", "0..n")
+ assoc.add_endpoint(self.realm, "virtual_host", "0..1")
+
+ assoc = ModelAssociation(self, "realms_to_queues")
+ assoc.add_endpoint(self.realm, "queue", "0..n")
+ assoc.add_endpoint(self.queue, "realm", "0..n")
+
+ assoc = ModelAssociation(self, "realms_to_exchanges")
+ assoc.add_endpoint(self.realm, "exchange", "0..n")
+ assoc.add_endpoint(self.exchange, "realm", "0..n")
+
+ assoc = ModelAssociation(self, "queue_to_bindings")
+ assoc.add_endpoint(self.queue, "binding", "0..n")
+ assoc.add_endpoint(self.binding, "queue", "0..1")
+
+ assoc = ModelAssociation(self, "exchange_to_bindings")
+ assoc.add_endpoint(self.exchange, "binding", "0..n")
+ assoc.add_endpoint(self.binding, "exchange", "0..1")
+
+ def get_cluster(self, id):
+ return self.get_index(self.cluster).get(id)
+
+ def get_clusters(self):
+ return self.get_index(self.cluster).values()
+
+ def get_server(self, id):
+ return self.get_index(self.server).get(id)
+
+ def get_servers(self):
+ return self.get_index(self.server).values()
+
+ def get_server_group(self, id):
+ return self.get_index(self.server_group).get(id)
+
+ def get_server_groups(self):
+ return self.get_index(self.server_group).values()
+
+ def get_virtual_host(self, id):
+ return self.get_index(self.virtual_host).get(id)
+
+ def get_queue(self, id):
+ return self.get_index(self.queue).get(id)
+
+ def get_exchange(self, id):
+ return self.get_index(self.exchange).get(id)
+
+ def get_realm(self, id):
+ return self.get_index(self.realm).get(id)
+
+class Cluster(ModelObject):
+ def __init__(self, model):
+ super(Cluster, self).__init__(model, model.cluster)
+
+ self.name = None
+
+class Server(ModelObject):
+ def __init__(self, model):
+ super(Server, self).__init__(model, model.server)
+
+ self.name = None
+ self.default_virtual_host = None
+
+ def write_xml(self, writer):
+ writer.write("<server id=\"server-%i\">" % self.id)
+ writer.write("<name>" + self.name + "</name>")
+ writer.write("<default-virtual-host ref=\"virtual-host-%i\"/>" \
+ % self.default_virtual_host.id)
+
+ for vhost in self.virtual_host_items():
+ vhost.write_xml(writer)
+
+ writer.write("</server>")
+
+class ServerGroup(ModelObject):
+ def __init__(self, model):
+ super(ServerGroup, self).__init__(model, model.server_group)
+
+ self.name = None
+
+class VirtualHost(ModelObject):
+ def __init__(self, model):
+ super(VirtualHost, self).__init__(model, model.virtual_host)
+
+ self.name = None
+
+ # XXX do this via associations? XXX this will leak a ref if
+ # the default exchange is removed
+
+ self.default_exchange = Exchange(model)
+ self.default_exchange.name = "default"
+ self.add_exchange(self.default_exchange)
+
+ def add_queue(self, queue):
+ self.do_add_queue(queue)
+
+ # Default binding
+
+ binding = Binding(self.model)
+ binding.routing_key = queue.name
+ binding.set_queue(queue)
+ binding.set_exchange(self.default_exchange)
+
+ def write_xml(self, writer):
+ writer.write("<virtual-host id=\"virtual-host-%i\">" % self.id)
+ writer.write("<name>%s</name>" % self.name)
+ writer.write("<default-exchange ref=\"exchange-%i\"/>" \
+ % self.default_exchange.id)
+
+ for queue in self.queue_items():
+ queue.write_xml(writer)
+
+ for exchange in self.exchange_items():
+ exchange.write_xml(writer)
+
+ for realm in self.realm_items():
+ realm.write_xml(writer)
+
+ writer.write("</virtual-host>")
+
+class VirtualHostGroup(ModelObject):
+ def __init__(self, model):
+ super(VirtualHostGroup, self).__init__(model, model.virtual_host_group)
+
+ self.name = None
+
+class Realm(ModelObject):
+ def __init__(self, model):
+ model.lock()
+
+ super(Realm, self).__init__(model, model.realm)
+
+ self.name = None
+
+ model.unlock()
+
+ def write_xml(self, writer):
+ writer.write("<realm id=\"realm-%i\">" % self.id)
+ writer.write("<name>%s</name>" % self.name)
+
+ for queue in self.queue_items():
+ writer.write("<queue ref=\"queue-%i\"/>" % queue.id)
+
+ for exchange in self.exchange_items():
+ writer.write("<exchange ref=\"exchange-%i\"/>" % exchange.id)
+
+ writer.write("</realm>")
+
+class Queue(ModelObject):
+ def __init__(self, model):
+ super(Queue, self).__init__(model, model.queue)
+
+ self.name = None
+ self.is_passive = False
+ self.is_durable = True
+ self.is_exclusive = False
+ self.is_auto_delete = False
+ self.latency_priority = "m" # h, m, or l
+
+ self.message_count = 41
+ self.error_count = 0
+ self.warning_count = 0
+
+ def remove(self):
+ for binding in self.binding_items().copy():
+ binding.remove()
+
+ super(Queue, self).remove()
+
+ def purge(self):
+ pass
+
+ def write_xml(self, writer):
+ writer.write("<queue id=\"queue-%i\">" % self.id)
+ writer.write("<name>%s</name>" % self.name)
+ writer.write("<latency-priority>%s</latency-priority>" \
+ % self.latency_priority)
+ writer.write("<message-count>%i</message-count>" % self.message_count)
+ writer.write("<error-count>%i</error-count>" % self.error_count)
+ writer.write("<warning-count>%i</warning-count>" % self.warning_count)
+
+ for realm in self.realm_items():
+ writer.write("<realm ref=\"realm-%i\"/>" % realm.id)
+
+ for binding in self.binding_items():
+ binding.write_xml(writer)
+
+ writer.write("</queue>")
+
+class Exchange(ModelObject):
+ def __init__(self, model):
+ super(Exchange, self).__init__(model, model.exchange)
+
+ self.name = None
+ self.type = "direct" # in ("direct", "topic", "fanout")
+ self.is_passive = False
+ self.is_durable = True
+ self.is_auto_delete = False
+ self.is_internal = False
+
+ def remove(self):
+ for binding in self.binding_items().copy():
+ binding.remove()
+
+ super(Exchange, self).remove()
+
+ def write_xml(self, writer):
+ writer.write("<exchange id=\"exchange-%i\">" % self.id)
+ writer.write("<name>%s</name>" % self.name)
+ #writer.write("<error-count>%i</error-count>" % self.error_count)
+ #writer.write("<warning-count>%i</warning-count>" % self.warning_count)
+
+ for realm in self.realm_items():
+ writer.write("<realm ref=\"realm-%i\"/>" % realm.id)
+
+ for binding in self.binding_items():
+ binding.write_xml(writer)
+
+ writer.write("</exchange>")
+
+class Binding(ModelObject):
+ def __init__(self, model):
+ super(Binding, self).__init__(model, model.binding)
+
+ self.routing_key = None
+
+ def write_xml(self, writer):
+ writer.write("<binding id=\"binding-%i\">" % self.id)
+ writer.write("<exchange ref=\"exchange-%i\"/>" % self.exchange.id)
+ writer.write("<queue ref=\"queue-%i\"/>" % self.queue.id)
+ writer.write("<routing-key>%s</routing-key>" % self.routing_key)
+ writer.write("</binding>")
Added: mgmt/cumin/python/cumin/page.py
===================================================================
--- mgmt/cumin/python/cumin/page.py (rev 0)
+++ mgmt/cumin/python/cumin/page.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,143 @@
+from wooly import *
+from wooly.debug import *
+from wooly.widgets import *
+from wooly.resources import *
+
+from server import *
+from cluster import *
+from widgets import *
+
+strings = StringCatalog(__file__)
+
+class CuminPage(Page):
+ def __init__(self, app, name):
+ super(CuminPage, self).__init__(app, name)
+
+ self.frames = self.FramesAttribute(app, "frames")
+ self.add_attribute(self.frames)
+
+ self.modal = Attribute(app, "modal")
+ self.add_attribute(self.modal)
+
+ self.citem = self.ContextItem(app, "citem")
+ self.add_child(self.citem)
+
+ self.main = MainFrame(app, "main")
+ self.add_child(self.main)
+
+ class FramesAttribute(Attribute):
+ def get_default(self, session):
+ return list()
+
+ def set_modal(self, session, modal):
+ self.modal.set(session, modal)
+
+ def save_session(self, session):
+ self.app.sessions.append(session)
+
+ def show_server(self, session, server):
+ return self.main.show_server(session, server)
+
+ def show_cluster(self, session, cluster):
+ return self.main.show_cluster(session, cluster)
+
+ def show_virtual_host(self, session, vhost):
+ frame = self.show_server(session, vhost.server)
+ return frame.show_virtual_host(session, vhost)
+
+ def show_queue(self, session, queue):
+ frame = self.show_virtual_host(session, queue.virtual_host)
+ return frame.show_queue(session, queue)
+
+ def show_exchange(self, session, exchange):
+ frame = self.show_virtual_host(session, exchange.virtual_host)
+ return frame.show_exchange(session, exchange)
+
+ def render_title(self, session, object):
+ return "Cumin"
+
+ def render_class(self, session, object):
+ return self.modal.get(session) and "modal"
+
+ def render_content(self, session, object):
+ return self.main.render(session, object)
+
+ def get_frames(self, session):
+ return self.frames.get(session)
+
+ def render_context_items(self, session, object):
+ writer = Writer()
+
+ for frame in self.get_frames(session):
+ writer.write(self.citem.render(session, frame))
+
+ return writer.to_string()
+
+ # XXX use a child template instead
+ class ContextItem(Widget):
+ def render_href(self, session, frame):
+ return frame.render_href(session, frame.get_object(session))
+
+ def render_content(self, session, frame):
+ return frame.render_title(session, frame.get_object(session))
+
+class MainFrame(CuminFrame):
+ def __init__(self, app, name):
+ super(MainFrame, self).__init__(app, name)
+
+ self.view = MainView(app, "view")
+ self.add_child(self.view)
+
+ self.server = ServerFrame(app, "server")
+ self.add_child(self.server)
+
+ self.cluster = ClusterFrame(app, "cluster")
+ self.add_child(self.cluster)
+
+ def get_object(self, session):
+ return self.app.model
+
+ def show_view(self, session):
+ return self.show_mode(session, self.view)
+
+ def show_server(self, session, server):
+ self.server.set_server(session, server)
+ return self.show_mode(session, self.server)
+
+ def show_cluster(self, session, cluster):
+ self.cluster.set_cluster(session, cluster)
+ return self.show_mode(session, self.cluster)
+
+ def render_href(self, session, model):
+ branch = session.branch()
+ self.show_view(branch)
+ return branch.marshal()
+
+ def render_title(self, session, model):
+ return "<img src=\"resource?name=logo.png\"/>"
+
+class MainView(Widget):
+ def __init__(self, app, name):
+ super(MainView, self).__init__(app, name)
+
+ self.tabs = TabSet(app, "tabs")
+ self.add_child(self.tabs)
+
+ self.tabs.add_child(self.ServerTab(app, "servers"))
+ self.tabs.add_child(ClusterSet(app, "clusters"))
+
+ def render_title(self, session, model):
+ return "Red Hat Messaging"
+
+ class ServerTab(TabSet):
+ def __init__(self, app, name):
+ super(MainView.ServerTab, self).__init__(app, name)
+
+ self.servers = ServerSet(app, "servers")
+ self.add_child(self.servers)
+
+ self.groups = ServerGroupTree(app, "groups")
+ self.add_child(self.groups)
+
+ def render_title(self, session, model):
+ return "Servers (%i)" % len(model.get_servers())
Added: mgmt/cumin/python/cumin/page.strings
===================================================================
--- mgmt/cumin/python/cumin/page.strings (rev 0)
+++ mgmt/cumin/python/cumin/page.strings 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,310 @@
+[CuminPage.css]
+body {
+ margin: 0;
+ padding: 0;
+ background-color: #fff;
+ font-size: 0.9em;
+}
+
+body.modal #head {
+ opacity: 0.2;
+}
+
+body.modal {
+ background-color: #f7f7f7;
+}
+
+img {
+ border: none;
+}
+
+* {
+ text-decoration: none;
+}
+
+a {
+ color: #06c;
+}
+
+#head, #foot {
+ padding: 0.5em 0.75em 0.4em 0.75em;
+}
+
+#head {
+ background-color: #564979;
+}
+
+#body {
+ padding: 1em;
+}
+
+#logo {
+ vertical-align: -15%;
+}
+
+h1, h2 {
+ margin: 0;
+}
+
+h1 {
+ font-size: 1.1em;
+}
+
+h1 img {
+ vertical-align: -50%;
+ margin: 0 0.5em 0 0;
+}
+
+h2 {
+ font-size: 1em;
+ font-weight: normal;
+}
+
+.oblock {
+ padding: 0;
+ background-color: white;
+}
+
+.iblock {
+ margin: 0;
+ padding: 0 1em;
+}
+
+ul#context {
+ display: inline;
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+ul#context li {
+ display: inline;
+}
+
+ul#context li:after {
+ content: " > ";
+ font-weight: bold;
+ font-size: 0.8em;
+ color: #fff;
+}
+
+ul#context li:last-child:after {
+ content: "";
+}
+
+ul#context li a {
+ color: #ff9f00;
+}
+
+ul#context li:first-child a {
+ vertical-align: -15%;
+}
+
+ul#context li:last-child a {
+ color: #fff;
+}
+
+ul.actions {
+ padding: 0;
+ margin: 1em 0;
+ list-style: none;
+}
+
+dl.properties {
+ margin: 1em 0;
+ width: 25em;
+}
+
+dl.properties dt, dd {
+ border-top: 1px dotted #ddd;
+ padding: 0.25em 0.5em;
+}
+
+dl.properties dt {
+ width: 10em;
+ float: left;
+ background-color: #f7f7f7;
+ margin-right: 0.5em;
+}
+
+ul.mobjects {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+ul.mobjects li {
+ margin: 0;
+ border-top: 1px solid #ccc;
+ padding: 0.5em 0;
+}
+
+ul.mobjects li:first-child {
+ margin: 0;
+ border: none;
+}
+
+ul.mobjects li a.action {
+ float: right;
+}
+
+a.action:before, ul.actions li:before {
+ content: "\00BB \0020";
+ font-weight: bold;
+ color: #dc9f2e;
+}
+
+ul.mobjects .flags {
+ font-size: small;
+ font-style: italic;
+}
+
+ul.mobjects .config {
+ padding: 0 0 0 2em;
+}
+
+ul.mobjects .status {
+ padding: 0 0 0 2em;
+ color: #936;
+}
+
+table.mobjects {
+ width: 100%;
+ border-collapse: collapse;
+ margin: 0;
+}
+
+table.mobjects tr {
+ border-top: 1px dotted #ccc;
+ vertical-align: top;
+}
+
+table.mobjects td {
+ padding: 0.5em;
+}
+
+table.mobjects th {
+ padding: 0.25em 0.5em;
+}
+
+table.mobjects th {
+ text-align: left;
+ font-weight: normal;
+ background-color: #f7f7f7;
+}
+
+form.mform {
+ width: 50em;
+ border: 1px solid #ddd;
+ background-color: #fff;
+}
+
+form.mform fieldset {
+ border: none;
+ padding: 0.75em;
+}
+
+form.mform .legend {
+ font-weight: bold;
+}
+
+form.mform .head, .mform .body, .mform .foot {
+ padding: 0.5em 0.75em;
+ margin: 0;
+}
+
+form.mform .head {
+ font-weight: bold;
+ color: white;
+ background-color: #564979;
+}
+
+form.mform .foot {
+ text-align: right;
+ border-top: 1px solid #ddd;
+}
+
+form.mform .field {
+ margin: 0.25em 0;
+}
+
+form.mform .field input {
+ border-style: groove;
+}
+
+form.mform ul.errors {
+ list-style: none;
+ display: block;
+ float: right;
+ color: red;
+ padding: 0.25em 0.5em;
+ border: 1px solid red;
+ margin: 0 0.5em;
+ max-width: 20em;
+}
+
+form.mform button {
+ border-style: groove;
+ padding: 0.25em 0.5em;
+ margin: 0.5em;
+}
+
+ul.radiotabs {
+ list-style: none;
+ margin: 0.25em 0 1em 0;
+ padding: 0;
+}
+
+ul.radiotabs li {
+ display: inline;
+ margin: 0 1em 0 0;
+}
+
+ul.radiotabs li a:before {
+ content: url(resource?name=radio-button.png);
+ margin: 0 0.5em 0 0;
+ vertical-align: -15%;
+}
+
+ul.radiotabs li a.selected {
+ color: black;
+}
+
+ul.radiotabs li a.selected:before {
+ content: url(resource?name=radio-button-checked.png);
+}
+
+[CuminPage.html]
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
+ <head>
+ <title>{title}</title>
+ <link rel="stylesheet" type="text/css" href="cumin.css"/>
+ <script src="resource?name=wooly.js"> </script>
+ </head>
+ <body class="{class}">
+ <div id="head"><ul id="context">{context_items}</ul></div>
+ <div id="body">{content}</div>
+ <div id="foot">
+ </div>
+ </body>
+</html>
+
+[ContextItem.html]
+<li><a href="{href}">{content}</a></li>
+
+[MainView.html]
+<div class="oblock">
+ <h1>{title}</h1>
+ <ul class="actions">
+ <li><a href="">Add Server</a></li>
+ <li><a href="">Add Server Group</a></li>
+ <li><a href="">Add Cluster</a></li>
+ </ul>
+ {tabs}
+</div>
+
+[ServerTab.html]
+<ul class="ServerTab radiotabs tabs">{tabs}</ul>
+<div class="ServerTab mode">{mode}</div>
Added: mgmt/cumin/python/cumin/queue.py
===================================================================
--- mgmt/cumin/python/cumin/queue.py (rev 0)
+++ mgmt/cumin/python/cumin/queue.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,416 @@
+from wooly import *
+from wooly.widgets import *
+from wooly.forms import *
+from wooly.resources import *
+
+from model import *
+from widgets import *
+from exchange import ExchangeInputSet
+
+strings = StringCatalog(__file__)
+
+class QueueXmlPage(Page):
+ def __init__(self, app, name):
+ super(QueueXmlPage, self).__init__(app, name)
+
+ self.queue = QueueParameter(app, "id")
+ self.add_parameter(self.queue)
+
+ def get_content_type(self, session):
+ return Page.xml_content_type
+
+ def do_render(self, session, object):
+ writer = Writer()
+
+ writer.write(Page.xml_1_0_declaration)
+ self.queue.get(session).write_xml(writer)
+
+ return writer.to_string()
+
+class QueueSet(ItemSet):
+ def render_title(self, session, vhost):
+ return "Queues (%s)" % len(vhost.queue_items())
+
+ def get_items(self, session, vhost):
+ return sorted(vhost.queue_items())
+
+ def render_item_href(self, session, queue):
+ branch = session.branch()
+ self.page().show_queue(branch, queue).show_view(branch)
+ return branch.marshal()
+
+ def render_item_name(self, session, queue):
+ return queue.name
+
+ def render_item_flags(self, session, queue):
+ flags = list()
+
+ if queue.is_durable:
+ flags.append("Durable")
+
+ if queue.is_auto_delete:
+ flags.append("Auto Delete")
+
+ return ", ".join(flags)
+
+ def render_item_config(self, session, queue):
+ bindings = list()
+
+ for binding in sorted(queue.binding_items()):
+ name = binding.get_exchange().name
+ key = binding.routing_key
+
+ branch = session.branch()
+ self.page().show_exchange(branch, binding.get_exchange())
+ href = branch.marshal()
+
+ bindings.append("<a href=\"%s\">exchange '%s'</a> with key '%s'"
+ % (href, name, key))
+
+ return ", ".join(bindings)
+
+ def render_item_status(self, session, queue):
+ return "%i messages in queue<br/>%i errors, %i warnings" \
+ % (queue.message_count, queue.error_count, queue.warning_count)
+
+class QueueParameter(Parameter):
+ def do_unmarshal(self, string):
+ return self.app.model.get_queue(int(string))
+
+ def do_marshal(self, queue):
+ return str(queue.id)
+
+class QueueFrame(CuminFrame):
+ def __init__(self, app, name):
+ super(QueueFrame, self).__init__(app, name)
+
+ self.param = QueueParameter(app, "id")
+ self.add_parameter(self.param)
+ self.set_object_attribute(self.param)
+
+ self.view = QueueView(app, "view")
+ self.add_child(self.view)
+
+ self.edit = QueueEdit(app, "edit")
+ self.add_child(self.edit)
+
+ self.remove = QueueRemove(app, "remove")
+ self.add_child(self.remove)
+
+ self.binding_add = QueueBindingAdd(app, "binding_add")
+ self.add_child(self.binding_add)
+
+ def set_queue(self, session, queue):
+ return self.param.set(session, queue)
+
+ def show_view(self, session):
+ return self.show_mode(session, self.view)
+
+ def show_edit(self, session):
+ return self.show_mode(session, self.edit)
+
+ def show_remove(self, session):
+ return self.show_mode(session, self.remove)
+
+ def show_binding_add(self, session):
+ return self.show_mode(session, self.binding_add)
+
+ def render_href(self, session, queue):
+ branch = session.branch()
+ self.show_view(branch)
+ return branch.marshal()
+
+ def render_title(self, session, queue):
+ return "Queue '%s'" % queue.name
+
+class QueueStatus(Widget):
+ def render_class(self, session, queue):
+ if queue.error_count:
+ return "QueueStatus red"
+ elif queue.warning_count:
+ return "QueueStatus yellow"
+ else:
+ return "QueueStatus green"
+
+ def render_url(self, session, queue):
+ return "queue.xml?id=%i" % queue.id
+
+ def render_message_info(self, session, queue):
+ return "%i %s in queue" % \
+ (queue.message_count,
+ queue.message_count == 1 and "message" or "messages")
+
+ def render_error_info(self, session, queue):
+ return "%i %s, %i %s" % \
+ (queue.error_count,
+ queue.error_count == 1 and "error" or "errors",
+ queue.warning_count,
+ queue.warning_count == 1 and "warning" or "warnings")
+
+class QueueView(Widget):
+ def __init__(self, app, name):
+ super(QueueView, self).__init__(app, name)
+
+ self.status = QueueStatus(app, "status")
+ self.add_child(self.status)
+
+ self.tabs = TabSet(app, "tabs")
+ self.add_child(self.tabs)
+
+ self.tabs.add_child(QueueBindingSet(app, "bindings"))
+ self.tabs.add_child(self.QueueLog(app, "log"))
+
+ class QueueLog(Widget):
+ def render_title(self, session, queue):
+ return "Log Messages"
+
+ def render_title(self, session, queue):
+ return "Queue '%s'" % queue.name
+
+ def render_queue_name(self, session, queue):
+ return queue.name
+
+ def render_latency_tuning(self, session, queue):
+ if queue.latency_priority == "h":
+ return "Lower Latency"
+ elif queue.latency_priority == "m":
+ return "Balanced"
+ elif queue.latency_priority == "l":
+ return "Higher Throughput"
+ else:
+ raise Exception()
+
+ def render_edit_queue_href(self, session, queue):
+ branch = session.branch()
+ self.page().show_queue(branch, queue).show_edit(branch)
+ return branch.marshal()
+
+ def render_remove_queue_href(self, session, queue):
+ branch = session.branch()
+ self.page().show_queue(branch, queue).show_remove(branch)
+ return branch.marshal()
+
+ def render_add_binding_href(self, session, queue):
+ branch = session.branch()
+ self.page().show_queue(branch, queue).show_binding_add(branch)
+ return branch.marshal()
+
+class QueueBindingSet(ItemSet):
+ def render_title(self, session, queue):
+ return "Bindings (%i)" % len(queue.binding_items())
+
+ def get_items(self, session, queue):
+ return sorted(queue.binding_items())
+
+ def render_item_href(self, session, binding):
+ branch = session.branch()
+ self.page().show_exchange(branch, binding.get_exchange())
+ return branch.marshal()
+
+ def render_item_remove_href(self, session, binding):
+ branch = session.branch()
+ return branch.marshal()
+
+ def render_item_name(self, session, binding):
+ return binding.get_exchange().name
+
+ def render_item_routing_key(self, session, binding):
+ return binding.routing_key
+
+class QueueForm(CuminForm):
+ def __init__(self, app, name):
+ super(QueueForm, self).__init__(app, name)
+
+ self.queue_name = TextInput(app, "queue_name", self)
+ self.add_child(self.queue_name)
+
+ # XXX Convert tuning stuff into single subwidget
+
+ self.latency_priority = Parameter(app, "tuning")
+ self.latency_priority.set_default("m")
+ self.add_parameter(self.latency_priority)
+
+ self.latency = RadioInput(app, "latency", self)
+ self.latency.set_parameter(self.latency_priority)
+ self.latency.set_value("h")
+ self.add_child(self.latency)
+
+ self.balanced = RadioInput(app, "balanced", self)
+ self.balanced.set_parameter(self.latency_priority)
+ self.balanced.set_value("m")
+ self.add_child(self.balanced)
+
+ self.throughput = RadioInput(app, "throughput", self)
+ self.throughput.set_parameter(self.latency_priority)
+ self.throughput.set_value("l")
+ self.add_child(self.throughput)
+
+ def validate(self, session):
+ valid = True
+
+ name = self.queue_name.get(session)
+
+ if name == "":
+ valid = False
+ self.queue_name.add_error(session, """
+ The queue name is empty; it is required
+ """)
+ elif " " in name:
+ valid = False
+ self.queue_name.add_error(session, """
+ The queue name is invalid; allowed characters are
+ letters, digits, ".", and "_"
+ """)
+
+ return valid
+
+class QueueAdd(QueueForm):
+ def on_cancel(self, session, vhost):
+ branch = session.branch()
+ self.page().show_virtual_host(branch, vhost).show_view(branch)
+ session.set_redirect(branch.marshal())
+
+ def on_submit(self, session, vhost):
+ if self.validate(session):
+ queue = Queue(self.app.model)
+
+ queue.lock()
+ try:
+ queue.name = self.queue_name.get(session)
+ queue.latency_priority = self.latency_priority.get(session)
+ finally:
+ queue.unlock()
+
+ vhost.add_queue(queue)
+
+ branch = session.branch()
+ self.page().show_queue(branch, queue).show_view(branch)
+ session.set_redirect(branch.marshal())
+
+ def render_title(self, session, vhost):
+ return "Add Queue to Virtual Host '%s'" % vhost.name
+
+class QueueEdit(QueueForm):
+ def on_cancel(self, session, queue):
+ branch = session.branch()
+ self.page().show_queue(branch, queue).show_view(branch)
+ session.set_redirect(branch.marshal())
+
+ def on_submit(self, session, queue):
+ if self.validate(session):
+ queue.lock()
+ try:
+ queue.name = self.queue_name.get(session)
+ queue.latency_priority = self.latency_priority.get(session)
+ finally:
+ queue.unlock()
+
+ branch = session.branch()
+ self.page().show_queue(branch, queue).show_view(branch)
+ session.set_redirect(branch.marshal())
+
+ def on_display(self, session, queue):
+ self.queue_name.set(session, queue.name)
+ self.latency_priority.set(session, queue.latency_priority)
+
+ def render_title(self, session, queue):
+ return "Edit Queue '%s'" % queue.name
+
+class QueueRemove(CuminConfirmForm):
+ def on_confirm(self, session, queue):
+ vhost = queue.get_virtual_host()
+
+ queue.remove()
+
+ branch = session.branch()
+ self.page().show_virtual_host(branch, vhost).show_view(branch)
+ session.set_redirect(branch.marshal())
+
+ def on_cancel(self, session, queue):
+ branch = session.branch()
+ self.page().show_queue(branch, queue).show_view(branch)
+ session.set_redirect(branch.marshal())
+
+ def render_title(self, session, queue):
+ return "Remove Queue '%s'" % queue.name
+
+ def render_confirm_content(self, session, queue):
+ return "Yes, Remove Queue '%s'" % queue.name
+
+ def render_cancel_content(self, session, queue):
+ return "No, Cancel"
+
+class QueueBindingAdd(CuminForm):
+ def __init__(self, app, name):
+ super(QueueBindingAdd, self).__init__(app, name)
+
+ self.exchanges = self.Exchanges(app, "exchanges", self)
+ self.add_child(self.exchanges)
+
+ self.routing_key = TextInput(app, "routing_key", self)
+ self.add_child(self.routing_key)
+
+ def render_title(self, session, queue):
+ return "Add Binding to Queue '%s'" % queue.name
+
+ def on_cancel(self, session, queue):
+ branch = session.branch()
+ self.page().show_queue(branch, queue).show_view(branch)
+ session.set_redirect(branch.marshal())
+
+ def validate(self, session):
+ valid = True
+
+ if not self.routing_key.get(session):
+ valid = False
+ self.routing_key.add_error(session, """
+ The routing key is empty; it is required
+ """)
+
+ if not self.exchanges.get(session):
+ valid = False
+ self.exchanges.add_error(session, """
+ No exchange selected; it is required
+ """)
+
+ return valid
+
+ def on_submit(self, session, queue):
+ if self.validate(session):
+ binding = Binding(self.app.model)
+
+ binding.lock()
+ try:
+ binding.routing_key = self.routing_key.get(session)
+ binding.set_queue(queue)
+ binding.set_exchange(self.exchanges.get(session))
+ finally:
+ binding.unlock()
+
+ branch = session.branch()
+ self.page().show_queue(branch, queue).show_view(branch)
+ session.set_redirect(branch.marshal())
+
+ class Exchanges(ExchangeInputSet):
+ def get_items(self, session, queue):
+ return sorted(queue.virtual_host.exchange_items())
+
+class QueueBindingRemove(CuminConfirmForm):
+ def on_confirm(self, session, binding):
+ branch = session.branch()
+ self.page().show_queue(branch, binding.get_queue()).show_view(branch)
+ session.set_redirect(branch.marshal())
+
+ def on_cancel(self, session, binding):
+ branch = session.branch()
+ self.page().show_queue(branch, binding.get_queue()).show_view(branch)
+ session.set_redirect(branch.marshal())
+
+ def render_title(self, session, binding):
+ return "Remove Binding"
+
+ def render_confirm_content(self, session, binding):
+ return "Yes, Remove Binding"
+
+ def render_cancel_content(self, session, binding):
+ return "No, Cancel"
Added: mgmt/cumin/python/cumin/queue.strings
===================================================================
--- mgmt/cumin/python/cumin/queue.strings (rev 0)
+++ mgmt/cumin/python/cumin/queue.strings 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,199 @@
+[QueueSet.css]
+ul.QueueSet li:before {
+ content: url(resource?name=queue-20.png);
+ vertical-align: -30%;
+ padding: 0 0.25em;
+}
+
+[QueueSet.html]
+<table class="QueueSet mobjects">
+<tr>
+ <th>Name</th>
+ <th>Exchanges</th>
+ <th>Status</th>
+</tr>
+{items}
+</table>
+
+[QueueSet.item_html]
+<tr>
+ <td><a href="{item_href}">{item_name}</a></td>
+ <td>{item_config}</td>
+ <td>{item_status}</td>
+</tr>
+
+[QueueForm.html]
+<form id="{id}" class="QueueForm mform" method="post" action="?">
+ <div class="head">
+ <h1>{title}</h1>
+ </div>
+ <div class="body">
+ <span class="legend">Name</span>
+ <fieldset>
+ <div class="field">{queue_name}</div>
+ </fieldset>
+ <span class="legend">Latency Tuning</span>
+ <fieldset>
+ <div class="field">
+ {latency}
+ <em>Lower Latency:</em> Tune for shorter delays, with reduced volume
+ </div>
+ <div class="field">
+ {balanced}
+ <em>Balanced</em>
+ </div>
+ <div class="field">
+ {throughput}
+ <em>Higher Throughput:</em> Tune for increased volume, with longer
+ delays
+ </div>
+ </fieldset>
+{hidden_inputs}
+ </div>
+ <div class="foot">
+ <div style="display: block; float: left;"><button>Help</button></div>
+{cancel}
+{submit}
+ </div>
+</form>
+<script defer="defer">
+var id = "{id}";
+(function() {
+ // XXX elements[0] is a fieldset, at least in firefox
+ var elem = wooly.doc().elem(id).node.elements[1];
+ elem.focus();
+ elem.select();
+}())
+</script>
+
+[QueueStatus.css]
+.QueueStatus {
+ float: right;
+ margin: 1em;
+ padding: 0.75em 1em;
+ width: 15em;
+}
+
+.QueueStatus h2 {
+ font-weight: bold;
+ margin: 0 0 0.5em 0;
+}
+
+.QueueStatus.red {
+ border: 1px solid #c99;
+ background-color: #fcc;
+}
+
+.QueueStatus.yellow {
+ border: 1px solid #cc9;
+ background-color: #ffc;
+}
+
+.QueueStatus.green {
+ border: 1px solid #9c9;
+ background-color: #cfc;
+}
+
+[QueueStatus.html]
+<script defer="defer">
+(function() {
+ var updateStatus = function(xml, elem) {
+ var mcount = xml.elems("message-count").next().text().get();
+ var messages = mcount + " " + (mcount == "1" && "message" || "messages");
+
+ var ecount = xml.elems("error-count").next().text().get();
+ var errors = ecount + " " + (ecount == "1" && "error" || "errors");
+
+ var wcount = xml.elems("warning-count").next().text().get();
+ var warnings = wcount + " " + (wcount == "1" && "warning" || "warnings");
+
+ if (ecount != "0") {
+ elem.node.className = "QueueStatus red";
+ } else if (wcount != "0") {
+ elem.node.className = "QueueStatus yellow";
+ } else {
+ elem.node.className = "QueueStatus green";
+ }
+
+ var divs = elem.elems("div");
+ divs.next().set(messages + " in queue");
+ divs.next().set(errors + ", " + warnings);
+ }
+
+ wooly.setIntervalUpdate("{id}", "{url}", updateStatus, 3000);
+}())
+</script>
+<div class="{class}" id="{id}">
+ <h2>Queue Status</h2>
+
+ <div>{message_info}</div>
+ <div>{error_info}</div>
+</div>
+
+[QueueView.html]
+<div class="QueueView oblock">
+ {status}
+
+ <h1><img src="resource?name=queue-36.png"> {title}</h1>
+
+ <dl class="properties">
+ <dt>Queue Name</dt><dd>{queue_name}</dd>
+ <dt>Latency Tuning</dt><dd>{latency_tuning}</dd>
+ </dl>
+
+ <ul class="actions">
+ <li><a href="{edit_queue_href}">Edit Queue</a></li>
+ <li><a href="{remove_queue_href}">Remove Queue</a></li>
+ <li><a href="{add_binding_href}">Add Binding</a></li>
+ </ul>
+
+ {tabs}
+</div>
+
+[QueueBindingSet.html]
+<table class="QueueBindingSet mobjects">
+ <tr>
+ <th>Exchange</th>
+ <th>Routing Key</th>
+ <th></th>
+ </tr>
+{items}
+</table>
+
+[QueueBindingSet.item_html]
+<tr>
+ <td><a href="{item_href}">exchange '{item_name}'</a></td>
+ <td>{item_routing_key}</td>
+ <td><a class="action" href="{item_remove_href}">Remove</a></td>
+</tr>
+
+[QueueBindingAdd.html]
+<form id="{id}" class="QueueBindingAdd mform" method="post" action="?">
+ <div class="head">
+ <h1>{title}</h1>
+ </div>
+ <div class="body">
+ <span class="legend">Exchange</span>
+ <fieldset>{exchanges}</fieldset>
+ <span class="legend">Routing Key</span>
+ <fieldset>
+ <div class="field">{routing_key}</div>
+ </fieldset>
+{hidden_inputs}
+ </div>
+ <div class="foot">
+ <div style="display: block; float: left;"><button>Help</button></div>
+{cancel}
+{submit}
+ </div>
+</form>
+<script defer="defer">
+var id = "{id}";
+(function() {
+ // XXX elements[0] is a fieldset, at least in firefox
+ var elem = wooly.doc().elem(id).node.elements[1];
+ elem.focus();
+ elem.select();
+}())
+</script>
+
Added: mgmt/cumin/python/cumin/realm.py
===================================================================
--- mgmt/cumin/python/cumin/realm.py (rev 0)
+++ mgmt/cumin/python/cumin/realm.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,56 @@
+from wooly import *
+from wooly.widgets import *
+from wooly.forms import *
+from wooly.resources import *
+
+from model import *
+from widgets import *
+
+strings = StringCatalog(__file__)
+
+class RealmSet(ItemSet):
+ def render_title(self, session, vhost):
+ return "Realms (%i)" % len(vhost.realm_items())
+
+ def get_items(self, session, vhost):
+ return sorted(vhost.realm_items())
+
+ def render_item_name(self, session, realm):
+ return realm.name
+
+class RealmParameter(Parameter):
+ def do_unmarshal(self, string):
+ return self.app.model.get_realm(int(string))
+
+ def do_marshal(self, queue):
+ return str(realm.id)
+
+class RealmInputSet(CheckboxInputSet):
+ def __init__(self, app, name, form):
+ super(RealmInputSet, self).__init__(app, name, form)
+
+ param = ListParameter(app, "param", RealmParameter(app, "item"))
+ self.add_parameter(param)
+ self.set_parameter(param)
+
+ def get_items(self, session, vhost):
+ return sorted(vhost.realm_items())
+
+ # XXX just parked here
+ def do_process(self, session, queue):
+ for realm in self.get(session):
+ if realm not in queue.realm_items():
+ queue.add_realm(realm)
+
+ for realm in list(queue.realm_items()):
+ if realm not in self.get(session):
+ queue.remove_realm(realm)
+
+ def render_item_value(self, session, realm):
+ return realm.id
+
+ def render_item_content(self, session, realm):
+ return realm.name
+
+ def render_item_checked_attr(self, session, realm):
+ return realm in self.param.get(session) and "checked=\"checked\""
Added: mgmt/cumin/python/cumin/realm.strings
===================================================================
--- mgmt/cumin/python/cumin/realm.strings (rev 0)
+++ mgmt/cumin/python/cumin/realm.strings 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,13 @@
+[RealmInputSet.item_html]
+<div class="field">
+ <input type="checkbox" name="{name}" value="{item_value}" tabindex="{tabindex}" {item_checked_attr}/>
+ {item_content}
+</div>
+
+[RealmSet.html]
+<ul class="RealmSet mobjects">{items}</ul>
+
+[RealmSet.item_html]
+<li>
+ <strong><a href="{item_href}">{item_name}</a></strong>
+</li>
Added: mgmt/cumin/python/cumin/server.py
===================================================================
--- mgmt/cumin/python/cumin/server.py (rev 0)
+++ mgmt/cumin/python/cumin/server.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,146 @@
+from wooly import *
+from wooly.widgets import *
+
+from virtualhost import *
+from widgets import *
+
+strings = StringCatalog(__file__)
+
+class ServerSet(ItemSet):
+ def render_title(self, session, model):
+ return "Servers (%i)" % len(model.get_servers())
+
+ def get_items(self, session, model):
+ return sorted(model.get_servers())
+
+ def render_item_href(self, session, server):
+ branch = session.branch()
+ self.page().show_server(branch, server).show_view(branch)
+ return branch.marshal()
+
+ def render_item_name(self, session, server):
+ return server.name
+
+ def render_item_cluster_name(self, session, server):
+ cluster = server.get_cluster()
+
+ if cluster:
+ return cluster.name
+
+ def render_item_cluster_href(self, session, server):
+ cluster = server.get_cluster()
+
+ if cluster:
+ branch = session.branch()
+ self.page().show_cluster(branch, cluster).show_view(branch)
+ return branch.marshal()
+
+class ServerParameter(Parameter):
+ def do_unmarshal(self, string):
+ return self.app.model.get_server(int(string))
+
+ def do_marshal(self, server):
+ return str(server.id)
+
+class ServerFrame(CuminFrame):
+ def __init__(self, app, name):
+ super(ServerFrame, self).__init__(app, name)
+
+ self.param = ServerParameter(app, "id")
+ self.add_parameter(self.param)
+ self.set_object_attribute(self.param)
+
+ self.view = ServerView(app, "view")
+ self.add_child(self.view)
+
+ self.vhost = VirtualHostFrame(app, "vhost")
+ self.add_child(self.vhost)
+
+ def set_server(self, session, server):
+ self.param.set(session, server)
+
+ def show_view(self, session):
+ return self.show_mode(session, self.view)
+
+ def show_virtual_host(self, session, vhost):
+ self.vhost.set_virtual_host(session, vhost)
+ return self.show_mode(session, self.vhost)
+
+ def show_queue(self, session, queue):
+ vhost = self.show_virtual_host(session, queue.virtual_host)
+ return vhost.show_queue(session, queue)
+
+ def show_exchange(self, session, exchange):
+ vhost = self.show_virtual_host(session, exchange.virtual_host)
+ return vhost.show_exchange(session, exchange)
+
+ def render_href(self, session, server):
+ branch = session.branch()
+ self.show_mode(branch, self.view)
+ return branch.marshal()
+
+ def render_title(self, session, server):
+ return "Server '%s'" % server.name
+
+class ServerView(Widget):
+ def __init__(self, app, name):
+ super(ServerView, self).__init__(app, name)
+
+ self.tabs = TabSet(app, "tabs")
+ self.add_child(self.tabs)
+
+ self.vhosts = VirtualHostSet(app, "virtual_hosts")
+ self.tabs.add_child(self.vhosts)
+
+ self.log = self.ServerLog(app, "log")
+ self.tabs.add_child(self.log)
+
+ def render_title(self, session, server):
+ return "Server '%s'" % server.name
+
+ class ServerLog(Widget):
+ def render_title(self, session, server):
+ return "Log Messages"
+
+class ServerGroupTree(Widget):
+ def __init__(self, app, name):
+ super(ServerGroupTree, self).__init__(app, name)
+
+ self.item_tmpl = Template(self, "item_html")
+
+ def render_title(self, session, model):
+ return "Server Groups (%i)" % len(model.get_server_groups())
+
+ def get_root_items(self, session, model):
+ roots = list()
+
+ for group in model.get_server_groups():
+ if not group.parent_items():
+ roots.append(group)
+
+ return roots
+
+ def get_child_items(self, session, group):
+ return group.child_items()
+
+ def render_root_items(self, session, model):
+ roots = self.get_root_items(session, model)
+
+ if roots:
+ writer = Writer()
+
+ for root in roots:
+ self.item_tmpl.render(session, root, writer)
+
+ return writer.to_string()
+
+ def render_child_items(self, session, object):
+ writer = Writer()
+
+ for child in self.get_child_items(session, object):
+ self.item_tmpl.render(session, child, writer)
+
+ return writer.to_string()
+
+ def render_item_name(self, session, group):
+ return group.name
Added: mgmt/cumin/python/cumin/server.strings
===================================================================
--- mgmt/cumin/python/cumin/server.strings (rev 0)
+++ mgmt/cumin/python/cumin/server.strings 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,44 @@
+[ServerSet.html]
+<table class="ServerSet mobjects">
+ <tr>
+ <th>Name</th>
+ <th>Cluster</th>
+ <th>Status</th>
+ </tr>
+{items}
+</table>
+
+[ServerSet.item_html]
+<tr>
+ <td><a href="{item_href}">{item_name}</a></td>
+ <td><a href="{item_cluster_href}">{item_cluster_name}</a></td>
+ <td>0 errors, 0 warnings</td>
+</tr>
+
+[ServerView.html]
+<div class="oblock">
+ <h1>{title}</h1>
+
+ <ul class="actions">
+ <li><a href="">Shutdown</a></li>
+ </ul>
+ {tabs}
+</div>
+
+[ServerGroupTree.css]
+ul.ServerGroupTree, ul.ServerGroupTree ul {
+ list-style: square;
+ color: #ccc;
+ padding: 0 0 0 2em;
+}
+
+ul.ServerGroupTree {
+ padding: 0 0 0 1em;
+}
+
+[ServerGroupTree.html]
+<ul class="ServerGroupTree">{root_items}</ul>
+
+[ServerGroupTree.item_html]
+<li><a href="">{item_name}</a></li>
+<ul>{child_items}</ul>
Added: mgmt/cumin/python/cumin/virtualhost.py
===================================================================
--- mgmt/cumin/python/cumin/virtualhost.py (rev 0)
+++ mgmt/cumin/python/cumin/virtualhost.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,117 @@
+from wooly import *
+from wooly.widgets import *
+
+from queue import *
+from realm import *
+from exchange import *
+from widgets import *
+
+strings = StringCatalog(__file__)
+
+class VirtualHostSet(ItemSet):
+ def render_title(self, session, server):
+ return "Virtual Hosts (%i)" % len(server.virtual_host_items())
+
+ def get_items(self, session, server):
+ return sorted(server.virtual_host_items())
+
+ def render_item_href(self, session, vhost):
+ branch = session.branch()
+ self.page().show_virtual_host(branch, vhost)
+ return branch.marshal()
+
+ def render_item_name(self, session, vhost):
+ return vhost.name
+
+class VirtualHostFrame(CuminFrame):
+ def __init__(self, app, name):
+ super(VirtualHostFrame, self).__init__(app, name)
+
+ self.param = self.VirtualHostParameter(app, "id")
+ self.add_parameter(self.param)
+ self.set_object_attribute(self.param)
+
+ self.view = VirtualHostView(app, "view")
+ self.add_child(self.view)
+
+ self.queue_add = QueueAdd(app, "queue_add")
+ self.add_child(self.queue_add)
+
+ self.queue = QueueFrame(app, "queue")
+ self.add_child(self.queue)
+
+ self.exchange_add = ExchangeAdd(app, "exchange_add")
+ self.add_child(self.exchange_add)
+
+ self.exchange = ExchangeFrame(app, "exchange")
+ self.add_child(self.exchange)
+
+ class VirtualHostParameter(Parameter):
+ def do_unmarshal(self, string):
+ return self.app.model.get_virtual_host(int(string))
+
+ def do_marshal(self, vhost):
+ return str(vhost.id)
+
+ def set_virtual_host(self, session, vhost):
+ return self.param.set(session, vhost)
+
+ def show_view(self, session):
+ return self.show_mode(session, self.view)
+
+ def show_queue_add(self, session):
+ return self.show_mode(session, self.queue_add)
+
+ def show_queue(self, session, queue):
+ self.queue.set_queue(session, queue)
+
+ return self.show_mode(session, self.queue)
+
+ def show_exchange_add(self, session):
+ return self.show_mode(session, self.exchange_add)
+
+ def show_exchange(self, session, exchange):
+ self.exchange.set_exchange(session, exchange)
+
+ return self.show_mode(session, self.exchange)
+
+ def render_href(self, session, vhost):
+ branch = session.branch()
+ self.show_view(branch)
+ return branch.marshal()
+
+ def render_title(self, session, vhost):
+ return "Virtual Host '%s'" % vhost.name
+
+class VirtualHostView(Widget):
+ def __init__(self, app, name):
+ super(VirtualHostView, self).__init__(app, name)
+
+ self.tabs = TabSet(app, "tabs")
+ self.add_child(self.tabs)
+
+ self.queues = QueueSet(app, "queues")
+ self.tabs.add_child(self.queues)
+
+ self.exchanges = ExchangeSet(app, "exchanges")
+ self.tabs.add_child(self.exchanges)
+
+ self.log = self.VirtualHostLog(app, "log")
+ self.tabs.add_child(self.log)
+
+ def render_title(self, session, vhost):
+ return "Virtual Host '%s'" % vhost.name
+
+ def render_add_queue_href(self, session, vhost):
+ branch = session.branch()
+ self.page().show_virtual_host(branch, vhost).show_queue_add(branch)
+ return branch.marshal()
+
+ def render_add_exchange_href(self, session, vhost):
+ branch = session.branch()
+ self.page().show_virtual_host(branch, vhost).show_exchange_add(branch)
+ return branch.marshal()
+
+ class VirtualHostLog(Widget):
+ def render_title(self, session, vhost):
+ return "Log Messages"
Added: mgmt/cumin/python/cumin/virtualhost.strings
===================================================================
--- mgmt/cumin/python/cumin/virtualhost.strings (rev 0)
+++ mgmt/cumin/python/cumin/virtualhost.strings 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,26 @@
+[VirtualHostSet.html]
+<table class="VirtualHostSet mobjects">
+ <tr>
+ <th>Name</th>
+ <th>Configuration</th>
+ <th>Status</th>
+ </tr>
+{items}
+</table>
+
+[VirtualHostSet.item_html]
+<tr>
+ <td><a href="{item_href}">{item_name}</a></td>
+ <td>10 queues, 5 exchanges</td>
+ <td>2 errors, 10 warnings</td>
+</tr>
+
+[VirtualHostView.html]
+<div class="oblock">
+ <h1>{title}</h1>
+ <ul class="actions">
+ <li><a href="{add_queue_href}">Add Queue</a></li>
+ <li><a href="{add_exchange_href}">Add Exchange</a></li>
+ </ul>
+{tabs}
+</div>
Added: mgmt/cumin/python/cumin/widgets.py
===================================================================
--- mgmt/cumin/python/cumin/widgets.py (rev 0)
+++ mgmt/cumin/python/cumin/widgets.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,102 @@
+from wooly import *
+from wooly.widgets import *
+from wooly.forms import *
+
+strings = StringCatalog(__file__)
+
+class CuminFrame(Frame, ModeSet):
+ def do_process(self, session, object):
+ self.page().get_frames(session).append(self)
+
+ super(CuminFrame, self).do_process(session, object)
+
+class CuminForm(Form):
+ def __init__(self, app, name):
+ super(CuminForm, self).__init__(app, name)
+
+ self.cancel = self.Cancel(app, "cancel", self)
+ self.cancel.set_tab_index(201)
+ self.add_child(self.cancel)
+
+ self.submit = self.Submit(app, "submit", self)
+ self.submit.set_tab_index(200)
+ self.add_child(self.submit)
+
+ def do_process(self, session, object):
+ self.page().set_modal(session, True)
+
+ if self.cancel.get(session):
+ self.cancel.set(session, False)
+
+ self.on_cancel(session, object)
+ elif self.submit.get(session):
+ self.submit.set(session, False)
+
+ self.on_submit(session, object)
+ else:
+ self.on_display(session, object)
+
+ def on_cancel(self, session, object):
+ pass
+
+ def on_submit(self, session, object):
+ pass
+
+ def on_display(self, session, object):
+ pass
+
+ class Cancel(FormButton):
+ def render_content(self, session, object):
+ return "Cancel"
+
+ class Submit(FormButton):
+ def render_content(self, session, object):
+ return "Submit"
+
+class CuminConfirmForm(Form):
+ def __init__(self, app, name):
+ super(CuminConfirmForm, self).__init__(app, name)
+
+ self.confirm = self.ConfirmButton(app, "confirm", self)
+ self.confirm.set_tab_index(101)
+ self.add_child(self.confirm)
+
+ self.cancel = self.CancelButton(app, "cancel", self)
+ self.add_child(self.cancel)
+
+ def do_process(self, session, object):
+ self.page().set_modal(session, True)
+
+ if self.confirm.get(session):
+ self.confirm.set(session, False)
+
+ self.on_confirm(session, object)
+ elif self.cancel.get(session):
+ self.cancel.set(session, False)
+
+ self.on_cancel(session, object)
+ else:
+ self.on_display(session, object)
+
+ def on_cancel(self, session, object):
+ pass
+
+ def on_confirm(self, session, object):
+ pass
+
+ def on_display(self, session, object):
+ pass
+
+ def render_confirm_content(self, session, object):
+ return "Confirm"
+
+ def render_cancel_content(self, session, object):
+ return "Cancel"
+
+ class ConfirmButton(FormButton):
+ def render_content(self, session, object):
+ return self.parent.render_confirm_content(session, object)
+
+ class CancelButton(FormButton):
+ def render_content(self, session, object):
+ return self.parent.render_cancel_content(session, object)
Added: mgmt/cumin/python/cumin/widgets.strings
===================================================================
--- mgmt/cumin/python/cumin/widgets.strings (rev 0)
+++ mgmt/cumin/python/cumin/widgets.strings 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,14 @@
+[CuminConfirmForm.html]
+<form id="{id}" class="QueueForm mform" method="post" action="?">
+ <div class="head">
+ <h1>{title}</h1>
+ </div>
+ <div class="body">
+ <div>{confirm}</div>
+ <div>{cancel}</div>
+{hidden_inputs}
+ </div>
+</form>
+<script>
+wooly.doc().elem("{id}").node.elements[1].focus();
+</script>
Added: mgmt/cumin/python/wooly/__init__.py
===================================================================
--- mgmt/cumin/python/wooly/__init__.py (rev 0)
+++ mgmt/cumin/python/wooly/__init__.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,639 @@
+import sys, os
+from cStringIO import StringIO
+from urllib import quote_plus, unquote_plus
+from copy import copy
+from time import time
+from datetime import datetime
+
+from resources import ResourceFinder, StringCatalog
+
+class Widget(object):
+ html = "{content}"
+
+ def __init__(self, app, name):
+ self.app = app
+ self.name = name
+ self.parent = None
+ self.children = list()
+ self.attributes = list()
+ self.parameters = list()
+ self.template = Template(self, "html")
+
+ self.cached_path = None
+ self.cached_page = None
+ self.child_index = None
+
+ app.add_widget(self)
+
+ self.strings = None
+
+ def path(self):
+ if not self.cached_path:
+ if not self.parent:
+ self.cached_path = ""
+ elif not self.parent.parent:
+ self.cached_path = self.name;
+ else:
+ self.cached_path = self.parent.path() + "." + self.name
+
+ return self.cached_path
+
+ def page(self):
+ if not self.cached_page:
+ if not self.parent:
+ self.cached_page = self
+ else:
+ self.cached_page = self.parent.page()
+
+ return self.cached_page
+
+ def add_child(self, widget):
+ self.children.append(widget)
+ widget.parent = self
+
+ def get_child(self, name):
+ if not self.child_index:
+ self.child_index = dict()
+
+ for child in self.children:
+ self.child_index[child.name] = child
+
+ return self.child_index.get(name, None)
+
+ def add_attribute(self, attribute):
+ self.attributes.append(attribute)
+ attribute.widget = self
+
+ def add_parameter(self, parameter):
+ self.parameters.append(parameter)
+ parameter.widget = self
+
+ def get_string(self, key):
+ for cls in self.__class__.__mro__:
+ str = None
+ module = sys.modules[cls.__module__]
+
+ strs = module.__dict__.get("strings")
+
+ if strs:
+ str = strs.get(cls.__name__ + "." + key)
+
+ if str:
+ return str
+
+ str = cls.__dict__.get(key)
+
+ if str:
+ return str
+
+ def scope(self, session, params):
+ params.update(self.parameters)
+
+ for child in self.children:
+ child.scope(session, params)
+
+ def process(self, session, object):
+ if session.debug:
+ call = WidgetCall(session.process_stack, self, session, object)
+ call.open()
+
+ self.do_process(session, object)
+
+ if session.debug:
+ call.close()
+
+ def do_process(self, session, object):
+ for child in self.children:
+ child.process(session, object)
+
+ def render(self, session, object):
+ if session.debug:
+ call = WidgetCall(session.render_stack, self, session, object)
+ call.open()
+
+ string = self.do_render(session, object)
+
+ if session.debug:
+ call.close()
+
+ return string
+
+ def do_render(self, session, object):
+ writer = Writer()
+
+ self.template.render(session, object, writer)
+
+ return writer.to_string()
+
+ def render_id(self, session, object):
+ return self.path()
+
+ def render_class(self, session, object):
+ return None
+
+ def render_href(self, session, object):
+ return None
+
+ def render_title(self, session, object):
+ return None
+
+ def render_content(self, session, object):
+ writer = Writer()
+
+ for child in self.children:
+ writer.write(child.render(session, object))
+
+ return writer.to_string()
+
+ def __str__(self):
+ return "%s '%s'" % (self.__class__.__name__, self.path())
+
+class Page(Widget):
+ xml_content_type = "text/xml"
+ html_content_type = "text/html"
+ xml_1_0_declaration = """<?xml version="1.0"?>"""
+ xhtml_1_1_doctype = """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">"""
+ xhtml_namespace = "http://www.w3.org/1999/xhtml"
+
+ def __init__(self, app, name):
+ super(Page, self).__init__(app, name)
+
+ def get_last_modified(self, session):
+ return datetime.utcnow()
+
+ def get_content_type(self, session):
+ return "text/html"
+
+ def save_session(self, session):
+ pass
+
+class Frame(Widget):
+ def __init__(self, app, name):
+ super(Frame, self).__init__(app, name)
+
+ self.object = None
+
+ def set_object_attribute(self, attribute):
+ self.object = attribute
+
+ def get_object(self, session):
+ if self.object:
+ return self.object.get(session)
+
+ def do_process(self, session, object):
+ new_object = self.get_object(session)
+ super(Frame, self).do_process(session, new_object)
+
+ def do_render(self, session, object):
+ new_object = self.get_object(session)
+ return super(Frame, self).do_render(session, new_object)
+
+class Application(object):
+ def __init__(self):
+ self.pages = dict()
+ self.default_page = None
+
+ # Registration lists XXX get rid of?
+ self.widgets = list()
+ self.parameters = list()
+
+ self.finder = ResourceFinder()
+ self.cached_css = None
+
+ self.sessions = list()
+
+ def add_page(self, page):
+ if page.parent:
+ raise Exception("Page '%s' is not a root widget" % page.name)
+
+ self.pages[page.name] = page
+
+ def get_page(self, name):
+ return self.pages.get(name, self.default_page)
+
+ def set_default_page(self, page):
+ self.default_page = page
+
+ def add_widget(self, widget):
+ self.widgets.append(widget)
+
+ def get_widget(self, key):
+ # XXX not fast
+ for widget in self.widgets:
+ if widget.path() == key:
+ return widget
+
+ def add_parameter(self, param):
+ self.parameters.append(param)
+
+ def get_parameter(self, key):
+ # XXX not fast
+ for param in self.parameters:
+ # XXX I'm not sure the param.widget test is what I want
+ if param.widget and param.path() == key:
+ return param
+
+ def add_resource_dir(self, dir):
+ self.finder.add_dir(dir)
+
+ def get_resource(self, name):
+ return self.finder.find(name)
+
+ def get_css(self):
+ if not self.cached_css:
+ writer = Writer()
+
+ for widget in self.widgets:
+ css = widget.get_string("css")
+
+ if css:
+ writer.write(css)
+ writer.write("\r\n") # HTTP newline
+
+ self.cached_css = writer.to_string()
+
+ return self.cached_css
+
+ def clear_caches(self):
+ self.cached_css = None
+
+class Attribute(object):
+ def __init__(self, app, name):
+ self.app = app
+ self.name = name
+ self.widget = None
+ self.default = None
+ self.is_required = True
+
+ def path(self):
+ if not self.widget:
+ raise Exception("Parameter has no widget")
+
+ if not self.widget.parent:
+ return self.name
+ else:
+ path = self.widget.path() + "." + self.name
+
+ return path
+
+ def set_required(self, is_required):
+ self.is_required = is_required
+
+ def validate(self, session):
+ value = self.get(session)
+
+ if value == None and self.is_required:
+ raise Exception("%s not set" % str(self))
+
+ def get(self, session):
+ value = session.get(self.path())
+
+ # Use strict test because empty collections are False
+ if value == None:
+ default = self.get_default(session)
+
+ if default != None:
+ value = self.set(session, default)
+
+ return value
+
+ def add(self, session, value):
+ self.set(session, value)
+
+ def set(self, session, value):
+ return session.set(self.path(), value)
+
+ def get_default(self, session):
+ return self.default
+
+ def set_default(self, default):
+ self.default = default
+
+ def __str__(self):
+ return "%s '%s'" % (self.__class__.__name__, self.path())
+
+class Parameter(Attribute):
+ def __init__(self, app, name):
+ super(Parameter, self).__init__(app, name)
+
+ app.add_parameter(self)
+
+ def marshal(self, object):
+ if object == None:
+ string = ""
+ else:
+ string = self.do_marshal(object)
+
+ return string
+
+ def do_marshal(self, object):
+ return str(object)
+
+ def unmarshal(self, string):
+ return self.do_unmarshal(string)
+
+ def do_unmarshal(self, string):
+ return string
+
+class Session(object):
+ def __init__(self, app, trunk=None):
+ self.app = app
+ self.trunk = trunk
+ self.page = None
+ self.values = dict()
+ self.errors = dict() # widget => list of str
+ self.redirect = None
+
+ self.debug = True
+
+ self.process_stack = list()
+ self.render_stack = list()
+
+ def print_process_calls(self, out=sys.stdout):
+ if self.process_stack:
+ self.process_stack[0].write(out)
+
+ def print_render_calls(self, out=sys.stdout):
+ if self.render_stack:
+ self.render_stack[0].write(out)
+
+ def branch(self):
+ return Session(self.app, self)
+
+ def get_page(self):
+ if self.page:
+ page = self.page
+ elif self.trunk:
+ page = self.trunk.get_page()
+ else:
+ page = None
+
+ return page
+
+ def set_page(self, page):
+ self.page = page
+
+ def get(self, key):
+ if key in self.values:
+ value = self.values[key]
+ elif self.trunk:
+ value = self.trunk.get(key)
+ else:
+ value = None
+
+ return value
+
+ def set(self, key, value):
+ # XXX interesting idea for debugging: catch where things get set
+ #if key.startswith("server.vhost.queue.edit.durable"):
+ # raise Exception()
+
+ self.values[key] = value
+
+ return value
+
+ def unset(self, key):
+ if key in self.values:
+ del self.values[key]
+
+ # XXX this is a little out of line with other session methods in
+ # that it uses widget as a key rather than having a method through
+ # widget to do that
+ def get_errors(self, widget):
+ return self.errors.get(widget)
+
+ def add_error(self, widget, error):
+ errors = self.errors.setdefault(widget, list())
+
+ errors.append(error)
+
+ def set_redirect(self, redirect):
+ self.redirect = redirect
+
+ def marshal(self):
+ return self.marshal_page() + "?" + self.marshal_url_vars()
+
+ def marshal_page(self):
+ return self.get_page().name
+
+ def marshal_url_vars(self, separator=";"):
+ params = set()
+ self.get_page().scope(self, params)
+ vars = list()
+
+ for param in params:
+ key = param.path()
+ value = self.get(key)
+ default = param.get_default(self)
+
+ if value not in (default, None):
+ skey = quote_plus(key)
+ svalue = quote_plus(param.marshal(value))
+
+ vars.append("%s=%s" % (skey, svalue))
+
+ return separator.join(vars)
+
+ def unmarshal(self, string):
+ if string.startswith("/"):
+ raise Exception("Illegal session string '" + string + "'")
+
+ elems = string.split("?")
+
+ self.unmarshal_page(elems[0])
+
+ try:
+ self.unmarshal_url_vars(elems[1])
+ except IndexError:
+ pass
+
+ def unmarshal_page(self, string):
+ self.set_page(self.app.get_page(string))
+
+ def unmarshal_url_vars(self, string, separator=";"):
+ vars = string.split(separator)
+
+ for var in vars:
+ try:
+ skey, svalue = var.split("=")
+
+ key = unquote_plus(skey)
+ value = unquote_plus(svalue)
+
+ param = self.app.get_parameter(key)
+
+ if param:
+ param.add(self, param.unmarshal(value))
+ except ValueError:
+ pass
+
+class StringIOWriter(object):
+ def __init__(self):
+ self.writer = StringIO()
+
+ def write(self, string):
+ self.writer.write(string)
+
+ def to_string(self):
+ string = self.writer.getvalue()
+
+ self.writer.close()
+
+ return string
+
+class ListWriter(object):
+ def __init__(self):
+ self.strings = list()
+
+ def write(self, string):
+ self.strings.append(string)
+
+ def to_string(self):
+ return "".join(self.strings)
+
+class Writer(StringIOWriter):
+ pass
+
+class Template(object):
+ def __init__(self, widget, key):
+ self.widget = widget
+ self.key = key
+ self.fragments = None
+
+ def compile(self):
+ text = self.widget.get_string(self.key)
+
+ if not text:
+ raise Exception("Template '%s.%s' not found" \
+ % (self.widget.__class__.__name__, self.key))
+
+ return self.resolve(self.parse(text))
+
+ def parse(self, text):
+ strings = list()
+
+ start = 0
+ end = text.find("{")
+
+ while True:
+ if (end == -1):
+ strings.append(text[start:])
+ break
+
+ strings.append(text[start:end])
+
+ ccurly = text.find("}", end + 1)
+
+ if ccurly == -1:
+ start = end
+ end = -1
+ else:
+ ocurly = text.find("{", end + 1)
+
+ if ocurly == -1:
+ start = end
+ end = ccurly + 1
+ elif ocurly < ccurly:
+ start = end
+ end = ocurly
+ else:
+ strings.append("{" + text[end + 1:ccurly] + "}")
+
+ start = ccurly + 1
+ end = ocurly
+
+ return strings
+
+ def resolve(self, strings):
+ fragments = list()
+
+ for string in strings:
+ if string.startswith("{") and string.endswith("}"):
+ # Might be a placeholder; look for a matching render
+ # method
+ key = string[1:-1]
+ method = self.find_method("render_" + key)
+
+ if method:
+ fragments.append(method)
+ else:
+ child = self.widget.get_child(key)
+
+ if child:
+ fragments.append(child)
+ else:
+ fragments.append(string)
+ else:
+ fragments.append(string)
+
+ return fragments
+
+ # XXX Ought to make sure what we're returning is a method.
+ def find_method(self, name):
+ for cls in self.widget.__class__.__mro__:
+ method = getattr(cls, name, None)
+
+ if method:
+ return method
+
+ def render(self, session, object, writer):
+ if not self.fragments:
+ self.fragments = self.compile()
+
+ for elem in self.fragments:
+ if type(elem) is str:
+ writer.write(elem)
+ elif callable(elem):
+ writer.write(str(elem(self.widget, session, object) or ""))
+ else:
+ writer.write(str(elem.render(session, object) or ""))
+
+class WidgetCall(object):
+ def __init__(self, stack, widget, session, object):
+ self.stack = stack
+ self.widget = widget
+ self.session = session
+ self.session_values = copy(session.values)
+ self.object = object
+
+ self.caller = None
+ self.callees = list()
+
+ self.start = None
+ self.end = None
+
+ def open(self):
+ if self.stack:
+ self.caller = self.stack[-1]
+ self.caller.callees.append(self)
+
+ self.stack.append(self)
+
+ self.start = time()
+
+ def close(self):
+ self.end = time()
+
+ if len(self.stack) > 1:
+ self.stack.pop()
+
+ def write(self, writer):
+ writer.write(str(self.widget))
+ writer.write(" (call %i, caller %i)" % (id(self), id(self.caller)))
+ writer.write(os.linesep)
+
+ writer.write(" session: " + str(self.session))
+ writer.write(os.linesep)
+
+ for item in self.session_values.iteritems():
+ writer.write(" value: %s = %s" % item)
+ writer.write(os.linesep)
+
+ writer.write(" object: " + str(self.object))
+ writer.write(os.linesep)
+
+ writer.write(" times: %f, %f" % (self.start, self.end or -1))
+ writer.write(os.linesep)
+
+ for call in self.callees:
+ call.write(writer)
Added: mgmt/cumin/python/wooly/debug.py
===================================================================
--- mgmt/cumin/python/wooly/debug.py (rev 0)
+++ mgmt/cumin/python/wooly/debug.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,158 @@
+from wooly import *
+from wooly.widgets import *
+
+class WidgetInspector(Widget):
+ css = """
+ .WidgetInspector {
+ background-color: white;
+ padding: 1em;
+ border: 1px solid #ccc;
+ min-height: 60em;
+ }
+
+ .WidgetInspector .list {
+ float: left;
+ width: 20em;
+ background-color: #f7f7f7;
+ padding: 0.75em 1em;
+ border: 1px dashed #ccc;
+ margin: 0 1em 0 0;
+ }
+
+ """
+
+ html = """
+ <div class="WidgetInspector">
+ <div class="list">{widgets}</div>
+ {view}
+ </div>
+ """
+
+ def __init__(self, app, name):
+ super(WidgetInspector, self).__init__(app, name)
+
+ self.widgets = WidgetList(app, "widgets")
+ self.add_child(self.widgets)
+
+ self.view = WidgetView(app, "view")
+ self.add_child(self.view)
+
+class WidgetView(Widget):
+ css = """
+ """
+
+ html = """
+ <h2>{title}</h2>
+ """
+
+ def render_title(self, session, object):
+ return self.parent.widgets.get_selected_widget(session).name
+
+class WidgetList(Widget):
+ css = """
+ .WidgetList ul {
+ list-style: none;
+ margin: 0;
+ padding: 0 0 0 1.5em;
+ }
+
+ .WidgetList .selected {
+ font-weight: bold;
+ }
+ """
+
+ html = """
+ <div class="WidgetList"><ul>{widgets}</ul></div>
+ """
+
+ def __init__(self, app, name):
+ super(WidgetList, self).__init__(app, name)
+
+ self.widget = Parameter(app, "widget")
+ self.add_parameter(self.widget)
+
+ self.item = self.WidgetItem(app, "item")
+ self.add_child(self.item)
+
+ def do_process(self, session, object):
+ print "do_process"
+
+ if not self.get_selected_widget(session):
+ self.set_selected_widget(session, self.page())
+
+ def get_selected_widget(self, session):
+ return self.app.get_widget(self.widget.get(session))
+
+ def set_selected_widget(self, session, widget):
+ self.widget.set(session, widget.path())
+
+ def render_title(self, session, object):
+ return "Widgets"
+
+ def render_widgets(self, session, object):
+ return self.item.render(session, self.page())
+
+ class WidgetItem(Widget):
+ html = """
+ <li class="{selected}">{class} <a href="{href}">{name}</a></li>
+ {children}
+ """
+
+ def render_selected(self, session, widget):
+ if widget == self.parent.get_selected_widget(session):
+ return "selected"
+
+ def render_href(self, session, widget):
+ branch = session.branch()
+ self.parent.set_selected_widget(branch, widget)
+ return branch.marshal()
+
+ def render_class(self, session, widget):
+ return widget.__class__.__name__
+
+ def render_name(self, session, widget):
+ return widget.name
+
+ def render_children(self, session, widget):
+ if len(widget.children):
+ writer = Writer()
+ writer.write("<ul>")
+
+ for child in widget.children:
+ writer.write(self.parent.item.render(session, child))
+
+ writer.write("</ul>")
+
+ return writer.to_string()
+
+ def xxx_render_widget(self, session, widget, depth, writer):
+ spacer = ". "
+ indent = spacer * depth
+
+ try:
+ cum_time = session.render_times[widget] * 1000
+ self_time = cum_time
+ for child in widget.children:
+ self_time -= session.render_times[child] * 1000
+
+ if widget.parent and cum_time > 0.2 * session.render_times[widget.parent] * 1000:
+ hot = "hot"
+ else:
+ hot = ""
+
+ stime = " (<span class='wooly debug timing %s'>%f, %f</span>)" % \
+ (hot, cum_time, self_time)
+ except KeyError:
+ stime = ""
+
+ writer.write("%s%s <b>%s</b>%s\n" % \
+ (indent, widget.__class__.__name__, widget.name, \
+ stime))
+
+ for param in widget.parameters:
+ writer.write("%s<span class='wooly debug param'>param %s <strong>%s</strong> = %s</span>\n" % \
+ (indent + spacer, param.__class__.__name__, \
+ param.name, param.get(session)))
+
+ for child in widget.children:
+ self.render_widget(session, child, depth + 1, writer)
Added: mgmt/cumin/python/wooly/devel.py
===================================================================
--- mgmt/cumin/python/wooly/devel.py (rev 0)
+++ mgmt/cumin/python/wooly/devel.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,42 @@
+import sys, os
+
+from wooly import *
+
+class DevelPage(Page):
+ html = """
+ <html>
+ <head>
+ <title>{title}</title>
+ </head>
+ <body>{rtrace}</body>
+ </html>
+ """
+
+ def __init__(self, app, name):
+ super(DevelPage, self).__init__(app, name)
+
+ self.render_trace = self.RenderTrace(app, "rtrace")
+ self.add_child(self.render_trace)
+
+ class RenderTrace(Widget):
+ def do_render(self, session, object):
+ writer = Writer()
+
+ writer.write("<ul>")
+
+ if self.app.sessions:
+ call = self.app.sessions[-1].render_stack[0]
+ self.render_call(session, call, writer)
+
+ writer.write("</ul>")
+
+ return writer.to_string()
+
+ def render_call(self, session, call, writer):
+ writer.write("<li>%s</li>" % str(call.widget))
+ writer.write("<ul>")
+
+ for c in call.callees:
+ self.render_call(session, c, writer)
+
+ writer.write("</ul>")
Added: mgmt/cumin/python/wooly/forms.py
===================================================================
--- mgmt/cumin/python/wooly/forms.py (rev 0)
+++ mgmt/cumin/python/wooly/forms.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,177 @@
+from wooly import *
+from parameters import *
+from resources import *
+from widgets import ItemSet
+
+strings = StringCatalog(__file__)
+
+class Form(Widget):
+ def __init__(self, app, name):
+ super(Form, self).__init__(app, name)
+
+ self.form_params = set()
+
+ def add_form_parameter(self, param):
+ self.form_params.add(param)
+
+ def render_hidden_inputs(self, session, object):
+ writer = Writer()
+
+ params = set()
+ session.get_page().scope(session, params)
+ params.difference_update(self.form_params)
+
+ for param in params:
+ key = param.path()
+ value = session.get(key)
+ default = param.get_default(session)
+
+ if value not in (default, None):
+ writer.write("<input type='hidden' name='%s' value='%s'/>" \
+ % (key, param.marshal(value)))
+
+ return writer.to_string()
+
+# XXX implement me
+#class FormInputItemSet(FormInput, ItemSet):
+# pass
+
+class FormInput(Widget):
+ def __init__(self, app, name, form):
+ super(FormInput, self).__init__(app, name)
+
+ self.form = form
+ self.param = None
+
+ self.tab_index = 100
+
+ def set_parameter(self, param):
+ if self.param:
+ raise Exception("Parameter already set")
+
+ self.param = param;
+ self.form.add_form_parameter(self.param)
+
+ def get_parameter(self):
+ return self.param
+
+ def get(self, session):
+ return self.param.get(session)
+
+ def set(self, session, value):
+ return self.param.set(session, value)
+
+ def get_default(self, session):
+ return self.param.get_default(session)
+
+ def set_default(self, default):
+ self.param.set_default(default)
+
+ def add_error(self, session, error):
+ session.add_error(self, error)
+
+ def get_errors(self, session):
+ return session.get_errors(self)
+
+ def set_tab_index(self, tab_index):
+ self.tab_index = tab_index
+
+ def render_name(self, session, object):
+ return self.param.path()
+
+ def render_value(self, session, object):
+ return self.param.marshal(self.param.get(session))
+
+ # XXX do this proper
+ def render_errors(self, session, object):
+ errors = self.get_errors(session)
+
+ if errors:
+ return "<ul class=\"errors\"><li>" + \
+ "</li><li>".join(errors) + \
+ "</li></ul>"
+
+ def render_tabindex(self, session, object):
+ return self.tab_index
+
+class TextInput(FormInput):
+ def __init__(self, app, name, form):
+ super(TextInput, self).__init__(app, name, form)
+
+ self.set_parameter(Parameter(app, "param"))
+ self.add_parameter(self.get_parameter())
+
+ self.size = 32
+
+ def set_size(self, size):
+ self.size = size
+
+ def render_size(self, session, object):
+ return self.size
+
+class CheckboxInput(FormInput):
+ def __init__(self, app, name, form):
+ super(CheckboxInput, self).__init__(app, name, form)
+
+ self.set_parameter(VoidBooleanParameter(app, "param"))
+ self.add_parameter(self.get_parameter())
+
+ def render_checked_attr(self, session, object):
+ return self.get(session) and "checked=\"checked\""
+
+class RadioInput(FormInput):
+ def __init__(self, app, name, form):
+ super(RadioInput, self).__init__(app, name, form)
+
+ self.value = None
+
+ def set_value(self, value):
+ self.value = value
+
+ def render_value(self, session, object):
+ return self.value
+
+ def render_checked_attr(self, session, object):
+ value = self.get(session)
+
+ return value and value == self.value and "checked=\"checked\""
+
+class FormButton(FormInput):
+ def __init__(self, app, name, form):
+ FormInput.__init__(self, app, name, form)
+
+ self.set_parameter(BooleanParameter(app, "param"))
+ self.add_parameter(self.get_parameter())
+
+ def do_process(self, session, object):
+ if self.get(session):
+ self.set(session, False)
+
+ self.on_submit(session, object)
+
+ def on_submit(self, session, object):
+ pass
+
+ def render_value(self, session, object):
+ branch = session.branch()
+
+ self.set(branch, True)
+
+ return super(FormButton, self).render_value(branch, object)
+
+class CheckboxInputSet(FormInput, ItemSet):
+ def __init__(self, app, name, form):
+ super(CheckboxInputSet, self).__init__(app, name, form)
+
+ def render_item_value(self, session, object):
+ return None
+
+ def render_item_checked_attr(self, session, object):
+ return None
+
+class RadioInputSet(FormInput, ItemSet):
+ def render_item_value(self, session, object):
+ return None
+
+ def render_item_checked_attr(self, session, object):
+ return None
Added: mgmt/cumin/python/wooly/forms.strings
===================================================================
--- mgmt/cumin/python/wooly/forms.strings (rev 0)
+++ mgmt/cumin/python/wooly/forms.strings 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,26 @@
+[FormButton.html]
+<button type="submit" name="{name}" value="{value}" tabindex="{tabindex}">{content}</button>
+
+[TextInput.html]
+{errors}
+<input type="text" name="{name}" value="{value}" tabindex="{tabindex}" size="{size}"/>
+
+[CheckboxInput.html]
+<input type="checkbox" name="{name}" value="{value}" tabindex="{tabindex}" {checked_attr}/>
+
+[RadioInput.html]
+<input type="radio" name="{name}" value="{value}" tabindex="{tabindex}" {checked_attr}/>
+
+[CheckboxInputSet.html]
+{errors}{items}
+
+[CheckboxInputSet.item_html]
+<input type="checkbox" name="{name}" value="{item_value}" tabindex="{tabindex}" {item_checked_attr}/>
+{item_content}
+
+[RadioInputSet.html]
+{errors}{items}
+
+[RadioInputSet.item_html]
+<input type="radio" name="{name}" value="{item_value}" tabindex="{tabindex}" {item_checked_attr}/>
+{item_content}
Added: mgmt/cumin/python/wooly/model.py
===================================================================
--- mgmt/cumin/python/wooly/model.py (rev 0)
+++ mgmt/cumin/python/wooly/model.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,301 @@
+from new import instancemethod
+from threading import RLock
+
+class Model(object):
+ def __init__(self):
+ self.indexes = dict()
+ self.mclasses = dict()
+ self.__lock = RLock();
+
+ def get_index(self, cls):
+ return self.indexes.setdefault(cls, dict())
+
+ def lock(self):
+ self.__lock.acquire()
+
+ def unlock(self):
+ self.__lock.release()
+
+class ModelClass(object):
+ def __init__(self, model, name):
+ self.model = model
+ self.name = name
+ self.endpoints = set()
+
+class ModelAssociation(object):
+ def __init__(self, model, name):
+ self.model = model
+ self.name = name
+ self.endpoints = set()
+
+ def add_endpoint(self, mclass, name, multiplicity):
+ if not isinstance(mclass, ModelClass):
+ raise TypeError()
+
+ if multiplicity not in ("0..1", "0..n"):
+ raise Exception("Multiplicity not recognized")
+
+ if len(self.endpoints) > 1:
+ raise Exception("Too many endpoints")
+
+ endpoint = self.Endpoint()
+ endpoint.name = name
+ endpoint.multiplicity = multiplicity
+
+ self.endpoints.add(endpoint)
+ endpoint.association = self
+
+ mclass.endpoints.add(endpoint)
+ endpoint.mclass = mclass
+
+ return endpoint
+
+ class Endpoint(object):
+ def __init__(self):
+ self.association = None
+ self.mclass = None
+
+ self.name = None
+ self.multiplicity = None
+
+ def other(self):
+ for end in self.association.endpoints:
+ if end is not self:
+ return end
+
+ def is_scalar(self):
+ return self.multiplicity == "0..1"
+
+ def set_scalar(self, this, that):
+ this.__dict__[self.name] = that
+
+ def get_scalar(self, this):
+ return this.__dict__[self.name]
+
+ def items(self, this):
+ return this.__dict__[self.name + "_set"]
+
+ def add(self, this, that):
+ if self.is_scalar():
+ self.set_scalar(this, that)
+ else:
+ self.items(this).add(that)
+
+ def remove(self, this, that):
+ if self.is_scalar():
+ print "is_scalar"
+ self.set_scalar(this, None)
+ else:
+ print "items(%s).remove(%s)" % (this.id, that.id)
+ self.items(this).remove(that)
+
+ def object_items(self, this):
+ return self.items(this)
+
+ def add_object(self, this, that):
+ this.lock()
+ try:
+ self.add(this, that)
+
+ that.lock()
+ try:
+ self.other().add(that, this)
+ finally:
+ that.unlock()
+ finally:
+ this.unlock()
+
+ def remove_object(self, this, that):
+ print "remove_object"
+
+ this.lock()
+ try:
+ self.remove(this, that)
+
+ that.lock()
+ try:
+ self.other().remove(that, this)
+ finally:
+ that.unlock()
+ finally:
+ this.unlock()
+
+ def get_object(self, this):
+ return self.get_scalar(this)
+
+ def set_object(self, this, new_that):
+ this.lock()
+ try:
+ old_that = self.get_scalar(this)
+
+ if old_that != None:
+ old_that.lock()
+ try:
+ self.other().remove(old_that, this)
+ finally:
+ old_that.unlock()
+
+ self.set_scalar(this, new_that)
+
+ if new_that != None:
+ new_that.lock()
+ try:
+ self.other().add(new_that, this)
+ finally:
+ new_that.unlock()
+ finally:
+ this.unlock()
+
+class ModelObject(object):
+ sequence = 100
+
+ def __init__(self, model, mclass):
+ self.model = model
+ self.mclass = mclass
+ self.__lock = RLock()
+
+ for end in self.mclass.endpoints:
+ if end.is_scalar():
+ self.add_scalar_attributes(end)
+ else:
+ self.add_set_attributes(end)
+
+ self.lock()
+ try:
+ self.__class__.sequence += 1
+ self.id = self.__class__.sequence
+ model.get_index(self.mclass)[self.id] = self
+ finally:
+ self.unlock()
+
+ def lock(self):
+ self.__lock.acquire()
+
+ def unlock(self):
+ self.__lock.release()
+
+ def setmethod(self, name, func):
+ if not hasattr(self, name):
+ method = instancemethod(func, self, self.__class__)
+ setattr(self, name, method)
+
+ def add_set_attributes(this, end):
+ setattr(this, end.name + "_set", set())
+
+ def items_method(self): return end.object_items(this)
+ this.setmethod(end.name + "_items", items_method)
+
+ def do_add_method(self, that):
+ if that == None:
+ raise Exception()
+
+ end.add_object(this, that)
+
+ this.setmethod("do_add_" + end.name, do_add_method)
+
+ def add_method(self, that): do_add_method(self, that)
+ this.setmethod("add_" + end.name, add_method)
+
+ def do_remove_method(self, that):
+ if that == None:
+ raise Exception()
+
+ end.remove_object(this, that)
+
+ this.setmethod("do_remove_" + end.name, do_remove_method)
+
+ def remove_method(self, that): do_remove_method(self, that)
+ this.setmethod("remove_" + end.name, remove_method)
+
+ def add_scalar_attributes(this, end):
+ end.set_scalar(this, None)
+
+ def get_method(self): return end.get_object(this)
+ this.setmethod("get_" + end.name, get_method)
+
+ def set_method(self, that): end.set_object(this, that)
+ this.setmethod("set_" + end.name, set_method)
+
+ # Note that this doesn't go through the add_someobject methods
+ def remove(self):
+ self.lock()
+ try:
+ for end in self.mclass.endpoints:
+ this = self
+
+ if end.is_scalar():
+ end.set_object(this, None)
+ else:
+ for that in end.items(this).copy():
+ end.remove_object(this, that)
+
+ del self.model.get_index(self.mclass)[self.id]
+ finally:
+ self.unlock()
+
+ def __str__(self):
+ return self.__class__.__name__ + "(" + str(self.id) + ")"
+
+class TestModel(Model):
+ def __init__(self):
+ super(TestModel, self).__init__()
+
+ self.order = ModelClass(self, self.Order)
+ self.item = ModelClass(self, self.Item)
+
+ self.assoc = ModelAssociation(self, "order_item")
+ self.assoc.add_endpoint(self.order, "item", "0..n")
+ self.assoc.add_endpoint(self.item, "order", "0..1")
+
+ class Order(ModelObject):
+ def __init__(self, model):
+ super(TestModel.Order, self).__init__(model, model.order)
+
+ class Item(ModelObject):
+ def __init__(self, model):
+ super(TestModel.Item, self).__init__(model, model.item)
+
+ def test(self):
+ def results(heading):
+ print heading
+ for item in order.item_set:
+ print " item", item, "item.order", item.order
+
+ item0 = self.Item(self)
+ item1 = self.Item(self)
+ item2 = self.Item(self)
+
+ order = self.Order(self)
+
+ order.add_item(item0)
+ order.add_item(item1)
+ order.add_item(item2)
+
+ results("beginning state")
+
+ order.remove_item(item0)
+
+ results("remove item0 from order.items")
+
+ item1.set_order(order)
+
+ results("remove order from item1.order")
+
+ order.add_item(item1)
+
+ results("a")
+
+ item1.set_order(None)
+
+ results("b")
+
+ item1.set_order(order)
+
+ results("c")
+
+ item1.remove()
+
+ results("d")
+
+if __name__ == "__main__":
+ TestModel().test()
Added: mgmt/cumin/python/wooly/pages.py
===================================================================
--- mgmt/cumin/python/wooly/pages.py (rev 0)
+++ mgmt/cumin/python/wooly/pages.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,54 @@
+from datetime import datetime
+
+from wooly import Page, Parameter
+
+class CssPage(Page):
+ def __init__(self, app, name):
+ super(CssPage, self).__init__(app, name)
+
+ self.then = datetime.utcnow()
+
+ def get_last_modified(self, session):
+ return self.then
+
+ def get_content_type(self, session):
+ return "text/css"
+
+ def do_render(self, session, object):
+ return self.app.get_css()
+
+class ResourcePage(Page):
+ def __init__(self, app, name):
+ super(ResourcePage, self).__init__(app, name)
+
+ self.rname = Parameter(app, "name")
+ self.add_parameter(self.rname)
+
+ self.then = datetime.utcnow()
+
+ def get_last_modified(self, session):
+ return self.then
+
+ def get_content_type(self, session):
+ name = self.rname.get(session)
+
+ if name:
+ if name.endswith(".png"):
+ type = "image/png"
+ elif name.endswith(".jpeg"):
+ type = "image/jpeg"
+ elif name.endswith(".html"):
+ type = "text/html"
+ else:
+ type = "text/plain"
+
+ return type
+
+ def do_render(self, session, object):
+ name = self.rname.get(session)
+
+ if name:
+ resource = self.app.get_resource(name)
+
+ if resource:
+ return resource.read()
Added: mgmt/cumin/python/wooly/parameters.py
===================================================================
--- mgmt/cumin/python/wooly/parameters.py (rev 0)
+++ mgmt/cumin/python/wooly/parameters.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,53 @@
+from copy import copy
+
+from wooly import *
+
+# XXX the marshal side of this is not implemented
+class ListParameter(Parameter):
+ def __init__(self, app, name, param):
+ super(ListParameter, self).__init__(app, name)
+
+ self.param = param
+ self.default = list()
+
+ def get_default(self, session):
+ return copy(self.default)
+
+ def add(self, session, value):
+ lst = self.get(session)
+ lst.append(value)
+ return lst
+
+ def do_unmarshal(self, string):
+ return self.param.do_unmarshal(string)
+
+class IntegerParameter(Parameter):
+ def do_unmarshal(self, string):
+ return int(string)
+
+class BooleanParameter(Parameter):
+ def __init__(self, model, name):
+ Parameter.__init__(self, model, name)
+
+ self.set_default(False)
+
+ def do_unmarshal(self, string):
+ return string == "t"
+
+ def do_marshal(self, object):
+ return object and "t" or "f"
+
+class VoidBooleanParameter(Parameter):
+ def set_default(self, default):
+ raise Exception("Unsupported operation")
+
+ def get(self, session):
+ return self.path() in session.values
+
+ def set(self, session, value):
+ key = self.path()
+
+ if value:
+ session.set(key, None)
+ else:
+ session.unset(key)
Added: mgmt/cumin/python/wooly/resources.py
===================================================================
--- mgmt/cumin/python/wooly/resources.py (rev 0)
+++ mgmt/cumin/python/wooly/resources.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,71 @@
+import os
+import wooly
+
+class StringCatalog(object):
+ def __init__(self, file):
+ self.strings = None
+ self.path = os.path.splitext(file)[0] + ".strings"
+
+ def clear(self):
+ self.strings = None
+
+ def load(self):
+ try:
+ file = open(self.path)
+ self.strings = parse_catalog_file(file)
+ finally:
+ file.close()
+
+ def get(self, key):
+ if not self.strings:
+ self.load()
+
+ return self.strings.get(key)
+
+def parse_catalog_file(file):
+ strings = dict()
+ key = None
+ writer = wooly.Writer()
+
+ for line in file:
+ line = line.rstrip()
+
+ if line.startswith("[") and line.endswith("]"):
+ if key:
+ strings[key] = writer.to_string().strip()
+
+ writer = wooly.Writer()
+
+ key = line[1:-1]
+
+ continue
+
+ writer.write(line)
+ writer.write("\r\n")
+
+ strings[key] = writer.to_string().strip()
+
+ return strings
+
+class ResourceFinder(object):
+ def __init__(self):
+ self.dirs = list()
+
+ def add_dir(self, dir):
+ self.dirs.append(dir)
+
+ def find(self, name):
+ file = None
+
+ for dir in self.dirs:
+ try:
+ path = os.path.join(dir, name)
+
+ # XXX +1 exposing template resolution is useful
+ #print "Looking for resource '%s'" % path
+
+ file = open(path, "r")
+ except IOError:
+ pass
+
+ return file
Added: mgmt/cumin/python/wooly/server.py
===================================================================
--- mgmt/cumin/python/wooly/server.py (rev 0)
+++ mgmt/cumin/python/wooly/server.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,112 @@
+from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
+from traceback import print_exc
+from datetime import datetime
+from time import strptime
+
+from wooly import *
+from devel import DevelPage
+
+class WebServer(object):
+ def __init__(self, app, port=8080):
+ self.app = app
+ self.port = port
+
+ def run(self):
+ server = HTTPServer(("", self.port), self.RequestHandler)
+
+ # XXX hack, because HTTPServer and python conspire to make
+ # this hard
+ server.app = self.app
+
+ print "Cumin server started on port %s" % (self.port)
+ server.serve_forever()
+
+ class RequestHandler(BaseHTTPRequestHandler):
+ http_date = "%a, %d %b %Y %H:%M:%S %Z"
+
+ def do_GET(self):
+ session = Session(self.server.app)
+ session.unmarshal(self.path[1:])
+
+ self.service(session)
+
+ def do_POST(self):
+ session = Session(self.server.app)
+ session.unmarshal_page(self.path.split("?")[0])
+
+ content_type = str(self.headers.getheader("content-type"))
+
+ if content_type == "application/x-www-form-urlencoded":
+ length = int(self.headers.getheader("content-length"))
+ vars = self.rfile.read(length)
+ else:
+ raise Exception("Content type '%s' is not supported" \
+ % content_type)
+
+ if vars:
+ session.unmarshal_url_vars(vars, "&")
+
+ self.service(session)
+
+ def service(self, session):
+ page = session.get_page()
+
+ try:
+ page.process(session, None)
+ except:
+ self.error(session)
+ return
+
+ if session.redirect:
+ self.send_response(303)
+ self.send_header("Location", session.redirect)
+ self.end_headers()
+ return
+
+ ims = self.headers.getheader("if-modified-since")
+ modified = page.get_last_modified(session).replace \
+ (microsecond=0)
+
+ if ims:
+ since = datetime(*strptime(str(ims), self.http_date)[0:6])
+
+ if modified <= since:
+ self.send_response(304)
+ self.end_headers()
+ return
+
+ try:
+ response = page.render(session, None)
+ except:
+ self.error(session)
+ return
+
+ self.send_response(200)
+
+ type = page.get_content_type(session)
+
+ if type:
+ self.send_header("Content-Type", type)
+
+ if modified:
+ ts = modified.strftime("%a, %d %b %Y %H:%M:%S GMT")
+ self.send_header("Last-Modified", ts)
+
+ self.end_headers()
+
+ self.wfile.write(response)
+
+ page.save_session(session)
+
+ def error(self, session):
+ self.send_response(500)
+ self.send_header("Content-Type", "text/plain")
+ self.end_headers()
+
+ self.wfile.write("APPLICATION ERROR\n")
+ self.wfile.write("\n----- python trace -----\n")
+ print_exc(None, self.wfile)
+ self.wfile.write("\n----- process trace -----\n")
+ session.print_process_calls(self.wfile)
+ self.wfile.write("\n----- render trace -----\n")
+ session.print_render_calls(self.wfile)
Added: mgmt/cumin/python/wooly/widgets.py
===================================================================
--- mgmt/cumin/python/wooly/widgets.py (rev 0)
+++ mgmt/cumin/python/wooly/widgets.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,147 @@
+from wooly import *
+from parameters import *
+from resources import *
+
+strings = StringCatalog(__file__)
+
+class ModeSet(Widget):
+ def __init__(self, app, name):
+ super(ModeSet, self).__init__(app, name)
+
+ self.mode = Parameter(app, "mode")
+ self.add_parameter(self.mode)
+
+ def add_child(self, mode):
+ super(ModeSet, self).add_child(mode)
+
+ if not self.mode.default:
+ self.mode.set_default(mode.name)
+
+ def get_selected_mode(self, session):
+ return self.get_child(self.mode.get(session))
+
+ def set_selected_mode(self, session, mode):
+ self.mode.set(session, mode.name)
+
+ def show_mode(self, session, mode):
+ self.set_selected_mode(session, mode)
+
+ return mode
+
+ def scope(self, session, params):
+ params.update(self.parameters)
+
+ mode = self.get_selected_mode(session)
+
+ if mode:
+ mode.scope(session, params)
+
+ def do_process(self, session, object):
+ mode = self.get_selected_mode(session)
+
+ if mode:
+ mode.process(session, object)
+
+ def do_render(self, session, object):
+ mode = self.get_selected_mode(session)
+
+ if mode:
+ return mode.render(session, object)
+
+class TabSet(ModeSet):
+ def __init__(self, app, name):
+ super(TabSet, self).__init__(app, name)
+
+ def do_render(self, session, object):
+ writer = Writer()
+
+ self.template.render(session, object, writer)
+
+ return writer.to_string()
+
+ # XXX make this use an item template
+ def render_tabs(self, session, object):
+ writer = Writer()
+ str = """<li><a href="%s" class="%s">%s</a></li>"""
+
+ for mode in self.children:
+ branch = session.branch()
+ self.set_selected_mode(branch, mode)
+ href = branch.marshal()
+
+ smode = self.get_selected_mode(session)
+ selected = smode == mode and "selected" or ""
+
+ content = mode.render_title(session, object)
+
+ writer.write(str % (href, selected, content))
+
+ return writer.to_string()
+
+ def render_mode(self, session, object):
+ mode = self.get_selected_mode(session)
+
+ if mode:
+ return mode.render(session, object)
+
+class Link(Widget):
+ def update_session(self, session, object):
+ pass
+
+ def render_href(self, session, object):
+ branch = session.branch()
+
+ self.update_session(branch, object)
+
+ return branch.marshal()
+
+class Toggle(Link):
+ def __init__(self, app, name):
+ super(Toggle, self).__init__(app, name)
+
+ self.toggled = BooleanParameter(app, "param")
+ self.add_parameter(self.toggled)
+
+ def get(self, session):
+ return self.toggled.get(session)
+
+ def set(self, session, toggled):
+ self.toggled.set(session, toggled)
+
+ def do_process(self, session, object):
+ if self.get(session):
+ self.on_click(session, object)
+
+ def on_click(self, session, object):
+ pass
+
+ def render_href(self, session, object):
+ branch = session.branch()
+ self.set(branch, not self.get(session))
+ return branch.marshal()
+
+ def render_state(self, session, object):
+ return self.toggled.get(session) and "on" or "off"
+
+class ItemSet(Widget):
+ def __init__(self, app, name):
+ super(ItemSet, self).__init__(app, name)
+
+ self.item_tmpl = Template(self, "item_html")
+
+ def get_items(self, session, object):
+ return None
+
+ def render_items(self, session, object):
+ items = self.get_items(session, object)
+
+ if items:
+ writer = Writer()
+
+ for item in items:
+ self.item_tmpl.render(session, item, writer)
+
+ return writer.to_string()
+
+ def render_item_content(self, session, item):
+ return None
Added: mgmt/cumin/python/wooly/widgets.strings
===================================================================
--- mgmt/cumin/python/wooly/widgets.strings (rev 0)
+++ mgmt/cumin/python/wooly/widgets.strings 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,60 @@
+[TabSet.css]
+ul.TabSet.tabs {
+ padding: 0;
+ margin: 1em 0 0 0;
+ list-style: none;
+}
+
+.TabSet.tabs li {
+ display: inline;
+}
+
+.TabSet.tabs li a {
+ padding: 0.25em 0.5em;
+ border-top: 1px solid #ccc;
+ border-right: 1px solid #ccc;
+ background-color: #f7f7f7;
+ color: #000;
+ line-height: 1.5em;
+}
+
+.TabSet.tabs li:first-child a {
+ border-left: 1px solid #ccc;
+}
+
+.TabSet.tabs li a.selected {
+ background-color: #fff;
+ position: relative;
+ z-index: 2;
+}
+
+.TabSet.mode {
+ background-color: white;
+ padding: 1em;
+ border: 1px solid #ccc;
+ margin: 0;
+ background-color: #fff;
+ position: relative;
+ z-index: 1;
+}
+
+[TabSet.html]
+<ul class="TabSet tabs">{tabs}</ul>
+<div class="TabSet mode">{mode}</div>
+
+[Link.html]
+<a href="{href}">{content}</a>
+
+[Toggle.css]
+.Toggle.on {
+ font-weight: bold;
+}
+
+[Toggle.html]
+<a href="{href}" class="Toggle {state}">{content}</a>
+
+[ItemSet.html]
+<ul class="ItemSet">{items}</ul>
+
+[ItemSet.item_html]
+<li>{item_content}</li>
Added: mgmt/cumin/resources/ajax-test.html
===================================================================
--- mgmt/cumin/resources/ajax-test.html (rev 0)
+++ mgmt/cumin/resources/ajax-test.html 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,32 @@
+<html>
+ <head>
+ <title>test</title>
+ <script>
+ var xhr = new XMLHttpRequest()
+
+ function getCount() {
+ xhr.open("get", "http://localhost:8080/count", true)
+ xhr.onreadystatechange = updateCount
+ xhr.send(null)
+ }
+
+ function updateCount() {
+ if (xhr.readyState == 4 && xhr.status == 200) {
+ countNode = xhr.responseXML.getElementsByTagName("count")[0]
+ count = countNode.firstChild.nodeValue
+
+ var body = document.getElementsByTagName("body")
+
+ var div = document.createElement("div")
+ div.appendChild(document.createTextNode(count))
+
+ body[0].appendChild(div)
+ }
+ }
+
+ setInterval(getCount, 5000)
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
Added: mgmt/cumin/resources/ajax.js
===================================================================
--- mgmt/cumin/resources/ajax.js (rev 0)
+++ mgmt/cumin/resources/ajax.js 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,67 @@
+// Rename this to wooly.js
+
+wooly = {};
+wooly.updaters = {};
+
+function WoolyUpdater(id, url, callback, interval) {
+ this.id = id;
+ this.url = url;
+ this.interval = interval;
+ this.callback = callback;
+ this.request = new XMLHttpRequest();
+
+ this.init = function() {
+ setInterval(this.fetch, this.interval);
+ }
+
+ this.fetch = function() {
+ this.request.open("get", this.url, true);
+ this.request.onreadystatechange = this.update
+ this.send(null)
+ }
+
+ this.update = function() {
+ if (request.readyState == 4 && request.status == 200) {
+ elem = document.getElementById(this.id)
+ this.callback(xml, elem)
+ }
+ }
+}
+
+function AjaxRequest() {
+ try {
+ this.request = window.XMLHttpRequest();
+ } catch (e) {
+ try {
+ this.request = new ActiveXObject("Msxml2.XMLHTTP");
+ } catch (ie) {
+ try {
+ this.request = new ActiveXObject("Microsoft.XMLHTTP");
+ } catch (iie) {
+ throw new Error("XMLHttpRequest not found");
+ }
+ }
+ }
+
+ // XXX configure with an xpath expression? pg 515 in the big js
+ // book
+
+ this.get = function(url, callback) {
+ this.request.open("GET", url, true);
+
+ // XXX set some headers
+ //this.request.setRequestHeader("If-Modified-Since",
+ // lastRequested.toString());
+
+ this.onreadystatechange = function() {
+ if (this.request.readyState == 4 && this.request.status == 200) {
+ callback(request.responseXML)
+ }
+ }
+
+ this.request.send(null)
+ }
+}
+
+req = new AjaxRequest();
+req.get("queue-xml?id={{id}}", updateStatus)
\ No newline at end of file
Added: mgmt/cumin/resources/exchange-20.png
===================================================================
(Binary files differ)
Property changes on: mgmt/cumin/resources/exchange-20.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: mgmt/cumin/resources/exchange-36.png
===================================================================
(Binary files differ)
Property changes on: mgmt/cumin/resources/exchange-36.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: mgmt/cumin/resources/exchange.svg
===================================================================
--- mgmt/cumin/resources/exchange.svg (rev 0)
+++ mgmt/cumin/resources/exchange.svg 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="744.09448819"
+ height="1052.3622047"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.45.1"
+ sodipodi:docbase="/home/justin/cumindev/cumin/resources"
+ sodipodi:docname="exchange.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="549.10742"
+ inkscape:cy="503.26882"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ inkscape:window-width="1418"
+ inkscape:window-height="956"
+ inkscape:window-x="29"
+ inkscape:window-y="45" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <g
+ id="g3181"
+ inkscape:export-filename="/home/justin/cumindev/cumin/resources/exchange-20.png"
+ inkscape:export-xdpi="3.506865"
+ inkscape:export-ydpi="3.506865">
+ <path
+ sodipodi:nodetypes="cccccccccccccc"
+ d="M 313.86973,832.3721 C 312.11118,709.27939 279.68924,569.91252 207.1601,445.66059 L 168.9849,468.05869 L 205.55073,331.59313 L 342.95181,368.40964 L 305.42972,390.07303 C 344.62364,462.24138 365.78921,497.41554 391.10471,587.93301 C 409.27317,551.38754 456.55215,499.0514 474.28581,483.53568 L 444.90847,454.15833 L 585.197,454.15833 L 585.197,590.33585 L 554.87823,560.01708 C 484.07919,636.62814 448.21282,711.11613 446.96398,832.3721 C 446.96398,832.3721 446.4501,832.3721 313.86973,832.3721 z "
+ style="fill:#ffaa66;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:12.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path2164" />
+ <path
+ transform="translate(47.55914,-118.77957)"
+ d="M 296 598.36218 A 54 54 0 1 1 188,598.36218 A 54 54 0 1 1 296 598.36218 z"
+ sodipodi:ry="54"
+ sodipodi:rx="54"
+ sodipodi:cy="598.36218"
+ sodipodi:cx="242"
+ id="path2190"
+ style="fill:#ff5577;fill-opacity:1;stroke:#000000;stroke-width:12.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="translate(229.66129,-27.66129)"
+ d="M 296 598.36218 A 54 54 0 1 1 188,598.36218 A 54 54 0 1 1 296 598.36218 z"
+ sodipodi:ry="54"
+ sodipodi:rx="54"
+ sodipodi:cy="598.36218"
+ sodipodi:cx="242"
+ id="path3165"
+ style="fill:#77aaff;fill-opacity:1;stroke:#000000;stroke-width:12.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+</svg>
Added: mgmt/cumin/resources/logo.png
===================================================================
(Binary files differ)
Property changes on: mgmt/cumin/resources/logo.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: mgmt/cumin/resources/logo.svg
===================================================================
--- mgmt/cumin/resources/logo.svg (rev 0)
+++ mgmt/cumin/resources/logo.svg 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="744.09448819"
+ height="1052.3622047"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.45"
+ sodipodi:modified="TRUE">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.35"
+ inkscape:cx="375"
+ inkscape:cy="520"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <rect
+ style="fill:#564979;fill-opacity:1;stroke:#bfdce8;stroke-width:0.07982907;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect2160"
+ width="39.203495"
+ height="22.692081"
+ x="176.57945"
+ y="149.64551" />
+ <g
+ id="g3141"
+ inkscape:export-filename="/home/jross/cumindev/cumin/resources/logo.png"
+ inkscape:export-xdpi="98.580963"
+ inkscape:export-ydpi="98.580963">
+ <text
+ transform="scale(1.0989239,0.9099811)"
+ sodipodi:linespacing="125%"
+ id="text3133"
+ y="178.24783"
+ x="164.23683"
+ style="font-size:10.9197731px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ff9f00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ y="178.24783"
+ x="164.23683"
+ id="tspan3135"
+ sodipodi:role="line">RHM</tspan></text>
+ <text
+ transform="scale(1.2362181,0.8089188)"
+ sodipodi:linespacing="125%"
+ id="text3137"
+ y="205.76395"
+ x="146.27437"
+ style="font-size:7.40763378px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"><tspan
+ y="205.76395"
+ x="146.27437"
+ id="tspan3139"
+ sodipodi:role="line">mgmt</tspan></text>
+ </g>
+ </g>
+</svg>
Added: mgmt/cumin/resources/object-20.png
===================================================================
(Binary files differ)
Property changes on: mgmt/cumin/resources/object-20.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: mgmt/cumin/resources/object-36.png
===================================================================
(Binary files differ)
Property changes on: mgmt/cumin/resources/object-36.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: mgmt/cumin/resources/object.svg
===================================================================
--- mgmt/cumin/resources/object.svg (rev 0)
+++ mgmt/cumin/resources/object.svg 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="744.09448819"
+ height="1052.3622047"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.45.1"
+ sodipodi:docbase="/home/justin/cumindev/cumin/resources"
+ sodipodi:docname="object.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.35"
+ inkscape:cx="375"
+ inkscape:cy="520"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ inkscape:window-width="814"
+ inkscape:window-height="619"
+ inkscape:window-x="0"
+ inkscape:window-y="25" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <g
+ id="g3139"
+ transform="translate(-194.28571,31.428571)"
+ inkscape:export-filename="/home/justin/cumindev/cumin/resources/object-20.png"
+ inkscape:export-xdpi="3.4734666"
+ inkscape:export-ydpi="3.4734666">
+ <rect
+ y="100.93361"
+ x="317.14285"
+ height="505.71429"
+ width="505.71429"
+ id="rect2166"
+ style="fill:#ffaa66;fill-opacity:1;stroke:#000000;stroke-width:12.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,0,0)"
+ y="438.85617"
+ x="79.941772"
+ height="147.90282"
+ width="147.90282"
+ id="rect2160"
+ style="fill:#77aaff;fill-opacity:1;stroke:#000000;stroke-width:12.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ transform="translate(485.71428,-20)"
+ d="M 282.85715 492.36218 A 88.571434 88.571434 0 1 1 105.71429,492.36218 A 88.571434 88.571434 0 1 1 282.85715 492.36218 z"
+ sodipodi:ry="88.571434"
+ sodipodi:rx="88.571434"
+ sodipodi:cy="492.36218"
+ sodipodi:cx="194.28572"
+ id="path2162"
+ style="fill:#ff5577;fill-opacity:1;stroke:#000000;stroke-width:12.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+</svg>
Added: mgmt/cumin/resources/purple.png
===================================================================
(Binary files differ)
Property changes on: mgmt/cumin/resources/purple.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: mgmt/cumin/resources/queue-20.png
===================================================================
(Binary files differ)
Property changes on: mgmt/cumin/resources/queue-20.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: mgmt/cumin/resources/queue-36.png
===================================================================
(Binary files differ)
Property changes on: mgmt/cumin/resources/queue-36.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: mgmt/cumin/resources/queue.svg
===================================================================
--- mgmt/cumin/resources/queue.svg (rev 0)
+++ mgmt/cumin/resources/queue.svg 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="744.09448819"
+ height="1052.3622047"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.45.1"
+ sodipodi:docbase="/home/justin/cumindev/cumin/resources"
+ sodipodi:docname="queue.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.68801116"
+ inkscape:cx="441.43343"
+ inkscape:cy="526.18109"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ inkscape:window-width="814"
+ inkscape:window-height="892"
+ inkscape:window-x="33"
+ inkscape:window-y="41" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <g
+ id="g3146">
+ <path
+ transform="matrix(0.9063078,0.4226182,-0.4226182,0.9063078,86.342292,293.33708)"
+ d="M 552.93207 223.99181 A 195.27341 52.415497 0 1 1 162.38525,223.99181 A 195.27341 52.415497 0 1 1 552.93207 223.99181 z"
+ sodipodi:ry="52.415497"
+ sodipodi:rx="195.27341"
+ sodipodi:cy="223.99181"
+ sodipodi:cx="357.65866"
+ id="path3134"
+ style="fill:#ffaa66;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:12.50000018;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.9063078,0.4226182,-0.4226182,0.9063078,116.01145,231.71374)"
+ d="M 552.93207 223.99181 A 195.27341 52.415497 0 1 1 162.38525,223.99181 A 195.27341 52.415497 0 1 1 552.93207 223.99181 z"
+ sodipodi:ry="52.415497"
+ sodipodi:rx="195.27341"
+ sodipodi:cy="223.99181"
+ sodipodi:cx="357.65866"
+ id="path4105"
+ style="fill:#ffaa66;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:12.50000018;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.9063078,0.4226182,-0.4226182,0.9063078,145.68064,170.09034)"
+ d="M 552.93207 223.99181 A 195.27341 52.415497 0 1 1 162.38525,223.99181 A 195.27341 52.415497 0 1 1 552.93207 223.99181 z"
+ sodipodi:ry="52.415497"
+ sodipodi:rx="195.27341"
+ sodipodi:cy="223.99181"
+ sodipodi:cx="357.65866"
+ id="path4109"
+ style="fill:#ffaa66;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:12.50000018;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.9063078,0.4226182,-0.4226182,0.9063078,175.34983,108.467)"
+ d="M 552.93207 223.99181 A 195.27341 52.415497 0 1 1 162.38525,223.99181 A 195.27341 52.415497 0 1 1 552.93207 223.99181 z"
+ sodipodi:ry="52.415497"
+ sodipodi:rx="195.27341"
+ sodipodi:cy="223.99181"
+ sodipodi:cx="357.65866"
+ id="path4113"
+ style="fill:#ffaa66;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:12.50000018;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path5088"
+ d="M 454.10516,344.26002 L 399.27203,461.85003 L 359.20085,443.16454 L 406.83279,566.23776 L 529.50338,522.5779 L 489.4322,503.89241 L 544.76381,385.23338 L 454.10516,344.26002 z "
+ style="fill:#ff5577;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:12.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ id="path4117"
+ d="M 310.19505,419.15001 L 365.02818,301.56001 L 324.95699,282.87451 L 449.85377,240.25274 L 495.25952,362.28789 L 455.18834,343.60238 L 399.85673,462.26141 L 310.19505,419.15001 z "
+ style="fill:#77aaff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:12.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ </g>
+</svg>
Added: mgmt/cumin/resources/radio-button-checked.png
===================================================================
(Binary files differ)
Property changes on: mgmt/cumin/resources/radio-button-checked.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: mgmt/cumin/resources/radio-button.png
===================================================================
(Binary files differ)
Property changes on: mgmt/cumin/resources/radio-button.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: mgmt/cumin/resources/radio-buttons.svg
===================================================================
--- mgmt/cumin/resources/radio-buttons.svg (rev 0)
+++ mgmt/cumin/resources/radio-buttons.svg 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="744.09448819"
+ height="1052.3622047"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.45"
+ sodipodi:docbase="/home/jross/cumindev/cumin/resources"
+ sodipodi:docname="radio-buttons.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ sodipodi:modified="TRUE">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="2.4431138"
+ inkscape:cx="261"
+ inkscape:cy="591.5"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ inkscape:window-width="814"
+ inkscape:window-height="620"
+ inkscape:window-x="423"
+ inkscape:window-y="159" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <g
+ id="g3167"
+ inkscape:export-filename="/home/jross/cumindev/cumin/resources/radio-button-checked.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <path
+ transform="matrix(0.5990025,0,0,0.5990025,87.699389,185.92954)"
+ d="M 243.24474 452.02853 A 12.020815 12.020815 0 1 1 219.20311,452.02853 A 12.020815 12.020815 0 1 1 243.24474 452.02853 z"
+ sodipodi:ry="12.020815"
+ sodipodi:rx="12.020815"
+ sodipodi:cy="452.02853"
+ sodipodi:cx="231.22392"
+ id="path2160"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#cccccc;stroke-width:1.66944211;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.5990025,0,0,0.5990025,86.746382,184.65886)"
+ d="M 239.88597 454.23822 A 6.9826794 6.9826794 0 1 1 225.92061,454.23822 A 6.9826794 6.9826794 0 1 1 239.88597 454.23822 z"
+ sodipodi:ry="6.9826794"
+ sodipodi:rx="6.9826794"
+ sodipodi:cy="454.23822"
+ sodipodi:cx="232.90329"
+ id="path3133"
+ style="fill:#4e9fdd;fill-opacity:1;stroke:#bfdce8;stroke-opacity:1;stroke-width:1.66944211;stroke-miterlimit:4;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ </g>
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#cccccc;stroke-width:1.66944206;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path3163"
+ sodipodi:cx="231.22392"
+ sodipodi:cy="452.02853"
+ sodipodi:rx="12.020815"
+ sodipodi:ry="12.020815"
+ d="M 243.24474 452.02853 A 12.020815 12.020815 0 1 1 219.20311,452.02853 A 12.020815 12.020815 0 1 1 243.24474 452.02853 z"
+ transform="matrix(0.5990025,0,0,0.5990025,121.41051,185.92954)"
+ inkscape:export-filename="/home/jross/cumindev/cumin/resources/radio-button.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+</svg>
Added: mgmt/cumin/resources/wooly.js
===================================================================
--- mgmt/cumin/resources/wooly.js (rev 0)
+++ mgmt/cumin/resources/wooly.js 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,221 @@
+var wooly;
+
+(function() {
+ wooly = new Wooly();
+
+ function assert() {
+ for (var i = 0; i < arguments.length; i++) {
+ if (!arguments[i]) {
+ throw new Error("Assertion failure in " + arguments.callee.caller.prototype);
+ }
+ }
+ }
+
+ function log() {
+ if (wooly.console) {
+ wooly.console.log.apply(wooly.console, arguments);
+ }
+ }
+
+ function dir() {
+ if (wooly.console) {
+ wooly.console.dir.apply(wooly.console, arguments);
+ }
+ }
+
+ function Wooly() {
+ this.request = new XMLHttpRequest();
+
+ this.assert = assert;
+ this.log = log;
+ this.dir = dir;
+
+ if (window.console) {
+ this.console = window.console;
+ }
+
+ this.setIntervalUpdate = function(id, url, callback, interval) {
+ var req = this.request;
+
+ function fetch() {
+ req.open("get", url, true);
+ req.onreadystatechange = update;
+ req.send(null);
+ }
+
+ var timerid = window.setInterval(fetch, interval);
+
+ function update() {
+ try {
+ if (req.readyState == 4 && req.status == 200) {
+ //dir(req);
+
+ var elem = wooly.doc().elem(id);
+
+ callback(wooly.doc(req.responseXML), elem);
+ }
+ } catch (e) {
+ log(e);
+ // XXX might want to retry for a bit before we do
+ // this
+ window.clearInterval(timerid);
+ throw e;
+ }
+ }
+ }
+
+ this._doc = new WoolyDocument(document);
+
+ this.doc = function(doc) {
+ if (doc) {
+ return new WoolyDocument(doc);
+ } else {
+ return this._doc;
+ }
+ }
+ }
+
+ function WoolyDocument(node) {
+ assert(node);
+
+ this.node = node;
+
+ this.elem = function(id) {
+ var node = this.node.getElementById(id);
+
+ if (node) {
+ return new WoolyElement(this, node);
+ }
+ }
+
+ this.elems = function(tag) {
+ var nodes = this.node.getElementsByTagName(tag);
+
+ return new WoolyIterator(this, WoolyElement,
+ nodes, 1, tag);
+ }
+ }
+
+ function WoolyIterator(doc, nodeClass, nodes, nodeType, nodeName) {
+ assert(doc);
+ assert(doc instanceof WoolyDocument);
+ assert(nodeClass);
+ assert(nodes);
+ assert(nodes instanceof NodeList);
+ assert(nodeType);
+ assert(typeof nodeType == "number");
+ if (nodeName) assert(typeof nodeName == "string");
+
+ this.doc = doc;
+ this.nodes = nodes;
+ this.nodeClass = nodeClass;
+ this.nodeType = nodeType;
+ this.nodeName = nodeName;
+
+ this.lastIndex = -1;
+
+ this.next = function() {
+ var node;
+
+ for (var i = this.lastIndex + 1; i < this.nodes.length; i++) {
+ node = this.nodes[i];
+
+ if (this.nodeType == null
+ || node.nodeType == this.nodeType) {
+ if (this.nodeName == null
+ || node.nodeName.toLowerCase() == this.nodeName) {
+ this.lastIndex = i;
+ return new this.nodeClass(this.doc, node);
+ }
+ }
+ }
+
+ return null;
+ }
+ }
+
+ function WoolyElement(doc, node) {
+ assert(doc);
+ assert(doc instanceof WoolyDocument);
+ assert(node);
+ assert(node instanceof Node, node.nodeType == 1);
+
+ this.doc = doc;
+ this.node = node;
+
+ this.clear = function() {
+ var child = this.node.firstChild;
+ var next;
+
+ while (child) {
+ next = child.nextSibling;
+ this.node.removeChild(child);
+ child = next;
+ }
+
+ return this;
+ }
+
+ this.add = function(content) {
+ if (typeof content == "string") {
+ this.add(new WoolyText(this.doc, null).set(content));
+ } else if (content.hasOwnProperty("node")) {
+ this.node.appendChild(content.node);
+ } else {
+ throw new Error("Content is of unexpected type");
+ }
+
+ return this;
+ }
+
+ this.set = function(content) {
+ this.clear().add(content);
+
+ return this;
+ }
+
+ this.elems = function(name) {
+ return new WoolyIterator(this.doc, WoolyElement,
+ this.node.childNodes,
+ 1, name);
+ }
+
+ this.text = function() {
+ var children = this.node.childNodes;
+
+ for (var i = 0; i < children.length; i++) {
+ var child = children[i];
+
+ if (child.nodeType == 3) return new WoolyText(this.doc, child);
+ }
+
+ return null;
+ }
+ }
+
+ function WoolyText(doc, node) {
+ assert(doc);
+ assert(doc instanceof WoolyDocument);
+ if (node) assert(node instanceof Node, node.nodeType == 3);
+
+ this.doc = doc;
+
+ if (node == null) {
+ this.node = doc.node.createTextNode("");
+ } else {
+ this.node = node;
+ }
+
+ this.get = function() {
+ return this.node.data
+ }
+
+ this.set = function(data) {
+ assert(typeof data == "string");
+
+ this.node.data = data
+
+ return this;
+ }
+ }
+}())
Added: mgmt/cumin-test-0/bin
===================================================================
--- mgmt/cumin-test-0/bin (rev 0)
+++ mgmt/cumin-test-0/bin 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1 @@
+link ../cumin/bin
\ No newline at end of file
Property changes on: mgmt/cumin-test-0/bin
___________________________________________________________________
Name: svn:special
+ *
Added: mgmt/cumin-test-0/lib
===================================================================
--- mgmt/cumin-test-0/lib (rev 0)
+++ mgmt/cumin-test-0/lib 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1 @@
+link ../lib
\ No newline at end of file
Property changes on: mgmt/cumin-test-0/lib
___________________________________________________________________
Name: svn:special
+ *
Added: mgmt/cumin-test-0/python
===================================================================
--- mgmt/cumin-test-0/python (rev 0)
+++ mgmt/cumin-test-0/python 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1 @@
+link ../cumin/python
\ No newline at end of file
Property changes on: mgmt/cumin-test-0/python
___________________________________________________________________
Name: svn:special
+ *
Added: mgmt/cumin-test-0/resources
===================================================================
--- mgmt/cumin-test-0/resources (rev 0)
+++ mgmt/cumin-test-0/resources 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1 @@
+link ../cumin/resources
\ No newline at end of file
Property changes on: mgmt/cumin-test-0/resources
___________________________________________________________________
Name: svn:special
+ *
Added: mgmt/etc/cumindev.el
===================================================================
--- mgmt/etc/cumindev.el (rev 0)
+++ mgmt/etc/cumindev.el 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,10 @@
+(setq cumindev-home (getenv "CUMINDEV_HOME"))
+
+(if cumindev-home
+ (progn
+ ;(desktop-read cumindev-home)
+ (shell "dev")
+ (setq tags-file-name (concat cumindev-home "/etc/cumindev.tags"))
+ (setq grep-command (concat "find " cumindev-home " -name \\*.py -print | xargs fgrep -n "))
+ (setq compile-command "cumin-test"))
+ (display-warning 'cumindev "Environment variable CUMINDEV_HOME not set" :error))
Added: mgmt/etc/cumindev.profile
===================================================================
--- mgmt/etc/cumindev.profile (rev 0)
+++ mgmt/etc/cumindev.profile 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,11 @@
+if [ -z "$CUMINDEV_HOME" ]; then
+ export CUMINDEV_HOME="$PWD"
+fi
+
+export CUMIN_HOME="$CUMINDEV_HOME"/cumin-test-0
+
+export PYTHONPATH="$CUMIN_HOME"/lib:"$CUMIN_HOME"/python
+
+export CUMINDEV_ORIGINAL_PATH="$PATH"
+
+export PATH="$CUMIN_HOME"/bin:"$CUMINDEV_HOME"/bin:"$CUMINDEV_ORIGINAL_PATH"
Added: mgmt/misc/templates.py
===================================================================
--- mgmt/misc/templates.py (rev 0)
+++ mgmt/misc/templates.py 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,113 @@
+text0 = """
+<form id="{id}" class="QueueForm mform" method="post" action="?">
+ <div class="head">
+ <h1>{title}</h1>
+ </div>
+ <div class="body">
+ <span class="legend">Name</span>
+ <fieldset>
+ <div class="field">{queue_name}</div>
+ </fieldset>
+ <span class="legend">Latency Tuning</span>
+ <fieldset>
+ <div class="field">
+ {latency}
+ <em>Lower Latency:</em> Tune for shorter delays, with reduced volume
+ </div>
+ <div class="field">
+ {balanced}
+ <em>Balanced</em>
+ </div>
+ <div class="field">
+ {throughput}
+ <em>Higher Throughput:</em> Tune for increased volume, with longer
+ delays
+ </div>
+ </fieldset>
+ <span class="legend">Realms</span>
+ <fieldset>{realms}</fieldset>
+{hidden_inputs}
+ </div>
+ <div class="foot">
+ <div style="display: block; float: left;"><button>Help</button></div>
+{cancel}
+{submit}
+ </div>
+</form>
+<script defer="defer">
+var id = "{id}";
+(function() {
+ // XXX elements[0] is a fieldset, at least in firefox
+ var elem = wooly.doc().elem(id).node.elements[1];
+ elem.focus();
+ elem.select();
+}())
+</script>
+"""
+
+def parse(text):
+ fragments = list()
+
+ start = 0
+ end = text.find("{")
+
+ while True:
+ if (end == -1):
+ fragments.append(text[start:])
+ break
+
+ fragments.append(text[start:end])
+
+ ccurly = text.find("}", end + 1)
+
+ if ccurly == -1:
+ start = end
+ end = -1
+ else:
+ ocurly = text.find("{", end + 1)
+
+ if ocurly == -1:
+ start = end
+ end = ccurly + 1
+ elif ocurly < ccurly:
+ start = end
+ end = ocurly
+ else:
+ fragments.append("{" + text[end + 1:ccurly] + "}")
+
+ start = ccurly + 1
+ end = ocurly
+
+ return fragments
+
+if __name__ == "__main__":
+ from time import clock
+ from cStringIO import StringIO
+
+ texts = ["x{y}z}a{b}c",
+ "x{y",
+ "x}y",
+ "{{{",
+ "}{}{",
+ "x{y{z}"]
+
+ for text in texts:
+ print text, parse(text)
+
+ frags = None
+ start = clock()
+
+ for i in range(10000):
+ frags = parse(text0)
+
+ print clock() - start
+
+ start = clock()
+
+ for i in range(10000):
+ buffer = StringIO()
+
+ for frag in frags:
+ buffer.write(frag)
+
+ print clock() - start
Added: mgmt/notes/Errors
===================================================================
--- mgmt/notes/Errors (rev 0)
+++ mgmt/notes/Errors 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,3 @@
+[justin@localhost cumindev]$ cumindev-etags
+/home/justin/cumindev/cumin/python/cumin/.#model.py: No such file or directory
+
Added: mgmt/notes/InterfaceQuestions
===================================================================
--- mgmt/notes/InterfaceQuestions (rev 0)
+++ mgmt/notes/InterfaceQuestions 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,5 @@
+ * Should the default exchange appear in the UI at all?
+
+ * Is there any place in the UI for transient queues and exchanges?
+ It would seem not, except perhaps in status information.
+
Added: mgmt/notes/ProtocolQuestions
===================================================================
--- mgmt/notes/ProtocolQuestions (rev 0)
+++ mgmt/notes/ProtocolQuestions 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,19 @@
+ * Why use null for the default exchange name? It would seem
+ consistent and more convenient in developing software to use a name
+ such as "amq.default"
+
+ * Can the routing key of the default binding to the default exchange
+ for new queues be changed? How different is the default exchange
+ from other types of exchanges? The docs suggest that the default
+ binding is for "point and shoot" use of the broker, so it would
+ make sense if the default exchange only supported simple
+ queue-named routing keys, no?
+
+ * I didn't run into anything that spelled out the multiplicity of
+ bindings vis a vis queues. I assumed that queues and exchanges
+ support many bindings.
+
+ * Can a queue, for instance, be in more than one realm?
+
+ * It strikes me that UML would answer many of my questions.
+
Added: mgmt/notes/Todo
===================================================================
--- mgmt/notes/Todo (rev 0)
+++ mgmt/notes/Todo 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,69 @@
+Big picture
+
+ * A more-or-less complete demonstration of an admin UI
+
+Higher
+
+Lower
+
+ * more form inputs, non scalar ones too
+
+ * Add an error banner to form
+
+ * use wsgiref instead of BaseHTTPServer
+
+ * Make sure HTTPServer handles concurrent requests; need to look at
+ documentation
+
+ - It does not, and it's not easily changed. Will need to switch to
+ wsgi stuff, I believe.
+
+ * When in queue mode, make the context nav go back to the right tab
+
+ * Change declared charset to iso-8859???, not utf-8, since it's
+ important to be honest
+
+ * Only do render timing conditionally
+
+ * Make debug and devel things contingent upon a start-time variable
+ "--debug"
+
+ * Make it a little simpler to express hrefs
+
+ * Add disabling to form inputs, and disable renaming of exchanges
+ that start with "amq." and the default exchange
+
+ * Make form help buttons pop up a (for now, empty) help page
+
+ * Icons: machine looking thing for vhost. For Cumin in general, I'm
+ not sure. The hammer and screwdriver?
+
+ * Make item counts in tab labels a little grayer, that is, less
+ intense than the name
+
+ * If debug is enabled, append a comment to the response containing
+ render and process traces
+
+ * Write a little test comparing wooly.Template to string.Template to
+ using the % operator
+
+ * Add ability to send a test message to a queue
+
+ * Add favicon and a mapping in the server to serve it
+
+ * Create a model.dtd
+
+ * Add scalar get/setters to ModelObject
+
+ * Separate wooly stuff into its own devel subdir
+
+ * When there is nothing in a set, render a [None]
+
+ * Add creation dates to some objects
+
+ * cumindev: Bind .strings to html-mode
+
+ * cumindev: add a cumin-test function and bind it to C-c C-c
+
+ * Consider adding a set_object to Frame, instead of having
+ set_somethingspecific on each frame.
Added: mgmt/notes/WoolyOverview
===================================================================
--- mgmt/notes/WoolyOverview (rev 0)
+++ mgmt/notes/WoolyOverview 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,40 @@
+Widget
+ - A display object
+ - Usually bound to a Template
+ - May have state represented in Parameters
+ - Lives in a tree of widgets
+ - Has a process method
+ - Manipulates state, both ui state and model state
+ - Called in the process phase, before rendering
+ - Has a render method
+ - Produces HTML
+ - Called after all processing is done
+
+Template
+ - A string with placeholders such as {foo}
+ - A placeholder {foo} resolves to: widget.render_foo(...)
+ - Or it resolves to: widget.get_child("foo").render(...)
+
+Application
+ - The static state of the app
+ - Holds Pages
+
+Page
+ - A top-level widget with some extra methods for producing HTTP
+ responses
+ - The root widget of all widget trees is a page
+
+Parameter
+ - Represents state for the life of the request/response
+ - Attached to a widget
+ - Stores its session-level state on a Session
+ - Marshals and unmarshals itself to url params
+
+Session
+ - The main source of state
+ - Can be "branched" for producing "future states", URLs
+
+ModeSet
+ - A widget that shows only one of its children
+ - Used for producing various UI behaviors, tabs for instance
+ - Generally useful for controlling visibility
Added: mgmt/notes/firebug-exception-bug.js
===================================================================
--- mgmt/notes/firebug-exception-bug.js (rev 0)
+++ mgmt/notes/firebug-exception-bug.js 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,23 @@
+var scratchy;
+
+(function() {
+ scratchy = new Scratchy();
+
+ function Scratchy() {
+ this.x = new Object();
+
+ this.itchy = function(callback, interval) {
+ var x = this.x;
+
+ setTimeout(show, 1000);
+
+ function show() {
+ try {
+ callback();
+ } catch (e) {
+ throw e;
+ }
+ }
+ }
+ }
+}());
Added: mgmt/notes/firebug-swallows-exceptions.html
===================================================================
--- mgmt/notes/firebug-swallows-exceptions.html (rev 0)
+++ mgmt/notes/firebug-swallows-exceptions.html 2007-10-08 15:51:14 UTC (rev 967)
@@ -0,0 +1,42 @@
+<html>
+<head>
+<title>Test</title>
+<script>
+var scratchy;
+
+(function() {
+ scratchy = new Scratchy();
+
+ function Scratchy() {
+ this.x = true;
+
+ this.itchy = function(callback) {
+ var y = this.x;
+
+ setTimeout(a, 1000);
+
+ function a() {
+ b();
+ }
+
+ function b() {
+ if (y) callback();
+ }
+ }
+ }
+}());
+</script>
+</head>
+<body>
+Test
+<script defer="defer">
+(function() {
+ var code = function() {
+ throw Error();
+ }
+
+ scratchy.itchy(code);
+}());
+</script>
+</body>
+</html>
\ No newline at end of file
[View Less]
17 years, 3 months
rhmessaging commits: r966 - /.
by rhmessaging-commits@lists.jboss.org
Author: nunofsantos
Date: 2007-10-08 11:10:54 -0400 (Mon, 08 Oct 2007)
New Revision: 966
Added:
mgmt/
Log:
add top-level management project
17 years, 3 months
rhmessaging commits: r965 - in store/trunk/cpp: lib/jrnl and 1 other directories.
by rhmessaging-commits@lists.jboss.org
Author: kpvdr
Date: 2007-10-05 16:46:46 -0400 (Fri, 05 Oct 2007)
New Revision: 965
Modified:
store/trunk/cpp/lib/TxnCtxt.h
store/trunk/cpp/lib/jrnl/README
store/trunk/cpp/lib/jrnl/data_tok.cpp
store/trunk/cpp/lib/jrnl/data_tok.hpp
store/trunk/cpp/lib/jrnl/deq_rec.cpp
store/trunk/cpp/lib/jrnl/deq_rec.hpp
store/trunk/cpp/lib/jrnl/enq_rec.cpp
store/trunk/cpp/lib/jrnl/enq_rec.hpp
store/trunk/cpp/lib/jrnl/file_hdr.hpp
store/trunk/cpp/lib/jrnl/jcfg.hpp
store/trunk/…
[View More]cpp/lib/jrnl/jcntl.cpp
store/trunk/cpp/lib/jrnl/jcntl.hpp
store/trunk/cpp/lib/jrnl/pmgr.cpp
store/trunk/cpp/lib/jrnl/pmgr.hpp
store/trunk/cpp/lib/jrnl/txn_rec.cpp
store/trunk/cpp/lib/jrnl/txn_rec.hpp
store/trunk/cpp/lib/jrnl/wmgr.cpp
store/trunk/cpp/lib/jrnl/wmgr.hpp
store/trunk/cpp/tests/jrnl/janalyze.py
store/trunk/cpp/tests/jrnl/jtest.cpp
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/tests.ods
store/trunk/cpp/tests/jrnl/wtests.csv
Log:
Transaction encoding path complete, txn decode path still incomplete
Modified: store/trunk/cpp/lib/TxnCtxt.h
===================================================================
--- store/trunk/cpp/lib/TxnCtxt.h 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/lib/TxnCtxt.h 2007-10-05 20:46:46 UTC (rev 965)
@@ -62,11 +62,13 @@
void completeTXN(bool commit){
for (TxnCtxt::ipqdef::iterator i = impactedQueues.begin(); i != impactedQueues.end(); i++) {
journal::jcntl* jc = static_cast<journal::jcntl*>((*i)->getExternalQueueStore());
- if (jc) /* if using journal */
+ if (jc) { /* if using journal */
+ journal::data_tok* dtokp = new journal::data_tok;
if (commit)
- jc->txn_commit(getXid());
+ jc->txn_commit(dtokp, getXid());
else
- jc->txn_abort(getXid());
+ jc->txn_abort(dtokp, getXid());
+ }
}
deleteXidRecord();
sync();
Modified: store/trunk/cpp/lib/jrnl/README
===================================================================
--- store/trunk/cpp/lib/jrnl/README 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/lib/jrnl/README 2007-10-05 20:46:46 UTC (rev 965)
@@ -7,6 +7,8 @@
libaio-dev (run "yum install libaio-dev" as root to install)
doxygen (required to generate documentation)
+TODO: *** THIS DOC IS OUT OF DATE ****
+
Building:
---------
For manual building, use the makefile Makefile.rtest in the tests/jrnl directory.
Modified: store/trunk/cpp/lib/jrnl/data_tok.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/data_tok.cpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/lib/jrnl/data_tok.cpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -51,6 +51,7 @@
_dblks_written(0),
_dblks_read(0),
_rid(0),
+ _xid(),
_sourceMsg(NULL)
{
pthread_mutex_init(&_mutex, NULL);
@@ -93,6 +94,22 @@
return "DEQ_SUBM";
case DEQ:
return "DEQ";
+ case ABORT_CACHED:
+ return "ABORT_CACHED";
+ case ABORT_PART:
+ return "ABORT_PART";
+ case ABORT_SUBM:
+ return "ABORT_SUBM";
+ case ABORTED:
+ return "ABORTED";
+ case COMMIT_CACHED:
+ return "COMMIT_CACHED";
+ case COMMIT_PART:
+ return "COMMIT_PART";
+ case COMMIT_SUBM:
+ return "COMMIT_SUBM";
+ case COMMITTED:
+ return "COMMITTED";
}
// Not using default: forces compiler to ensure all cases are covered.
return "<wstate unknown>";
@@ -144,6 +161,7 @@
_dblks_written = 0;
_dblks_read = 0;
_rid = 0;
+ _xid.clear();
}
} // namespace journal
Modified: store/trunk/cpp/lib/jrnl/data_tok.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/data_tok.hpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/lib/jrnl/data_tok.hpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -67,6 +67,9 @@
class data_tok
{
public:
+ // TODO: Fix this, separate write state from operation
+ // ie: wstate = NONE, CACHED, PART, SUBM, COMPL
+ // op = ENQUEUE, DEQUEUE, ABORT, COMMIT
enum write_state
{
NONE, ///< Data block not sent to journal
@@ -77,7 +80,15 @@
DEQ_CACHED, ///< Data block dequeue written to page cache
DEQ_PART, ///< Data block part-submitted to AIO, waiting for page buffer to free up
DEQ_SUBM, ///< Data block dequeue submitted to AIO
- DEQ ///< Data block dequeue AIO write complete (dequeue complete)
+ DEQ, ///< Data block dequeue AIO write complete (dequeue complete)
+ ABORT_CACHED,
+ ABORT_PART,
+ ABORT_SUBM,
+ ABORTED,
+ COMMIT_CACHED,
+ COMMIT_PART,
+ COMMIT_SUBM,
+ COMMITTED
};
enum read_state
@@ -98,6 +109,7 @@
u_int32_t _dblks_written; ///< Data blocks read/written
u_int32_t _dblks_read; ///< Data blocks read/written
u_int64_t _rid; ///< RID of data set by enqueue operation
+ std::string _xid; ///< XID set by enqueue operation
u_int64_t _dequeue_rid; ///< RID of data set by dequeue operation
qpid::broker::PersistableMessage* _sourceMsg; ///< Pointer back to source Message in Broker
@@ -109,10 +121,10 @@
inline void setSourceMessage(qpid::broker::PersistableMessage* msg) {_sourceMsg = msg;}
inline const u_int64_t id() const { return _icnt; }
- inline const write_state wstate() const {return _wstate; }
+ inline const write_state wstate() const { return _wstate; }
const char* wstate_str() const;
static const char* wstate_str(write_state wstate);
- inline const read_state rstate() const {return _rstate; }
+ inline const read_state rstate() const { return _rstate; }
const char* rstate_str() const;
static const char* rstate_str(read_state rstate);
inline const bool is_writable() const { return _wstate == NONE || _wstate == ENQ_PART; }
@@ -138,6 +150,14 @@
inline void set_rid(const u_int64_t rid) { _rid = rid; }
inline const u_int64_t dequeue_rid() const throw (jexception) {return _dequeue_rid; }
inline void set_dequeue_rid(const u_int64_t rid) { _dequeue_rid = rid; }
+
+ inline const bool has_xid() const { return !_xid.empty(); }
+ inline const std::string& xid() const { return _xid; }
+ inline void clear_xid() { _xid.clear(); }
+ inline void set_xid(const std::string& xid) { _xid.assign(xid); }
+ inline void set_xid(const void* xidp, const size_t xid_len)
+ { _xid.assign((const char*)xidp, xid_len); }
+
void reset();
};
Modified: store/trunk/cpp/lib/jrnl/deq_rec.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/deq_rec.cpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/lib/jrnl/deq_rec.cpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -33,6 +33,7 @@
#include <jrnl/deq_rec.hpp>
#include <assert.h>
+#include <errno.h>
#include <iomanip>
#include <sstream>
#include <jrnl/jerrno.hpp>
@@ -44,41 +45,54 @@
deq_rec::deq_rec():
_deq_hdr(RHM_JDAT_DEQ_MAGIC, RHM_JDAT_VERSION, 0, 0, 0, 0),
- _xid(),
- _deq_tail()
-{}
-
-deq_rec::deq_rec(const u_int64_t rid, const u_int64_t drid):
- _deq_hdr(RHM_JDAT_DEQ_MAGIC, RHM_JDAT_VERSION, 0, rid, drid, 0),
- _xid(),
+ _xidp(NULL),
+ _buff(NULL),
_deq_tail(_deq_hdr._hdr)
{}
-deq_rec::deq_rec(const u_int64_t rid, const u_int64_t drid, const std::string& xid):
- _deq_hdr(RHM_JDAT_DEQ_MAGIC, RHM_JDAT_VERSION, 0, rid, drid, xid.size()),
- _xid(xid),
+deq_rec::deq_rec(const u_int64_t rid, const u_int64_t drid, const void* const xidp,
+ const size_t xidlen):
+ _deq_hdr(RHM_JDAT_DEQ_MAGIC, RHM_JDAT_VERSION, 0, rid, drid, xidlen),
+ _xidp(xidp),
+ _buff(NULL),
_deq_tail(_deq_hdr._hdr)
{}
deq_rec::~deq_rec()
-{}
+{
+ if (_buff)
+ ::free(_buff);
+}
void
-deq_rec::reset(const u_int64_t rid, const u_int64_t drid)
+deq_rec::reset()
{
- _deq_hdr._hdr._rid = rid;
- _deq_hdr._deq_rid = drid;
+ _deq_hdr._hdr._rid = 0;
+ _deq_hdr._deq_rid = 0;
_deq_hdr._xidsize = 0;
- _deq_tail._rid = rid;
+ _deq_tail._rid = 0;
+ _xidp = NULL;
+ if (_buff)
+ {
+ ::free(_buff);
+ _buff = NULL;
+ }
}
void
-deq_rec::reset(const u_int64_t rid, const u_int64_t drid, const std::string& xid)
+deq_rec::reset(const u_int64_t rid, const u_int64_t drid, const void* const xidp,
+ const size_t xidlen)
{
_deq_hdr._hdr._rid = rid;
_deq_hdr._deq_rid = drid;
- _deq_hdr._xidsize = xid.size();
+ _deq_hdr._xidsize = xidlen;
_deq_tail._rid = rid;
+ _xidp = xidp;
+ if (_buff)
+ {
+ ::free(_buff);
+ _buff = NULL;
+ }
}
u_int32_t
@@ -86,7 +100,8 @@
{
assert(wptr != NULL);
assert(max_size_dblks > 0);
- assert(_xid.size() == _deq_hdr._xidsize);
+ if (_xidp == NULL)
+ assert(_deq_hdr._xidsize == 0);
size_t rec_offs = rec_offs_dblks * JRNL_DBLK_SIZE;
size_t rem = max_size_dblks * JRNL_DBLK_SIZE;
@@ -102,7 +117,7 @@
{
if (wsize > rem)
wsize = rem;
- ::memcpy(wptr, (const char*)_xid.c_str() + rec_offs, wsize);
+ ::memcpy(wptr, (char*)_xidp + rec_offs, wsize);
wr_cnt += wsize;
rem -= wsize;
}
@@ -130,7 +145,7 @@
size_t wsize = _deq_hdr._xidsize > rec_offs ? _deq_hdr._xidsize - rec_offs : 0;
if (wsize)
{
- ::memcpy(wptr, _xid.c_str() + rec_offs, wsize);
+ ::memcpy(wptr, (char*)_xidp + rec_offs, wsize);
wr_cnt += wsize;
}
rec_offs -= _deq_hdr._xidsize - wsize;
@@ -140,9 +155,9 @@
::memcpy((char*)wptr + wr_cnt, (char*)&_deq_tail + rec_offs, wsize);
wr_cnt += wsize;
#ifdef RHM_CLEAN
- ::memset((char*)wptr + wr_cnt, RHM_CLEAN_CHAR,
- (size_dblks(rec_size()) * JRNL_DBLK_SIZE) -
- (rec_offs_dblks * JRNL_DBLK_SIZE) - wr_cnt);
+ size_t rec_offs = rec_offs_dblks * JRNL_DBLK_SIZE;
+ size_t dblk_rec_size = size_dblks(rec_size() - rec_offs) * JRNL_DBLK_SIZE;
+ ::memset((char*)wptr + wr_cnt, RHM_CLEAN_CHAR, dblk_rec_size - wr_cnt);
#endif
}
rec_offs -= sizeof(_deq_tail) - wsize;
@@ -161,7 +176,7 @@
if (rem)
{
wsize = rem >= _deq_hdr._xidsize ? _deq_hdr._xidsize : rem;
- ::memcpy((char*)wptr + wr_cnt, _xid.c_str(), wsize);
+ ::memcpy((char*)wptr + wr_cnt, _xidp, wsize);
wr_cnt += wsize;
rem -= wsize;
}
@@ -178,14 +193,14 @@
{
if (_deq_hdr._xidsize)
{
- ::memcpy((char*)wptr + wr_cnt, _xid.c_str(), _deq_hdr._xidsize);
+ ::memcpy((char*)wptr + wr_cnt, _xidp, _deq_hdr._xidsize);
wr_cnt += _deq_hdr._xidsize;
::memcpy((char*)wptr + wr_cnt, (void*)&_deq_tail, sizeof(_deq_tail));
wr_cnt += sizeof(_deq_tail);
}
#ifdef RHM_CLEAN
- ::memset((char*)wptr + wr_cnt, RHM_CLEAN_CHAR,
- (size_dblks(rec_size()) * JRNL_DBLK_SIZE) - wr_cnt);
+ size_t dblk_rec_size = size_dblks(rec_size()) * JRNL_DBLK_SIZE;
+ ::memset((char*)wptr + wr_cnt, RHM_CLEAN_CHAR, dblk_rec_size - wr_cnt);
#endif
}
}
@@ -215,7 +230,7 @@
// Part of xid still outstanding, copy remainder of xid and tail
const size_t xid_offs = rec_offs - deq_hdr::size();
const size_t xid_rem = _deq_hdr._xidsize - xid_offs;
- _xid.append((char*)rptr, xid_rem);
+ ::memcpy((char*)_buff + xid_offs, rptr, xid_rem);
rd_cnt = xid_rem;
::memcpy((void*)&_deq_tail, ((char*)rptr + rd_cnt), sizeof(_deq_tail));
chk_tail();
@@ -236,7 +251,7 @@
// Remainder of xid fits within this page, tail split
const size_t xid_offs = rec_offs - deq_hdr::size();
const size_t xid_rem = _deq_hdr._xidsize - xid_offs;
- _xid.append((char*)rptr, xid_rem);
+ ::memcpy((char*)_buff + xid_offs, rptr, xid_rem);
rd_cnt += xid_rem;
const size_t tail_rem = (max_size_dblks * JRNL_DBLK_SIZE) - rd_cnt;
if (tail_rem)
@@ -249,7 +264,7 @@
{
// Remainder of xid split
const size_t xid_cp_size = (max_size_dblks * JRNL_DBLK_SIZE);
- _xid.append((char*)rptr, xid_cp_size);
+ ::memcpy((char*)_buff + rec_offs - deq_hdr::size(), rptr, xid_cp_size);
rd_cnt += xid_cp_size;
}
}
@@ -268,6 +283,13 @@
chk_hdr();
if (_deq_hdr._xidsize)
{
+ _buff = ::malloc(_deq_hdr._xidsize);
+ if (_buff == NULL)
+ {
+ std::stringstream ss;
+ ss << "_buff malloc(): errno=" << errno;
+ throw jexception(jerrno::JERR__MALLOC, ss.str(), "deq_rec", "decode");
+ }
const u_int32_t hdr_xid_dblks = size_dblks(deq_hdr::size() + _deq_hdr._xidsize);
const u_int32_t hdr_xid_tail_dblks = size_dblks(enq_hdr::size() + _deq_hdr._xidsize +
rec_tail::size());
@@ -277,16 +299,16 @@
if (hdr_xid_tail_dblks <= max_size_dblks)
{
// Entire header, xid and tail fits within this page
- ::memcpy((void*)&_deq_tail, (char*)rptr + rd_cnt + _deq_hdr._xidsize,
- sizeof(_deq_tail));
+ ::memcpy(_buff, (char*)rptr + rd_cnt, _deq_hdr._xidsize);
+ rd_cnt += _deq_hdr._xidsize;
+ ::memcpy((void*)&_deq_tail, (char*)rptr + rd_cnt, sizeof(_deq_tail));
+ rd_cnt += sizeof(_deq_tail);
chk_tail();
- _xid.assign((char*)rptr + rd_cnt, _deq_hdr._xidsize);
- rd_cnt += _deq_hdr._xidsize + sizeof(_deq_tail);
}
else if (hdr_xid_dblks <= max_size_dblks)
{
// Entire header and xid fit within this page, tail split
- _xid.assign((char*)rptr + rd_cnt, _deq_hdr._xidsize);
+ ::memcpy(_buff, (char*)rptr + rd_cnt, _deq_hdr._xidsize);
rd_cnt += _deq_hdr._xidsize;
const size_t tail_rem = (max_size_dblks * JRNL_DBLK_SIZE) - rd_cnt;
if (tail_rem)
@@ -299,7 +321,7 @@
{
// Header fits within this page, xid split
const size_t xid_cp_size = (max_size_dblks * JRNL_DBLK_SIZE) - rd_cnt;
- _xid.assign((char*)rptr + rd_cnt, xid_cp_size);
+ ::memcpy(_buff, (char*)rptr + rd_cnt, xid_cp_size);
rd_cnt += xid_cp_size;
}
}
@@ -314,9 +336,9 @@
ss << "deq_rec: m=" << _deq_hdr._hdr._magic;
ss << " v=" << (int)_deq_hdr._hdr._version;
ss << " rid=" << _deq_hdr._hdr._rid;
- ss << " dren=" << _deq_hdr._deq_rid;
- if (_deq_hdr._xidsize)
- ss << " xid=\"" << _xid << "\"";
+ ss << " drid=" << _deq_hdr._deq_rid;
+ if (_xidp)
+ ss << " xid=\"" << _xidp << "\"";
str.append(ss.str());
return str;
}
Modified: store/trunk/cpp/lib/jrnl/deq_rec.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/deq_rec.hpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/lib/jrnl/deq_rec.hpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -55,22 +55,29 @@
class deq_rec : public jrec
{
private:
- deq_hdr _deq_hdr; ///< Dequeue header
- std::string _xid; ///< XID - empty string means no XID is set
- rec_tail _deq_tail; ///< Record tail, only encoded if XID is present
+ deq_hdr _deq_hdr; ///< Dequeue header
+ const void* _xidp; ///< xid pointer for encoding (writing to disk)
+ void* _buff; ///< Pointer to buffer to receive data read from disk
+ rec_tail _deq_tail; ///< Record tail, only encoded if XID is present
public:
+ // constructor used for read operations and xid must have memory allocated
deq_rec();
- deq_rec(const u_int64_t rid, const u_int64_t drid);
- deq_rec(const u_int64_t rid, const u_int64_t drid, const std::string& xid);
+ // constructor used for write operations, where xid already exists
+ deq_rec(const u_int64_t rid, const u_int64_t drid, const void* const xidp,
+ const size_t xidlen);
~deq_rec();
- void reset(const u_int64_t rid, const u_int64_t drid);
- void reset(const u_int64_t rid, const u_int64_t drid, const std::string& xid);
+ // Prepare instance for use in reading data from journal
+ void reset();
+ // Prepare instance for use in writing data to journal
+ void reset(const u_int64_t rid, const u_int64_t drid, const void* const xidp,
+ const size_t xidlen);
u_int32_t encode(void* wptr, u_int32_t rec_offs_dblks, u_int32_t max_size_dblks)
throw (jexception);
u_int32_t decode(hdr& h, void* rptr, u_int32_t rec_offs_dblks, u_int32_t max_size_dblks)
throw (jexception);
+ inline const void* const get_xid() { return _buff; }
std::string& str(std::string& str) const;
inline const size_t data_size() const { return 0; } // This record never carries data
const size_t xid_size() const;
Modified: store/trunk/cpp/lib/jrnl/enq_rec.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/enq_rec.cpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/lib/jrnl/enq_rec.cpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -349,6 +349,10 @@
rd_cnt = _enq_hdr.size();
chk_hdr();
_data_size = _enq_hdr._dsize;
+ if (_enq_hdr._xidsize)
+ {
+ // TODO: Decode xid here
+ }
if (_data_size)
{
Modified: store/trunk/cpp/lib/jrnl/enq_rec.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/enq_rec.hpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/lib/jrnl/enq_rec.hpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -56,12 +56,12 @@
{
private:
enq_hdr _enq_hdr;
- const void* _xidp; ///< xid pointer
- const void* _data; ///< Pointer to data to be written to disk
- void* _buff; ///< Pointer to buffer to receive data read from disk
+ const void* _xidp; ///< xid pointer for encoding (for writing to disk)
+ const void* _data; ///< Pointer to data to be written to disk
+ void* _buff; ///< Pointer to buffer to receive data read from disk
rec_tail _enq_tail;
- size_t _max_data_size; ///< Max buffer size for decoding into during read
- size_t _data_size; ///< Size of data (bytes)
+ size_t _max_data_size; ///< Max buffer size for decoding into during read
+ size_t _data_size; ///< Size of data (bytes)
public:
/**
Modified: store/trunk/cpp/lib/jrnl/file_hdr.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/file_hdr.hpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/lib/jrnl/file_hdr.hpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -336,7 +336,7 @@
* The rid field below is the rid of the dequeue record itself; the deq-rid field is the rid of a
* previous enqueue record being dequeued by this record.
*
- * Record header info in binary format (24 bytes):
+ * Record header info in binary format (32 bytes):
* <pre>
* 0 7
* +---+---+---+---+---+---+---+---+ -+
@@ -389,7 +389,7 @@
/**
- * \brief Struct for DTX commit and abort records.
+ * \brief Struct for transaction commit and abort records.
*
* Struct for DTX commit and abort records. Only the magic distinguishes between them. Since
* this record must be used in the context of a valid XID, the xidsize field must not be zero.
Modified: store/trunk/cpp/lib/jrnl/jcfg.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/jcfg.hpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/lib/jrnl/jcfg.hpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -75,8 +75,8 @@
#define JRNL_INFO_EXTENSION "jinf" ///< Extension for journal info files
#define JRNL_DATA_EXTENSION "jdat" ///< Extension for journal data files
-#define RHM_JDAT_DTXA_MAGIC 0x614d4852 ///< ("RHMa" in little endian) Magic for dtx abort hdrs
-#define RHM_JDAT_DTXC_MAGIC 0x634d4852 ///< ("RHMc" in little endian) Magic for dtx commit hdrs
+#define RHM_JDAT_TXA_MAGIC 0x614d4852 ///< ("RHMa" in little endian) Magic for dtx abort hdrs
+#define RHM_JDAT_TXC_MAGIC 0x634d4852 ///< ("RHMc" in little endian) Magic for dtx commit hdrs
#define RHM_JDAT_DEQ_MAGIC 0x644d4852 ///< ("RHMd" in little endian) Magic for deq rec hdrs
#define RHM_JDAT_ENQ_MAGIC 0x654d4852 ///< ("RHMe" in little endian) Magic for enq rec hdrs
#define RHM_JDAT_FILE_MAGIC 0x664d4852 ///< ("RHMf" in little endian) Magic for file hdrs
Modified: store/trunk/cpp/lib/jrnl/jcntl.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/jcntl.cpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/lib/jrnl/jcntl.cpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -245,15 +245,17 @@
}
const iores
-jcntl::txn_abort(const std::string& /*xid*/) throw (jexception)
+jcntl::txn_abort(data_tok* const dtokp, const std::string& xid) throw (jexception)
{
- return RHM_IORES_NOTIMPL;
+ check_wstatus("txn_abort");
+ return _wmgr.abort(dtokp, xid.c_str(), xid.size());
}
const iores
-jcntl::txn_commit(const std::string& /*xid*/) throw (jexception)
+jcntl::txn_commit(data_tok* const dtokp, const std::string& xid) throw (jexception)
{
- return RHM_IORES_NOTIMPL;
+ check_wstatus("txn_commit");
+ return _wmgr.commit(dtokp, xid.c_str(), xid.size());
}
const bool
Modified: store/trunk/cpp/lib/jrnl/jcntl.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/jcntl.hpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/lib/jrnl/jcntl.hpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -447,7 +447,7 @@
*
* \exception TODO
*/
- const iores txn_abort(const std::string& xid) throw (jexception);
+ const iores txn_abort(data_tok* const dtokp, const std::string& xid) throw (jexception);
/**
* \brief Commit the transaction for all records enqueued or dequeued with the matching xid.
@@ -460,7 +460,7 @@
*
* \exception TODO
*/
- const iores txn_commit(const std::string& xid) throw (jexception);
+ const iores txn_commit(data_tok* const dtokp, const std::string& xid) throw (jexception);
/**
* \brief Check whether all the enqueue records for the given xid have reached disk.
Modified: store/trunk/cpp/lib/jrnl/pmgr.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/pmgr.cpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/lib/jrnl/pmgr.cpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -89,6 +89,9 @@
_pg_cntr(0),
_pg_offset_dblks(0),
_aio_evt_rem(0),
+ _enq_rec(),
+ _deq_rec(),
+ _txn_rec(),
_cb(NULL)
{}
@@ -110,6 +113,8 @@
_pg_offset_dblks(0),
_aio_evt_rem(0),
_enq_rec(),
+ _deq_rec(),
+ _txn_rec(),
_cb(NULL)
{
initialize();
Modified: store/trunk/cpp/lib/jrnl/pmgr.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/pmgr.hpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/lib/jrnl/pmgr.hpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -132,8 +132,6 @@
deq_rec _deq_rec; ///< Dequeue record used for encoding/decoding
txn_rec _txn_rec; ///< Transaction record used for encoding/decoding
- // TODO: move _cb down to wmgr, it is the only class that uses it There is no need for
- // read callbacks based on AIO. - (check this asertion)
aio_cb _cb; ///< Callback function pointer for AIO events
public:
Modified: store/trunk/cpp/lib/jrnl/txn_rec.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/txn_rec.cpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/lib/jrnl/txn_rec.cpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -33,6 +33,7 @@
#include <jrnl/txn_rec.hpp>
#include <assert.h>
+#include <errno.h>
#include <iomanip>
#include <sstream>
#include <jrnl/jerrno.hpp>
@@ -44,39 +45,58 @@
txn_rec::txn_rec():
_txn_hdr(),
- _xid(),
- _dtx_tail()
-{}
+ _xidp(NULL),
+ _buff(NULL),
+ _txn_tail()
+{
+ _txn_hdr._hdr._version = RHM_JDAT_VERSION;
+}
-txn_rec::txn_rec(const u_int32_t magic, const u_int64_t rid):
- _txn_hdr(magic, RHM_JDAT_VERSION, 0, rid, 0),
- _xid(),
- _dtx_tail(_txn_hdr._hdr)
+txn_rec::txn_rec(const u_int32_t magic, const u_int64_t rid, const void* const xidp,
+ const size_t xidlen):
+ _txn_hdr(magic, RHM_JDAT_VERSION, 0, rid, xidlen),
+ _xidp(xidp),
+ _buff(NULL),
+ _txn_tail(_txn_hdr._hdr)
{}
-txn_rec::txn_rec(const u_int32_t magic, const u_int64_t rid, const std::string& xid):
- _txn_hdr(magic, RHM_JDAT_VERSION, 0, rid, xid.size()),
- _xid(xid),
- _dtx_tail(_txn_hdr._hdr)
-{}
-
txn_rec::~txn_rec()
-{}
+{
+ if (_buff)
+ ::free(_buff);
+}
void
-txn_rec::reset(const u_int64_t rid)
+txn_rec::reset(const u_int32_t magic)
{
- _txn_hdr._hdr._rid = rid;
+ _txn_hdr._hdr._magic = magic;
+ _txn_hdr._hdr._rid = 0;
_txn_hdr._xidsize = 0;
- _dtx_tail._rid = rid;
+ _xidp = NULL;
+ if (_buff)
+ {
+ ::free(_buff);
+ _buff = NULL;
+ }
+ _txn_tail._xmagic = ~magic;
+ _txn_tail._rid = 0;
}
void
-txn_rec::reset(const u_int64_t rid, const std::string& xid)
+txn_rec::reset(const u_int32_t magic, const u_int64_t rid, const void* const xidp,
+ const size_t xidlen)
{
+ _txn_hdr._hdr._magic = magic;
_txn_hdr._hdr._rid = rid;
- _txn_hdr._xidsize = xid.size();
- _dtx_tail._rid = rid;
+ _txn_hdr._xidsize = xidlen;
+ _xidp = xidp;
+ if (_buff)
+ {
+ ::free(_buff);
+ _buff = NULL;
+ }
+ _txn_tail._xmagic = ~magic;
+ _txn_tail._rid = rid;
}
u_int32_t
@@ -84,8 +104,7 @@
{
assert(wptr != NULL);
assert(max_size_dblks > 0);
- assert(_xid.size() == _txn_hdr._xidsize);
- assert(_txn_hdr._xidsize > 0);
+ assert(_xidp != NULL && _txn_hdr._xidsize > 0);
size_t rec_offs = rec_offs_dblks * JRNL_DBLK_SIZE;
size_t rem = max_size_dblks * JRNL_DBLK_SIZE;
@@ -101,24 +120,24 @@
{
if (wsize > rem)
wsize = rem;
- ::memcpy(wptr, (const char*)_xid.c_str() + rec_offs, wsize);
+ ::memcpy(wptr, (char*)_xidp + rec_offs, wsize);
wr_cnt += wsize;
rem -= wsize;
}
rec_offs -= _txn_hdr._xidsize - wsize2;
if (rem)
{
- wsize = sizeof(_dtx_tail) > rec_offs ? sizeof(_dtx_tail) - rec_offs : 0;
+ wsize = sizeof(_txn_tail) > rec_offs ? sizeof(_txn_tail) - rec_offs : 0;
wsize2 = wsize;
if (wsize)
{
if (wsize > rem)
wsize = rem;
- ::memcpy((char*)wptr + wr_cnt, (char*)&_dtx_tail + rec_offs, wsize);
+ ::memcpy((char*)wptr + wr_cnt, (char*)&_txn_tail + rec_offs, wsize);
wr_cnt += wsize;
rem -= wsize;
}
- rec_offs -= sizeof(_dtx_tail) - wsize2;
+ rec_offs -= sizeof(_txn_tail) - wsize2;
}
assert(rem == 0);
assert(rec_offs == 0);
@@ -129,22 +148,22 @@
size_t wsize = _txn_hdr._xidsize > rec_offs ? _txn_hdr._xidsize - rec_offs : 0;
if (wsize)
{
- ::memcpy(wptr, _xid.c_str() + rec_offs, wsize);
+ ::memcpy(wptr, (char*)_xidp + rec_offs, wsize);
wr_cnt += wsize;
}
rec_offs -= _txn_hdr._xidsize - wsize;
- wsize = sizeof(_dtx_tail) > rec_offs ? sizeof(_dtx_tail) - rec_offs : 0;
+ wsize = sizeof(_txn_tail) > rec_offs ? sizeof(_txn_tail) - rec_offs : 0;
if (wsize)
{
- ::memcpy((char*)wptr + wr_cnt, (char*)&_dtx_tail + rec_offs, wsize);
+ ::memcpy((char*)wptr + wr_cnt, (char*)&_txn_tail + rec_offs, wsize);
wr_cnt += wsize;
#ifdef RHM_CLEAN
- ::memset((char*)wptr + wr_cnt, RHM_CLEAN_CHAR,
- (size_dblks(rec_size()) * JRNL_DBLK_SIZE) -
- (rec_offs_dblks * JRNL_DBLK_SIZE) - wr_cnt);
+ size_t rec_offs = rec_offs_dblks * JRNL_DBLK_SIZE;
+ size_t dblk_rec_size = size_dblks(rec_size() - rec_offs) * JRNL_DBLK_SIZE;
+ ::memset((char*)wptr + wr_cnt, RHM_CLEAN_CHAR, dblk_rec_size - wr_cnt);
#endif
}
- rec_offs -= sizeof(_dtx_tail) - wsize;
+ rec_offs -= sizeof(_txn_tail) - wsize;
assert(rec_offs == 0);
}
}
@@ -160,14 +179,14 @@
if (rem)
{
wsize = rem >= _txn_hdr._xidsize ? _txn_hdr._xidsize : rem;
- ::memcpy((char*)wptr + wr_cnt, _xid.c_str(), wsize);
+ ::memcpy((char*)wptr + wr_cnt, _xidp, wsize);
wr_cnt += wsize;
rem -= wsize;
}
if (rem)
{
- wsize = rem >= sizeof(_dtx_tail) ? sizeof(_dtx_tail) : rem;
- ::memcpy((char*)wptr + wr_cnt, (void*)&_dtx_tail, wsize);
+ wsize = rem >= sizeof(_txn_tail) ? sizeof(_txn_tail) : rem;
+ ::memcpy((char*)wptr + wr_cnt, (void*)&_txn_tail, wsize);
wr_cnt += wsize;
rem -= wsize;
}
@@ -175,16 +194,13 @@
}
else // No split required
{
- if (_txn_hdr._xidsize)
- {
- ::memcpy((char*)wptr + wr_cnt, _xid.c_str(), _txn_hdr._xidsize);
- wr_cnt += _txn_hdr._xidsize;
- ::memcpy((char*)wptr + wr_cnt, (void*)&_dtx_tail, sizeof(_dtx_tail));
- wr_cnt += sizeof(_dtx_tail);
- }
+ ::memcpy((char*)wptr + wr_cnt, _xidp, _txn_hdr._xidsize);
+ wr_cnt += _txn_hdr._xidsize;
+ ::memcpy((char*)wptr + wr_cnt, (void*)&_txn_tail, sizeof(_txn_tail));
+ wr_cnt += sizeof(_txn_tail);
#ifdef RHM_CLEAN
- ::memset((char*)wptr + wr_cnt, RHM_CLEAN_CHAR,
- (size_dblks(rec_size()) * JRNL_DBLK_SIZE) - wr_cnt);
+ size_t dblk_rec_size = size_dblks(rec_size()) * JRNL_DBLK_SIZE;
+ ::memset((char*)wptr + wr_cnt, RHM_CLEAN_CHAR, dblk_rec_size - wr_cnt);
#endif
}
}
@@ -214,18 +230,18 @@
// Part of xid still outstanding, copy remainder of xid and tail
const size_t xid_offs = rec_offs - deq_hdr::size();
const size_t xid_rem = _txn_hdr._xidsize - xid_offs;
- _xid.append((char*)rptr, xid_rem);
+ ::memcpy((char*)_buff + xid_offs, rptr, xid_rem);
rd_cnt = xid_rem;
- ::memcpy((void*)&_dtx_tail, ((char*)rptr + rd_cnt), sizeof(_dtx_tail));
+ ::memcpy((void*)&_txn_tail, ((char*)rptr + rd_cnt), sizeof(_txn_tail));
chk_tail();
- rd_cnt += sizeof(_dtx_tail);
+ rd_cnt += sizeof(_txn_tail);
}
else
{
// Tail or part of tail only outstanding, complete tail
const size_t tail_offs = rec_offs - deq_hdr::size() - _txn_hdr._xidsize;
const size_t tail_rem = rec_tail::size() - tail_offs;
- ::memcpy((char*)&_dtx_tail + tail_offs, rptr, tail_rem);
+ ::memcpy((char*)&_txn_tail + tail_offs, rptr, tail_rem);
chk_tail();
rd_cnt = tail_rem;
}
@@ -235,12 +251,12 @@
// Remainder of xid fits within this page, tail split
const size_t xid_offs = rec_offs - deq_hdr::size();
const size_t xid_rem = _txn_hdr._xidsize - xid_offs;
- _xid.append((char*)rptr, xid_rem);
+ ::memcpy((char*)_buff + xid_offs, rptr, xid_rem);
rd_cnt += xid_rem;
const size_t tail_rem = (max_size_dblks * JRNL_DBLK_SIZE) - rd_cnt;
if (tail_rem)
{
- ::memcpy((void*)&_dtx_tail, ((char*)rptr + xid_rem), tail_rem);
+ ::memcpy((void*)&_txn_tail, ((char*)rptr + xid_rem), tail_rem);
rd_cnt += tail_rem;
}
}
@@ -248,7 +264,7 @@
{
// Remainder of xid split
const size_t xid_cp_size = (max_size_dblks * JRNL_DBLK_SIZE);
- _xid.append((char*)rptr, xid_cp_size);
+ ::memcpy((char*)_buff + rec_offs - deq_hdr::size(), rptr, xid_cp_size);
rd_cnt += xid_cp_size;
}
}
@@ -263,8 +279,15 @@
_txn_hdr._xidsize = *(size_t*)((char*)rptr + rd_cnt);
rd_cnt = _txn_hdr.size();
chk_hdr();
+ _buff = ::malloc(_txn_hdr._xidsize);
+ if (_buff == NULL)
+ {
+ std::stringstream ss;
+ ss << "_buff malloc(): errno=" << errno;
+ throw jexception(jerrno::JERR__MALLOC, ss.str(), "txn_rec", "decode");
+ }
const u_int32_t hdr_xid_dblks = size_dblks(deq_hdr::size() + _txn_hdr._xidsize);
- const u_int32_t hdr_xid_tail_dblks = size_dblks(enq_hdr::size() + _txn_hdr._xidsize +
+ const u_int32_t hdr_xid_tail_dblks = size_dblks(enq_hdr::size() + _txn_hdr._xidsize +
rec_tail::size());
// Check if record (header + xid + tail) fits within this page, we can check the
@@ -272,21 +295,21 @@
if (hdr_xid_tail_dblks <= max_size_dblks)
{
// Entire header, xid and tail fits within this page
- ::memcpy((void*)&_dtx_tail, (char*)rptr + rd_cnt + _txn_hdr._xidsize,
- sizeof(_dtx_tail));
+ ::memcpy(_buff, (char*)rptr + rd_cnt, _txn_hdr._xidsize);
+ rd_cnt += _txn_hdr._xidsize;
+ ::memcpy((void*)&_txn_tail, (char*)rptr + rd_cnt, sizeof(_txn_tail));
+ rd_cnt += sizeof(_txn_tail);
chk_tail();
- _xid.assign((char*)rptr + rd_cnt, _txn_hdr._xidsize);
- rd_cnt += _txn_hdr._xidsize + sizeof(_dtx_tail);
}
else if (hdr_xid_dblks <= max_size_dblks)
{
// Entire header and xid fit within this page, tail split
- _xid.assign((char*)rptr + rd_cnt, _txn_hdr._xidsize);
+ ::memcpy(_buff, (char*)rptr + rd_cnt, _txn_hdr._xidsize);
rd_cnt += _txn_hdr._xidsize;
const size_t tail_rem = (max_size_dblks * JRNL_DBLK_SIZE) - rd_cnt;
if (tail_rem)
{
- ::memcpy((void*)&_dtx_tail, (char*)rptr + rd_cnt, tail_rem);
+ ::memcpy((void*)&_txn_tail, (char*)rptr + rd_cnt, tail_rem);
rd_cnt += tail_rem;
}
}
@@ -294,7 +317,7 @@
{
// Header fits within this page, xid split
const size_t xid_cp_size = (max_size_dblks * JRNL_DBLK_SIZE) - rd_cnt;
- _xid.assign((char*)rptr + rd_cnt, xid_cp_size);
+ ::memcpy(_buff, (char*)rptr + rd_cnt, xid_cp_size);
rd_cnt += xid_cp_size;
}
}
@@ -305,13 +328,13 @@
txn_rec::str(std::string& str) const
{
std::stringstream ss;
- if (_txn_hdr._hdr._magic == RHM_JDAT_DTXA_MAGIC)
+ if (_txn_hdr._hdr._magic == RHM_JDAT_TXA_MAGIC)
ss << "dtxa_rec: m=" << _txn_hdr._hdr._magic;
else
ss << "dtxc_rec: m=" << _txn_hdr._hdr._magic;
ss << " v=" << (int)_txn_hdr._hdr._version;
ss << " rid=" << _txn_hdr._hdr._rid;
- ss << " xid=\"" << _xid << "\"";
+ ss << " xid=\"" << _xidp << "\"";
str.append(ss.str());
return str;
}
@@ -332,13 +355,13 @@
txn_rec::chk_hdr() const throw (jexception)
{
jrec::chk_hdr(_txn_hdr._hdr);
- if (_txn_hdr._hdr._magic != RHM_JDAT_DTXA_MAGIC && _txn_hdr._hdr._magic != RHM_JDAT_DTXC_MAGIC)
+ if (_txn_hdr._hdr._magic != RHM_JDAT_TXA_MAGIC && _txn_hdr._hdr._magic != RHM_JDAT_TXC_MAGIC)
{
std::stringstream ss;
ss << std::hex << std::setfill('0');
ss << "dtx magic: rid=0x" << std::setw(16) << _txn_hdr._hdr._rid;
- ss << ": expected=(0x" << std::setw(8) << RHM_JDAT_DTXA_MAGIC;
- ss << " or 0x" << RHM_JDAT_DTXC_MAGIC;
+ ss << ": expected=(0x" << std::setw(8) << RHM_JDAT_TXA_MAGIC;
+ ss << " or 0x" << RHM_JDAT_TXC_MAGIC;
ss << ") read=0x" << std::setw(2) << (int)_txn_hdr._hdr._magic;
throw jexception(jerrno::JERR_DREC_INVRHDR, ss.str(), "txn_rec", "chk_hdr");
}
@@ -354,7 +377,7 @@
void
txn_rec::chk_tail() const throw (jexception)
{
- jrec::chk_tail(_dtx_tail, _txn_hdr._hdr);
+ jrec::chk_tail(_txn_tail, _txn_hdr._hdr);
}
} // namespace journal
Modified: store/trunk/cpp/lib/jrnl/txn_rec.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/txn_rec.hpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/lib/jrnl/txn_rec.hpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -56,21 +56,28 @@
{
private:
txn_hdr _txn_hdr; ///< transaction header
- std::string _xid; ///< XID
- rec_tail _dtx_tail; ///< Record tail
+ const void* _xidp; ///< xid pointer for encoding (writing to disk)
+ void* _buff; ///< Pointer to buffer to receive data read from disk
+ rec_tail _txn_tail; ///< Record tail
public:
+ // constructor used for read operations and xid must have memory allocated
txn_rec();
- txn_rec(const u_int32_t magic, const u_int64_t rid);
- txn_rec(const u_int32_t magic, const u_int64_t rid, const std::string& xid);
+ // constructor used for write operations, where xid already exists
+ txn_rec(const u_int32_t magic, const u_int64_t rid, const void* const xidp,
+ const size_t xidlen);
~txn_rec();
- void reset(const u_int64_t rid);
- void reset(const u_int64_t rid, const std::string& xid);
+ // Prepare instance for use in reading data from journal
+ void reset(const u_int32_t magic);
+ // Prepare instance for use in writing data to journal
+ void reset(const u_int32_t magic, const u_int64_t rid, const void* const xidp,
+ const size_t xidlen);
u_int32_t encode(void* wptr, u_int32_t rec_offs_dblks, u_int32_t max_size_dblks)
throw (jexception);
u_int32_t decode(hdr& h, void* rptr, u_int32_t rec_offs_dblks, u_int32_t max_size_dblks)
throw (jexception);
+ inline const void* const get_xid() { return _buff; }
std::string& str(std::string& str) const;
inline const size_t data_size() const { return 0; } // This record never carries data
const size_t xid_size() const;
Modified: store/trunk/cpp/lib/jrnl/wmgr.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/wmgr.cpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/lib/jrnl/wmgr.cpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -50,7 +50,9 @@
_fhdr_buff(NULL),
_cached_offset_dblks(0),
_enq_busy(false),
- _deq_busy(false)
+ _deq_busy(false),
+ _abort_busy(false),
+ _commit_busy(false)
{}
wmgr::wmgr(jcntl* jc, enq_map& emap, wrfc& wrfc, std::deque<data_tok*>* const dtokl,
@@ -62,7 +64,9 @@
_fhdr_buff(NULL),
_cached_offset_dblks(0),
_enq_busy(false),
- _deq_busy(false)
+ _deq_busy(false),
+ _abort_busy(false),
+ _commit_busy(false)
{}
wmgr::~wmgr()
@@ -96,10 +100,10 @@
if (this_data_len != tot_data_len)
return RHM_IORES_NOTIMPL;
- if (_deq_busy)
+ if (_deq_busy || _abort_busy || _commit_busy)
return RHM_IORES_BUSY;
- iores res = pre_write_check(true, dtokp);
+ iores res = pre_write_check(WMGR_ENQUEUE, dtokp);
if (res != RHM_IORES_SUCCESS)
return res;
@@ -118,18 +122,17 @@
else
_enq_busy = true;
- u_int64_t rid;
- if (dtokp->getSourceMessage())
- {
- rid = dtokp->rid();
- assert(rid != 0);
- }
- else
- rid = cont ? _wrfc.rid() - 1 : _wrfc.get_incr_rid();
+ u_int64_t rid = initialize_rid(cont, dtokp);
_enq_rec.reset(rid, data_buff, tot_data_len, xid_ptr, xid_len, transient);
if (!cont)
+ {
dtokp->set_rid(rid);
+ if (xid_len)
+ dtokp->set_xid(xid_ptr, xid_len);
+ else
+ dtokp->clear_xid();
+ }
bool done = false;
while (!done)
{
@@ -224,10 +227,10 @@
if (xid_len)
assert(xid_ptr != NULL);
- if (_enq_busy)
+ if (_enq_busy || _abort_busy || _commit_busy)
return RHM_IORES_BUSY;
- iores res = pre_write_check(false, dtokp);
+ iores res = pre_write_check(WMGR_DEQUEUE, dtokp);
if (res != RHM_IORES_SUCCESS)
return res;
@@ -246,19 +249,12 @@
else
{
_deq_busy = true;
- dtokp->set_dblocks_written(0); // Reset dblks_written from enqueue op
+ dtokp->set_dblocks_written(0); // Reset dblks_written from previous op
}
- u_int64_t rid;
- if (dtokp->getSourceMessage())
- {
- rid = dtokp->dequeue_rid();
- assert(rid != 0);
- }
- else
- rid = _wrfc.get_incr_rid();
+ u_int64_t rid = initialize_rid(cont, dtokp);
- _deq_rec.reset(rid, dtokp->rid());
+ _deq_rec.reset(rid, dtokp->rid(), xid_ptr, xid_len);
bool done = false;
while (!done)
{
@@ -290,7 +286,7 @@
// Has the file header been written (i.e. write pointers still at 0)?
if (_wrfc.empty())
{
- u_int32_t rec_dblks_rem = _enq_rec.rec_size_dblks() - data_offs_dblks;
+ u_int32_t rec_dblks_rem = _deq_rec.rec_size_dblks() - data_offs_dblks;
bool file_fit = rec_dblks_rem <= JRNL_FILE_SIZE * JRNL_SBLK_SIZE;
bool file_full = rec_dblks_rem == JRNL_FILE_SIZE * JRNL_SBLK_SIZE;
size_t fro = 0;
@@ -329,8 +325,8 @@
cont = true;
else
{
- // Set last data_tok in page only to state ENQ_PART
- dtokp->set_wstate(data_tok::ENQ_PART);
+ // Set last data_tok in page only to state DEQ_PART
+ dtokp->set_wstate(data_tok::DEQ_PART);
done = true;
}
}
@@ -344,6 +340,218 @@
}
const iores
+wmgr::abort(data_tok* dtokp, const void* const xid_ptr, const size_t xid_len) throw (jexception)
+{
+ // commit and abort MUST have a valid xid
+ assert(xid_ptr != NULL && xid_len > 0);
+
+ if (_enq_busy || _deq_busy || _commit_busy)
+ return RHM_IORES_BUSY;
+
+ iores res = pre_write_check(WMGR_ABORT, dtokp);
+ if (res != RHM_IORES_SUCCESS)
+ return res;
+
+ bool cont = false;
+ if (_abort_busy) // If abort() exited last time with RHM_IORES_FULL or RHM_IORES_AIO_WAIT
+ {
+ if (dtokp->wstate() == data_tok::ABORT_PART)
+ cont = true;
+ else
+ {
+ std::stringstream ss;
+ ss << "This data_tok: id=" << dtokp->id() << " state=" << dtokp->wstate_str();
+ throw jexception(jerrno::JERR_WMGR_DEQDISCONT, ss.str(), "wmgr", "abort");
+ }
+ }
+ else
+ _abort_busy = true;
+
+ u_int64_t rid = initialize_rid(cont, dtokp);
+ _txn_rec.reset(RHM_JDAT_TXA_MAGIC, rid, xid_ptr, xid_len);
+ bool done = false;
+ while (!done)
+ {
+ assert(_pg_offset_dblks < JRNL_WMGR_PAGE_SIZE * JRNL_SBLK_SIZE);
+ void* wptr = (void*)((char*)_page_ptr_arr[_pg_index] + _pg_offset_dblks * JRNL_DBLK_SIZE);
+ u_int32_t data_offs_dblks = dtokp->dblocks_written();
+ u_int32_t ret = _txn_rec.encode(wptr, data_offs_dblks,
+ (JRNL_WMGR_PAGE_SIZE * JRNL_SBLK_SIZE) - _pg_offset_dblks);
+ _pg_offset_dblks += ret;
+ _cached_offset_dblks += ret;
+ dtokp->incr_dblocks_written(ret);
+
+ // Is the encoding of this record complete?
+ if (dtokp->dblocks_written() >= _txn_rec.rec_size_dblks())
+ {
+ dtokp->set_wstate(data_tok::ABORT_SUBM);
+ _page_cb_arr[_pg_index]._pdtokl->push_back(dtokp);
+ done = true;
+ }
+
+ // Has the file header been written (i.e. write pointers still at 0)?
+ if (_wrfc.empty())
+ {
+ u_int32_t rec_dblks_rem = _txn_rec.rec_size_dblks() - data_offs_dblks;
+ bool file_fit = rec_dblks_rem <= JRNL_FILE_SIZE * JRNL_SBLK_SIZE;
+ bool file_full = rec_dblks_rem == JRNL_FILE_SIZE * JRNL_SBLK_SIZE;
+ size_t fro = 0;
+ if (cont)
+ {
+ if (file_fit && !file_full)
+ fro = (rec_dblks_rem + JRNL_SBLK_SIZE) * JRNL_DBLK_SIZE;
+ }
+ else
+ fro = JRNL_SBLK_SIZE * JRNL_DBLK_SIZE;
+ write_fhdr(rid, _wrfc.index(), fro);
+ }
+
+ // Is the page full? If so, flush.
+ if (_pg_offset_dblks >= JRNL_WMGR_PAGE_SIZE * JRNL_SBLK_SIZE)
+ {
+ res = write_flush();
+ assert(res == RHM_IORES_SUCCESS);
+
+ if (_page_cb_arr[_pg_index]._state == AIO_PENDING && !done)
+ {
+ res = RHM_IORES_AIO_WAIT;
+ dtokp->set_wstate(data_tok::ABORT_PART);
+ done = true;
+ }
+
+ // File full?
+ if (_pg_cntr >= (JRNL_FILE_SIZE / JRNL_WMGR_PAGE_SIZE))
+ {
+ iores rfres = rotate_file();
+ if (rfres != RHM_IORES_SUCCESS)
+ res = rfres;
+ if (!done)
+ {
+ if (rfres == RHM_IORES_SUCCESS)
+ cont = true;
+ else
+ {
+ // Set last data_tok in page only to state ABORT_PART
+ dtokp->set_wstate(data_tok::ABORT_PART);
+ done = true;
+ }
+ }
+ }
+ }
+ }
+ if (dtokp->wstate() >= data_tok::ABORT_SUBM)
+ _abort_busy = false;
+
+ return res;
+}
+
+const iores
+wmgr::commit(data_tok* dtokp, const void* const xid_ptr, const size_t xid_len) throw (jexception)
+{
+ // commit and abort MUST have a valid xid
+ assert(xid_ptr != NULL && xid_len > 0);
+
+ if (_enq_busy || _deq_busy || _abort_busy)
+ return RHM_IORES_BUSY;
+
+ iores res = pre_write_check(WMGR_COMMIT, dtokp);
+ if (res != RHM_IORES_SUCCESS)
+ return res;
+
+ bool cont = false;
+ if (_commit_busy) // If commit() exited last time with RHM_IORES_FULL or RHM_IORES_AIO_WAIT
+ {
+ if (dtokp->wstate() == data_tok::COMMIT_PART)
+ cont = true;
+ else
+ {
+ std::stringstream ss;
+ ss << "This data_tok: id=" << dtokp->id() << " state=" << dtokp->wstate_str();
+ throw jexception(jerrno::JERR_WMGR_DEQDISCONT, ss.str(), "wmgr", "commit");
+ }
+ }
+ else
+ _commit_busy = true;
+
+ u_int64_t rid = initialize_rid(cont, dtokp);
+ _txn_rec.reset(RHM_JDAT_TXC_MAGIC, rid, xid_ptr, xid_len);
+ bool done = false;
+ while (!done)
+ {
+ assert(_pg_offset_dblks < JRNL_WMGR_PAGE_SIZE * JRNL_SBLK_SIZE);
+ void* wptr = (void*)((char*)_page_ptr_arr[_pg_index] + _pg_offset_dblks * JRNL_DBLK_SIZE);
+ u_int32_t data_offs_dblks = dtokp->dblocks_written();
+ u_int32_t ret = _txn_rec.encode(wptr, data_offs_dblks,
+ (JRNL_WMGR_PAGE_SIZE * JRNL_SBLK_SIZE) - _pg_offset_dblks);
+ _pg_offset_dblks += ret;
+ _cached_offset_dblks += ret;
+ dtokp->incr_dblocks_written(ret);
+
+ // Is the encoding of this record complete?
+ if (dtokp->dblocks_written() >= _txn_rec.rec_size_dblks())
+ {
+ dtokp->set_wstate(data_tok::COMMIT_SUBM);
+ _page_cb_arr[_pg_index]._pdtokl->push_back(dtokp);
+ done = true;
+ }
+
+ // Has the file header been written (i.e. write pointers still at 0)?
+ if (_wrfc.empty())
+ {
+ u_int32_t rec_dblks_rem = _txn_rec.rec_size_dblks() - data_offs_dblks;
+ bool file_fit = rec_dblks_rem <= JRNL_FILE_SIZE * JRNL_SBLK_SIZE;
+ bool file_full = rec_dblks_rem == JRNL_FILE_SIZE * JRNL_SBLK_SIZE;
+ size_t fro = 0;
+ if (cont)
+ {
+ if (file_fit && !file_full)
+ fro = (rec_dblks_rem + JRNL_SBLK_SIZE) * JRNL_DBLK_SIZE;
+ }
+ else
+ fro = JRNL_SBLK_SIZE * JRNL_DBLK_SIZE;
+ write_fhdr(rid, _wrfc.index(), fro);
+ }
+
+ // Is the page full? If so, flush.
+ if (_pg_offset_dblks >= JRNL_WMGR_PAGE_SIZE * JRNL_SBLK_SIZE)
+ {
+ res = write_flush();
+ assert(res == RHM_IORES_SUCCESS);
+
+ if (_page_cb_arr[_pg_index]._state == AIO_PENDING && !done)
+ {
+ res = RHM_IORES_AIO_WAIT;
+ dtokp->set_wstate(data_tok::COMMIT_PART);
+ done = true;
+ }
+
+ // File full?
+ if (_pg_cntr >= (JRNL_FILE_SIZE / JRNL_WMGR_PAGE_SIZE))
+ {
+ iores rfres = rotate_file();
+ if (rfres != RHM_IORES_SUCCESS)
+ res = rfres;
+ if (!done)
+ {
+ if (rfres == RHM_IORES_SUCCESS)
+ cont = true;
+ else
+ {
+ // Set last data_tok in page only to state COMMIT_PART
+ dtokp->set_wstate(data_tok::COMMIT_PART);
+ done = true;
+ }
+ }
+ }
+ }
+ }
+ if (dtokp->wstate() >= data_tok::COMMIT_SUBM)
+ _commit_busy = false;
+
+ return res;
+}
+
+const iores
wmgr::flush()
{
iores res = write_flush();
@@ -470,6 +678,14 @@
assert(dtp->wstate() == data_tok::DEQ_SUBM);
dtp->set_wstate(data_tok::DEQ);
break;
+ case data_tok::ABORT_SUBM:
+ assert(dtp->wstate() == data_tok::ABORT_SUBM);
+ dtp->set_wstate(data_tok::ABORTED);
+ break;
+ case data_tok::COMMIT_SUBM:
+ assert(dtp->wstate() == data_tok::COMMIT_SUBM);
+ dtp->set_wstate(data_tok::COMMITTED);
+ break;
default:
std::stringstream ss;
ss << "dtok_state=" << dtp->wstate_str();
@@ -519,7 +735,7 @@
}
const iores
-wmgr::pre_write_check(bool enqueue, data_tok* dtokp) throw (jexception)
+wmgr::pre_write_check(_op_type op, data_tok* dtokp) throw (jexception)
{
// Check status of current file
if (!_wrfc.is_reset())
@@ -528,7 +744,7 @@
return RHM_IORES_FULL;
}
- // Check status of current page
+ // Check status of current page is ok for writing
if (_page_cb_arr[_pg_index]._state != IN_USE)
{
if (_page_cb_arr[_pg_index]._state == UNUSED)
@@ -538,25 +754,56 @@
else
{
std::stringstream ss;
- ss << "op=" << (enqueue ? "enqueue" : "dequeue") << " index=" << _pg_index;
- ss << " state=" << _page_cb_arr[_pg_index].state_str();
+ ss << "op=" << _op_str[op] << " index=" << _pg_index << " state=";
+ ss << _page_cb_arr[_pg_index].state_str();
throw jexception(jerrno::JERR_WMGR_BADPGSTATE, ss.str(), "wmgr", "pre_write_check");
}
}
- // Check state of data_tok
- bool res = enqueue ? dtokp->is_writable() : dtokp->is_dequeueable();
- if (!res)
+ // operation-specific checks
+ switch (op)
{
- std::stringstream ss;
- ss << "op=" << (enqueue ? "enqueue" : "dequeue") << " dtok_id=" << dtokp->id();
- ss << " dtok_state=" << dtokp->wstate_str();
- throw jexception(jerrno::JERR_WMGR_BADDTOKSTATE, ss.str(), "wmgr", "pre_write_check");
+ case WMGR_ENQUEUE:
+ if (!dtokp->is_writable())
+ {
+ std::stringstream ss;
+ ss << "op=" << _op_str[op] << " dtok_id=" << dtokp->id();
+ ss << " dtok_state=" << dtokp->wstate_str();
+ throw jexception(jerrno::JERR_WMGR_BADDTOKSTATE, ss.str(), "wmgr",
+ "pre_write_check");
+ }
+ break;
+ case WMGR_DEQUEUE:
+ if (!dtokp->is_dequeueable())
+ {
+ std::stringstream ss;
+ ss << "op=" << _op_str[op] << " dtok_id=" << dtokp->id();
+ ss << " dtok_state=" << dtokp->wstate_str();
+ throw jexception(jerrno::JERR_WMGR_BADDTOKSTATE, ss.str(), "wmgr",
+ "pre_write_check");
+ }
+ break;
+ case WMGR_ABORT:
+ break;
+ case WMGR_COMMIT:
+ break;
}
return RHM_IORES_SUCCESS;
}
+const u_int64_t
+wmgr::initialize_rid(const bool cont, data_tok* dtokp)
+{
+ if (dtokp->getSourceMessage())
+ {
+ u_int64_t rid = dtokp->rid();
+ assert(rid != 0);
+ return rid;
+ }
+ return cont ? _wrfc.rid() - 1 : _wrfc.get_incr_rid();
+}
+
void
wmgr::dblk_roundup()
{
@@ -590,5 +837,9 @@
_wrfc.add_subm_cnt_dblks(JRNL_SBLK_SIZE);
}
+// static
+
+const char* wmgr::_op_str[] = {"enqueue", "dequeue", "abort", "commit"};
+
} // namespace journal
} // namespace rhm
Modified: store/trunk/cpp/lib/jrnl/wmgr.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/wmgr.hpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/lib/jrnl/wmgr.hpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -75,10 +75,20 @@
iocb _fhdr_iocb; ///< IO control block for file header writes
u_int32_t _cached_offset_dblks; ///< Amount of unwritten data in page (dblocks)
std::deque<data_tok*> _ddtokl; ///< Deferred dequeue data_tok list
- // TODO: Convert _enq_busy into a proper threadsafe lock
+ // TODO: Convert _enq_busy etc into a proper threadsafe lock
+ // TODO: Convert to enum? Are these encodes mutually exclusive?
bool _enq_busy; ///< Flag true if enqueue is in progress
bool _deq_busy; ///< Flag true if dequeue is in progress
+ bool _abort_busy; ///< Flag true if abort is in progress
+ bool _commit_busy; ///< Flag true if commit is in progress
+ enum _op_type { WMGR_ENQUEUE = 0, WMGR_DEQUEUE, WMGR_ABORT, WMGR_COMMIT };
+ static const char* _op_str[];
+ enq_rec _enq_rec; ///< Enqueue record used for encoding/decoding
+ deq_rec _deq_rec; ///< Dequeue record used for encoding/decoding
+ txn_rec _txn_rec; ///< Transaction record used for encoding/decoding
+ aio_cb _cb; ///< Callback function pointer for AIO events
+
public:
wmgr(jcntl* jc, enq_map& emap, wrfc& wrfc);
wmgr(jcntl* jc, enq_map& emap, wrfc& wrfc, std::deque<data_tok*>* const dtokl,
@@ -92,12 +102,17 @@
const size_t xid_len, const bool transient) throw (jexception);
const iores dequeue(data_tok* dtokp, const void* const xid_ptr, const size_t xid_len)
throw (jexception);
+ const iores abort(data_tok* dtokp, const void* const xid_ptr, const size_t xid_len)
+ throw (jexception);
+ const iores commit(data_tok* dtokp, const void* const xid_ptr, const size_t xid_len)
+ throw (jexception);
const iores flush();
const u_int32_t get_events(page_state state) throw (jexception);
private:
void initialize() throw (jexception);
- const iores pre_write_check(bool enqueue, data_tok* dtokp) throw (jexception);
+ const iores pre_write_check(_op_type op, data_tok* dtokp) throw (jexception);
+ const u_int64_t initialize_rid(const bool cont, data_tok* dtokp);
const iores write_flush();
const iores rotate_file();
void dblk_roundup();
Modified: store/trunk/cpp/tests/jrnl/janalyze.py
===================================================================
--- store/trunk/cpp/tests/jrnl/janalyze.py 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/tests/jrnl/janalyze.py 2007-10-05 20:46:46 UTC (rev 965)
@@ -31,6 +31,16 @@
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
+COMMENT_COL = 19
+
transient_mask = 0x1
def load(f, klass):
@@ -215,6 +225,8 @@
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):
@@ -245,16 +257,18 @@
return '%s %sdrid=%d' % (Hdr.__str__(self), print_xid(self.xidsize, self.xid), self.deq_rid)
-class TxHdr(Hdr):
+class TxnHdr(Hdr):
format = '=Q'
def init(self, f, foffs, xidsize):
- self.xidsize = xid
+ 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):
@@ -278,7 +292,7 @@
return self.xid_complete and self.tail_complete
def __str__(self):
- return '%s x=%d xid=\"%s\"' % (Hdr.__str__(self), self.xidsize, self.xid)
+ return '%s %s' % (Hdr.__str__(self), print_xid(self.xidsize, self.xid))
class RecTail(Sizeable):
@@ -338,11 +352,16 @@
def complete(self):
return self.xid_complete and self.data_complete and self.tail_complete
+
+ def print_flags(self):
+ if self.flags & transient_mask > 0:
+ return '*TRANSIENT*'
+ return ''
def __str__(self):
- if self.enq_tail == None:
- return '%s %s [no tail]' % (Hdr.__str__(self), self.dsize, dstr)
- return '%s %s%s %s' % (Hdr.__str__(self), print_xid(self.xidsize, self.xid), print_data(self.dsize, self.data), self.enq_tail)
+# if self.enq_tail == None:
+# return '%s %s [no tail]' % (Hdr.__str__(self), self.dsize, dstr)
+ 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:
@@ -366,11 +385,11 @@
self.transient = tparams['transient']
else:
self.tnum = None
- self.num_msgs = 0
- self.msg_len = 0
- self.auto_deq = False
- self.xid_len = 0
- self.transient = False
+ self.num_msgs = None
+ self.msg_len = None
+ self.auto_deq = None
+ self.xid_len = None
+ self.transient = None
self.file_start = 0
self.file_num = 0
self.fro = 0x200
@@ -421,30 +440,46 @@
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:
- if hdr.flags & transient_mask == 0:
- raise Exception('Expected transient record, found persistent')
- else:
- if hdr.flags & transient_mask != 0:
- raise Exception('Expected persistent record, found transient')
+ if self.transient != None:
+ if self.transient:
+ if hdr.flags & transient_mask == 0:
+ raise Exception('Expected transient record, found persistent')
+ else:
+ if hdr.flags & transient_mask != 0:
+ raise Exception('Expected persistent record, found transient')
stop = not self.check_rid(hdr)
if stop:
- warn = ' (WARNING: rid out of order, last rid = %d - could be overwrite boundary.)' % hdr.rid
+ 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)
+ 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:
- warn = ' (WARNING: rid out of order, last rid = %d - could be overwrite boundary.)' % hdr.rid
- elif self.tnum != None:
- warn = 'WARNING: Dequeue record rid=%d found in non-dequeue test - ignoring.' % hdr.rid
+ 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()
@@ -491,7 +526,7 @@
return self.file_num
def check_rid(self, hdr):
- if self.last_rid != -1 and hdr.rid != self.last_rid + 1:
+ if self.last_rid != -1 and hdr.rid != self.last_rid + 1:
return False
self.last_rid = hdr.rid
return True
@@ -500,16 +535,17 @@
f=open(filename, 'r')
for l in f:
sl = l.strip().split(',')
- if len(sl[1]) > 0: #Comments are in col 0, remaining cols are empty
+ if len(sl[0]) > 0 and sl[0][0] != '"':
try:
- if (int(sl[0]) == tnum):
- return { 'num_msgs':int(sl[1]),
- 'min_size':int(sl[2]),
- 'max_size':int(sl[3]),
- 'auto_deq':sl[4] != 'FALSE',
- 'xid_min_size':int(sl[5]),
- 'xid_max_size':int(sl[6]),
- 'transient':sl[7] != 'FALSE' }
+ 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'),
+ 'comment':sl[COMMENT_COL] }
except Exception:
pass
return None
@@ -541,8 +577,8 @@
CLASSES = {
- "a": TxHdr,
- "c": TxHdr,
+ "a": TxnHdr,
+ "c": TxnHdr,
"d": DeqHdr,
"e": EnqRec,
"f": FileHdr
Modified: store/trunk/cpp/tests/jrnl/jtest.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/jtest.cpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/tests/jrnl/jtest.cpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -344,6 +344,17 @@
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 COMMENT_COL 19
+
// static method
void
jtest::get_test(targs* tap, const std::string& filename, const unsigned tnum) throw (rhm::journal::jexception)
@@ -369,21 +380,23 @@
toks.push_back(pch);
pch = strtok(NULL, ",");
}
- if (toks.size() >= 5)
+ if (toks.size() > TRANSIENT_COL && toks[TEST_NUM_COL][0] != '"')
{
- unsigned this_tnum = atoi(toks[0]);
+ unsigned this_tnum = atoi(toks[TEST_NUM_COL]);
if (this_tnum == tnum)
{
found = true;
- tap->_num_msgs = atol(toks[1]);
- tap->_min_msg_size = atol(toks[2]);
- tap->_max_msg_size = atol(toks[3]);
- tap->_auto_deq = strcmp(toks[4], "FALSE") != 0;
- tap->_min_xid_size = atol(toks[5]);
- tap->_max_xid_size = atol(toks[6]);
- tap->_transient = strcmp(toks[7], "FALSE") != 0;
- if (toks.size() > 8)
- tap->_comment = toks[8];
+ tap->_num_msgs = atol(toks[NUM_MSGS_COL]);
+ tap->_min_msg_size = atol(toks[MIN_MSG_SIZE_COL]);
+ tap->_max_msg_size = atol(toks[MAX_MSG_SIZE_COL]);
+ tap->_min_xid_size = atol(toks[MIN_XID_SIZE_COL]);
+ tap->_max_xid_size = atol(toks[MAX_XID_SIZE_COL]);
+ tap->_auto_deq = !(strcmp(toks[AUTO_DEQ_COL], "FALSE") == 0 ||
+ strcmp(toks[AUTO_DEQ_COL], "0") == 0);
+ tap->_transient = !(strcmp(toks[TRANSIENT_COL], "FALSE") == 0 ||
+ strcmp(toks[TRANSIENT_COL], "0") == 0);
+ if (toks.size() > COMMENT_COL)
+ tap->_comment = toks[COMMENT_COL];
else
tap->_comment = NULL;
std::cout << "Test " << tnum << ": Messages=" << tap->_num_msgs << " Size=" <<
@@ -413,7 +426,8 @@
{
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.");
+ throw rhm::journal::jexception(EXCEPTION_BASE+6,
+ "Test data not found in CSV test data file.");
}
}
Modified: store/trunk/cpp/tests/jrnl/msg_producer.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/msg_producer.cpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/tests/jrnl/msg_producer.cpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -56,6 +56,8 @@
_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),
_tot_dblks(0),
_tot_dsize(0)
@@ -69,15 +71,6 @@
msg_producer::~msg_producer()
{
- 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();
instance_cnt--;
}
@@ -102,6 +95,8 @@
_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();
@@ -161,6 +156,7 @@
if (ws >= rhm::journal::data_tok::ENQ_SUBM)
{
written = true;
+ _num_msgs_enq_subm++;
_tot_dblks += dtokp->dblocks_written();
_tot_dsize += dtokp->dsize();
}
@@ -177,7 +173,7 @@
if (aio_sleep_cnt >= MAX_AIO_SLEEPS)
throw rhm::journal::jexception(EXCEPTION_BASE+2,
"Page cache full (AIO events outstanding for all pages); "
- "exceeced wait time for pages to free.", "msg_producer",
+ "exceeded wait time for pages to free.", "msg_producer",
"produce");
//std::cout << "$" << dtokp->id() << " " << std::flush;
usleep(AIO_SLEEP_TIME);
@@ -202,17 +198,15 @@
jfull_sleep_cnt++;
break;
default:
- std::cout << "msg_producer::produce() Unexpected msg state: id=" <<
- dtokp->id() << " ws=" << wsstr << " eres=" << iores_str[eres] <<
- std::flush;
- throw rhm::journal::jexception(EXCEPTION_BASE+4,
- "Unknown return from enqueue() or enqueue_tx()", "msg_producer",
- "produce");
+ 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(), "msg_producer",
+ "produce");
}
//print_dbug(msgCntr, size, (char*)msg, true);
}
- _num_msgs_enq_subm++;
// Submit deferred dequeues (if any)
if (_auto_dequeue)
@@ -265,11 +259,18 @@
if (st == rhm::journal::data_tok::ENQ)
{
_num_msgs_enq++;
-//std::cout << "^" << dtokp->id() << " " << std::flush;
+//std::cout << ">E" << dtokp->id() << " " << std::flush;
_dd_dtok_list.push_back(dtokp);
}
else if (dtokp->wstate() == rhm::journal::data_tok::DEQ)
+//{ std::cout << ">D" << dtokp->id() << " " << std::flush;
_num_msgs_deq++;
+//}
+ else if (dtokp->wstate() == rhm::journal::data_tok::ABORTED ||
+ dtokp->wstate() == 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;
this_dtok_list.pop_front();
}
}
@@ -312,7 +313,12 @@
bool written = false;
while (!written)
{
- rhm::journal::iores dres = _jcptr->dequeue_data_record(ddtokp);
+ 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)
{
@@ -324,7 +330,7 @@
if (aio_sleep_cnt >= MAX_AIO_SLEEPS)
throw rhm::journal::jexception(EXCEPTION_BASE+6,
"Page cache full (AIO events outstanding for all pages); "
- "exceeced wait time for pages to free.", "msg_producer",
+ "exceeded wait time for pages to free.", "msg_producer",
"send_deferred_dequeues");
//std::cout << "$" << dres << " " << std::flush;
jc.get_wr_events();
@@ -332,11 +338,56 @@
aio_sleep_cnt++;
break;
default:
- std::cout << "msg_producer::send_deferred_dequeues()"
- " Unexpected msg state: id=" << ddtokp->id() << " ws=" << wsstr <<
- " dres=" << iores_str[dres] << std::flush;
+ std::stringstream ss;
+ ss << "msg_producer::send_deferred_dequeues() Unexpected msg state: id=" <<
+ ddtokp->id() << " ws=" << wsstr << " res=" << iores_str[dres];
+ throw rhm::journal::jexception(EXCEPTION_BASE+7, ss.str(), "msg_producer",
+ "send_deferred_dequeues");
}
}
+
+ // If transactional, commit for even rids, abort for odd rids
+ if (ddtokp->has_xid())
+ {
+ 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);
+ while (!written)
+ {
+ rhm::journal::iores dres;
+ if (ddtokp->rid()%2)
+ dres = _jcptr->txn_abort(txn_dtokp, ddtokp->xid());
+ else
+ dres = _jcptr->txn_commit(txn_dtokp, ddtokp->xid());
+
+ const char* wsstr = ddtokp->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=" << ddtokp->id() << " ws=" <<
+ wsstr << " res=" << iores_str[dres];
+ throw rhm::journal::jexception(EXCEPTION_BASE+9, ss.str(),
+ "msg_producer", "send_deferred_dequeues");
+ }
+ }
+ }
ditr = _dd_dtok_list.erase(ditr);
}
#ifndef RHM_WRONLY
@@ -361,7 +412,7 @@
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+7, ss.str(), "msg_producer",
+ throw rhm::journal::jexception(EXCEPTION_BASE+10, ss.str(), "msg_producer",
"jrnl_flush");
}
//std::cout << "+" << std::flush;
@@ -380,7 +431,7 @@
while (!_dd_dtok_list.empty() && !_interrupt_flag)
{
if (++cnt > 10000)
- throw rhm::journal::jexception(EXCEPTION_BASE+8,
+ throw rhm::journal::jexception(EXCEPTION_BASE+11,
"Timeout waiting for all messages to be read.", "msg_producer",
"jrnl_flush");
usleep(1000);
@@ -400,7 +451,7 @@
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+9, ss.str(), "msg_producer",
+ throw rhm::journal::jexception(EXCEPTION_BASE+12, ss.str(), "msg_producer",
"jrnl_flush");
}
//std::cout << "*" << std::flush;
Modified: store/trunk/cpp/tests/jrnl/msg_producer.hpp
===================================================================
--- store/trunk/cpp/tests/jrnl/msg_producer.hpp 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/tests/jrnl/msg_producer.hpp 2007-10-05 20:46:46 UTC (rev 965)
@@ -75,6 +75,8 @@
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
Modified: store/trunk/cpp/tests/jrnl/rtest
===================================================================
--- store/trunk/cpp/tests/jrnl/rtest 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/tests/jrnl/rtest 2007-10-05 20:46:46 UTC (rev 965)
@@ -36,21 +36,21 @@
W_DO_TEST=T
W_TEST_FILE=wtests.csv
W_TEST_START=0
-W_TEST_STOP=99
+W_TEST_STOP=196
W_NITER=5
# Read test
R_DO_TEST=T
R_TEST_FILE=rtests.csv
R_TEST_START=0
-R_TEST_STOP=45
+R_TEST_STOP=126
R_NITER=5
# Read-Write test
RW_DO_TEST=T
RW_TEST_FILE=rwtests.csv
RW_TEST_START=0
-RW_TEST_STOP=49
+RW_TEST_STOP=148
RW_NITER=5
RM=rm
Modified: store/trunk/cpp/tests/jrnl/rtests.csv
===================================================================
--- store/trunk/cpp/tests/jrnl/rtests.csv 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/tests/jrnl/rtests.csv 2007-10-05 20:46:46 UTC (rev 965)
@@ -1,72 +1,147 @@
-"Initialize only",,,,,,,,,
-0,0,0,0,FALSE,0,0,FALSE,,"No messages"
-,,,,,,,,,
-"Within first block, page, file",,,,,,,,,
-1,1,10,10,FALSE,0,0,FALSE,,"10-byte message"
-2,10,10,10,FALSE,0,0,FALSE,,"10-byte message"
-3,1,10,10,TRUE,0,0,FALSE,,"10-byte message"
-4,10,10,10,TRUE,0,0,FALSE,,"10-byte message"
-,,,,,,,,,
-"Transition from one d-block to two per message",,,,,,,,,
-5,10,84,84,FALSE,0,0,FALSE,,"1 dblk exact fit"
-6,10,85,85,FALSE,0,0,FALSE,,"1 dblk + 1 byte"
-7,10,84,84,TRUE,0,0,FALSE,,"1 dblk exact fit"
-8,10,85,85,TRUE,0,0,FALSE,,"1 dblk + 1 byte"
-,,,,,,,,,
-"Transition from one s-block to two per message",,,,,,,,,
-9,10,468,468,FALSE,0,0,FALSE,,"1 sblk exact fit"
-10,10,469,469,FALSE,0,0,FALSE,,"1 sblk + 1 byte"
-11,10,468,468,TRUE,0,0,FALSE,,"1 sblk exact fit"
-12,10,469,469,TRUE,0,0,FALSE,,"1 sblk + 1 byte"
-,,,,,,,,,
-"Transition from first page to second",,,,,,,,,
-13,8,8148,8148,FALSE,0,0,FALSE,,"8 * 1/8 page; Total = 1 page exact fit"
-14,9,8148,8148,FALSE,0,0,FALSE,,"9 * 1/8 page"
-15,8,8149,8149,FALSE,0,0,FALSE,,"8 * (1/8 page + 1 byte)"
-16,8,8020,8020,TRUE,0,0,FALSE,,"8 * (1/8 page – 1 dblk for deq record); Total = 1 page exact fit with deqs"
-17,9,8020,8020,TRUE,0,0,FALSE,,"9 * (1/8 page – 1 dblk for deq record)"
-18,8,8021,8021,TRUE,0,0,FALSE,,"8 * (1/8 page – 1 dblk for deq record + 1 byte)"
-,,,,,,,,,
-"Page cache rollover (from last page back to page 0) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,,,,
-19,16,65492,65492,FALSE,0,0,FALSE,,"16 * (1 page exact fit); Total = entire cache exactly"
-20,17,65492,65492,FALSE,0,0,FALSE,,"17 * (1 page exact fit); Total = entire cache + reuse of 1 page"
-21,11,98260,98260,FALSE,0,0,FALSE,,"11 * 1.5 pages"
-22,11,98132,98132,TRUE,0,0,FALSE,,"11 * (1.5 pages including 1 sblk for deq record)"
-,,,,,,,,,
-"File transition (from file 0000 to 0001) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,,,,
-23,24,65492,65492,FALSE,0,0,FALSE,,"24 * (1 page exact fit); Total = entire file exactly"
-24,25,65492,65492,FALSE,0,0,FALSE,,"25 * (1 page exact fit); Total = entire file + 1 page"
-25,10,163796,163796,FALSE,0,0,FALSE,,"10 * (2.5 pages); Total = entire file + 2 pages"
-26,10,163668,163668,TRUE,0,0,FALSE,,"10 * (2.5 pages including 1 sblk for deq record); Total = entire file + 2 pages"
-,,,,,,,,,
-"File rollover (from file 0007 to 0000) - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,,,,
-27,16,786388,786388,FALSE,0,0,FALSE,,"16 * (12 pages = ½ file); Total = 8 files exactly"
-,,,,,,,,,
-"Multi-page messages (large messages) - tests various paths in encoder; no dequeues required to test this functionality.",,,,,,,,,
-28,16,65492,65492,FALSE,0,0,FALSE,,"16 * (1 page exact fit)"
-29,16,65493,65493,FALSE,0,0,FALSE,,"16 * (1 page + 1 byte): tail split"
-30,16,65503,65503,FALSE,0,0,FALSE,,"16 * (1 page + 11 bytes): tail split"
-31,16,65504,65504,FALSE,0,0,FALSE,,"16 * (1 page + 12 bytes): tail separated exactly"
-32,16,65505,65505,FALSE,0,0,FALSE,,"16 * (1 page + 13 bytes): data split"
-33,16,131028,131028,FALSE,0,0,FALSE,,"16 * (2 pages exact fit)"
-34,16,131029,131029,FALSE,0,0,FALSE,,"16 * (2 pages + 1 byte): tail split"
-35,16,131039,131039,FALSE,0,0,FALSE,,"16 * (2 pages + 11 bytes): tail split"
-36,16,131040,131040,FALSE,0,0,FALSE,,"16 * (2 pages + 12 bytes): tail separated exactly"
-37,16,131041,131041,FALSE,0,0,FALSE,,"16 * (2 pages + 13 bytes) data split"
-38,16,262100,262100,FALSE,0,0,FALSE,,"16 * (4 pages exact fit)"
-39,16,262101,262101,FALSE,0,0,FALSE,,"16 * (4 pages + 1 byte: tail split)"
-40,16,262111,262111,FALSE,0,0,FALSE,,"16 * (4 pages + 1 byte: tail split)"
-41,16,262112,262112,FALSE,0,0,FALSE,,"16 * (4 pages + 12 bytes: tail separated)"
-42,16,262113,262113,FALSE,0,0,FALSE,,"16 * (4 pages + 13 bytes: data split)"
-43,16,229332,229332,FALSE,0,0,FALSE,,"16 * (3.5 pages)"
-44,16,229333,229333,FALSE,0,0,FALSE,,"16 * (3.5 pages + 1 byte)"
-,,,,,,,,,
-"These set up journals for circular tests (repeatedly reading same journal) Make sure value testing is off!",,,,,,,,,
-45,98304,0,84,FALSE,0,0,FALSE,,"1 dblk no dequeues"
-46,49152,0,84,TRUE,0,0,FALSE,,"1 dblk with dequeues"
-47,49152,0,212,FALSE,0,0,FALSE,,"2 dblk no dequeues"
-48,24576,0,212,TRUE,0,0,FALSE,,"2 dblk with dequeues"
-49,32768,212,212,TRUE,0,0,FALSE,,"2 dblk fixed with dequeues"
-,,,,,,,,,
-"Circular tests",,,,,,,,,
-50,10000000,0,0,FALSE,0,0,FALSE,,"Read 10,000,000 messages from one of the circular test journals above"
+,,,,,,,"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","bytes","dblks","bytes","dblks","bytes","dblks","comment"
+,,,,,,,,,,,,,,,,,,,
+"Initialize only",,,,,,,,,,,,,,,,,,,
+0,"L",,0,0,0,0,0,0,0,0,FALSE,FALSE,,,,,,,"No messages - journal creation/initialization only"
+,,,,,,,,,,,,,,,,,,,
+"Simple message combinations of persistent/transient, dequeued/non-dequeued, transactional/non-transactional",,,,,,,,,,,,,,,,,,,
+1,"L",,1,0,1,0,10,10,0,0,FALSE,FALSE,54,1,0,0,0,0,"1 * 10-byte message"
+2,"L",,10,0,10,0,10,10,0,0,FALSE,FALSE,54,1,0,0,0,0,"10 * 10-byte message"
+3,"L",,1,0,1,0,10,10,0,0,FALSE,TRUE,54,1,0,0,0,0,"1 * 10-byte message [transient]"
+4,"L",,10,0,10,0,10,10,0,0,FALSE,TRUE,54,1,0,0,0,0,"10 * 10-byte message [transient]"
+5,"L",,1,0,1,0,10,10,10,10,FALSE,FALSE,64,1,0,0,0,0,"1 * 10-byte message [txn]"
+6,"L",,10,0,10,0,10,10,10,10,FALSE,FALSE,64,1,0,0,0,0,"10 * 10-byte message [txn]"
+7,"L",,1,0,1,0,10,10,10,10,FALSE,TRUE,64,1,0,0,0,0,"1 * 10-byte message [txn transient]"
+8,"L",,10,0,10,0,10,10,10,10,FALSE,TRUE,64,1,0,0,0,0,"10 * 10-byte message [txn transient]"
+9,"L",,1,0,1,0,10,10,0,0,TRUE,FALSE,54,1,32,1,0,0,"1 * 10-byte message [deq]"
+10,"L",,10,0,10,0,10,10,0,0,TRUE,FALSE,54,1,32,1,0,0,"10 * 10-byte message [deq]"
+11,"L",,1,0,1,0,10,10,0,0,TRUE,TRUE,54,1,32,1,0,0,"1 * 10-byte message [transient deq]"
+12,"L",,10,0,10,0,10,10,0,0,TRUE,TRUE,54,1,32,1,0,0,"10 * 10-byte message [transient deq]"
+13,"L",,1,0,1,0,10,10,10,10,TRUE,FALSE,64,1,54,1,46,1,"1 * 10-byte message [txn deq]"
+14,"L",,10,0,10,0,10,10,10,10,TRUE,FALSE,64,1,54,1,46,1,"10 * 10-byte message [txn deq]"
+15,"L",,1,0,1,0,10,10,10,10,TRUE,TRUE,64,1,54,1,46,1,"1 * 10-byte message [txn transient deq]"
+16,"L",,10,0,10,0,10,10,10,10,TRUE,TRUE,64,1,54,1,46,1,"10 * 10-byte message [txn transient deq]"
+,,,,,,,,,,,,,,,,,,,
+"Transition from one d-block to two per message",,,,,,,,,,,,,,,,,,,
+17,"L",,10,0,10,0,84,84,0,0,FALSE,FALSE,128,1,0,0,0,0,"1 dblk exact fit"
+18,"L",,10,0,10,1,85,85,0,0,FALSE,FALSE,129,2,0,0,0,0,"1 dblk + 1 byte"
+19,"L",,10,0,10,0,58,58,26,26,FALSE,FALSE,128,1,0,0,0,0,"1 dblk exact fit [txn]"
+20,"L",,10,0,10,1,59,59,26,26,FALSE,FALSE,129,2,0,0,0,0,"1 dblk + 1 byte [txn]"
+,,,,,,,,,,,,,,,,,,,
+"Transition from one s-block to two per message",,,,,,,,,,,,,,,,,,,
+21,"L",,10,0,10,0,468,468,0,0,FALSE,FALSE,512,4,0,0,0,0,"1 sblk exact fit"
+22,"L",,10,0,10,1,469,469,0,0,FALSE,FALSE,513,5,0,0,0,0,"1 sblk + 1 byte"
+23,"L",,10,0,10,0,442,442,26,26,FALSE,FALSE,512,4,0,0,0,0,"1 sblk exact fit [txn]"
+24,"L",,10,0,10,1,443,443,26,26,FALSE,FALSE,513,5,0,0,0,0,"1 sblk + 1 byte [txn]"
+,,,,,,,,,,,,,,,,,,,
+"Transition from first page to second",,,,,,,,,,,,,,,,,,,
+25,"L",,8,0,8,0,4052,4052,0,0,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page"
+26,"L",,8,1,9,0,4052,4052,0,0,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page"
+27,"L",,8,0,8,1,4053,4053,0,0,FALSE,FALSE,4097,33,0,0,0,0,"1/8 page + 1 byte"
+28,"L",,8,0,8,0,3796,3796,256,256,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page [txn]"
+29,"L",,8,1,9,0,3796,3796,256,256,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page [txn]"
+30,"L",,8,0,8,1,3797,3797,256,256,FALSE,FALSE,4097,33,0,0,0,0,"1/8 page + 1 byte [txn]"
+31,"L",,8,0,8,0,3924,3924,0,0,TRUE,FALSE,3968,31,32,1,0,0,"1/8 page incl deq [deq]"
+32,"L",,8,1,9,0,3924,3924,0,0,TRUE,FALSE,3968,31,32,1,0,0,"1/8 page incl deq [deq]"
+33,"L",,8,0,8,1,3925,3925,0,0,TRUE,FALSE,3969,32,32,1,0,0,"1/8 page incl deq + 1 byte [deq]"
+34,"L",,8,0,8,0,3028,3028,256,256,TRUE,FALSE,3328,26,300,3,292,3,"1/8 page incl deq & txn [deq txn]"
+35,"L",,8,1,9,0,3028,3028,256,256,TRUE,FALSE,3328,26,300,3,292,3,"1/8 page incl deq & txn [deq txn]"
+36,"L",,8,0,8,1,3029,3029,256,256,TRUE,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) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,,,,,,,,,,,,,,
+37,"L",1,32,0,32,0,32724,32724,0,0,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
+38,"L",1,32,1,33,0,32724,32724,0,0,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
+39,"L",1,32,0,32,1,32725,32725,0,0,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte"
+40,"L",1.5,22,0,22,0,49108,49108,0,0,FALSE,FALSE,49152,384,0,0,0,0,"1.5 pages"
+41,"L",1,32,0,32,0,32468,32468,256,256,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
+42,"L",1,32,1,33,0,32468,32468,256,256,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
+43,"L",1,32,0,32,1,32469,32469,256,256,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte [txn]"
+44,"L",1.5,22,0,22,0,48852,48852,256,256,FALSE,FALSE,49152,384,0,0,0,0,"1.5 pages [txn]"
+45,"L",1,32,0,32,0,32596,32596,0,0,TRUE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
+46,"L",1,32,1,33,0,32596,32596,0,0,TRUE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
+47,"L",1,32,0,32,1,32597,32597,0,0,TRUE,FALSE,32641,256,32,1,0,0,"1 page incl deq + 1 byte [deq]"
+48,"L",1.5,22,0,22,0,48980,48980,0,0,TRUE,FALSE,49024,383,32,1,0,0,"1.5 pages incl deq [deq]"
+49,"L",1,32,0,32,0,31700,31700,256,256,TRUE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
+50,"L",1,32,1,33,0,31700,31700,256,256,TRUE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
+51,"L",1,32,0,32,1,31701,31701,256,256,TRUE,FALSE,32001,251,300,3,292,3,"1 page incl deq & txn + 1 byte [deq txn]"
+52,"L",1.5,22,0,22,0,48084,48084,256,256,TRUE,FALSE,48384,378,300,3,292,3,"1.5 pages incl deq & txn [deq txn]"
+,,,,,,,,,,,,,,,,,,,
+"File transition (from file 0000 to 0001) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,,,,,,,,,,,,,,
+53,"L",1,48,0,48,0,32724,32724,0,0,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
+54,"L",1,48,1,49,0,32724,32724,0,0,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
+55,"L",1,48,0,48,1,32725,32725,0,0,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte"
+56,"L",2.5,20,0,20,0,81876,81876,0,0,FALSE,FALSE,81920,640,0,0,0,0,"2.5 pages"
+57,"L",1,48,0,48,0,32468,32468,256,256,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
+58,"L",1,48,1,49,0,32468,32468,256,256,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
+59,"L",1,48,0,48,1,32469,32469,256,256,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte [txn]"
+60,"L",2.5,20,0,20,0,81620,81620,256,256,FALSE,FALSE,81920,640,0,0,0,0,"2.5 pages [txn]"
+61,"L",1,48,0,48,0,32596,32596,0,0,TRUE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
+62,"L",1,48,1,49,0,32596,32596,0,0,TRUE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
+63,"L",1,48,0,48,1,32597,32597,0,0,TRUE,FALSE,32641,256,32,1,0,0,"1 page incl deq + 1 byte [deq]"
+64,"L",2.5,20,0,20,0,81748,81748,0,0,TRUE,FALSE,81792,639,32,1,0,0,"2.5 pages incl deq [deq]"
+65,"L",1,48,0,48,0,31700,31700,256,256,TRUE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
+66,"L",1,48,1,49,0,31700,31700,256,256,TRUE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
+67,"L",1,48,0,48,1,31701,31701,256,256,TRUE,FALSE,32001,251,300,3,292,3,"1 page incl deq & txn + 1 byte [deq txn]"
+68,"L",2.5,20,0,20,0,80852,80852,256,256,TRUE,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",,,,,,,,,,,,,,,,,,,
+69,"L",0.5,16,0,16,0,786388,786388,0,0,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file"
+70,"L",0.5,16,0,16,0,786132,786132,256,256,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file"
+,,,,,,,,,,,,,,,,,,,
+"Multi-page messages (large messages) - tests various paths in encoder.",,,,,,,,,,,,,,,,,,,
+71,"L",1,16,0,16,0,32724,32724,0,0,FALSE,FALSE,32768,256,0,0,0,0,"data 1 page"
+72,"L",1,16,0,16,1,32725,32725,0,0,FALSE,FALSE,32769,257,0,0,0,0,"data 1 page + 1 byte (tail split; 1 byte over page boundary)"
+73,"L",1,16,0,16,11,32735,32735,0,0,FALSE,FALSE,32779,257,0,0,0,0,"data 1 page + 11 bytes (tail split; 11 bytes over page boundary)"
+74,"L",1,16,0,16,12,32736,32736,0,0,FALSE,FALSE,32780,257,0,0,0,0,"data 1 page + 12 bytes (tail separated exactly onto next page)"
+75,"L",1,16,0,16,13,32737,32737,0,0,FALSE,FALSE,32781,257,0,0,0,0,"data 1 page + 13 bytes (xid split; 1 byte over page boundary)"
+76,"L",1,16,0,16,0,32468,32468,256,256,FALSE,FALSE,32768,256,0,0,0,0,"data 1 page [txn]"
+77,"L",1,16,0,16,1,32469,32469,256,256,FALSE,FALSE,32769,257,0,0,0,0,"data 1 page + 1 byte (tail split; 1 byte over page boundary) [txn]"
+78,"L",1,16,0,16,11,32479,32479,256,256,FALSE,FALSE,32779,257,0,0,0,0,"data 1 page + 11 bytes (tail split; 11 bytes over page boundary) [txn]"
+79,"L",1,16,0,16,12,32480,32480,256,256,FALSE,FALSE,32780,257,0,0,0,0,"data 1 page + 12 bytes (tail separated exactly onto next page) [txn]"
+80,"L",1,16,0,16,13,32481,32481,256,256,FALSE,FALSE,32781,257,0,0,0,0,"data 1 page + 13 bytes (xid split; 1 byte over page boundary) [txn]"
+81,"L",2,16,0,16,0,65492,65492,0,0,FALSE,FALSE,65536,512,0,0,0,0,"data 2 pages"
+82,"L",2,16,0,16,1,65493,65493,0,0,FALSE,FALSE,65537,513,0,0,0,0,"data 2 pages + 1 byte (tail split; 1 byte over page boundary)"
+83,"L",2,16,0,16,11,65503,65503,0,0,FALSE,FALSE,65547,513,0,0,0,0,"data 2 pages + 11 bytes (tail split; 11 bytes over page boundary)"
+84,"L",2,16,0,16,12,65504,65504,0,0,FALSE,FALSE,65548,513,0,0,0,0,"data 2 pages + 12 bytes (tail separated exactly onto next page)"
+85,"L",2,16,0,16,13,65505,65505,0,0,FALSE,FALSE,65549,513,0,0,0,0,"data 2 pages + 13 bytes (xid split; 1 byte over page boundary)"
+86,"L",2,16,0,16,0,65236,65236,256,256,FALSE,FALSE,65536,512,0,0,0,0,"data 2 pages [txn]"
+87,"L",2,16,0,16,1,65237,65237,256,256,FALSE,FALSE,65537,513,0,0,0,0,"data 2 pages + 1 byte (tail split; 1 byte over page boundary) [txn]"
+88,"L",2,16,0,16,11,65247,65247,256,256,FALSE,FALSE,65547,513,0,0,0,0,"data 2 pages + 11 bytes (tail split; 11 bytes over page boundary) [txn]"
+89,"L",2,16,0,16,12,65248,65248,256,256,FALSE,FALSE,65548,513,0,0,0,0,"data 2 pages + 12 bytes (tail separated exactly onto next page) [txn]"
+90,"L",2,16,0,16,13,65249,65249,256,256,FALSE,FALSE,65549,513,0,0,0,0,"data 2 pages + 13 bytes (xid split; 1 byte over page boundary) [txn]"
+91,"L",4,16,0,16,0,131028,131028,0,0,FALSE,FALSE,131072,1024,0,0,0,0,"data 4 pages"
+92,"L",4,16,0,16,1,131029,131029,0,0,FALSE,FALSE,131073,1025,0,0,0,0,"data 4 pages + 1 byte (tail split; 1 byte over page boundary)"
+93,"L",4,16,0,16,11,131039,131039,0,0,FALSE,FALSE,131083,1025,0,0,0,0,"data 4 pages + 11 bytes (tail split; 11 bytes over page boundary)"
+94,"L",4,16,0,16,12,131040,131040,0,0,FALSE,FALSE,131084,1025,0,0,0,0,"data 4 pages + 12 bytes (tail separated exactly onto next page)"
+95,"L",4,16,0,16,13,131041,131041,0,0,FALSE,FALSE,131085,1025,0,0,0,0,"data 4 pages + 13 bytes (xid split; 1 byte over page boundary)"
+96,"L",4,16,0,16,0,130772,130772,256,256,FALSE,FALSE,131072,1024,0,0,0,0,"data 4 pages [txn]"
+97,"L",4,16,0,16,1,130773,130773,256,256,FALSE,FALSE,131073,1025,0,0,0,0,"data 4 pages + 1 byte (tail split; 1 byte over page boundary) [txn]"
+98,"L",4,16,0,16,11,130783,130783,256,256,FALSE,FALSE,131083,1025,0,0,0,0,"data 4 pages + 11 bytes (tail split; 11 bytes over page boundary) [txn]"
+99,"L",4,16,0,16,12,130784,130784,256,256,FALSE,FALSE,131084,1025,0,0,0,0,"data 4 pages + 12 bytes (tail separated exactly onto next page) [txn]"
+100,"L",4,16,0,16,13,130785,130785,256,256,FALSE,FALSE,131085,1025,0,0,0,0,"data 4 pages + 13 bytes (xid split; 1 byte over page boundary) [txn]"
+101,"L",3.5,16,0,16,0,114644,114644,0,0,FALSE,FALSE,114688,896,0,0,0,0,"data 4 pages + 12 bytes (tail separated exactly onto next page) [txn]"
+102,"L",3.5,16,0,16,1,114645,114645,0,0,FALSE,FALSE,114689,897,0,0,0,0,"data 4 pages + 13 bytes (xid split; 1 byte over page boundary) [txn]"
+103,"L",3.5,16,0,16,0,114388,114388,256,256,FALSE,FALSE,114688,896,0,0,0,0,"data 4 pages + 12 bytes (tail separated exactly onto next page) [txn]"
+104,"L",3.5,16,0,16,1,114389,114389,256,256,FALSE,FALSE,114689,897,0,0,0,0,"data 4 pages + 13 bytes (xid split; 1 byte over page boundary) [txn]"
+105,"L",1,16,0,16,-1,10,10,32735,32735,FALSE,FALSE,32789,257,0,0,0,0,"xid 1 page – 1 byte; data 10 bytes (exact fit) [txn]"
+106,"L",1,16,0,16,0,10,10,32736,32736,FALSE,FALSE,32790,257,0,0,0,0,"xid 1 page; data 10 bytes (exact fit) [txn]"
+107,"L",1,16,0,16,1,10,10,32737,32737,FALSE,FALSE,32791,257,0,0,0,0,"xid 1 page + 1 byte; data 10 bytes (exact fit) [txn]"
+108,"L",2,16,0,16,-1,10,10,65503,65503,FALSE,FALSE,65557,513,0,0,0,0,"xid 2 pages – 1 byte; data 10 bytes (exact fit) [txn]"
+109,"L",2,16,0,16,0,10,10,65504,65504,FALSE,FALSE,65558,513,0,0,0,0,"xid 2 pages; data 10 bytes (exact fit) [txn]"
+110,"L",2,16,0,16,1,10,10,65505,65505,FALSE,FALSE,65559,513,0,0,0,0,"xid 2 pages + 1 byte; data 10 bytes (exact fit) [txn]"
+111,"L",4,16,0,16,-1,10,10,131039,131039,FALSE,FALSE,131093,1025,0,0,0,0,"xid 4 pages – 1 byte; data 10 bytes (exact fit) [txn]"
+112,"L",4,16,0,16,0,10,10,131040,131040,FALSE,FALSE,131094,1025,0,0,0,0,"xid 4 pages; data 10 bytes (exact fit) [txn]"
+113,"L",4,16,0,16,1,10,10,131041,131041,FALSE,FALSE,131095,1025,0,0,0,0,"xid 4 pages + 1 byte; data 10 bytes (exact fit) [txn]"
+114,"L",3.5,16,0,16,0,10,10,114656,114656,FALSE,FALSE,114710,897,0,0,0,0,"xid 3.5 pages; data 10 bytes (exact fit) [txn]"
+115,"L",3.5,16,0,16,1,10,10,114657,114657,FALSE,FALSE,114711,897,0,0,0,0,"xid 3.5 pages + 1 byte; data 10 bytes (exact fit) [txn]"
+116,"L",1,16,0,16,-1,10,10,32735,32735,TRUE,FALSE,32789,257,32779,257,32771,257,"xid 1 page – 1 byte; data 10 bytes (exact fit) [txn]"
+117,"L",1,16,0,16,0,10,10,32736,32736,TRUE,FALSE,32790,257,32780,257,32772,257,"xid 1 page; data 10 bytes (exact fit) [txn]"
+118,"L",1,16,0,16,1,10,10,32737,32737,TRUE,FALSE,32791,257,32781,257,32773,257,"xid 1 page + 1 byte; data 10 bytes (exact fit) [txn]"
+119,"L",2,16,0,16,-1,10,10,65503,65503,TRUE,FALSE,65557,513,65547,513,65539,513,"xid 2 pages – 1 byte; data 10 bytes (exact fit) [txn]"
+120,"L",2,16,0,16,0,10,10,65504,65504,TRUE,FALSE,65558,513,65548,513,65540,513,"xid 2 pages; data 10 bytes (exact fit) [txn]"
+121,"L",2,16,0,16,1,10,10,65505,65505,TRUE,FALSE,65559,513,65549,513,65541,513,"xid 2 pages + 1 byte; data 10 bytes (exact fit) [txn]"
+122,"L",4,16,0,16,-1,10,10,131039,131039,TRUE,FALSE,131093,1025,131083,1025,131075,1025,"xid 4 pages – 1 byte; data 10 bytes (exact fit) [txn]"
+123,"L",4,16,0,16,0,10,10,131040,131040,TRUE,FALSE,131094,1025,131084,1025,131076,1025,"xid 4 pages; data 10 bytes (exact fit) [txn]"
+124,"L",4,16,0,16,1,10,10,131041,131041,TRUE,FALSE,131095,1025,131085,1025,131077,1025,"xid 4 pages + 1 byte; data 10 bytes (exact fit) [txn]"
+125,"L",3.5,16,0,16,0,10,10,114656,114656,TRUE,FALSE,114710,897,114700,897,114692,897,"xid 3.5 pages; data 10 bytes (exact fit) [txn]"
+126,"L",3.5,16,0,16,1,10,10,114657,114657,TRUE,FALSE,114711,897,114701,897,114693,897,"xid 3.5 pages + 1 byte; data 10 bytes (exact fit) [txn]"
Modified: store/trunk/cpp/tests/jrnl/rwtests.csv
===================================================================
--- store/trunk/cpp/tests/jrnl/rwtests.csv 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/tests/jrnl/rwtests.csv 2007-10-05 20:46:46 UTC (rev 965)
@@ -1,68 +1,169 @@
-"Initialize only",,,,,,,,,
-0,0,0,0,FALSE,0,0,FALSE,,"No messages"
-,,,,,,,,,
-"Within first block, page, file",,,,,,,,,
-1,1,10,10,FALSE,0,0,FALSE,,"10-byte message"
-2,10,10,10,FALSE,0,0,FALSE,,"10-byte message"
-3,1,10,10,TRUE,0,0,FALSE,,"10-byte message"
-4,10,10,10,TRUE,0,0,FALSE,,"10-byte message"
-,,,,,,,,,
-"Transition from one d-block to two per message",,,,,,,,,
-5,10,84,84,FALSE,0,0,FALSE,,"1 dblk exact fit"
-6,10,85,85,FALSE,0,0,FALSE,,"1 dblk + 1 byte"
-7,10,84,84,TRUE,0,0,FALSE,,"1 dblk exact fit"
-8,10,85,85,TRUE,0,0,FALSE,,"1 dblk + 1 byte"
-,,,,,,,,,
-"Transition from one s-block to two per message",,,,,,,,,
-9,10,468,468,FALSE,0,0,FALSE,,"1 sblk exact fit"
-10,10,469,469,FALSE,0,0,FALSE,,"1 sblk + 1 byte"
-11,10,468,468,TRUE,0,0,FALSE,,"1 sblk exact fit"
-12,10,469,469,TRUE,0,0,FALSE,,"1 sblk + 1 byte"
-,,,,,,,,,
-"Transition from first page to second",,,,,,,,,
-13,8,4052,4052,FALSE,0,0,FALSE,,"8 * 1/8 page; Total = 1 page exact fit"
-14,9,4052,4052,FALSE,0,0,FALSE,,"9 * 1/8 page"
-15,8,4053,4053,FALSE,0,0,FALSE,,"8 * (1/8 page + 1 byte)"
-16,8,3924,3924,TRUE,0,0,FALSE,,"8 * (1/8 page - 1 dblk for deq record); Total = 1 page exact fit with deqs"
-17,9,3924,3924,TRUE,0,0,FALSE,,"9 * (1/8 page - 1 dblk for deq record)"
-18,8,3925,3925,TRUE,0,0,FALSE,,"8 * (1/8 page - 1 dblk for deq record + 1 byte)"
-,,,,,,,,,
-"Page cache rollover (from page 32 back to page 0) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,,,,
-19,32,32724,32724,FALSE,0,0,FALSE,,"32 * (1 page exact fit); Total = entire cache exactly"
-20,33,32724,32724,FALSE,0,0,FALSE,,"33 * (1 page exact fit); Total = entire cache + reuse of 1 page"
-21,22,49108,49108,FALSE,0,0,FALSE,,"22 * 1.5 pages"
-22,22,48980,48980,TRUE,0,0,FALSE,,"22 * (1.5 pages including 1 sblk for deq record)"
-,,,,,,,,,
-"File transition (from file 0000 to 0001) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,,,,
-23,48,32724,32724,FALSE,0,0,FALSE,,"48 * (1 page exact fit); Total = entire file exactly"
-24,49,32724,32724,FALSE,0,0,FALSE,,"49 * (1 page exact fit); Total = entire file + 1 page"
-25,20,81876,81876,FALSE,0,0,FALSE,,"20 * (2.5 pages); Total = entire file + 2 pages"
-26,20,81748,81748,TRUE,0,0,FALSE,,"20 * (2.5 pages including 1 sblk for deq record); Total = entire file + 2 pages"
-,,,,,,,,,
-"File rollover (from file 0007 to 0000) - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,,,,
-27,16,786388,786388,FALSE,FALSE,FALSE,FALSE,,"16 * (24 pages = ½ file); Total = 8 files exactly"
-28,16,786260,786260,TRUE,0,0,FALSE,,"16 * (24 pages = ½ file); Total = 8 files exactly"
-29,17,786260,786260,TRUE,0,0,FALSE,,"17 * (24 pages = ½ file); Total = 8 files + file 0 overwritten by ½ file"
-30,16,786261,786261,TRUE,0,0,FALSE,,"16 * (24 pages + 1 byte); Total = 8 files + file 0 overwritten by 16 sblks"
-31,32,786260,786260,TRUE,0,0,FALSE,,"32 * (24 pages = ½ file); Total = 16 files exactly, all files overwritten once"
-32,33,786260,786260,TRUE,0,0,FALSE,,"33 * (24 pages = ½ file); Total = 16 ½ files, all files overwritten once + file 0 overwritten again by ½ file"
-33,32,786261,786261,TRUE,0,0,FALSE,,"32 * (24 pages + 1 byte); All files overwritten once + file 0 overwritten again by 32 sblks"
-,,,,,,,,,
-"Multi-page messages (large messages) - tests various paths in encoder; no dequeues required to test this functionality.",,,,,,,,,
-34,16,32724,32724,FALSE,0,0,FALSE,,"16 * (1 page exact fit)"
-35,16,32725,32725,FALSE,0,0,FALSE,,"16 * (1 page + 1 byte): tail split"
-36,16,32735,32735,FALSE,0,0,FALSE,,"16 * (1 page + 11 bytes): tail split"
-37,16,32736,32736,FALSE,0,0,FALSE,,"16 * (1 page + 12 bytes): tail separated exactly"
-38,16,32737,32737,FALSE,0,0,FALSE,,"16 * (1 page + 13 bytes): data split"
-39,16,65492,65492,FALSE,0,0,FALSE,,"16 * (2 pages exact fit)"
-40,16,65493,65493,FALSE,0,0,FALSE,,"16 * (2 pages + 1 byte): tail split"
-41,16,65503,65503,FALSE,0,0,FALSE,,"16 * (2 pages + 11 bytes): tail split"
-42,16,65504,65504,FALSE,0,0,FALSE,,"16 * (2 pages + 12 bytes): tail separated exactly"
-43,16,65505,65505,FALSE,0,0,FALSE,,"16 * (2 pages + 13 bytes) data split"
-44,16,131028,131028,FALSE,0,0,FALSE,,"16 * (4 pages exact fit)"
-45,16,131029,131029,FALSE,0,0,FALSE,,"16 * (4 pages + 1 byte: tail split)"
-46,16,131039,131039,FALSE,0,0,FALSE,,"16 * (4 pages + 1 byte: tail split)"
-47,16,131040,131040,FALSE,0,0,FALSE,,"16 * (4 pages + 12 bytes: tail separated)"
-48,16,131041,131041,FALSE,0,0,FALSE,,"16 * (4 pages + 13 bytes: data split)"
-49,16,114644,114644,FALSE,0,0,FALSE,,"16 * (3.5 pages)"
-50,16,114645,114645,FALSE,0,0,FALSE,,"16 * (3.5 pages + 1 byte)"
+,,,,,,,"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","bytes","dblks","bytes","dblks","bytes","dblks","comment"
+,,,,,,,,,,,,,,,,,,,
+"Initialize only",,,,,,,,,,,,,,,,,,,
+0,"L",,0,0,0,0,0,0,0,0,FALSE,FALSE,,,,,,,"No messages - journal creation/initialization only"
+,,,,,,,,,,,,,,,,,,,
+"Simple message combinations of persistent/transient, dequeued/non-dequeued, transactional/non-transactional",,,,,,,,,,,,,,,,,,,
+1,"L",,1,0,1,0,10,10,0,0,FALSE,FALSE,54,1,0,0,0,0,"1 * 10-byte message"
+2,"L",,10,0,10,0,10,10,0,0,FALSE,FALSE,54,1,0,0,0,0,"10 * 10-byte message"
+3,"L",,1,0,1,0,10,10,0,0,FALSE,TRUE,54,1,0,0,0,0,"1 * 10-byte message [transient]"
+4,"L",,10,0,10,0,10,10,0,0,FALSE,TRUE,54,1,0,0,0,0,"10 * 10-byte message [transient]"
+5,"L",,1,0,1,0,10,10,10,10,FALSE,FALSE,64,1,0,0,0,0,"1 * 10-byte message [txn]"
+6,"L",,10,0,10,0,10,10,10,10,FALSE,FALSE,64,1,0,0,0,0,"10 * 10-byte message [txn]"
+7,"L",,1,0,1,0,10,10,10,10,FALSE,TRUE,64,1,0,0,0,0,"1 * 10-byte message [txn transient]"
+8,"L",,10,0,10,0,10,10,10,10,FALSE,TRUE,64,1,0,0,0,0,"10 * 10-byte message [txn transient]"
+9,"L",,1,0,1,0,10,10,0,0,TRUE,FALSE,54,1,32,1,0,0,"1 * 10-byte message [deq]"
+10,"L",,10,0,10,0,10,10,0,0,TRUE,FALSE,54,1,32,1,0,0,"10 * 10-byte message [deq]"
+11,"L",,1,0,1,0,10,10,0,0,TRUE,TRUE,54,1,32,1,0,0,"1 * 10-byte message [transient deq]"
+12,"L",,10,0,10,0,10,10,0,0,TRUE,TRUE,54,1,32,1,0,0,"10 * 10-byte message [transient deq]"
+13,"L",,1,0,1,0,10,10,10,10,TRUE,FALSE,64,1,54,1,46,1,"1 * 10-byte message [txn deq]"
+14,"L",,10,0,10,0,10,10,10,10,TRUE,FALSE,64,1,54,1,46,1,"10 * 10-byte message [txn deq]"
+15,"L",,1,0,1,0,10,10,10,10,TRUE,TRUE,64,1,54,1,46,1,"1 * 10-byte message [txn transient deq]"
+16,"L",,10,0,10,0,10,10,10,10,TRUE,TRUE,64,1,54,1,46,1,"10 * 10-byte message [txn transient deq]"
+,,,,,,,,,,,,,,,,,,,
+"Transition from one d-block to two per message",,,,,,,,,,,,,,,,,,,
+17,"L",,10,0,10,0,84,84,0,0,FALSE,FALSE,128,1,0,0,0,0,"1 dblk exact fit"
+18,"L",,10,0,10,1,85,85,0,0,FALSE,FALSE,129,2,0,0,0,0,"1 dblk + 1 byte"
+19,"L",,10,0,10,0,58,58,26,26,FALSE,FALSE,128,1,0,0,0,0,"1 dblk exact fit [txn]"
+20,"L",,10,0,10,1,59,59,26,26,FALSE,FALSE,129,2,0,0,0,0,"1 dblk + 1 byte [txn]"
+,,,,,,,,,,,,,,,,,,,
+"Transition from one s-block to two per message",,,,,,,,,,,,,,,,,,,
+21,"L",,10,0,10,0,468,468,0,0,FALSE,FALSE,512,4,0,0,0,0,"1 sblk exact fit"
+22,"L",,10,0,10,1,469,469,0,0,FALSE,FALSE,513,5,0,0,0,0,"1 sblk + 1 byte"
+23,"L",,10,0,10,0,442,442,26,26,FALSE,FALSE,512,4,0,0,0,0,"1 sblk exact fit [txn]"
+24,"L",,10,0,10,1,443,443,26,26,FALSE,FALSE,513,5,0,0,0,0,"1 sblk + 1 byte [txn]"
+,,,,,,,,,,,,,,,,,,,
+"Transition from first page to second",,,,,,,,,,,,,,,,,,,
+25,"L",,8,0,8,0,4052,4052,0,0,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page"
+26,"L",,8,1,9,0,4052,4052,0,0,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page"
+27,"L",,8,0,8,1,4053,4053,0,0,FALSE,FALSE,4097,33,0,0,0,0,"1/8 page + 1 byte"
+28,"L",,8,0,8,0,3796,3796,256,256,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page [txn]"
+29,"L",,8,1,9,0,3796,3796,256,256,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page [txn]"
+30,"L",,8,0,8,1,3797,3797,256,256,FALSE,FALSE,4097,33,0,0,0,0,"1/8 page + 1 byte [txn]"
+31,"L",,8,0,8,0,3924,3924,0,0,TRUE,FALSE,3968,31,32,1,0,0,"1/8 page incl deq [deq]"
+32,"L",,8,1,9,0,3924,3924,0,0,TRUE,FALSE,3968,31,32,1,0,0,"1/8 page incl deq [deq]"
+33,"L",,8,0,8,1,3925,3925,0,0,TRUE,FALSE,3969,32,32,1,0,0,"1/8 page incl deq + 1 byte [deq]"
+34,"L",,8,0,8,0,3028,3028,256,256,TRUE,FALSE,3328,26,300,3,292,3,"1/8 page incl deq & txn [deq txn]"
+35,"L",,8,1,9,0,3028,3028,256,256,TRUE,FALSE,3328,26,300,3,292,3,"1/8 page incl deq & txn [deq txn]"
+36,"L",,8,0,8,1,3029,3029,256,256,TRUE,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) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,,,,,,,,,,,,,,
+37,"L",1,32,0,32,0,32724,32724,0,0,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
+38,"L",1,32,1,33,0,32724,32724,0,0,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
+39,"L",1,32,0,32,1,32725,32725,0,0,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte"
+40,"L",1.5,22,0,22,0,49108,49108,0,0,FALSE,FALSE,49152,384,0,0,0,0,"1.5 pages"
+41,"L",1,32,0,32,0,32468,32468,256,256,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
+42,"L",1,32,1,33,0,32468,32468,256,256,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
+43,"L",1,32,0,32,1,32469,32469,256,256,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte [txn]"
+44,"L",1.5,22,0,22,0,48852,48852,256,256,FALSE,FALSE,49152,384,0,0,0,0,"1.5 pages [txn]"
+45,"L",1,32,0,32,0,32596,32596,0,0,TRUE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
+46,"L",1,32,1,33,0,32596,32596,0,0,TRUE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
+47,"L",1,32,0,32,1,32597,32597,0,0,TRUE,FALSE,32641,256,32,1,0,0,"1 page incl deq + 1 byte [deq]"
+48,"L",1.5,22,0,22,0,48980,48980,0,0,TRUE,FALSE,49024,383,32,1,0,0,"1.5 pages incl deq [deq]"
+49,"L",1,32,0,32,0,31700,31700,256,256,TRUE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
+50,"L",1,32,1,33,0,31700,31700,256,256,TRUE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
+51,"L",1,32,0,32,1,31701,31701,256,256,TRUE,FALSE,32001,251,300,3,292,3,"1 page incl deq & txn + 1 byte [deq txn]"
+52,"L",1.5,22,0,22,0,48084,48084,256,256,TRUE,FALSE,48384,378,300,3,292,3,"1.5 pages incl deq & txn [deq txn]"
+,,,,,,,,,,,,,,,,,,,
+"File transition (from file 0000 to 0001) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,,,,,,,,,,,,,,
+53,"L",1,48,0,48,0,32724,32724,0,0,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
+54,"L",1,48,1,49,0,32724,32724,0,0,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
+55,"L",1,48,0,48,1,32725,32725,0,0,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte"
+56,"L",2.5,20,0,20,0,81876,81876,0,0,FALSE,FALSE,81920,640,0,0,0,0,"2.5 pages"
+57,"L",1,48,0,48,0,32468,32468,256,256,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
+58,"L",1,48,1,49,0,32468,32468,256,256,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
+59,"L",1,48,0,48,1,32469,32469,256,256,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte [txn]"
+60,"L",2.5,20,0,20,0,81620,81620,256,256,FALSE,FALSE,81920,640,0,0,0,0,"2.5 pages [txn]"
+61,"L",1,48,0,48,0,32596,32596,0,0,TRUE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
+62,"L",1,48,1,49,0,32596,32596,0,0,TRUE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
+63,"L",1,48,0,48,1,32597,32597,0,0,TRUE,FALSE,32641,256,32,1,0,0,"1 page incl deq + 1 byte [deq]"
+64,"L",2.5,20,0,20,0,81748,81748,0,0,TRUE,FALSE,81792,639,32,1,0,0,"2.5 pages incl deq [deq]"
+65,"L",1,48,0,48,0,31700,31700,256,256,TRUE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
+66,"L",1,48,1,49,0,31700,31700,256,256,TRUE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
+67,"L",1,48,0,48,1,31701,31701,256,256,TRUE,FALSE,32001,251,300,3,292,3,"1 page incl deq & txn + 1 byte [deq txn]"
+68,"L",2.5,20,0,20,0,80852,80852,256,256,TRUE,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",,,,,,,,,,,,,,,,,,,
+69,"L",0.5,16,0,16,0,786388,786388,0,0,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file"
+70,"L",0.5,16,1,17,0,786388,786388,0,0,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file"
+71,"L",0.5,16,0,16,1,786389,786389,0,0,FALSE,FALSE,786433,6145,0,0,0,0,"24 pages + 1 byte"
+72,"L",0.5,16,0,16,0,786132,786132,256,256,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file [txn]"
+73,"L",0.5,16,1,17,0,786132,786132,256,256,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file [txn]"
+74,"L",0.5,16,0,16,1,786133,786133,256,256,FALSE,FALSE,786433,6145,0,0,0,0,"24 pages + 1 byte [txn]"
+75,"L",0.25,32,0,32,0,786388,786388,0,0,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file"
+76,"L",0.25,32,1,33,0,786388,786388,0,0,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file"
+77,"L",0.25,32,0,32,1,786389,786389,0,0,FALSE,FALSE,786433,6145,0,0,0,0,"24 pages + 1 byte"
+78,"L",0.25,32,0,32,0,786132,786132,256,256,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file [txn]"
+79,"L",0.25,32,1,33,0,786132,786132,256,256,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file [txn]"
+80,"L",0.25,32,0,32,1,786133,786133,256,256,FALSE,FALSE,786433,6145,0,0,0,0,"24 pages + 1 byte [txn]"
+81,"L",0.5,16,0,16,0,786260,786260,0,0,TRUE,FALSE,786304,6143,32,1,0,0,"24 pages incl deq = ½ file [deq]"
+82,"L",0.5,16,1,17,0,786260,786260,0,0,TRUE,FALSE,786304,6143,32,1,0,0,"24 pages incl deq = ½ file [deq]"
+83,"L",0.5,16,0,16,1,786261,786261,0,0,TRUE,FALSE,786305,6144,32,1,0,0,"24 pages incl deq + 1 byte [deq]"
+84,"L",0.5,16,0,16,0,785364,785364,256,256,TRUE,FALSE,785664,6138,300,3,292,3,"24 pages incl deq & txn = ½ file [deq txn]"
+85,"L",0.5,16,1,17,0,785364,785364,256,256,TRUE,FALSE,785664,6138,300,3,292,3,"24 pages incl deq & txn = ½ file [deq txn]"
+86,"L",0.5,16,0,16,1,785365,785365,256,256,TRUE,FALSE,785665,6139,300,3,292,3,"24 pages incl deq & txn + 1 byte [deq txn]"
+87,"L",0.25,32,0,32,0,786260,786260,0,0,TRUE,FALSE,786304,6143,32,1,0,0,"24 pages incl deq = ½ file [deq]"
+88,"L",0.25,32,1,33,0,786260,786260,0,0,TRUE,FALSE,786304,6143,32,1,0,0,"24 pages incl deq = ½ file [deq]"
+89,"L",0.25,32,0,32,1,786261,786261,0,0,TRUE,FALSE,786305,6144,32,1,0,0,"24 pages incl deq + 1 byte [deq]"
+90,"L",0.25,32,0,32,0,785364,785364,256,256,TRUE,FALSE,785664,6138,300,3,292,3,"24 pages incl deq & txn = ½ file [deq txn]"
+91,"L",0.25,32,1,33,0,785364,785364,256,256,TRUE,FALSE,785664,6138,300,3,292,3,"24 pages incl deq & txn = ½ file [deq txn]"
+92,"L",0.25,32,0,32,1,785365,785365,256,256,TRUE,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.",,,,,,,,,,,,,,,,,,,
+93,"L",1,16,0,16,0,32724,32724,0,0,FALSE,FALSE,32768,256,0,0,0,0,"data 1 page"
+94,"L",1,16,0,16,1,32725,32725,0,0,FALSE,FALSE,32769,257,0,0,0,0,"data 1 page + 1 byte (tail split; 1 byte over page boundary)"
+95,"L",1,16,0,16,11,32735,32735,0,0,FALSE,FALSE,32779,257,0,0,0,0,"data 1 page + 11 bytes (tail split; 11 bytes over page boundary)"
+96,"L",1,16,0,16,12,32736,32736,0,0,FALSE,FALSE,32780,257,0,0,0,0,"data 1 page + 12 bytes (tail separated exactly onto next page)"
+97,"L",1,16,0,16,13,32737,32737,0,0,FALSE,FALSE,32781,257,0,0,0,0,"data 1 page + 13 bytes (xid split; 1 byte over page boundary)"
+98,"L",1,16,0,16,0,32468,32468,256,256,FALSE,FALSE,32768,256,0,0,0,0,"data 1 page [txn]"
+99,"L",1,16,0,16,1,32469,32469,256,256,FALSE,FALSE,32769,257,0,0,0,0,"data 1 page + 1 byte (tail split; 1 byte over page boundary) [txn]"
+100,"L",1,16,0,16,11,32479,32479,256,256,FALSE,FALSE,32779,257,0,0,0,0,"data 1 page + 11 bytes (tail split; 11 bytes over page boundary) [txn]"
+101,"L",1,16,0,16,12,32480,32480,256,256,FALSE,FALSE,32780,257,0,0,0,0,"data 1 page + 12 bytes (tail separated exactly onto next page) [txn]"
+102,"L",1,16,0,16,13,32481,32481,256,256,FALSE,FALSE,32781,257,0,0,0,0,"data 1 page + 13 bytes (xid split; 1 byte over page boundary) [txn]"
+103,"L",2,16,0,16,0,65492,65492,0,0,FALSE,FALSE,65536,512,0,0,0,0,"data 2 pages"
+104,"L",2,16,0,16,1,65493,65493,0,0,FALSE,FALSE,65537,513,0,0,0,0,"data 2 pages + 1 byte (tail split; 1 byte over page boundary)"
+105,"L",2,16,0,16,11,65503,65503,0,0,FALSE,FALSE,65547,513,0,0,0,0,"data 2 pages + 11 bytes (tail split; 11 bytes over page boundary)"
+106,"L",2,16,0,16,12,65504,65504,0,0,FALSE,FALSE,65548,513,0,0,0,0,"data 2 pages + 12 bytes (tail separated exactly onto next page)"
+107,"L",2,16,0,16,13,65505,65505,0,0,FALSE,FALSE,65549,513,0,0,0,0,"data 2 pages + 13 bytes (xid split; 1 byte over page boundary)"
+108,"L",2,16,0,16,0,65236,65236,256,256,FALSE,FALSE,65536,512,0,0,0,0,"data 2 pages [txn]"
+109,"L",2,16,0,16,1,65237,65237,256,256,FALSE,FALSE,65537,513,0,0,0,0,"data 2 pages + 1 byte (tail split; 1 byte over page boundary) [txn]"
+110,"L",2,16,0,16,11,65247,65247,256,256,FALSE,FALSE,65547,513,0,0,0,0,"data 2 pages + 11 bytes (tail split; 11 bytes over page boundary) [txn]"
+111,"L",2,16,0,16,12,65248,65248,256,256,FALSE,FALSE,65548,513,0,0,0,0,"data 2 pages + 12 bytes (tail separated exactly onto next page) [txn]"
+112,"L",2,16,0,16,13,65249,65249,256,256,FALSE,FALSE,65549,513,0,0,0,0,"data 2 pages + 13 bytes (xid split; 1 byte over page boundary) [txn]"
+113,"L",4,16,0,16,0,131028,131028,0,0,FALSE,FALSE,131072,1024,0,0,0,0,"data 4 pages"
+114,"L",4,16,0,16,1,131029,131029,0,0,FALSE,FALSE,131073,1025,0,0,0,0,"data 4 pages + 1 byte (tail split; 1 byte over page boundary)"
+115,"L",4,16,0,16,11,131039,131039,0,0,FALSE,FALSE,131083,1025,0,0,0,0,"data 4 pages + 11 bytes (tail split; 11 bytes over page boundary)"
+116,"L",4,16,0,16,12,131040,131040,0,0,FALSE,FALSE,131084,1025,0,0,0,0,"data 4 pages + 12 bytes (tail separated exactly onto next page)"
+117,"L",4,16,0,16,13,131041,131041,0,0,FALSE,FALSE,131085,1025,0,0,0,0,"data 4 pages + 13 bytes (xid split; 1 byte over page boundary)"
+118,"L",4,16,0,16,0,130772,130772,256,256,FALSE,FALSE,131072,1024,0,0,0,0,"data 4 pages [txn]"
+119,"L",4,16,0,16,1,130773,130773,256,256,FALSE,FALSE,131073,1025,0,0,0,0,"data 4 pages + 1 byte (tail split; 1 byte over page boundary) [txn]"
+120,"L",4,16,0,16,11,130783,130783,256,256,FALSE,FALSE,131083,1025,0,0,0,0,"data 4 pages + 11 bytes (tail split; 11 bytes over page boundary) [txn]"
+121,"L",4,16,0,16,12,130784,130784,256,256,FALSE,FALSE,131084,1025,0,0,0,0,"data 4 pages + 12 bytes (tail separated exactly onto next page) [txn]"
+122,"L",4,16,0,16,13,130785,130785,256,256,FALSE,FALSE,131085,1025,0,0,0,0,"data 4 pages + 13 bytes (xid split; 1 byte over page boundary) [txn]"
+123,"L",3.5,16,0,16,0,114644,114644,0,0,FALSE,FALSE,114688,896,0,0,0,0,"data 4 pages + 12 bytes (tail separated exactly onto next page) [txn]"
+124,"L",3.5,16,0,16,1,114645,114645,0,0,FALSE,FALSE,114689,897,0,0,0,0,"data 4 pages + 13 bytes (xid split; 1 byte over page boundary) [txn]"
+125,"L",3.5,16,0,16,0,114388,114388,256,256,FALSE,FALSE,114688,896,0,0,0,0,"data 4 pages + 12 bytes (tail separated exactly onto next page) [txn]"
+126,"L",3.5,16,0,16,1,114389,114389,256,256,FALSE,FALSE,114689,897,0,0,0,0,"data 4 pages + 13 bytes (xid split; 1 byte over page boundary) [txn]"
+127,"L",1,16,0,16,-1,10,10,32735,32735,FALSE,FALSE,32789,257,0,0,0,0,"xid 1 page – 1 byte; data 10 bytes (exact fit) [txn]"
+128,"L",1,16,0,16,0,10,10,32736,32736,FALSE,FALSE,32790,257,0,0,0,0,"xid 1 page; data 10 bytes (exact fit) [txn]"
+129,"L",1,16,0,16,1,10,10,32737,32737,FALSE,FALSE,32791,257,0,0,0,0,"xid 1 page + 1 byte; data 10 bytes (exact fit) [txn]"
+130,"L",2,16,0,16,-1,10,10,65503,65503,FALSE,FALSE,65557,513,0,0,0,0,"xid 2 pages – 1 byte; data 10 bytes (exact fit) [txn]"
+131,"L",2,16,0,16,0,10,10,65504,65504,FALSE,FALSE,65558,513,0,0,0,0,"xid 2 pages; data 10 bytes (exact fit) [txn]"
+132,"L",2,16,0,16,1,10,10,65505,65505,FALSE,FALSE,65559,513,0,0,0,0,"xid 2 pages + 1 byte; data 10 bytes (exact fit) [txn]"
+133,"L",4,16,0,16,-1,10,10,131039,131039,FALSE,FALSE,131093,1025,0,0,0,0,"xid 4 pages – 1 byte; data 10 bytes (exact fit) [txn]"
+134,"L",4,16,0,16,0,10,10,131040,131040,FALSE,FALSE,131094,1025,0,0,0,0,"xid 4 pages; data 10 bytes (exact fit) [txn]"
+135,"L",4,16,0,16,1,10,10,131041,131041,FALSE,FALSE,131095,1025,0,0,0,0,"xid 4 pages + 1 byte; data 10 bytes (exact fit) [txn]"
+136,"L",3.5,16,0,16,0,10,10,114656,114656,FALSE,FALSE,114710,897,0,0,0,0,"xid 3.5 pages; data 10 bytes (exact fit) [txn]"
+137,"L",3.5,16,0,16,1,10,10,114657,114657,FALSE,FALSE,114711,897,0,0,0,0,"xid 3.5 pages + 1 byte; data 10 bytes (exact fit) [txn]"
+138,"L",1,16,0,16,-1,10,10,32735,32735,TRUE,FALSE,32789,257,32779,257,32771,257,"xid 1 page – 1 byte; data 10 bytes (exact fit) [txn]"
+139,"L",1,16,0,16,0,10,10,32736,32736,TRUE,FALSE,32790,257,32780,257,32772,257,"xid 1 page; data 10 bytes (exact fit) [txn]"
+140,"L",1,16,0,16,1,10,10,32737,32737,TRUE,FALSE,32791,257,32781,257,32773,257,"xid 1 page + 1 byte; data 10 bytes (exact fit) [txn]"
+141,"L",2,16,0,16,-1,10,10,65503,65503,TRUE,FALSE,65557,513,65547,513,65539,513,"xid 2 pages – 1 byte; data 10 bytes (exact fit) [txn]"
+142,"L",2,16,0,16,0,10,10,65504,65504,TRUE,FALSE,65558,513,65548,513,65540,513,"xid 2 pages; data 10 bytes (exact fit) [txn]"
+143,"L",2,16,0,16,1,10,10,65505,65505,TRUE,FALSE,65559,513,65549,513,65541,513,"xid 2 pages + 1 byte; data 10 bytes (exact fit) [txn]"
+144,"L",4,16,0,16,-1,10,10,131039,131039,TRUE,FALSE,131093,1025,131083,1025,131075,1025,"xid 4 pages – 1 byte; data 10 bytes (exact fit) [txn]"
+145,"L",4,16,0,16,0,10,10,131040,131040,TRUE,FALSE,131094,1025,131084,1025,131076,1025,"xid 4 pages; data 10 bytes (exact fit) [txn]"
+146,"L",4,16,0,16,1,10,10,131041,131041,TRUE,FALSE,131095,1025,131085,1025,131077,1025,"xid 4 pages + 1 byte; data 10 bytes (exact fit) [txn]"
+147,"L",3.5,16,0,16,0,10,10,114656,114656,TRUE,FALSE,114710,897,114700,897,114692,897,"xid 3.5 pages; data 10 bytes (exact fit) [txn]"
+148,"L",3.5,16,0,16,1,10,10,114657,114657,TRUE,FALSE,114711,897,114701,897,114693,897,"xid 3.5 pages + 1 byte; data 10 bytes (exact fit) [txn]"
Modified: store/trunk/cpp/tests/jrnl/tests.ods
===================================================================
(Binary files differ)
Modified: store/trunk/cpp/tests/jrnl/wtests.csv
===================================================================
--- store/trunk/cpp/tests/jrnl/wtests.csv 2007-10-04 19:54:30 UTC (rev 964)
+++ store/trunk/cpp/tests/jrnl/wtests.csv 2007-10-05 20:46:46 UTC (rev 965)
@@ -1,139 +1,255 @@
-"Initialize only",,,,,,,,,
-0,0,0,0,FALSE,0,0,FALSE,,"No messages"
-,,,,,,,,,
-"Within first block, page, file",,,,,,,,,
-1,1,10,10,FALSE,0,0,FALSE,,"1 * 10-byte message"
-2,10,10,10,FALSE,0,0,FALSE,,"10 * 10-byte message"
-3,1,10,10,FALSE,0,0,TRUE,,"1 * 10-byte message, transient"
-4,10,10,10,FALSE,0,0,TRUE,,"10 * 10-byte message, transient"
-5,1,10,10,FALSE,10,10,FALSE,,"1 * 10-byte message, txn"
-6,10,10,10,FALSE,10,10,FALSE,,"10 * 10-byte message, txn"
-7,1,10,10,FALSE,10,10,TRUE,,"1 * 10-byte message, txn, transient"
-8,10,10,10,FALSE,10,10,TRUE,,"10 * 10-byte message, txn, transient"
-9,1,10,10,TRUE,0,0,FALSE,,"1 * 10-byte message, deq"
-10,10,10,10,TRUE,0,0,FALSE,,"10 * 10-byte message, deq"
-11,1,10,10,TRUE,0,0,TRUE,,"1 * 10-byte message, transient, deq"
-12,10,10,10,TRUE,0,0,TRUE,,"10 * 10-byte message, transient, deq"
-13,1,10,10,TRUE,10,10,FALSE,,"1 * 10-byte message, txn, deq"
-14,10,10,10,TRUE,10,10,FALSE,,"10 * 10-byte message, txn, deq"
-15,1,10,10,TRUE,10,10,TRUE,,"1 * 10-byte message, txn, transient, deq"
-16,10,10,10,TRUE,10,10,TRUE,,"10 * 10-byte message, txn, transient, deq"
-,,,,,,,,,
-"Transition from one d-block to two per message",,,,,,,,,
-17,10,84,84,FALSE,0,0,FALSE,,"1 dblk exact fit"
-18,10,85,85,FALSE,0,0,FALSE,,"1 dblk + 1 byte"
-19,10,58,58,FALSE,26,26,FALSE,,"1 dblk exact fit, txn"
-20,10,59,59,FALSE,26,26,FALSE,,"1 dblk + 1 byte, txn"
-,,,,,,,,,
-"Transition from one s-block to two per message",,,,,,,,,
-21,10,468,468,FALSE,0,0,FALSE,,"1 sblk exact fit"
-22,10,469,469,FALSE,0,0,FALSE,,"1 sblk + 1 byte"
-23,10,442,442,FALSE,26,26,FALSE,,"1 sblk exact fit, txn"
-24,10,443,443,FALSE,26,26,FALSE,,"1 sblk + 1 byte, txn"
-,,,,,,,,,
-"Transition from first page to second",,,,,,,,,
-25,8,4052,4052,FALSE,0,0,FALSE,,"8 * 1/8 page; Total = 1 page exact fit"
-26,9,4052,4052,FALSE,0,0,FALSE,,"9 * 1/8 page"
-27,8,4053,4053,FALSE,0,0,FALSE,,"8 * (1/8 page + 1 byte)"
-28,8,3796,3796,FALSE,256,256,FALSE,,"8 * 1/8 page; Total = 1 page exact fit, txn"
-29,9,3796,3796,FALSE,256,256,FALSE,,"9 * 1/8 page, txn"
-30,8,3797,3797,FALSE,256,256,FALSE,,"8 * (1/8 page + 1 byte), txn"
-,,,,,,,,,
-"Page cache rollover (from page 32 back to page 0) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,,,,
-31,32,32724,32724,FALSE,0,0,FALSE,,"32 * (1 page exact fit); Total = entire cache exactly"
-32,33,32724,32724,FALSE,0,0,FALSE,,"33 * (1 page exact fit); Total = entire cache + reuse of 1 page"
-33,22,49108,49108,FALSE,0,0,FALSE,,"22 * 1.5 pages"
-34,32,32468,32468,FALSE,256,256,FALSE,,"32 * (1 page exact fit); Total = entire cache exactly, txn"
-35,33,32468,32468,FALSE,256,256,FALSE,,"33 * (1 page exact fit); Total = entire cache + reuse of 1 page, txn"
-36,22,48852,48852,FALSE,256,256,FALSE,,"22 * 1.5 pages, txn"
-,,,,,,,,,
-"File transition (from file 0000 to 0001) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,,,,
-37,48,32724,32724,FALSE,0,0,FALSE,,"48 * (1 page exact fit); Total = entire file exactly"
-38,49,32724,32724,FALSE,0,0,FALSE,,"49 * (1 page exact fit); Total = entire file + 1 page"
-39,20,81876,81876,FALSE,0,0,FALSE,,"20 * (2.5 pages); Total = entire file + 2 pages"
-40,48,32468,32468,FALSE,256,256,FALSE,,"48 * (1 page exact fit); Total = entire file exactly, txn"
-41,49,32468,32468,FALSE,256,256,FALSE,,"49 * (1 page exact fit); Total = entire file + 1 page, txn"
-42,20,81620,81620,FALSE,256,256,FALSE,,"20 * (2.5 pages); Total = entire file + 2 pages, txn"
-,,,,,,,,,
-"File rollover (from file 0007 to 0000) - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,,,,
-43,16,786388,786388,FALSE,0,0,FALSE,,"16 * (24 pages = ½ file); Total = 8 files exactly"
-44,17,786388,786388,FALSE,0,0,FALSE,,"17 * (24 pages = ½ file); Total = 8 files + file 0 overwritten by ½ file"
-45,16,786389,786389,FALSE,0,0,FALSE,,"16 * (24 pages + 1 byte); Total = 8 files + file 0 overwritten by 16 sblks"
-46,32,786388,786388,FALSE,0,0,FALSE,,"32 * (24 pages = ½ file); Total = 16 files exactly, all files overwritten once"
-47,33,786388,786388,FALSE,0,0,FALSE,,"33 * (24 pages = ½ file); Total = 16 ½ files, all files overwritten once + file 0 overwritten again by ½ file"
-48,32,786389,786389,FALSE,0,0,FALSE,,"32 * (24 pages + 1 byte); All files overwritten once + file 0 overwritten again by 32 sblks"
-49,16,786132,786132,FALSE,256,256,FALSE,,"16 * (24 pages = ½ file); Total = 8 files exactly, txn"
-50,17,786132,786132,FALSE,256,256,FALSE,,"17 * (24 pages = ½ file); Total = 8 files + file 0 overwritten by ½ file, txn"
-51,16,786133,786133,FALSE,256,256,FALSE,,"16 * (24 pages + 1 byte); Total = 8 files + file 0 overwritten by 16 sblks, txn"
-52,32,786132,786132,FALSE,256,256,FALSE,,"32 * (24 pages = ½ file); Total = 16 files exactly, all files overwritten once, txn"
-53,33,786132,786132,FALSE,256,256,FALSE,,"33 * (24 pages = ½ file); Total = 16 ½ files, all files overwritten once + file 0 overwritten again by ½ file, txn"
-54,32,786133,786133,FALSE,256,256,FALSE,,"32 * (24 pages + 1 byte); All files overwritten once + file 0 overwritten again by 32 sblks, txn"
-,,,,,,,,,
-"Multi-page messages (large messages) - tests various paths in encoder; no dequeues required to test this functionality.",,,,,,,,,
-55,16,10,10,FALSE,32724,32724,FALSE,,"16 * (xid 1 page exact fit)"
-56,16,10,10,FALSE,32725,32725,FALSE,,"16 * (xid 1 page + 1 byte): tail split"
-57,16,10,10,FALSE,32735,32735,FALSE,,"16 * (xid 1 page + 11 bytes): tail split"
-58,16,10,10,FALSE,32736,32736,FALSE,,"16 * (xid 1 page + 12 bytes): tail separated exactly"
-59,16,10,10,FALSE,32737,32737,FALSE,,"16 * (xid 1 page + 13 bytes): data split"
-60,16,10,10,FALSE,65492,65492,FALSE,,"16 * (xid 2 pages exact fit)"
-61,16,10,10,FALSE,65493,65493,FALSE,,"16 * (xid 2 pages + 1 byte): tail split"
-62,16,10,10,FALSE,65503,65503,FALSE,,"16 * (xid 2 pages + 11 bytes): tail split"
-63,16,10,10,FALSE,65504,65504,FALSE,,"16 * (xid 2 pages + 12 bytes): tail separated exactly"
-64,16,10,10,FALSE,65505,65505,FALSE,,"16 * (xid 2 pages + 13 bytes) data split"
-65,16,32724,32724,FALSE,0,0,FALSE,,"16 * (1 page exact fit)"
-66,16,32725,32725,FALSE,0,0,FALSE,,"16 * (1 page + 1 byte): tail split"
-67,16,32735,32735,FALSE,0,0,FALSE,,"16 * (1 page + 11 bytes): tail split"
-68,16,32736,32736,FALSE,0,0,FALSE,,"16 * (1 page + 12 bytes): tail separated exactly"
-69,16,32737,32737,FALSE,0,0,FALSE,,"16 * (1 page + 13 bytes): data split"
-70,16,65492,65492,FALSE,0,0,FALSE,,"16 * (2 pages exact fit)"
-71,16,65493,65493,FALSE,0,0,FALSE,,"16 * (2 pages + 1 byte): tail split"
-72,16,65503,65503,FALSE,0,0,FALSE,,"16 * (2 pages + 11 bytes): tail split"
-73,16,65504,65504,FALSE,0,0,FALSE,,"16 * (2 pages + 12 bytes): tail separated exactly"
-74,16,65505,65505,FALSE,0,0,FALSE,,"16 * (2 pages + 13 bytes) data split"
-75,16,131028,131028,FALSE,0,0,FALSE,,"16 * (4 pages exact fit)"
-76,16,131029,131029,FALSE,0,0,FALSE,,"16 * (4 pages + 1 byte: tail split)"
-77,16,131039,131039,FALSE,0,0,FALSE,,"16 * (4 pages + 1 byte: tail split)"
-78,16,131040,131040,FALSE,0,0,FALSE,,"16 * (4 pages + 12 bytes: tail separated)"
-79,16,131041,131041,FALSE,0,0,FALSE,,"16 * (4 pages + 13 bytes: data split)"
-80,16,114644,114644,FALSE,0,0,FALSE,,"16 * (3.5 pages)"
-81,16,114645,114645,FALSE,0,0,FALSE,,"16 * (3.5 pages + 1 byte)"
-,,,,,,,,,
-"Large (multi-megabyte) messages - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,,,,
-82,32,1572820,1572820,FALSE,0,0,FALSE,,"32 * (48 pages = 1 file exactly)"
-83,32,1572821,1572821,FALSE,0,0,FALSE,,"32 * (48 pages + 1 byte)"
-84,32,1605588,1605588,FALSE,0,0,FALSE,,"32 * (49 pages = 1 file + 1 page)"
-85,16,3145684,3145684,FALSE,0,0,FALSE,,"16 * (96 pages = 2 files exactly)"
-86,16,3145685,3145685,FALSE,0,0,FALSE,,"16 * (96 pages + 1 byte)"
-87,16,3178452,3178452,FALSE,0,0,FALSE,,"16 * (97 pages = 2 files + 1 page"
-88,8,6291412,6291412,FALSE,0,0,FALSE,,"8 * (192 pages = 4 files exactly)"
-89,8,6291413,6291413,FALSE,0,0,FALSE,,"8 * (192 pages + 1 byte)"
-90,8,6324180,6324180,FALSE,0,0,FALSE,,"8 * (193 pages = 4 files + 1 page)"
-91,32,1572692,1572692,TRUE,0,0,FALSE,,"32 * (48 pages including 1 sblk for deq record = 1 file exactly)"
-92,32,1572693,1572693,TRUE,0,0,FALSE,,"32 * (48 pages including 1 sblk for deq record + 1 byte)"
-93,32,1605460,1605460,TRUE,0,0,FALSE,,"32 * (49 pages including 1 sblk for deq record = 1 file + 1 page)"
-94,16,3145556,3145556,TRUE,0,0,FALSE,,"16 * (96 pages including 1 sblk for deq record = 2 files exactly)"
-95,16,3145557,3145557,TRUE,0,0,FALSE,,"16 * (96 pages including 1 sblk for deq record + 1 byte)"
-96,16,3178324,3178324,TRUE,0,0,FALSE,,"16 * (97 pages including 1 sblk for deq record = 2 files + 1 page"
-97,8,6291284,6291284,TRUE,0,0,FALSE,,"8 * (192 pages including 1 sblk for deq record = 4 files exactly)"
-98,8,6291285,6291285,TRUE,0,0,FALSE,,"8 * (192 pages including 1 sblk for deq record + 1 byte)"
-99,8,6324052,6324052,TRUE,0,0,FALSE,,"8 * (193 pages including 1 sblk for deq record = 4 files + 1 page)"
-,,,,,,,,,
-"High volume tests of random message lengths - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,,,,
-100,5000000,0,84,FALSE,0,0,FALSE,,"1 dblk max"
-101,3000000,0,340,FALSE,0,0,FALSE,,"3 dblks max"
-102,1600000,0,1236,FALSE,0,0,FALSE,,"10 dblks max"
-103,600000,0,3796,FALSE,0,0,FALSE,,"30 dblks max"
-104,200000,0,12756,FALSE,0,0,FALSE,,"100 dblks max"
-105,60000,0,38356,FALSE,0,0,FALSE,,"300 dblks max"
-106,20000,0,127956,FALSE,0,0,FALSE,,"1000 dblks max"
-107,2500000,0,84,TRUE,0,0,FALSE,,"1 dblk max"
-108,1500000,0,340,TRUE,0,0,FALSE,,"3 dblks max"
-109,800000,0,1236,TRUE,0,0,FALSE,,"10 dblks max"
-110,300000,0,3796,TRUE,0,0,FALSE,,"30 dblks max"
-111,100000,0,12756,TRUE,0,0,FALSE,,"100 dblks max"
-112,30000,0,38356,TRUE,0,0,FALSE,,"300 dblks max"
-113,10000,0,127956,TRUE,0,0,FALSE,,"1000 dblks max"
-,,,,,,,,,
-"STANDARD PERFORMANCE BENCHMARK: 10,000,000 writes, data=212b (2 dblks)",,,,,,,,,
-114,10000000,212,212,FALSE,0,0,FALSE,,"2 dblks"
-115,10000000,212,212,TRUE,0,0,FALSE,,"2 dblks"
+,,,,,,,"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","bytes","dblks","bytes","dblks","bytes","dblks","comment"
+,,,,,,,,,,,,,,,,,,,
+"Initialize only",,,,,,,,,,,,,,,,,,,
+0,"L",0,0,0,0,0,0,0,0,0,FALSE,FALSE,44,1,0,0,0,0,"No messages - journal creation/initialization only"
+,,,,,,,,,,,,,,,,,,,
+"Simple message combinations of persistent/transient, dequeued/non-dequeued, transactional/non-transactional",,,,,,,,,,,,,,,,,,,
+1,"L",1,1,0,1,0,10,10,0,0,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,54,1,0,0,0,0,"10 * 10-byte message"
+3,"L",1,1,0,1,0,10,10,0,0,FALSE,TRUE,54,1,0,0,0,0,"1 * 10-byte message [transient]"
+4,"L",1,10,0,10,0,10,10,0,0,FALSE,TRUE,54,1,0,0,0,0,"10 * 10-byte message [transient]"
+5,"L",1,1,0,1,0,10,10,10,10,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,64,1,0,0,0,0,"10 * 10-byte message [txn]"
+7,"L",1,1,0,1,0,10,10,10,10,FALSE,TRUE,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,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,54,1,32,1,0,0,"1 * 10-byte message [deq]"
+10,"L",1,10,0,10,0,10,10,0,0,TRUE,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,54,1,32,1,0,0,"1 * 10-byte message [transient deq]"
+12,"L",1,10,0,10,0,10,10,0,0,TRUE,TRUE,54,1,32,1,0,0,"10 * 10-byte message [transient deq]"
+13,"L",1,1,0,1,0,10,10,10,10,TRUE,FALSE,64,1,54,1,46,1,"1 * 10-byte message [txn deq]"
+14,"L",1,10,0,10,0,10,10,10,10,TRUE,FALSE,64,1,54,1,46,1,"10 * 10-byte message [txn deq]"
+15,"L",1,1,0,1,0,10,10,10,10,TRUE,TRUE,64,1,54,1,46,1,"1 * 10-byte message [txn transient deq]"
+16,"L",1,10,0,10,0,10,10,10,10,TRUE,TRUE,64,1,54,1,46,1,"10 * 10-byte message [txn transient deq]"
+,,,,,,,,,,,,,,,,,,,
+"Transition from one d-block to two per message",,,,,,,,,,,,,,,,,,,
+17,"L",1,10,0,10,0,84,84,0,0,FALSE,FALSE,128,1,0,0,0,0,"1 dblk exact fit"
+18,"L",1,10,0,10,1,85,85,0,0,FALSE,FALSE,129,2,0,0,0,0,"1 dblk + 1 byte"
+19,"L",1,10,0,10,0,58,58,26,26,FALSE,FALSE,128,1,0,0,0,0,"1 dblk exact fit [txn]"
+20,"L",1,10,0,10,1,59,59,26,26,FALSE,FALSE,129,2,0,0,0,0,"1 dblk + 1 byte [txn]"
+,,,,,,,,,,,,,,,,,,,
+"Transition from one s-block to two per message",,,,,,,,,,,,,,,,,,,
+21,"L",1,10,0,10,0,468,468,0,0,FALSE,FALSE,512,4,0,0,0,0,"1 sblk exact fit"
+22,"L",1,10,0,10,1,469,469,0,0,FALSE,FALSE,513,5,0,0,0,0,"1 sblk + 1 byte"
+23,"L",1,10,0,10,0,442,442,26,26,FALSE,FALSE,512,4,0,0,0,0,"1 sblk exact fit [txn]"
+24,"L",1,10,0,10,1,443,443,26,26,FALSE,FALSE,513,5,0,0,0,0,"1 sblk + 1 byte [txn]"
+,,,,,,,,,,,,,,,,,,,
+"Transition from first page to second",,,,,,,,,,,,,,,,,,,
+25,"L",1,8,0,8,0,4052,4052,0,0,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page"
+26,"L",1,8,1,9,0,4052,4052,0,0,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page"
+27,"L",1,8,0,8,1,4053,4053,0,0,FALSE,FALSE,4097,33,0,0,0,0,"1/8 page + 1 byte"
+28,"L",1,8,0,8,0,3796,3796,256,256,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page [txn]"
+29,"L",1,8,1,9,0,3796,3796,256,256,FALSE,FALSE,4096,32,0,0,0,0,"1/8 page [txn]"
+30,"L",1,8,0,8,1,3797,3797,256,256,FALSE,FALSE,4097,33,0,0,0,0,"1/8 page + 1 byte [txn]"
+31,"L",1,8,0,8,0,3924,3924,0,0,TRUE,FALSE,3968,31,32,1,0,0,"1/8 page incl deq [deq]"
+32,"L",1,8,1,9,0,3924,3924,0,0,TRUE,FALSE,3968,31,32,1,0,0,"1/8 page incl deq [deq]"
+33,"L",1,8,0,8,1,3925,3925,0,0,TRUE,FALSE,3969,32,32,1,0,0,"1/8 page incl deq + 1 byte [deq]"
+34,"L",1,8,0,8,0,3028,3028,256,256,TRUE,FALSE,3328,26,300,3,292,3,"1/8 page incl deq & txn [deq txn]"
+35,"L",1,8,1,9,0,3028,3028,256,256,TRUE,FALSE,3328,26,300,3,292,3,"1/8 page incl deq & txn [deq txn]"
+36,"L",1,8,0,8,1,3029,3029,256,256,TRUE,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) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,,,,,,,,,,,,,,
+37,"L",1,32,0,32,0,32724,32724,0,0,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
+38,"L",1,32,1,33,0,32724,32724,0,0,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
+39,"L",1,32,0,32,1,32725,32725,0,0,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte"
+40,"L",1.5,22,0,22,0,49108,49108,0,0,FALSE,FALSE,49152,384,0,0,0,0,"1.5 pages"
+41,"L",1,32,0,32,0,32468,32468,256,256,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
+42,"L",1,32,1,33,0,32468,32468,256,256,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
+43,"L",1,32,0,32,1,32469,32469,256,256,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte [txn]"
+44,"L",1.5,22,0,22,0,48852,48852,256,256,FALSE,FALSE,49152,384,0,0,0,0,"1.5 pages [txn]"
+45,"L",1,32,0,32,0,32596,32596,0,0,TRUE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
+46,"L",1,32,1,33,0,32596,32596,0,0,TRUE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
+47,"L",1,32,0,32,1,32597,32597,0,0,TRUE,FALSE,32641,256,32,1,0,0,"1 page incl deq + 1 byte [deq]"
+48,"L",1.5,22,0,22,0,48980,48980,0,0,TRUE,FALSE,49024,383,32,1,0,0,"1.5 pages incl deq [deq]"
+49,"L",1,32,0,32,0,31700,31700,256,256,TRUE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
+50,"L",1,32,1,33,0,31700,31700,256,256,TRUE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
+51,"L",1,32,0,32,1,31701,31701,256,256,TRUE,FALSE,32001,251,300,3,292,3,"1 page incl deq & txn + 1 byte [deq txn]"
+52,"L",1.5,22,0,22,0,48084,48084,256,256,TRUE,FALSE,48384,378,300,3,292,3,"1.5 pages incl deq & txn [deq txn]"
+,,,,,,,,,,,,,,,,,,,
+"File transition (from file 0000 to 0001) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,,,,,,,,,,,,,,
+53,"L",1,48,0,48,0,32724,32724,0,0,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
+54,"L",1,48,1,49,0,32724,32724,0,0,FALSE,FALSE,32768,256,0,0,0,0,"1 page"
+55,"L",1,48,0,48,1,32725,32725,0,0,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte"
+56,"L",2.5,20,0,20,0,81876,81876,0,0,FALSE,FALSE,81920,640,0,0,0,0,"2.5 pages"
+57,"L",1,48,0,48,0,32468,32468,256,256,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
+58,"L",1,48,1,49,0,32468,32468,256,256,FALSE,FALSE,32768,256,0,0,0,0,"1 page [txn]"
+59,"L",1,48,0,48,1,32469,32469,256,256,FALSE,FALSE,32769,257,0,0,0,0,"1 page + 1 byte [txn]"
+60,"L",2.5,20,0,20,0,81620,81620,256,256,FALSE,FALSE,81920,640,0,0,0,0,"2.5 pages [txn]"
+61,"L",1,48,0,48,0,32596,32596,0,0,TRUE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
+62,"L",1,48,1,49,0,32596,32596,0,0,TRUE,FALSE,32640,255,32,1,0,0,"1 page incl deq [deq]"
+63,"L",1,48,0,48,1,32597,32597,0,0,TRUE,FALSE,32641,256,32,1,0,0,"1 page incl deq + 1 byte [deq]"
+64,"L",2.5,20,0,20,0,81748,81748,0,0,TRUE,FALSE,81792,639,32,1,0,0,"2.5 pages incl deq [deq]"
+65,"L",1,48,0,48,0,31700,31700,256,256,TRUE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
+66,"L",1,48,1,49,0,31700,31700,256,256,TRUE,FALSE,32000,250,300,3,292,3,"1 page incl deq & txn [deq txn]"
+67,"L",1,48,0,48,1,31701,31701,256,256,TRUE,FALSE,32001,251,300,3,292,3,"1 page incl deq & txn + 1 byte [deq txn]"
+68,"L",2.5,20,0,20,0,80852,80852,256,256,TRUE,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",,,,,,,,,,,,,,,,,,,
+69,"L",0.5,16,0,16,0,786388,786388,0,0,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file"
+70,"L",0.5,16,1,17,0,786388,786388,0,0,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file"
+71,"L",0.5,16,0,16,1,786389,786389,0,0,FALSE,FALSE,786433,6145,0,0,0,0,"24 pages + 1 byte"
+72,"L",0.5,16,0,16,0,786132,786132,256,256,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file [txn]"
+73,"L",0.5,16,1,17,0,786132,786132,256,256,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file [txn]"
+74,"L",0.5,16,0,16,1,786133,786133,256,256,FALSE,FALSE,786433,6145,0,0,0,0,"24 pages + 1 byte [txn]"
+75,"L",0.25,32,0,32,0,786388,786388,0,0,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file"
+76,"L",0.25,32,1,33,0,786388,786388,0,0,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file"
+77,"L",0.25,32,0,32,1,786389,786389,0,0,FALSE,FALSE,786433,6145,0,0,0,0,"24 pages + 1 byte"
+78,"L",0.25,32,0,32,0,786132,786132,256,256,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file [txn]"
+79,"L",0.25,32,1,33,0,786132,786132,256,256,FALSE,FALSE,786432,6144,0,0,0,0,"24 pages = ½ file [txn]"
+80,"L",0.25,32,0,32,1,786133,786133,256,256,FALSE,FALSE,786433,6145,0,0,0,0,"24 pages + 1 byte [txn]"
+81,"L",0.5,16,0,16,0,786260,786260,0,0,TRUE,FALSE,786304,6143,32,1,0,0,"24 pages incl deq = ½ file [deq]"
+82,"L",0.5,16,1,17,0,786260,786260,0,0,TRUE,FALSE,786304,6143,32,1,0,0,"24 pages incl deq = ½ file [deq]"
+83,"L",0.5,16,0,16,1,786261,786261,0,0,TRUE,FALSE,786305,6144,32,1,0,0,"24 pages incl deq + 1 byte [deq]"
+84,"L",0.5,16,0,16,0,785364,785364,256,256,TRUE,FALSE,785664,6138,300,3,292,3,"24 pages incl deq & txn = ½ file [deq txn]"
+85,"L",0.5,16,1,17,0,785364,785364,256,256,TRUE,FALSE,785664,6138,300,3,292,3,"24 pages incl deq & txn = ½ file [deq txn]"
+86,"L",0.5,16,0,16,1,785365,785365,256,256,TRUE,FALSE,785665,6139,300,3,292,3,"24 pages incl deq & txn + 1 byte [deq txn]"
+87,"L",0.25,32,0,32,0,786260,786260,0,0,TRUE,FALSE,786304,6143,32,1,0,0,"24 pages incl deq = ½ file [deq]"
+88,"L",0.25,32,1,33,0,786260,786260,0,0,TRUE,FALSE,786304,6143,32,1,0,0,"24 pages incl deq = ½ file [deq]"
+89,"L",0.25,32,0,32,1,786261,786261,0,0,TRUE,FALSE,786305,6144,32,1,0,0,"24 pages incl deq + 1 byte [deq]"
+90,"L",0.25,32,0,32,0,785364,785364,256,256,TRUE,FALSE,785664,6138,300,3,292,3,"24 pages incl deq & txn = ½ file [deq txn]"
+91,"L",0.25,32,1,33,0,785364,785364,256,256,TRUE,FALSE,785664,6138,300,3,292,3,"24 pages incl deq & txn = ½ file [deq txn]"
+92,"L",0.25,32,0,32,1,785365,785365,256,256,TRUE,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.",,,,,,,,,,,,,,,,,,,
+93,"L",1,16,0,16,0,32724,32724,0,0,FALSE,FALSE,32768,256,0,0,0,0,"data 1 page"
+94,"L",1,16,0,16,1,32725,32725,0,0,FALSE,FALSE,32769,257,0,0,0,0,"data 1 page + 1 byte (tail split; 1 byte over page boundary)"
+95,"L",1,16,0,16,11,32735,32735,0,0,FALSE,FALSE,32779,257,0,0,0,0,"data 1 page + 11 bytes (tail split; 11 bytes over page boundary)"
+96,"L",1,16,0,16,12,32736,32736,0,0,FALSE,FALSE,32780,257,0,0,0,0,"data 1 page + 12 bytes (tail separated exactly onto next page)"
+97,"L",1,16,0,16,13,32737,32737,0,0,FALSE,FALSE,32781,257,0,0,0,0,"data 1 page + 13 bytes (xid split; 1 byte over page boundary)"
+98,"L",1,16,0,16,0,32468,32468,256,256,FALSE,FALSE,32768,256,0,0,0,0,"data 1 page [txn]"
+99,"L",1,16,0,16,1,32469,32469,256,256,FALSE,FALSE,32769,257,0,0,0,0,"data 1 page + 1 byte (tail split; 1 byte over page boundary) [txn]"
+100,"L",1,16,0,16,11,32479,32479,256,256,FALSE,FALSE,32779,257,0,0,0,0,"data 1 page + 11 bytes (tail split; 11 bytes over page boundary) [txn]"
+101,"L",1,16,0,16,12,32480,32480,256,256,FALSE,FALSE,32780,257,0,0,0,0,"data 1 page + 12 bytes (tail separated exactly onto next page) [txn]"
+102,"L",1,16,0,16,13,32481,32481,256,256,FALSE,FALSE,32781,257,0,0,0,0,"data 1 page + 13 bytes (xid split; 1 byte over page boundary) [txn]"
+103,"L",2,16,0,16,0,65492,65492,0,0,FALSE,FALSE,65536,512,0,0,0,0,"data 2 pages"
+104,"L",2,16,0,16,1,65493,65493,0,0,FALSE,FALSE,65537,513,0,0,0,0,"data 2 pages + 1 byte (tail split; 1 byte over page boundary)"
+105,"L",2,16,0,16,11,65503,65503,0,0,FALSE,FALSE,65547,513,0,0,0,0,"data 2 pages + 11 bytes (tail split; 11 bytes over page boundary)"
+106,"L",2,16,0,16,12,65504,65504,0,0,FALSE,FALSE,65548,513,0,0,0,0,"data 2 pages + 12 bytes (tail separated exactly onto next page)"
+107,"L",2,16,0,16,13,65505,65505,0,0,FALSE,FALSE,65549,513,0,0,0,0,"data 2 pages + 13 bytes (xid split; 1 byte over page boundary)"
+108,"L",2,16,0,16,0,65236,65236,256,256,FALSE,FALSE,65536,512,0,0,0,0,"data 2 pages [txn]"
+109,"L",2,16,0,16,1,65237,65237,256,256,FALSE,FALSE,65537,513,0,0,0,0,"data 2 pages + 1 byte (tail split; 1 byte over page boundary) [txn]"
+110,"L",2,16,0,16,11,65247,65247,256,256,FALSE,FALSE,65547,513,0,0,0,0,"data 2 pages + 11 bytes (tail split; 11 bytes over page boundary) [txn]"
+111,"L",2,16,0,16,12,65248,65248,256,256,FALSE,FALSE,65548,513,0,0,0,0,"data 2 pages + 12 bytes (tail separated exactly onto next page) [txn]"
+112,"L",2,16,0,16,13,65249,65249,256,256,FALSE,FALSE,65549,513,0,0,0,0,"data 2 pages + 13 bytes (xid split; 1 byte over page boundary) [txn]"
+113,"L",4,16,0,16,0,131028,131028,0,0,FALSE,FALSE,131072,1024,0,0,0,0,"data 4 pages"
+114,"L",4,16,0,16,1,131029,131029,0,0,FALSE,FALSE,131073,1025,0,0,0,0,"data 4 pages + 1 byte (tail split; 1 byte over page boundary)"
+115,"L",4,16,0,16,11,131039,131039,0,0,FALSE,FALSE,131083,1025,0,0,0,0,"data 4 pages + 11 bytes (tail split; 11 bytes over page boundary)"
+116,"L",4,16,0,16,12,131040,131040,0,0,FALSE,FALSE,131084,1025,0,0,0,0,"data 4 pages + 12 bytes (tail separated exactly onto next page)"
+117,"L",4,16,0,16,13,131041,131041,0,0,FALSE,FALSE,131085,1025,0,0,0,0,"data 4 pages + 13 bytes (xid split; 1 byte over page boundary)"
+118,"L",4,16,0,16,0,130772,130772,256,256,FALSE,FALSE,131072,1024,0,0,0,0,"data 4 pages [txn]"
+119,"L",4,16,0,16,1,130773,130773,256,256,FALSE,FALSE,131073,1025,0,0,0,0,"data 4 pages + 1 byte (tail split; 1 byte over page boundary) [txn]"
+120,"L",4,16,0,16,11,130783,130783,256,256,FALSE,FALSE,131083,1025,0,0,0,0,"data 4 pages + 11 bytes (tail split; 11 bytes over page boundary) [txn]"
+121,"L",4,16,0,16,12,130784,130784,256,256,FALSE,FALSE,131084,1025,0,0,0,0,"data 4 pages + 12 bytes (tail separated exactly onto next page) [txn]"
+122,"L",4,16,0,16,13,130785,130785,256,256,FALSE,FALSE,131085,1025,0,0,0,0,"data 4 pages + 13 bytes (xid split; 1 byte over page boundary) [txn]"
+123,"L",3.5,16,0,16,0,114644,114644,0,0,FALSE,FALSE,114688,896,0,0,0,0,"data 4 pages + 12 bytes (tail separated exactly onto next page) [txn]"
+124,"L",3.5,16,0,16,1,114645,114645,0,0,FALSE,FALSE,114689,897,0,0,0,0,"data 4 pages + 13 bytes (xid split; 1 byte over page boundary) [txn]"
+125,"L",3.5,16,0,16,0,114388,114388,256,256,FALSE,FALSE,114688,896,0,0,0,0,"data 4 pages + 12 bytes (tail separated exactly onto next page) [txn]"
+126,"L",3.5,16,0,16,1,114389,114389,256,256,FALSE,FALSE,114689,897,0,0,0,0,"data 4 pages + 13 bytes (xid split; 1 byte over page boundary) [txn]"
+127,"L",1,16,0,16,-1,10,10,32735,32735,FALSE,FALSE,32789,257,0,0,0,0,"xid 1 page – 1 byte; data 10 bytes (exact fit) [txn]"
+128,"L",1,16,0,16,0,10,10,32736,32736,FALSE,FALSE,32790,257,0,0,0,0,"xid 1 page; data 10 bytes (exact fit) [txn]"
+129,"L",1,16,0,16,1,10,10,32737,32737,FALSE,FALSE,32791,257,0,0,0,0,"xid 1 page + 1 byte; data 10 bytes (exact fit) [txn]"
+130,"L",2,16,0,16,-1,10,10,65503,65503,FALSE,FALSE,65557,513,0,0,0,0,"xid 2 pages – 1 byte; data 10 bytes (exact fit) [txn]"
+131,"L",2,16,0,16,0,10,10,65504,65504,FALSE,FALSE,65558,513,0,0,0,0,"xid 2 pages; data 10 bytes (exact fit) [txn]"
+132,"L",2,16,0,16,1,10,10,65505,65505,FALSE,FALSE,65559,513,0,0,0,0,"xid 2 pages + 1 byte; data 10 bytes (exact fit) [txn]"
+133,"L",4,16,0,16,-1,10,10,131039,131039,FALSE,FALSE,131093,1025,0,0,0,0,"xid 4 pages – 1 byte; data 10 bytes (exact fit) [txn]"
+134,"L",4,16,0,16,0,10,10,131040,131040,FALSE,FALSE,131094,1025,0,0,0,0,"xid 4 pages; data 10 bytes (exact fit) [txn]"
+135,"L",4,16,0,16,1,10,10,131041,131041,FALSE,FALSE,131095,1025,0,0,0,0,"xid 4 pages + 1 byte; data 10 bytes (exact fit) [txn]"
+136,"L",3.5,16,0,16,0,10,10,114656,114656,FALSE,FALSE,114710,897,0,0,0,0,"xid 3.5 pages; data 10 bytes (exact fit) [txn]"
+137,"L",3.5,16,0,16,1,10,10,114657,114657,FALSE,FALSE,114711,897,0,0,0,0,"xid 3.5 pages + 1 byte; data 10 bytes (exact fit) [txn]"
+138,"L",1,16,0,16,-1,10,10,32735,32735,TRUE,FALSE,32789,257,32779,257,32771,257,"xid 1 page – 1 byte; data 10 bytes (exact fit) [txn]"
+139,"L",1,16,0,16,0,10,10,32736,32736,TRUE,FALSE,32790,257,32780,257,32772,257,"xid 1 page; data 10 bytes (exact fit) [txn]"
+140,"L",1,16,0,16,1,10,10,32737,32737,TRUE,FALSE,32791,257,32781,257,32773,257,"xid 1 page + 1 byte; data 10 bytes (exact fit) [txn]"
+141,"L",2,16,0,16,-1,10,10,65503,65503,TRUE,FALSE,65557,513,65547,513,65539,513,"xid 2 pages – 1 byte; data 10 bytes (exact fit) [txn]"
+142,"L",2,16,0,16,0,10,10,65504,65504,TRUE,FALSE,65558,513,65548,513,65540,513,"xid 2 pages; data 10 bytes (exact fit) [txn]"
+143,"L",2,16,0,16,1,10,10,65505,65505,TRUE,FALSE,65559,513,65549,513,65541,513,"xid 2 pages + 1 byte; data 10 bytes (exact fit) [txn]"
+144,"L",4,16,0,16,-1,10,10,131039,131039,TRUE,FALSE,131093,1025,131083,1025,131075,1025,"xid 4 pages – 1 byte; data 10 bytes (exact fit) [txn]"
+145,"L",4,16,0,16,0,10,10,131040,131040,TRUE,FALSE,131094,1025,131084,1025,131076,1025,"xid 4 pages; data 10 bytes (exact fit) [txn]"
+146,"L",4,16,0,16,1,10,10,131041,131041,TRUE,FALSE,131095,1025,131085,1025,131077,1025,"xid 4 pages + 1 byte; data 10 bytes (exact fit) [txn]"
+147,"L",3.5,16,0,16,0,10,10,114656,114656,TRUE,FALSE,114710,897,114700,897,114692,897,"xid 3.5 pages; data 10 bytes (exact fit) [txn]"
+148,"L",3.5,16,0,16,1,10,10,114657,114657,TRUE,FALSE,114711,897,114701,897,114693,897,"xid 3.5 pages + 1 byte; data 10 bytes (exact fit) [txn]"
+,,,,,,,,,,,,,,,,,,,
+"Large (multi-megabyte) messages - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,,,,,,,,,,,,,,
+149,"L",1,32,0,32,0,1572820,1572820,0,0,FALSE,FALSE,1572864,12288,0,0,0,0,"48 pages = 1 file exactly"
+150,"L",1,32,0,32,1,1572821,1572821,0,0,FALSE,FALSE,1572865,12289,0,0,0,0,"48 pages + 1 byte"
+151,"L",1,32,0,32,0,1605588,1605588,0,0,FALSE,FALSE,1605632,12544,0,0,0,0,"49 pages = 1 file + 1 page"
+152,"L",1,32,0,32,1,1589205,1589205,0,0,FALSE,FALSE,1589249,12417,0,0,0,0,"49 pages + 1 byte = 1 file + 1 page + 1 byte"
+153,"L",1,32,0,32,0,1572565,1572565,255,255,FALSE,FALSE,1572864,12288,0,0,0,0,"48 pages = 1 file exactly [txn]"
+154,"L",1,32,0,32,1,1572566,1572566,255,255,FALSE,FALSE,1572865,12289,0,0,0,0,"48 pages + 1 byte [txn]"
+155,"L",1,32,0,32,0,1588949,1588949,255,255,FALSE,FALSE,1589248,12416,0,0,0,0,"49 pages = 1 file + 1 page [txn]"
+156,"L",1,32,0,32,1,1584854,1584854,255,255,FALSE,FALSE,1585153,12385,0,0,0,0,"49 pages + 1 byte = 1 file + 1 page + 1 byte [txn]"
+157,"L",1,32,0,32,0,1572692,1572692,0,0,TRUE,FALSE,1572736,12287,32,1,0,0,"48 pages incl deq = 1 file exactly [deq]"
+158,"L",1,32,0,32,1,1572693,1572693,0,0,TRUE,FALSE,1572737,12288,32,1,0,0,"48 pages incl deq + 1 byte [deq]"
+159,"L",1,32,0,32,0,1595220,1595220,0,0,TRUE,FALSE,1595264,12463,32,1,0,0,"49 pages incl deq = 1 file + 1 page [deq]"
+160,"L",1,32,0,32,1,1589077,1589077,0,0,TRUE,FALSE,1589121,12416,32,1,0,0,"49 pages incl deq + 1 byte = 1 file + 1 page + 1 byte [deq]"
+161,"L",1,32,0,32,0,1571797,1571797,255,255,TRUE,FALSE,1572096,12282,299,3,291,3,"48 pages incl deq & txn = 1 file exactly [deq txn]"
+162,"L",1,32,0,32,1,1571798,1571798,255,255,TRUE,FALSE,1572097,12283,299,3,291,3,"48 pages incl deq & txn + 1 byte [deq txn]"
+163,"L",1,32,0,32,0,1571797,1571797,255,255,TRUE,FALSE,1572096,12282,299,3,291,3,"49 pages incl deq & txn = 1 file + 1 page [deq txn]"
+164,"L",1,32,0,32,1,1571798,1571798,255,255,TRUE,FALSE,1572097,12283,299,3,291,3,"49 pages incl deq & txn + 1 byte = 1 file + 1 page + 1 byte [deq txn]"
+165,"L",2,16,0,16,0,3145684,3145684,0,0,FALSE,FALSE,3145728,24576,0,0,0,0,"96 pages = 2 files exactly"
+166,"L",2,16,0,16,1,3145685,3145685,0,0,FALSE,FALSE,3145729,24577,0,0,0,0,"96 pages + 1 byte"
+167,"L",2,16,0,16,0,3146708,3146708,0,0,FALSE,FALSE,3146752,24584,0,0,0,0,"97 pages = 2 files + 1 page"
+168,"L",2,16,0,16,1,3145685,3145685,0,0,FALSE,FALSE,3145729,24577,0,0,0,0,"97 pages + 1 byte = 2 files + 1 page + 1 byte"
+169,"L",2,16,0,16,0,3145429,3145429,255,255,FALSE,FALSE,3145728,24576,0,0,0,0,"96 pages = 2 files exactly [txn]"
+170,"L",2,16,0,16,1,3145430,3145430,255,255,FALSE,FALSE,3145729,24577,0,0,0,0,"96 pages + 1 byte [txn]"
+171,"L",2,16,0,16,0,3145429,3145429,255,255,FALSE,FALSE,3145728,24576,0,0,0,0,"97 pages = 2 files + 1 page [txn]"
+172,"L",2,16,0,16,1,3145430,3145430,255,255,FALSE,FALSE,3145729,24577,0,0,0,0,"97 pages + 1 byte = 2 files + 1 page + 1 byte [txn]"
+173,"L",2,16,0,16,0,3145556,3145556,0,0,TRUE,FALSE,3145600,24575,32,1,0,0,"96 pages incl deq = 2 files exactly [deq]"
+174,"L",2,16,0,16,1,3145557,3145557,0,0,TRUE,FALSE,3145601,24576,32,1,0,0,"96 pages incl deq + 1 byte [deq]"
+175,"L",2,16,0,16,0,3145556,3145556,0,0,TRUE,FALSE,3145600,24575,32,1,0,0,"97 pages incl deq = 2 files + 1 page [deq]"
+176,"L",2,16,0,16,1,3145557,3145557,0,0,TRUE,FALSE,3145601,24576,32,1,0,0,"97 pages incl deq + 1 byte = 2 files + 1 page + 1 byte [deq]"
+177,"L",2,16,0,16,0,3144661,3144661,255,255,TRUE,FALSE,3144960,24570,299,3,291,3,"96 pages incl deq & txn = 2 files exactly [deq txn]"
+178,"L",2,16,0,16,1,3144662,3144662,255,255,TRUE,FALSE,3144961,24571,299,3,291,3,"96 pages incl deq & txn + 1 byte [deq txn]"
+179,"L",2,16,0,16,0,3144661,3144661,255,255,TRUE,FALSE,3144960,24570,299,3,291,3,"97 pages incl deq & txn = 2 files + 1 page [deq txn]"
+180,"L",2,16,0,16,1,3144662,3144662,255,255,TRUE,FALSE,3144961,24571,299,3,291,3,"97 pages incl deq & txn + 1 byte = 2 files + 1 page + 1 byte [deq txn]"
+181,"L",4,8,0,8,0,6291412,6291412,0,0,FALSE,FALSE,6291456,49152,0,0,0,0,"192 pages = 2 files exactly"
+182,"L",4,8,0,8,1,6291413,6291413,0,0,FALSE,FALSE,6291457,49153,0,0,0,0,"192 pages + 1 byte"
+183,"L",4,8,0,8,0,6291412,6291412,0,0,FALSE,FALSE,6291456,49152,0,0,0,0,"193 pages = 2 files + 1 page"
+184,"L",4,8,0,8,1,6291413,6291413,0,0,FALSE,FALSE,6291457,49153,0,0,0,0,"193 pages + 1 byte = 2 files + 1 page + 1 byte"
+185,"L",4,8,0,8,0,6291157,6291157,255,255,FALSE,FALSE,6291456,49152,0,0,0,0,"192 pages = 2 files exactly [txn]"
+186,"L",4,8,0,8,1,6291158,6291158,255,255,FALSE,FALSE,6291457,49153,0,0,0,0,"192 pages + 1 byte [txn]"
+187,"L",4,8,0,8,0,6291157,6291157,255,255,FALSE,FALSE,6291456,49152,0,0,0,0,"193 pages = 2 files + 1 page [txn]"
+188,"L",4,8,0,8,1,6291158,6291158,255,255,FALSE,FALSE,6291457,49153,0,0,0,0,"193 pages + 1 byte = 2 files + 1 page + 1 byte [txn]"
+189,"L",4,8,0,8,0,6291284,6291284,0,0,TRUE,FALSE,6291328,49151,32,1,0,0,"192 pages incl deq = 2 files exactly [deq]"
+190,"L",4,8,0,8,1,6291285,6291285,0,0,TRUE,FALSE,6291329,49152,32,1,0,0,"192 pages incl deq + 1 byte [deq]"
+191,"L",4,8,0,8,0,6291284,6291284,0,0,TRUE,FALSE,6291328,49151,32,1,0,0,"193 pages incl deq = 2 files + 1 page [deq]"
+192,"L",4,8,0,8,1,6291285,6291285,0,0,TRUE,FALSE,6291329,49152,32,1,0,0,"193 pages incl deq + 1 byte = 2 files + 1 page + 1 byte [deq]"
+193,"L",4,8,0,8,0,6290389,6290389,255,255,TRUE,FALSE,6290688,49146,299,3,291,3,"192 pages incl deq & txn = 2 files exactly [deq txn]"
+194,"L",4,8,0,8,1,6290390,6290390,255,255,TRUE,FALSE,6290689,49147,299,3,291,3,"192 pages incl deq & txn + 1 byte [deq txn]"
+195,"L",4,8,0,8,0,6290389,6290389,255,255,TRUE,FALSE,6290688,49146,299,3,291,3,"193 pages incl deq & txn = 2 files + 1 page [deq txn]"
+196,"L",4,8,0,8,1,6290390,6290390,255,255,TRUE,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",,,,,,,,,,,,,,,,,,,
+197,"M",1,5000000,0,5000000,0,0,84,0,0,FALSE,FALSE,128,1,0,0,0,0,"1 dblk max"
+198,"M",3,3000000,0,3000000,0,0,340,0,0,FALSE,FALSE,384,3,0,0,0,0,"3 dblks max"
+199,"M",10,1600000,0,1600000,0,0,1236,0,0,FALSE,FALSE,1280,10,0,0,0,0,"10 dblks max"
+200,"M",30,6000000,0,6000000,0,0,3796,0,0,FALSE,FALSE,3840,30,0,0,0,0,"30 dblks max"
+201,"M",100,200000,0,200000,0,0,12756,0,0,FALSE,FALSE,12800,100,0,0,0,0,"100 dblks max"
+202,"M",300,60000,0,60000,0,0,38356,0,0,FALSE,FALSE,38400,300,0,0,0,0,"300 dblks max"
+203,"M",1000,20000,0,20000,0,0,127956,0,0,FALSE,FALSE,128000,1000,0,0,0,0,"1000 dblks max"
+204,"M",1,5000000,0,5000000,0,0,100,1,100,FALSE,FALSE,244,2,0,0,0,0,"100 bytes xid max + 100 bytes data max [txn]"
+205,"M",3,3000000,0,3000000,0,0,300,1,300,FALSE,FALSE,644,6,0,0,0,0,"300 bytes xid max + 300 bytes data max [txn]"
+206,"M",10,1600000,0,1600000,0,0,1000,1,1000,FALSE,FALSE,2044,16,0,0,0,0,"1000 bytes xid max + 1000 bytes data max [txn]"
+207,"M",30,6000000,0,6000000,0,0,3000,1,3000,FALSE,FALSE,6044,48,0,0,0,0,"3000 bytes xid max + 3000 bytes data max [txn]"
+208,"M",100,200000,0,200000,0,0,10000,1,10000,FALSE,FALSE,20044,157,0,0,0,0,"10000 bytes xid max + 10000 bytes data max [txn]"
+209,"M",300,60000,0,60000,0,0,30000,1,30000,FALSE,FALSE,60044,470,0,0,0,0,"30000 bytes xid max + 30000 bytes data max [txn]"
+210,"M",1000,20000,0,20000,0,0,100000,1,100000,FALSE,FALSE,200044,1563,0,0,0,0,"100000 bytes xid max + 100000 bytes data max [txn]"
+211,"M",1,5000000,0,5000000,0,0,84,0,0,TRUE,FALSE,128,1,32,1,0,0,"1 dblk max [deq]"
+212,"M",3,3000000,0,3000000,0,0,340,0,0,TRUE,FALSE,384,3,32,1,0,0,"3 dblks max [deq]"
+213,"M",10,1600000,0,1600000,0,0,1236,0,0,TRUE,FALSE,1280,10,32,1,0,0,"10 dblks max [deq]"
+214,"M",30,6000000,0,6000000,0,0,3796,0,0,TRUE,FALSE,3840,30,32,1,0,0,"30 dblks max [deq]"
+215,"M",100,200000,0,200000,0,0,12756,0,0,TRUE,FALSE,12800,100,32,1,0,0,"100 dblks max [deq]"
+216,"M",300,60000,0,60000,0,0,38356,0,0,TRUE,FALSE,38400,300,32,1,0,0,"300 dblks max [deq]"
+217,"M",1000,20000,0,20000,0,0,127956,0,0,TRUE,FALSE,128000,1000,32,1,0,0,"1000 dblks max [deq]"
+218,"M",1,5000000,0,5000000,0,0,100,1,100,TRUE,FALSE,244,2,144,2,136,2,"100 bytes xid max + 100 bytes data max [deq txn]"
+219,"M",3,3000000,0,3000000,0,0,300,1,300,TRUE,FALSE,644,6,344,3,336,3,"300 bytes xid max + 300 bytes data max [deq txn]"
+220,"M",10,1600000,0,1600000,0,0,1000,1,1000,TRUE,FALSE,2044,16,1044,9,1036,9,"1000 bytes xid max + 1000 bytes data max [deq txn]"
+221,"M",30,6000000,0,6000000,0,0,3000,1,3000,TRUE,FALSE,6044,48,3044,24,3036,24,"3000 bytes xid max + 3000 bytes data max [deq txn]"
+222,"M",100,200000,0,200000,0,0,10000,1,10000,TRUE,FALSE,20044,157,10044,79,10036,79,"10000 bytes xid max + 10000 bytes data max [deq txn]"
+223,"M",300,60000,0,60000,0,0,30000,1,30000,TRUE,FALSE,60044,470,30044,235,30036,235,"30000 bytes xid max + 30000 bytes data max [deq txn]"
+224,"M",1000,20000,0,20000,0,0,100000,1,100000,TRUE,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)",,,,,,,,,,,,,,,,,,,
+198,"M",1,10000000,0,10000000,0,212,212,0,0,FALSE,FALSE,256,2,0,0,0,0,"212 bytes data (2 dblks enq)"
+199,"M",1,10000000,0,10000000,0,212,212,256,256,FALSE,FALSE,512,4,0,0,0,0,"212 bytes data + 256 bytes xid (4 dblks enq)"
+200,"M",1,10000000,0,10000000,0,212,212,0,0,TRUE,FALSE,256,2,32,1,0,0,"212 bytes data (2 dblks enq + 1 dblk deq)"
+201,"M",1,10000000,0,10000000,0,212,212,256,256,TRUE,FALSE,512,4,300,3,292,3,"212 bytes data + 256 bytes xid (4 dblks enq + 3 dblks deq + 3 dblks txn)"
[View Less]
17 years, 3 months
rhmessaging commits: r964 - store/trunk/cpp/lib.
by rhmessaging-commits@lists.jboss.org
Author: cctrieloff
Date: 2007-10-04 15:54:30 -0400 (Thu, 04 Oct 2007)
New Revision: 964
Modified:
store/trunk/cpp/lib/BdbMessageStore.cpp
store/trunk/cpp/lib/TxnCtxt.h
Log:
code clean up for async tx / dtx
Modified: store/trunk/cpp/lib/BdbMessageStore.cpp
===================================================================
--- store/trunk/cpp/lib/BdbMessageStore.cpp 2007-10-04 19:52:33 UTC (rev 963)
+++ store/trunk/cpp/lib/BdbMessageStore.cpp 2007-10-04 19:54:30 UTC (rev 964)
@@ -391,7 +…
[View More]391,7 @@
journal::data_tok dtokp;
size_t readSize = 0;
// char** buff = 0;
- unsigned aio_sleep_cnt = 0;
+// unsigned aio_sleep_cnt = 0;
unsigned msg_count=0;
bool read = true;
@@ -446,10 +446,10 @@
break;
}
case rhm::journal::RHM_IORES_AIO_WAIT:
- if (++aio_sleep_cnt > MAX_AIO_SLEEPS)
+/* if (++aio_sleep_cnt > MAX_AIO_SLEEPS)
{
THROW_STORE_EXCEPTION("Store error, disk time out on recover for:" + queue->getName());
- }
+ }*/
::usleep(AIO_SLEEP_TIME);
break;
case rhm::journal::RHM_IORES_EMPTY:
@@ -792,7 +792,7 @@
dtokp->setSourceMessage (&message);
dtokp->set_rid(message.getPersistenceId()); // set the messageID into the Journal header (record-id)
- unsigned aio_sleep_cnt = 0;
+// unsigned aio_sleep_cnt = 0;
bool written = false;
while (!written)
{
@@ -805,13 +805,12 @@
written = true;
break;
case rhm::journal::RHM_IORES_AIO_WAIT:
- if (aio_sleep_cnt >= MAX_AIO_SLEEPS){
+/* if (++aio_sleep_cnt >= MAX_AIO_SLEEPS){
delete dtokp;
THROW_STORE_EXCEPTION("Error storing message -- AIO timeout for: " + queue->getName());
- }
- usleep(AIO_SLEEP_TIME);
+ }*/
+ usleep(AIO_SLEEP_TIME); // TODO move sleep to wait for IO in get events
jc->get_wr_events();
- aio_sleep_cnt++;
break;
case rhm::journal::RHM_IORES_FULL:
delete dtokp;
@@ -892,7 +891,7 @@
void BdbMessageStore::async_dequeue(TransactionContext* ctxt, PersistableMessage& msg, const PersistableQueue& queue)
{
- unsigned aio_sleep_cnt = 0;
+// unsigned aio_sleep_cnt = 0;
bool written = false;
journal::data_tok* ddtokp = new journal::data_tok;
ddtokp->setSourceMessage (&msg);
@@ -923,13 +922,12 @@
written = true;
break;
case rhm::journal::RHM_IORES_AIO_WAIT:
- if (aio_sleep_cnt >= MAX_AIO_SLEEPS){
+/* if (++aio_sleep_cnt >= MAX_AIO_SLEEPS){
delete ddtokp;
THROW_STORE_EXCEPTION("Error dequeuing message -- AIO timeout for: " + queue.getName());
- }
+ } */
+ usleep(AIO_SLEEP_TIME); // TODO add sleep time to get events call as option
jc->get_wr_events();
- usleep(AIO_SLEEP_TIME);
- aio_sleep_cnt++;
break;
default:
delete ddtokp;
@@ -1017,7 +1015,7 @@
auto_ptr<TransactionContext> BdbMessageStore::begin()
{
- TxnCtxt* txn(new TxnCtxt());
+ TxnCtxt* txn(new TxnCtxt(true));
txn->begin(env);
return auto_ptr<TransactionContext>(txn);
}
Modified: store/trunk/cpp/lib/TxnCtxt.h
===================================================================
--- store/trunk/cpp/lib/TxnCtxt.h 2007-10-04 19:52:33 UTC (rev 963)
+++ store/trunk/cpp/lib/TxnCtxt.h 2007-10-04 19:54:30 UTC (rev 964)
@@ -47,6 +47,7 @@
ipqdef impactedQueues; // list of Queues used in the txn
static unsigned int count;
mutable qpid::sys::Mutex Lock;
+ bool loggedtx;
unsigned int getCount() {
qpid::sys::Mutex::ScopedLock locker(Lock);
@@ -73,8 +74,8 @@
public:
- TxnCtxt() : txn(0) {
- tid = "rhm-tid" + getCount();
+ TxnCtxt(bool _loggedtx=false) : loggedtx(_loggedtx), txn(0) {
+ if (loggedtx) tid = "rhm-tid" + getCount();
}
/**
@@ -83,15 +84,12 @@
*@return if the data sucessfully synced.
*/
void sync(){
- bool allWritten = true;
+ bool allWritten = false;
bool firstloop = true;
- unsigned aio_sleep_cnt = 0;
- while (!allWritten){
- if (!firstloop) ::usleep(AIO_SLEEP_TIME);
+ while (loggedtx && !allWritten){
+ if (!firstloop) ::usleep(AIO_SLEEP_TIME); // move this into the get events call aiolib..
allWritten = true;
- unsigned qcnt = 0;
for (TxnCtxt::ipqdef::iterator i = impactedQueues.begin(); i != impactedQueues.end(); i++) {
- qcnt ++;
journal::jcntl* jc = static_cast<journal::jcntl*>((*i)->getExternalQueueStore());
if (jc && !(jc->is_txn_synced(getXid())))
{
@@ -102,10 +100,6 @@
}
}
firstloop = false;
- if (++aio_sleep_cnt > MAX_AIO_SLEEPS*qcnt)
- {
- THROW_STORE_EXCEPTION("Store error, disk time out on sync for:" + getXid());
- }
}
}
[View Less]
17 years, 3 months
rhmessaging commits: r963 - store/trunk/cpp/lib/jrnl.
by rhmessaging-commits@lists.jboss.org
Author: cctrieloff
Date: 2007-10-04 15:52:33 -0400 (Thu, 04 Oct 2007)
New Revision: 963
Modified:
store/trunk/cpp/lib/jrnl/jcntl.cpp
Log:
correct scope of txn_sync
Modified: store/trunk/cpp/lib/jrnl/jcntl.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/jcntl.cpp 2007-10-04 14:50:53 UTC (rev 962)
+++ store/trunk/cpp/lib/jrnl/jcntl.cpp 2007-10-04 19:52:33 UTC (rev 963)
@@ -257,7 +257,7 @@
}
const bool
-is_txn_synced(const std::string&…
[View More]amp; /*xid*/) throw (jexception)
+jcntl::is_txn_synced(const std::string& /*xid*/) throw (jexception)
{
return RHM_IORES_NOTIMPL;
}
[View Less]
17 years, 3 months
rhmessaging commits: r962 - in store/trunk/cpp: etc and 1 other directory.
by rhmessaging-commits@lists.jboss.org
Author: nunofsantos
Date: 2007-10-04 10:50:53 -0400 (Thu, 04 Oct 2007)
New Revision: 962
Modified:
store/trunk/cpp/Makefile.am
store/trunk/cpp/etc/rhmd
store/trunk/cpp/rhm.spec.in
Log:
specfile changes to support init.d script
Modified: store/trunk/cpp/Makefile.am
===================================================================
--- store/trunk/cpp/Makefile.am 2007-10-04 14:12:07 UTC (rev 961)
+++ store/trunk/cpp/Makefile.am 2007-10-04 14:50:53 UTC (rev 962)
@@ -1,7 +1,7 @@
…
[View More]AUTOMAKE_OPTIONS = 1.9.6 foreign
ACLOCAL_AMFLAGS = -I m4
-EXTRA_DIST = README
+EXTRA_DIST = README etc/rhmd
SUBDIRS = lib tests docs
@@ -12,7 +12,7 @@
#
# Build RPMs from the distribution tarball.
#
-RPMDIRS=rpm/BUILD rpm/RPMS rpm/SPECS rpm/SRPMS
+RPMDIRS=rpm/BUILD rpm/RPMS rpm/SPECS rpm/SRPMS
RPMMACROS=--define "_topdir @abs_builddir@/rpm" --define "_sourcedir @abs_builddir@"
# Override this variable e.g. with -bs to produce srpm only
RPMOPTS=-ba
Modified: store/trunk/cpp/etc/rhmd
===================================================================
--- store/trunk/cpp/etc/rhmd 2007-10-04 14:12:07 UTC (rev 961)
+++ store/trunk/cpp/etc/rhmd 2007-10-04 14:50:53 UTC (rev 962)
@@ -17,6 +17,8 @@
# description: Qpidd is an AMQP broker. It receives, stores, routes and forwards messages using the AMQP protocol.
# processname: qpidd
+lockfile=/var/lock/subsys/rhmd
+
LIBBDBSTORE=libbdbstore.so.0
# See how we were called.
Modified: store/trunk/cpp/rhm.spec.in
===================================================================
--- store/trunk/cpp/rhm.spec.in 2007-10-04 14:12:07 UTC (rev 961)
+++ store/trunk/cpp/rhm.spec.in 2007-10-04 14:50:53 UTC (rev 962)
@@ -3,7 +3,7 @@
#
Name: rhm
Version: @VERSION@
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: Red Hat extensions to the Qpid messaging system
Group: System Environment/Libraries
License: LGPL
@@ -37,6 +37,7 @@
%install
rm -rf %{buildroot}
make install DESTDIR=%{buildroot}
+install -Dp -m0755 etc/rhmd %{buildroot}%{_initrddir}/rhmd
rm -f %{buildroot}%_libdir/*.a
rm -f %{buildroot}%_libdir/*.la
rm -f %{buildroot}%_libdir/*.so
@@ -52,12 +53,30 @@
%doc README COPYING
%_libdir/libbdbstore.so.0
%_libdir/libbdbstore.so.0.1.0
+%{_initrddir}/rhmd
-%post -p /sbin/ldconfig
+%post
+# This adds the proper /etc/rc*.d links for the script
+/sbin/chkconfig --add qpidd
+/sbin/ldconfig
-%postun -p /sbin/ldconfig
+%preun
+# Check that this is actual deinstallation, not just removing for upgrade.
+if [ $1 = 0 ]; then
+ /sbin/service rhmd stop >/dev/null 2>&1 || :
+ /sbin/chkconfig --del rhmd
+fi
+%postun
+if [ "$1" -ge "1" ]; then
+ /sbin/service rhmd condrestart >/dev/null 2>&1 || :
+fi
+/sbin/ldconfig
+
+
%changelog
+* Thu Oct 04 2007 Nuno Santos <nsantos(a)redhat.com> - 0.2-2
+- Add rhmd init script
* Wed Jul 25 2007 Nuno Santos <nsantos(a)redhat.com> - 0.2-1
- Disable rpath; bump release to match numbers of qpidc trunk packages
* Tue Apr 17 2007 Alan Conway <aconway(a)redhat.com> - 0.1-3
[View Less]
17 years, 3 months
rhmessaging commits: r961 - in store/trunk/cpp: etc and 1 other directory.
by rhmessaging-commits@lists.jboss.org
Author: nunofsantos
Date: 2007-10-04 10:12:07 -0400 (Thu, 04 Oct 2007)
New Revision: 961
Added:
store/trunk/cpp/etc/
store/trunk/cpp/etc/rhmd
Log:
add init script for rhmd, which calls qpidd with persistent storage enabled
Added: store/trunk/cpp/etc/rhmd
===================================================================
--- store/trunk/cpp/etc/rhmd (rev 0)
+++ store/trunk/cpp/etc/rhmd 2007-10-04 14:12:07 UTC (rev 961)
@@ -0,0 +1,33 @@
+#!/bin/bash
+#
+# rhmd …
[View More] Startup script for the Qpid messaging daemon with bdbstore enabled
+#
+
+### BEGIN INIT INFO
+# Provides: qpidd
+# Required-Start: $local_fs
+# Required-Stop: $local_fs
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: start or stop qpidd with persistent store
+# Description: Qpidd is an AMQP broker. It receives, stores, routes and forwards messages using the AMQP protocol.
+### END INIT INFO
+
+# chkconfig: - 85 15
+# description: Qpidd is an AMQP broker. It receives, stores, routes and forwards messages using the AMQP protocol.
+# processname: qpidd
+
+LIBBDBSTORE=libbdbstore.so.0
+
+# See how we were called.
+case "$1" in
+ start|stop|restart|reload|status)
+ QPIDD_OPTIONS="-s $LIBBDBSTORE"
+ . /etc/rc.d/init.d/qpidd
+ exit $?
+ ;;
+ *)
+ echo 1>&2 $"Usage: $0 {start|stop|restart|condrestart|status}"
+ exit 1
+ ;;
+esac
Property changes on: store/trunk/cpp/etc/rhmd
___________________________________________________________________
Name: svn:executable
+ *
[View Less]
17 years, 3 months
rhmessaging commits: r960 - in store/trunk/cpp: lib/jrnl and 1 other directories.
by rhmessaging-commits@lists.jboss.org
Author: kpvdr
Date: 2007-10-02 16:45:10 -0400 (Tue, 02 Oct 2007)
New Revision: 960
Added:
store/trunk/cpp/lib/jrnl/txn_rec.cpp
store/trunk/cpp/lib/jrnl/txn_rec.hpp
Removed:
store/trunk/cpp/lib/jrnl/dtx_rec.cpp
store/trunk/cpp/lib/jrnl/dtx_rec.hpp
Modified:
store/trunk/cpp/lib/BdbMessageStore.cpp
store/trunk/cpp/lib/Makefile.am
store/trunk/cpp/lib/TxnCtxt.h
store/trunk/cpp/lib/jrnl/deq_rec.cpp
store/trunk/cpp/lib/jrnl/enq_rec.cpp
store/trunk/cpp/lib/jrnl/enq_rec.…
[View More]hpp
store/trunk/cpp/lib/jrnl/file_hdr.cpp
store/trunk/cpp/lib/jrnl/file_hdr.hpp
store/trunk/cpp/lib/jrnl/jcntl.cpp
store/trunk/cpp/lib/jrnl/jcntl.hpp
store/trunk/cpp/lib/jrnl/pmgr.cpp
store/trunk/cpp/lib/jrnl/pmgr.hpp
store/trunk/cpp/lib/jrnl/rmgr.cpp
store/trunk/cpp/lib/jrnl/rmgr.hpp
store/trunk/cpp/lib/jrnl/wmgr.cpp
store/trunk/cpp/lib/jrnl/wmgr.hpp
store/trunk/cpp/tests/jrnl/JournalSystemTests.cpp
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/tests.ods
store/trunk/cpp/tests/jrnl/wtests.csv
Log:
Wired dtx encoding for enqueue records, other fixes and cleanups
Modified: store/trunk/cpp/lib/BdbMessageStore.cpp
===================================================================
--- store/trunk/cpp/lib/BdbMessageStore.cpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/lib/BdbMessageStore.cpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -910,7 +910,7 @@
{
rhm::journal::iores dres;
try {
- dres = jc->dequeue_tx_data_record(ddtokp, tid);
+ dres = jc->dequeue_txn_data_record(ddtokp, tid);
} catch (rhm::journal::jexception& e) {
std::string str;
delete ddtokp;
Modified: store/trunk/cpp/lib/Makefile.am
===================================================================
--- store/trunk/cpp/lib/Makefile.am 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/lib/Makefile.am 2007-10-02 20:45:10 UTC (rev 960)
@@ -35,7 +35,6 @@
TxnCtxt.h \
jrnl/data_tok.cpp \
jrnl/deq_rec.cpp \
- jrnl/dtx_rec.cpp \
jrnl/enq_map.cpp \
jrnl/enq_rec.cpp \
jrnl/file_hdr.cpp \
@@ -50,12 +49,12 @@
jrnl/pmgr.cpp \
jrnl/rmgr.cpp \
jrnl/rrfc.cpp \
+ jrnl/txn_rec.cpp \
jrnl/wmgr.cpp \
jrnl/wrfc.cpp \
jrnl/aio_cb.hpp \
jrnl/data_tok.hpp \
jrnl/deq_rec.hpp \
- jrnl/dtx_rec.hpp \
jrnl/enq_map.hpp \
jrnl/enq_rec.hpp \
jrnl/file_hdr.hpp \
@@ -72,6 +71,7 @@
jrnl/rcvdat.hpp \
jrnl/rmgr.hpp \
jrnl/rrfc.hpp \
+ jrnl/txn_rec.hpp \
jrnl/wmgr.hpp \
jrnl/wrfc.hpp
Modified: store/trunk/cpp/lib/TxnCtxt.h
===================================================================
--- store/trunk/cpp/lib/TxnCtxt.h 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/lib/TxnCtxt.h 2007-10-02 20:45:10 UTC (rev 960)
@@ -63,9 +63,9 @@
journal::jcntl* jc = static_cast<journal::jcntl*>((*i)->getExternalQueueStore());
if (jc) /* if using journal */
if (commit)
- jc->commit_dtx(getXid());
+ jc->txn_commit(getXid());
else
- jc->abort_dtx(getXid());
+ jc->txn_abort(getXid());
}
deleteXidRecord();
sync();
@@ -93,7 +93,7 @@
for (TxnCtxt::ipqdef::iterator i = impactedQueues.begin(); i != impactedQueues.end(); i++) {
qcnt ++;
journal::jcntl* jc = static_cast<journal::jcntl*>((*i)->getExternalQueueStore());
- if (jc && !(jc->is_dtx_synced(getXid())))
+ if (jc && !(jc->is_txn_synced(getXid())))
{
if (firstloop)
jc->flush();
Modified: store/trunk/cpp/lib/jrnl/deq_rec.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/deq_rec.cpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/lib/jrnl/deq_rec.cpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -43,19 +43,19 @@
{
deq_rec::deq_rec():
- _deq_hdr(RHM_JDAT_DEQ_MAGIC, 0, 0, 0, RHM_JDAT_VERSION),
+ _deq_hdr(RHM_JDAT_DEQ_MAGIC, RHM_JDAT_VERSION, 0, 0, 0, 0),
_xid(),
_deq_tail()
{}
deq_rec::deq_rec(const u_int64_t rid, const u_int64_t drid):
- _deq_hdr(RHM_JDAT_DEQ_MAGIC, rid, drid, 0, RHM_JDAT_VERSION),
+ _deq_hdr(RHM_JDAT_DEQ_MAGIC, RHM_JDAT_VERSION, 0, rid, drid, 0),
_xid(),
_deq_tail(_deq_hdr._hdr)
{}
deq_rec::deq_rec(const u_int64_t rid, const u_int64_t drid, const std::string& xid):
- _deq_hdr(RHM_JDAT_DEQ_MAGIC, rid, drid, xid.size(), RHM_JDAT_VERSION),
+ _deq_hdr(RHM_JDAT_DEQ_MAGIC, RHM_JDAT_VERSION, 0, rid, drid, xid.size()),
_xid(xid),
_deq_tail(_deq_hdr._hdr)
{}
Deleted: store/trunk/cpp/lib/jrnl/dtx_rec.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/dtx_rec.cpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/lib/jrnl/dtx_rec.cpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -1,361 +0,0 @@
-/**
-* \file dtx_rec.cpp
-*
-* Red Hat Messaging - Message Journal
-*
-* This file contains the code for the rhm::journal::dtx_rec (journal dequeue
-* record) class. See comments in file dtx_rec.hpp for details.
-*
-* \author Kim van der Riet
-*
-* Copyright 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 <jrnl/dtx_rec.hpp>
-
-#include <assert.h>
-#include <iomanip>
-#include <sstream>
-#include <jrnl/jerrno.hpp>
-
-namespace rhm
-{
-namespace journal
-{
-
-dtx_rec::dtx_rec():
- _dtx_hdr(),
- _xid(),
- _dtx_tail()
-{}
-
-dtx_rec::dtx_rec(const u_int32_t magic, const u_int64_t rid):
- _dtx_hdr(magic, rid, 0, RHM_JDAT_VERSION),
- _xid(),
- _dtx_tail(_dtx_hdr._hdr)
-{}
-
-dtx_rec::dtx_rec(const u_int32_t magic, const u_int64_t rid, const std::string& xid):
- _dtx_hdr(magic, rid, xid.size(), RHM_JDAT_VERSION),
- _xid(xid),
- _dtx_tail(_dtx_hdr._hdr)
-{}
-
-dtx_rec::~dtx_rec()
-{}
-
-void
-dtx_rec::reset(const u_int64_t rid)
-{
- _dtx_hdr._hdr._rid = rid;
- _dtx_hdr._xidsize = 0;
- _dtx_tail._rid = rid;
-}
-
-void
-dtx_rec::reset(const u_int64_t rid, const std::string& xid)
-{
- _dtx_hdr._hdr._rid = rid;
- _dtx_hdr._xidsize = xid.size();
- _dtx_tail._rid = rid;
-}
-
-u_int32_t
-dtx_rec::encode(void* wptr, u_int32_t rec_offs_dblks, u_int32_t max_size_dblks) throw (jexception)
-{
- assert(wptr != NULL);
- assert(max_size_dblks > 0);
- assert(_xid.size() == _dtx_hdr._xidsize);
- assert(_dtx_hdr._xidsize > 0);
-
- size_t rec_offs = rec_offs_dblks * JRNL_DBLK_SIZE;
- size_t rem = max_size_dblks * JRNL_DBLK_SIZE;
- size_t wr_cnt = 0;
- if (rec_offs_dblks) // Continuation of split dequeue record (over 2 or more pages)
- {
- if (size_dblks(rec_size()) - rec_offs_dblks > max_size_dblks) // Further split required
- {
- rec_offs -= sizeof(_dtx_hdr);
- size_t wsize = _dtx_hdr._xidsize > rec_offs ? _dtx_hdr._xidsize - rec_offs : 0;
- size_t wsize2 = wsize;
- if (wsize)
- {
- if (wsize > rem)
- wsize = rem;
- ::memcpy(wptr, (const char*)_xid.c_str() + rec_offs, wsize);
- wr_cnt += wsize;
- rem -= wsize;
- }
- rec_offs -= _dtx_hdr._xidsize - wsize2;
- if (rem)
- {
- wsize = sizeof(_dtx_tail) > rec_offs ? sizeof(_dtx_tail) - rec_offs : 0;
- wsize2 = wsize;
- if (wsize)
- {
- if (wsize > rem)
- wsize = rem;
- ::memcpy((char*)wptr + wr_cnt, (char*)&_dtx_tail + rec_offs, wsize);
- wr_cnt += wsize;
- rem -= wsize;
- }
- rec_offs -= sizeof(_dtx_tail) - wsize2;
- }
- assert(rem == 0);
- assert(rec_offs == 0);
- }
- else // No further split required
- {
- rec_offs -= sizeof(_dtx_hdr);
- size_t wsize = _dtx_hdr._xidsize > rec_offs ? _dtx_hdr._xidsize - rec_offs : 0;
- if (wsize)
- {
- ::memcpy(wptr, _xid.c_str() + rec_offs, wsize);
- wr_cnt += wsize;
- }
- rec_offs -= _dtx_hdr._xidsize - wsize;
- wsize = sizeof(_dtx_tail) > rec_offs ? sizeof(_dtx_tail) - rec_offs : 0;
- if (wsize)
- {
- ::memcpy((char*)wptr + wr_cnt, (char*)&_dtx_tail + rec_offs, wsize);
- wr_cnt += wsize;
-#ifdef RHM_CLEAN
- ::memset((char*)wptr + wr_cnt, RHM_CLEAN_CHAR,
- (size_dblks(rec_size()) * JRNL_DBLK_SIZE) -
- (rec_offs_dblks * JRNL_DBLK_SIZE) - wr_cnt);
-#endif
- }
- rec_offs -= sizeof(_dtx_tail) - wsize;
- assert(rec_offs == 0);
- }
- }
- else // Start at beginning of data record
- {
- // Assumption: the header will always fit into the first dblk
- ::memcpy(wptr, (void*)&_dtx_hdr, sizeof(_dtx_hdr));
- wr_cnt = sizeof(_dtx_hdr);
- if (size_dblks(rec_size()) > max_size_dblks) // Split required
- {
- size_t wsize;
- rem -= sizeof(_dtx_hdr);
- if (rem)
- {
- wsize = rem >= _dtx_hdr._xidsize ? _dtx_hdr._xidsize : rem;
- ::memcpy((char*)wptr + wr_cnt, _xid.c_str(), wsize);
- wr_cnt += wsize;
- rem -= wsize;
- }
- if (rem)
- {
- wsize = rem >= sizeof(_dtx_tail) ? sizeof(_dtx_tail) : rem;
- ::memcpy((char*)wptr + wr_cnt, (void*)&_dtx_tail, wsize);
- wr_cnt += wsize;
- rem -= wsize;
- }
- assert(rem == 0);
- }
- else // No split required
- {
- if (_dtx_hdr._xidsize)
- {
- ::memcpy((char*)wptr + wr_cnt, _xid.c_str(), _dtx_hdr._xidsize);
- wr_cnt += _dtx_hdr._xidsize;
- ::memcpy((char*)wptr + wr_cnt, (void*)&_dtx_tail, sizeof(_dtx_tail));
- wr_cnt += sizeof(_dtx_tail);
- }
-#ifdef RHM_CLEAN
- ::memset((char*)wptr + wr_cnt, RHM_CLEAN_CHAR,
- (size_dblks(rec_size()) * JRNL_DBLK_SIZE) - wr_cnt);
-#endif
- }
- }
- return size_dblks(wr_cnt);
-}
-
-u_int32_t
-dtx_rec::decode(hdr& h, void* rptr, u_int32_t rec_offs_dblks, u_int32_t max_size_dblks)
- throw (jexception)
-{
- assert(rptr != NULL);
- assert(max_size_dblks > 0);
-
- size_t rd_cnt = 0;
- if (rec_offs_dblks) // Continuation of record on new page
- {
- const u_int32_t hdr_xid_dblks = size_dblks(deq_hdr::size() + _dtx_hdr._xidsize);
- const u_int32_t hdr_xid_tail_dblks = size_dblks(enq_hdr::size() + _dtx_hdr._xidsize +
- rec_tail::size());
- const size_t rec_offs = rec_offs_dblks * JRNL_DBLK_SIZE;
-
- if (hdr_xid_tail_dblks - rec_offs_dblks <= max_size_dblks)
- {
- // Remainder of xid fits within this page
- if (rec_offs - deq_hdr::size() < _dtx_hdr._xidsize)
- {
- // Part of xid still outstanding, copy remainder of xid and tail
- const size_t xid_offs = rec_offs - deq_hdr::size();
- const size_t xid_rem = _dtx_hdr._xidsize - xid_offs;
- _xid.append((char*)rptr, xid_rem);
- rd_cnt = xid_rem;
- ::memcpy((void*)&_dtx_tail, ((char*)rptr + rd_cnt), sizeof(_dtx_tail));
- chk_tail();
- rd_cnt += sizeof(_dtx_tail);
- }
- else
- {
- // Tail or part of tail only outstanding, complete tail
- const size_t tail_offs = rec_offs - deq_hdr::size() - _dtx_hdr._xidsize;
- const size_t tail_rem = rec_tail::size() - tail_offs;
- ::memcpy((char*)&_dtx_tail + tail_offs, rptr, tail_rem);
- chk_tail();
- rd_cnt = tail_rem;
- }
- }
- else if (hdr_xid_dblks - rec_offs_dblks <= max_size_dblks)
- {
- // Remainder of xid fits within this page, tail split
- const size_t xid_offs = rec_offs - deq_hdr::size();
- const size_t xid_rem = _dtx_hdr._xidsize - xid_offs;
- _xid.append((char*)rptr, xid_rem);
- rd_cnt += xid_rem;
- const size_t tail_rem = (max_size_dblks * JRNL_DBLK_SIZE) - rd_cnt;
- if (tail_rem)
- {
- ::memcpy((void*)&_dtx_tail, ((char*)rptr + xid_rem), tail_rem);
- rd_cnt += tail_rem;
- }
- }
- else
- {
- // Remainder of xid split
- const size_t xid_cp_size = (max_size_dblks * JRNL_DBLK_SIZE);
- _xid.append((char*)rptr, xid_cp_size);
- rd_cnt += xid_cp_size;
- }
- }
- else // Start of record
- {
- // Get and check header
- _dtx_hdr._hdr.copy(h);
- rd_cnt = sizeof(hdr);
-#if defined(JRNL_BIG_ENDIAN) && defined(JRNL_32_BIT)
- rd_cnt += sizeof(u_int32_t); // Filler 0
-#endif
- _dtx_hdr._xidsize = *(size_t*)((char*)rptr + rd_cnt);
- rd_cnt = _dtx_hdr.size();
- chk_hdr();
- const u_int32_t hdr_xid_dblks = size_dblks(deq_hdr::size() + _dtx_hdr._xidsize);
- const u_int32_t hdr_xid_tail_dblks = size_dblks(enq_hdr::size() + _dtx_hdr._xidsize +
- rec_tail::size());
-
- // Check if record (header + xid + tail) fits within this page, we can check the
- // tail before the expense of copying data to memory
- if (hdr_xid_tail_dblks <= max_size_dblks)
- {
- // Entire header, xid and tail fits within this page
- ::memcpy((void*)&_dtx_tail, (char*)rptr + rd_cnt + _dtx_hdr._xidsize,
- sizeof(_dtx_tail));
- chk_tail();
- _xid.assign((char*)rptr + rd_cnt, _dtx_hdr._xidsize);
- rd_cnt += _dtx_hdr._xidsize + sizeof(_dtx_tail);
- }
- else if (hdr_xid_dblks <= max_size_dblks)
- {
- // Entire header and xid fit within this page, tail split
- _xid.assign((char*)rptr + rd_cnt, _dtx_hdr._xidsize);
- rd_cnt += _dtx_hdr._xidsize;
- const size_t tail_rem = (max_size_dblks * JRNL_DBLK_SIZE) - rd_cnt;
- if (tail_rem)
- {
- ::memcpy((void*)&_dtx_tail, (char*)rptr + rd_cnt, tail_rem);
- rd_cnt += tail_rem;
- }
- }
- else
- {
- // Header fits within this page, xid split
- const size_t xid_cp_size = (max_size_dblks * JRNL_DBLK_SIZE) - rd_cnt;
- _xid.assign((char*)rptr + rd_cnt, xid_cp_size);
- rd_cnt += xid_cp_size;
- }
- }
- return size_dblks(rd_cnt);
-}
-
-std::string&
-dtx_rec::str(std::string& str) const
-{
- std::stringstream ss;
- if (_dtx_hdr._hdr._magic == RHM_JDAT_DTXA_MAGIC)
- ss << "dtxa_rec: m=" << _dtx_hdr._hdr._magic;
- else
- ss << "dtxc_rec: m=" << _dtx_hdr._hdr._magic;
- ss << " v=" << (int)_dtx_hdr._hdr._version;
- ss << " rid=" << _dtx_hdr._hdr._rid;
- ss << " xid=\"" << _xid << "\"";
- str.append(ss.str());
- return str;
-}
-
-const size_t
-dtx_rec::xid_size() const
-{
- return _dtx_hdr._xidsize;
-}
-
-const size_t
-dtx_rec::rec_size() const
-{
- return deq_hdr::size() + _dtx_hdr._xidsize + rec_tail::size();
-}
-
-void
-dtx_rec::chk_hdr() const throw (jexception)
-{
- jrec::chk_hdr(_dtx_hdr._hdr);
- if (_dtx_hdr._hdr._magic != RHM_JDAT_DTXA_MAGIC && _dtx_hdr._hdr._magic != RHM_JDAT_DTXC_MAGIC)
- {
- std::stringstream ss;
- ss << std::hex << std::setfill('0');
- ss << "dtx magic: rid=0x" << std::setw(16) << _dtx_hdr._hdr._rid;
- ss << ": expected=(0x" << std::setw(8) << RHM_JDAT_DTXA_MAGIC;
- ss << " or 0x" << RHM_JDAT_DTXC_MAGIC;
- ss << ") read=0x" << std::setw(2) << (int)_dtx_hdr._hdr._magic;
- throw jexception(jerrno::JERR_DREC_INVRHDR, ss.str(), "dtx_rec", "chk_hdr");
- }
-}
-
-void
-dtx_rec::chk_hdr(u_int64_t rid) const throw (jexception)
-{
- chk_hdr();
- jrec::chk_rid(_dtx_hdr._hdr, rid);
-}
-
-void
-dtx_rec::chk_tail() const throw (jexception)
-{
- jrec::chk_tail(_dtx_tail, _dtx_hdr._hdr);
-}
-
-} // namespace journal
-} // namespace rhm
Deleted: store/trunk/cpp/lib/jrnl/dtx_rec.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/dtx_rec.hpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/lib/jrnl/dtx_rec.hpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -1,88 +0,0 @@
-/**
-* \file dtx_rec.hpp
-*
-* Red Hat Messaging - Message Journal
-*
-* This file contains the code for the rhm::journal::dtx_rec (journal data
-* record) class. See class documentation for details.
-*
-* \author Kim van der Riet
-*
-* Copyright 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 rhm_journal_dtx_rec_hpp
-#define rhm_journal_dtx_rec_hpp
-
-namespace rhm
-{
-namespace journal
-{
-class dtx_rec;
-}
-}
-
-#include <jrnl/jrec.hpp>
-
-namespace rhm
-{
-namespace journal
-{
-
- /**
- * \class dtx_rec
- * \brief Class to handle a single journal DTX commit or abort record.
- */
- class dtx_rec : public jrec
- {
- private:
- dtx_hdr _dtx_hdr; ///< DTX header
- std::string _xid; ///< XID
- rec_tail _dtx_tail; ///< Record tail
-
- public:
- dtx_rec();
- dtx_rec(const u_int32_t magic, const u_int64_t rid);
- dtx_rec(const u_int32_t magic, const u_int64_t rid, const std::string& xid);
- ~dtx_rec();
-
- void reset(const u_int64_t rid);
- void reset(const u_int64_t rid, const std::string& xid);
- u_int32_t encode(void* wptr, u_int32_t rec_offs_dblks, u_int32_t max_size_dblks)
- throw (jexception);
- u_int32_t decode(hdr& h, void* rptr, u_int32_t rec_offs_dblks, u_int32_t max_size_dblks)
- throw (jexception);
- std::string& str(std::string& str) const;
- inline const size_t data_size() const { return 0; } // This record never carries data
- const size_t xid_size() const;
- const size_t rec_size() const;
-
- private:
- void chk_hdr() const throw (jexception);
- void chk_hdr(u_int64_t rid) const throw (jexception);
- void chk_tail() const throw (jexception);
- }; // class dtx_rec
-
-} // namespace journal
-} // namespace rhm
-
-#endif // ifndef rhm_journal_dtx_rec_hpp
Modified: store/trunk/cpp/lib/jrnl/enq_rec.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/enq_rec.cpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/lib/jrnl/enq_rec.cpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -46,57 +46,39 @@
// instance for use with write or read operations
enq_rec::enq_rec():
jrec(), // superclass
- _enq_hdr(RHM_JDAT_ENQ_MAGIC, 0, 0, 0, RHM_JDAT_VERSION),
- _xid(),
+ _enq_hdr(RHM_JDAT_ENQ_MAGIC, RHM_JDAT_VERSION, 0, 0, 0),
+ _xidp(NULL),
_data(NULL),
_buff(NULL),
_enq_tail(_enq_hdr._hdr),
_max_data_size(0),
- _data_size(0),
- _rec_size(0)
+ _data_size(0)
{}
-// Constructor used for write operations, where dbuf contains data to be written.
-enq_rec::enq_rec(const u_int64_t rid, const void* const dbuf, const size_t dlen):
- jrec(), // superclass
- _enq_hdr(RHM_JDAT_ENQ_MAGIC, rid, 0, dlen, RHM_JDAT_VERSION),
- _xid(),
- _data(dbuf),
- _buff(NULL),
- _enq_tail(_enq_hdr._hdr),
- _max_data_size(0),
- _data_size(dlen),
- _rec_size(size_dblks(enq_hdr::size() + _enq_hdr._xidsize + dlen + rec_tail::size()) *
- JRNL_DBLK_SIZE)
-{}
-
// Constructor used for transactional write operations, where dbuf contains data to be written.
enq_rec::enq_rec(const u_int64_t rid, const void* const dbuf, const size_t dlen,
- const std::string& xid):
+ const void* const xidp, const size_t xidlen, bool transient):
jrec(), // superclass
- _enq_hdr(RHM_JDAT_ENQ_MAGIC, rid, xid.size(), dlen, RHM_JDAT_VERSION),
- _xid(xid),
+ _enq_hdr(RHM_JDAT_ENQ_MAGIC, RHM_JDAT_VERSION, rid, xidlen, dlen,
+ transient),
+ _xidp(xidp),
_data(dbuf),
_buff(NULL),
_enq_tail(_enq_hdr._hdr),
_max_data_size(0),
- _data_size(dlen),
- _rec_size(size_dblks(enq_hdr::size() + _enq_hdr._xidsize + dlen + rec_tail::size()) *
- JRNL_DBLK_SIZE)
+ _data_size(dlen)
{}
-// Constructor used for read operations, where buf contains preallocated space
-// to receive data.
+// Constructor used for read operations, where buf contains preallocated space to receive data.
enq_rec::enq_rec(void* const buf, const size_t bufsize):
jrec(), // superclass
- _enq_hdr(RHM_JDAT_ENQ_MAGIC, 0, 0, bufsize, RHM_JDAT_VERSION),
- _xid(),
+ _enq_hdr(RHM_JDAT_ENQ_MAGIC, RHM_JDAT_VERSION, 0, 0, bufsize),
+ _xidp(NULL),
_data(NULL),
_buff(buf),
_enq_tail(_enq_hdr._hdr),
_max_data_size(bufsize),
- _data_size(0),
- _rec_size(0)
+ _data_size(0)
{}
enq_rec::~enq_rec()
@@ -110,36 +92,22 @@
#endif
}
-// Prepare instance for use in writing data to journal, where dbuf contains data to be written.
-void
-enq_rec::reset(const u_int64_t rid, const void* const dbuf, const size_t dlen)
-{
- _enq_hdr._hdr._rid = rid;
- _enq_hdr._xidsize = 0;
- _enq_hdr._dsize = dlen;
- _data = dbuf;
- _buff = NULL;
- _enq_tail._rid = rid;
- _max_data_size = 0;
- _data_size = dlen;
- _rec_size = size_dblks(dlen + enq_hdr::size() + rec_tail::size()) * JRNL_DBLK_SIZE;
-}
-
// Prepare instance for use in writing transactional data to journal, where dbuf contains data to
// be written.
void
enq_rec::reset(const u_int64_t rid, const void* const dbuf, const size_t dlen,
- const std::string& xid)
+ const void* const xidp, const size_t xidlen, bool transient)
{
_enq_hdr._hdr._rid = rid;
- _enq_hdr._xidsize = xid.size();
+ _enq_hdr.set_transient(transient);
+ _enq_hdr._xidsize = xidlen;
_enq_hdr._dsize = dlen;
+ _xidp = xidp;
_data = dbuf;
_buff = NULL;
_enq_tail._rid = rid;
_max_data_size = 0;
_data_size = dlen;
- _rec_size = size_dblks(dlen + enq_hdr::size() + rec_tail::size()) * JRNL_DBLK_SIZE;
}
// Prepare instance for use in reading data from journal, where buf contains preallocated space
@@ -150,12 +118,12 @@
_enq_hdr._hdr._rid = 0;
_enq_hdr._xidsize = 0;
_enq_hdr._dsize = bufsize;
+ _xidp = NULL;
_data = NULL;
_buff = buf;
_enq_tail._rid = 0;
_max_data_size = bufsize;
_data_size = 0;
- _rec_size = 0;
}
u_int32_t
@@ -163,7 +131,8 @@
{
assert(wptr != NULL);
assert(max_size_dblks > 0);
- assert(_xid.size() == _enq_hdr._xidsize);
+ if (_xidp == NULL)
+ assert(_enq_hdr._xidsize == 0);
size_t rec_offs = rec_offs_dblks * JRNL_DBLK_SIZE;
size_t rem = max_size_dblks * JRNL_DBLK_SIZE;
@@ -179,7 +148,7 @@
{
if (wsize > rem)
wsize = rem;
- ::memcpy(wptr, (const char*)_xid.c_str() + rec_offs, wsize);
+ ::memcpy(wptr, (const char*)_xidp + rec_offs, wsize);
wr_cnt = wsize;
rem -= wsize;
}
@@ -221,7 +190,7 @@
size_t wsize = _enq_hdr._xidsize > rec_offs ? _enq_hdr._xidsize - rec_offs : 0;
if (wsize)
{
- ::memcpy(wptr, _xid.c_str() + rec_offs, wsize);
+ ::memcpy(wptr, (char*)_xidp + rec_offs, wsize);
wr_cnt += wsize;
}
rec_offs -= _enq_hdr._xidsize - wsize;
@@ -238,8 +207,9 @@
::memcpy((char*)wptr + wr_cnt, (char*)&_enq_tail + rec_offs, wsize);
wr_cnt += wsize;
#ifdef RHM_CLEAN
- ::memset((char*)wptr + wr_cnt, RHM_CLEAN_CHAR,
- _rec_size - (rec_offs_dblks * JRNL_DBLK_SIZE) - wr_cnt);
+ size_t rec_offs = rec_offs_dblks * JRNL_DBLK_SIZE;
+ size_t dblk_rec_size = size_dblks(rec_size() - rec_offs) * JRNL_DBLK_SIZE;
+ ::memset((char*)wptr + wr_cnt, RHM_CLEAN_CHAR, dblk_rec_size - wr_cnt);
#endif
}
rec_offs -= sizeof(_enq_tail) - wsize;
@@ -258,7 +228,7 @@
if (rem)
{
wsize = rem >= _enq_hdr._xidsize ? _enq_hdr._xidsize : rem;
- ::memcpy((char*)wptr + wr_cnt, _xid.c_str(), wsize);
+ ::memcpy((char*)wptr + wr_cnt, _xidp, wsize);
wr_cnt += wsize;
rem -= wsize;
}
@@ -282,15 +252,16 @@
{
if (_enq_hdr._xidsize)
{
- ::memcpy((char*)wptr + wr_cnt, _xid.c_str(), _xid.size());
- wr_cnt += _xid.size();
+ ::memcpy((char*)wptr + wr_cnt, _xidp, _enq_hdr._xidsize);
+ wr_cnt += _enq_hdr._xidsize;
}
::memcpy((char*)wptr + wr_cnt, _data, _data_size);
wr_cnt += _data_size;
::memcpy((char*)wptr + wr_cnt, (void*)&_enq_tail, sizeof(_enq_tail));
wr_cnt += sizeof(_enq_tail);
#ifdef RHM_CLEAN
- ::memset((char*)wptr + wr_cnt, RHM_CLEAN_CHAR, _rec_size - wr_cnt);
+ size_t dblk_rec_size = size_dblks(rec_size()) * JRNL_DBLK_SIZE;
+ ::memset((char*)wptr + wr_cnt, RHM_CLEAN_CHAR, dblk_rec_size - wr_cnt);
#endif
}
}
@@ -425,8 +396,8 @@
ss << "enq_rec: m=" << _enq_hdr._hdr._magic;
ss << " v=" << (int)_enq_hdr._hdr._version;
ss << " rid=" << _enq_hdr._hdr._rid;
- if (_xid.size())
- ss << " xid=\"" << _xid << "\"";
+ if (_xidp)
+ ss << " xid=\"" << _xidp << "\"";
ss << " len=" << _enq_hdr._dsize;
str.append(ss.str());
return str;
@@ -441,13 +412,13 @@
const size_t
enq_rec::xid_size() const
{
- return _xid.size();
+ return _enq_hdr._xidsize;
}
const size_t
enq_rec::rec_size() const
{
- return enq_hdr::size() + _xid.size() + _data_size + rec_tail::size();
+ return enq_hdr::size() + _enq_hdr._xidsize + _data_size + rec_tail::size();
}
void
Modified: store/trunk/cpp/lib/jrnl/enq_rec.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/enq_rec.hpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/lib/jrnl/enq_rec.hpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -56,13 +56,12 @@
{
private:
enq_hdr _enq_hdr;
- std::string _xid; ///< XID
+ const void* _xidp; ///< xid pointer
const void* _data; ///< Pointer to data to be written to disk
void* _buff; ///< Pointer to buffer to receive data read from disk
rec_tail _enq_tail;
size_t _max_data_size; ///< Max buffer size for decoding into during read
size_t _data_size; ///< Size of data (bytes)
- size_t _rec_size; ///< Size of data blocks required for record (bytes)
public:
/**
@@ -74,14 +73,8 @@
/**
* \brief Constructor used for write operations, where mbuf contains data to be written.
*/
- enq_rec(const u_int64_t rid, const void* const dbuf, const size_t dlen);
-
- /**
- * \brief Constructor used for transactional write operations, where mbuf contains data to
- * be written.
- */
enq_rec(const u_int64_t rid, const void* const dbuf, const size_t dlen,
- const std::string& xid);
+ const void* const xidp, const size_t xidlen, bool transient);
/**
* \brief Constructor used for read operations, where buf contains preallocated space
@@ -95,9 +88,8 @@
~enq_rec();
// Prepare instance for use in writing data to journal
- void reset(const u_int64_t rid, const void* const dbuf, const size_t dlen);
void reset(const u_int64_t rid, const void* const dbuf, const size_t dlen,
- const std::string& xid);
+ const void* const xidp, const size_t xidlen, bool transient);
// Prepare instance for use in reading data from journal
void reset(void* const buf, const size_t bufsize);
Modified: store/trunk/cpp/lib/jrnl/file_hdr.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/file_hdr.cpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/lib/jrnl/file_hdr.cpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -52,8 +52,7 @@
_rid(0)
{}
-hdr::hdr(const u_int32_t magic, const u_int64_t rid, const u_int8_t version,
- const u_int8_t uflag):
+hdr::hdr(const u_int32_t magic, const u_int8_t version, const u_int16_t uflag, const u_int64_t rid):
_magic(magic),
_version(version),
#if defined(JRNL_BIG_ENDIAN)
@@ -133,10 +132,10 @@
#endif
{}
-file_hdr::file_hdr(const u_int32_t magic, const u_int64_t rid, const u_int32_t fid,
- const size_t fro, const bool settime, const u_int8_t version, const u_int8_t uflag)
+file_hdr::file_hdr(const u_int32_t magic, const u_int8_t version, const u_int16_t uflag,
+ const u_int64_t rid, const u_int32_t fid, const size_t fro, const bool settime)
throw (jexception):
- _hdr(magic, rid, version, uflag),
+ _hdr(magic, version, uflag, rid),
_fid(fid),
_res(0),
#if defined(JRNL_BIG_ENDIAN) && defined(JRNL_32_BIT)
@@ -178,15 +177,6 @@
}
_ts_sec = ts.tv_sec;
_ts_nsec = ts.tv_nsec;
-// This version uses a call with microsecond resolution instead of nanosecond resolution...
-// timeval tv;
-// if (::gettimeofday(&tv, 0))
-// ;
-// else
-// {
-// _ts_sec = tv.tv_sec;
-// _ts_nsec = tv.tv_usec * 1000;
-// }
}
void
@@ -217,9 +207,9 @@
#endif
{}
-enq_hdr::enq_hdr(const u_int32_t magic, const u_int64_t rid, const size_t xidsize,
- const size_t dsize, const u_int8_t version, const bool transient):
- _hdr(magic, rid, version, transient?ENQ_HDR_TRANSIENT_MASK:0),
+enq_hdr::enq_hdr(const u_int32_t magic, const u_int8_t version, const u_int64_t rid,
+ const size_t xidsize, const size_t dsize, const bool transient):
+ _hdr(magic, version, transient ? ENQ_HDR_TRANSIENT_MASK : 0, rid),
#if defined(JRNL_BIG_ENDIAN) && defined(JRNL_32_BIT)
_filler0(0),
#endif
@@ -236,9 +226,18 @@
#endif
{}
-const u_int32_t enq_hdr::ENQ_HDR_TRANSIENT_MASK = 0x1;
+void
+enq_hdr::set_transient(const bool transient)
+{
+ if (transient)
+ _hdr._uflag |= ENQ_HDR_TRANSIENT_MASK;
+ else
+ _hdr._uflag &= (~ENQ_HDR_TRANSIENT_MASK);
+}
+const u_int16_t enq_hdr::ENQ_HDR_TRANSIENT_MASK = 0x1;
+
// ***** struct deq_hdr *****
deq_hdr::deq_hdr():
@@ -253,9 +252,9 @@
#endif
{}
-deq_hdr::deq_hdr(const u_int32_t magic, const u_int64_t rid, const u_int64_t deq_rid,
- const size_t xidsize, const u_int8_t version, const u_int8_t uflag):
- _hdr(magic, rid, version, uflag),
+deq_hdr::deq_hdr(const u_int32_t magic, const u_int8_t version, const u_int16_t uflag,
+ const u_int64_t rid, const u_int64_t deq_rid, const size_t xidsize):
+ _hdr(magic, version, uflag, rid),
_deq_rid(deq_rid),
#if defined(JRNL_BIG_ENDIAN) && defined(JRNL_32_BIT)
_filler0(0),
@@ -267,10 +266,10 @@
{}
-// ***** struct dtx_hdr *****
+// ***** struct txn_hdr *****
-dtx_hdr::dtx_hdr():
+txn_hdr::txn_hdr():
_hdr(),
#if defined(JRNL_BIG_ENDIAN) && defined(JRNL_32_BIT)
_filler0(0),
@@ -281,9 +280,9 @@
#endif
{}
-dtx_hdr::dtx_hdr(const u_int32_t magic, const u_int64_t rid, const size_t xidsize,
- const u_int8_t version, const u_int8_t uflag):
- _hdr(magic, rid, version, uflag),
+txn_hdr::txn_hdr(const u_int32_t magic, const u_int8_t version, const u_int16_t uflag,
+ const u_int64_t rid, const size_t xidsize):
+ _hdr(magic, version, uflag, rid),
#if defined(JRNL_BIG_ENDIAN) && defined(JRNL_32_BIT)
_filler0(0),
#endif
Modified: store/trunk/cpp/lib/jrnl/file_hdr.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/file_hdr.hpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/lib/jrnl/file_hdr.hpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -92,8 +92,8 @@
/**
* \brief Convenience constructor which initializes values during construction.
*/
- hdr(const u_int32_t magic, const u_int64_t rid, const u_int8_t version = 0,
- const u_int8_t uflag = 0);
+ hdr(const u_int32_t magic, const u_int8_t version, const u_int16_t uflag,
+ const u_int64_t rid);
/**
* \brief Convenience copy method.
@@ -232,9 +232,9 @@
/**
* \brief Convenience constructor which initializes values during construction.
*/
- file_hdr(const u_int32_t magic, const u_int64_t rid, const u_int32_t fid,
- const size_t fro, const bool settime = false, const u_int8_t version = 0,
- const u_int8_t uflag = 0) throw (jexception);
+ file_hdr(const u_int32_t magic, const u_int8_t version, const u_int16_t uflag,
+ const u_int64_t rid, const u_int32_t fid, const size_t fro,
+ const bool settime = false) throw (jexception);
/**
* \brief Gets the current time from the system clock and sets the timestamp in the struct.
@@ -301,7 +301,7 @@
#if defined(JRNL_LITTLE_ENDIAN) && defined(JRNL_32_BIT)
u_int32_t _filler1; ///< Little-endian filler for 32-bit size_t
#endif
- static const u_int32_t ENQ_HDR_TRANSIENT_MASK;
+ static const u_int16_t ENQ_HDR_TRANSIENT_MASK;
/**
* \brief Default constructor, which sets all values to 0.
@@ -311,10 +311,11 @@
/**
* \brief Convenience constructor which initializes values during construction.
*/
- enq_hdr(const u_int32_t magic, const u_int64_t rid, const size_t xidsize,
- const size_t dsize, const u_int8_t version = 0, const bool transient = false);
+ enq_hdr(const u_int32_t magic, const u_int8_t version, const u_int64_t rid,
+ const size_t xidsize, const size_t dsize, const bool transient = false);
inline const bool is_transient() { return _hdr._uflag & ENQ_HDR_TRANSIENT_MASK; }
+ void set_transient(const bool transient);
/**
* \brief Returns the size of the header in bytes.
@@ -377,8 +378,8 @@
/**
* \brief Convenience constructor which initializes values during construction.
*/
- deq_hdr(const u_int32_t magic, const u_int64_t rid, const u_int64_t deq_rid,
- const size_t xidsize, const u_int8_t version = 0, const u_int8_t uflag = 0);
+ deq_hdr(const u_int32_t magic, const u_int8_t version, const u_int16_t uflag,
+ const u_int64_t rid, const u_int64_t deq_rid, const size_t xidsize);
/**
* \brief Returns the size of the header in bytes.
@@ -418,7 +419,7 @@
* entianness without some sort of binary conversion utility. Thus buffering
* will be needed for types that change size between 32- and 64-bit compiles.
*/
- struct dtx_hdr
+ struct txn_hdr
{
hdr _hdr; ///< Common header
#if defined(JRNL_BIG_ENDIAN) && defined(JRNL_32_BIT)
@@ -432,18 +433,18 @@
/**
* \brief Default constructor, which sets all values to 0.
*/
- dtx_hdr();
+ txn_hdr();
/**
* \brief Convenience constructor which initializes values during construction.
*/
- dtx_hdr(const u_int32_t magic, const u_int64_t rid, const size_t xidsize,
- const u_int8_t version = 0, const u_int8_t uflag = 0);
+ txn_hdr(const u_int32_t magic, const u_int8_t version, const u_int16_t uflag,
+ const u_int64_t rid, const size_t xidsize);
/**
* \brief Returns the size of the header in bytes.
*/
- inline static const size_t size() { return sizeof(dtx_hdr); }
+ inline static const size_t size() { return sizeof(txn_hdr); }
};
#pragma pack()
Modified: store/trunk/cpp/lib/jrnl/jcntl.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/jcntl.cpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/lib/jrnl/jcntl.cpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -128,6 +128,7 @@
std::set<std::string> prep_xid_list;
for (bdbstore::PreparedTransaction::list::iterator i = prep_tx_list.begin();
i != prep_tx_list.end(); i++);
+// TODO!
// prep_xid_list.insert(i->??);
// Verify journal dir and journal files
@@ -193,29 +194,32 @@
throw (jexception)
{
check_wstatus("enqueue_data_record");
- return _wmgr.enqueue(data_buff, tot_data_len, this_data_len, dtokp, transient);
+ return _wmgr.enqueue(data_buff, tot_data_len, this_data_len, dtokp, NULL, 0, transient);
}
const iores
-jcntl::enqueue_tx_data_record(const void* const data_buff, const size_t tot_data_len,
+jcntl::enqueue_txn_data_record(const void* const data_buff, const size_t tot_data_len,
const size_t this_data_len, data_tok* dtokp, const std::string& xid,
const bool transient) throw (jexception)
{
check_wstatus("enqueue_tx_data_record");
- return _wmgr.enqueue_tx(data_buff, tot_data_len, this_data_len, dtokp, xid, transient);
+ return _wmgr.enqueue(data_buff, tot_data_len, this_data_len, dtokp, xid.c_str(), xid.size(),
+ transient);
}
const iores
-jcntl::get_data_record(const u_int64_t& /*rid*/, const size_t& /*dsize*/, const size_t& /*dsize_avail*/,
- const void** const /*data*/, bool /*auto_discard*/) throw (jexception)
+jcntl::get_data_record(const u_int64_t& rid, const size_t& dsize, const size_t& dsize_avail,
+ const void** const data, bool auto_discard) throw (jexception)
{
- return RHM_IORES_NOTIMPL;
+ check_rstatus("get_data_record");
+ return _rmgr.get(rid, dsize, dsize_avail, data, auto_discard);
}
const iores
-jcntl::discard_data_record() throw (jexception)
+jcntl::discard_data_record(data_tok* const dtokp) throw (jexception)
{
- return RHM_IORES_NOTIMPL;
+ check_rstatus("discard_data_record");
+ return _rmgr.discard(dtokp);
}
const iores
@@ -230,28 +234,34 @@
jcntl::dequeue_data_record(data_tok* const dtokp) throw (jexception)
{
check_wstatus("dequeue_data");
- return _wmgr.dequeue(dtokp);
+ return _wmgr.dequeue(dtokp, NULL, 0);
}
const iores
-jcntl::dequeue_tx_data_record(data_tok* const dtokp, const std::string& xid) throw (jexception)
+jcntl::dequeue_txn_data_record(data_tok* const dtokp, const std::string& xid) throw (jexception)
{
check_wstatus("dequeue_data");
- return _wmgr.dequeue_tx(dtokp, xid);
+ return _wmgr.dequeue(dtokp, xid.c_str(), xid.size());
}
const iores
-jcntl::abort_dtx(const std::string& /*xid*/) throw (jexception)
+jcntl::txn_abort(const std::string& /*xid*/) throw (jexception)
{
return RHM_IORES_NOTIMPL;
}
const iores
-jcntl::commit_dtx(const std::string& /*xid*/) throw (jexception)
+jcntl::txn_commit(const std::string& /*xid*/) throw (jexception)
{
return RHM_IORES_NOTIMPL;
}
+const bool
+is_txn_synced(const std::string& /*xid*/) throw (jexception)
+{
+ return RHM_IORES_NOTIMPL;
+}
+
const u_int32_t
jcntl::get_wr_events() throw (jexception)
{
Modified: store/trunk/cpp/lib/jrnl/jcntl.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/jcntl.hpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/lib/jrnl/jcntl.hpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -315,7 +315,7 @@
*
* \exception TODO
*/
- const iores enqueue_tx_data_record(const void* const data_buff, const size_t tot_data_len,
+ const iores enqueue_txn_data_record(const void* const data_buff, const size_t tot_data_len,
const size_t this_data_len, data_tok* dtokp, const std::string& xid,
const bool transient = false) throw (jexception);
@@ -385,7 +385,7 @@
*
* \exception TODO
*/
- const iores discard_data_record() throw (jexception);
+ const iores discard_data_record(data_tok* const dtokp) throw (jexception);
/**
* \brief Reads data from the journal.
@@ -433,7 +433,7 @@
*
* \exception TODO
*/
- const iores dequeue_tx_data_record(data_tok* const dtokp, const std::string& xid)
+ const iores dequeue_txn_data_record(data_tok* const dtokp, const std::string& xid)
throw (jexception);
/**
@@ -447,7 +447,7 @@
*
* \exception TODO
*/
- const iores abort_dtx(const std::string& xid) throw (jexception);
+ const iores txn_abort(const std::string& xid) throw (jexception);
/**
* \brief Commit the transaction for all records enqueued or dequeued with the matching xid.
@@ -460,7 +460,7 @@
*
* \exception TODO
*/
- const iores commit_dtx(const std::string& xid) throw (jexception);
+ const iores txn_commit(const std::string& xid) throw (jexception);
/**
* \brief Check whether all the enqueue records for the given xid have reached disk.
@@ -469,7 +469,7 @@
*
* \exception TODO
*/
- const bool is_dtx_synced(const std::string& xid) throw (jexception);
+ const bool is_txn_synced(const std::string& xid) throw (jexception);
/**
* \brief Forces a check for returned AIO write events.
Modified: store/trunk/cpp/lib/jrnl/pmgr.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/pmgr.cpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/lib/jrnl/pmgr.cpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -262,5 +262,28 @@
return "<page_state unknown>";
}
+const char*
+pmgr::iores_str(iores res)
+{
+ switch (res)
+ {
+ case RHM_IORES_SUCCESS:
+ return "RHM_IORES_SUCCESS";
+ case RHM_IORES_AIO_WAIT:
+ return "RHM_IORES_AIO_WAIT";
+ case RHM_IORES_EMPTY:
+ return "RHM_IORES_EMPTY";
+ case RHM_IORES_FULL:
+ return "RHM_IORES_FULL";
+ case RHM_IORES_BUSY:
+ return "RHM_IORES_BUSY";
+ case RHM_IORES_TXPENDING:
+ return "RHM_IORES_TXPENDING";
+ case RHM_IORES_NOTIMPL:
+ return "RHM_IORES_NOTIMPL";
+ }
+ return "<iores unknown>";
+}
+
} // namespace journal
} // namespace rhm
Modified: store/trunk/cpp/lib/jrnl/pmgr.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/pmgr.hpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/lib/jrnl/pmgr.hpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -47,10 +47,10 @@
#include <jrnl/aio_cb.hpp>
#include <jrnl/data_tok.hpp>
#include <jrnl/deq_rec.hpp>
-#include <jrnl/dtx_rec.hpp>
#include <jrnl/enq_map.hpp>
#include <jrnl/enq_rec.hpp>
#include <jrnl/nlfh.hpp>
+#include <jrnl/txn_rec.hpp>
namespace rhm
{
@@ -130,7 +130,7 @@
enq_rec _enq_rec; ///< Enqueue record used for encoding/decoding
deq_rec _deq_rec; ///< Dequeue record used for encoding/decoding
- dtx_rec _dtx_rec; ///< Transaction record used for encoding/decoding
+ txn_rec _txn_rec; ///< Transaction record used for encoding/decoding
// TODO: move _cb down to wmgr, it is the only class that uses it There is no need for
// read callbacks based on AIO. - (check this asertion)
@@ -145,6 +145,7 @@
virtual const u_int32_t get_events(page_state state) throw (jexception) = 0;
inline const u_int32_t get_aio_evt_rem() const { return _aio_evt_rem; }
static const char* page_state_str(page_state ps);
+ static const char* iores_str(iores res);
protected:
virtual void initialize() throw (jexception);
Modified: store/trunk/cpp/lib/jrnl/rmgr.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/rmgr.cpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/lib/jrnl/rmgr.cpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -66,29 +66,156 @@
}
const iores
+rmgr::get(const u_int64_t& /*rid*/, const size_t& /*dsize*/, const size_t& /*dsize_avail*/,
+ const void** const /*data*/, bool /*auto_discard*/) throw (jexception)
+{
+//std::cout << " rmgr::get()" << std::flush;
+ iores res = pre_read_check(NULL);
+ if (res != RHM_IORES_SUCCESS)
+ return res;
+
+ return RHM_IORES_NOTIMPL;
+
+// TODO - untangle this...
+// _hdr.reset();
+// // Read header, determine next record type
+// while (true)
+// {
+// if(dblks_rem() == 0 && _rrfc.is_compl() && !_rrfc.is_wr_aio_outstanding())
+// {
+// aio_cycle(); // check if any AIOs have returned
+// return RHM_IORES_EMPTY;
+// }
+// if (_page_cb_arr[_pg_index]._state != AIO_COMPLETE)
+// {
+// aio_cycle();
+// return RHM_IORES_AIO_WAIT;
+// }
+// void* rptr = (void*)((char*)_page_ptr_arr[_pg_index] +
+// (_pg_offset_dblks * JRNL_DBLK_SIZE));
+// ::memcpy(&_hdr, rptr, sizeof(hdr));
+// switch (_hdr._magic)
+// {
+// case RHM_JDAT_ENQ_MAGIC:
+// {
+// size_t xid_size = *((size_t*)((char*)rptr + sizeof(hdr)
+// #if defined(JRNL_BIG_ENDIAN) && defined(JRNL_32_BIT)
+// + sizeof(u_int32_t) // filler0
+// #endif
+// ));
+// size_t data_size = *((size_t*)((char*)rptr + sizeof(hdr) + sizeof(u_int64_t)
+// #if defined(JRNL_BIG_ENDIAN) && defined(JRNL_32_BIT)
+// + sizeof(u_int32_t) // filler1
+// #endif
+// ));
+// // TODO: Check if transaction is still in transaction map. If so, block read
+// // (unless in recovery, in whcih case return info normally
+// // std::string xid = ?? (decode xid here)
+// // if (xid_size && !readonly && tx_map.exists(xid))
+// // return RHM_IORES_TXPENDING;
+// rid = _hdr._rid;
+// dsize = data_size;
+//
+// // Analyze how much of message is available
+// void* data_ptr = (char*)rptr + sizeof(enq_hdr) + xid_size;
+// void* page_end_ptr = (char*)_page_base_ptr + _pagesize * _sblksize * _pages;
+// u_int16_t data_start_pg_index = _pg_index;
+// u_int16_t data_start_pg_index = _pg_index;
+// for (u_int16_t i=0; i<_pages; i++)
+// {
+// pi = (i + _pg_index) % _pages;
+// if (data_ptr >= _page_ptr_arr[pi] &&
+// data_ptr < (char*)_page_ptr_arr[pi] + _pagesize * _sblksize)
+// data_end_pg_index = pi; // found start page index
+//
+// }
+// u_int16_t data_end_pg_index;
+// u_int16_t last_pg_avail_index;
+//
+// void* data_ptr = (char*)rptr + sizeof(enq_hdr) + xid_size;
+// void* page_end_ptr = (char*)_page_base_ptr + _pagesize * _sblksize * _pages;
+// if (data_ptr >= page_end_ptr) // folded, go back to first page...
+// data_ptr = (char*)_page_base_ptr + data_ptr - page_end_ptr;
+// void* data_end_ptr = (char*)data_ptr + data_size;
+// if (data_end_ptr >= page_end_ptr) // folded, go back to first page...
+// data_end_ptr = (char*)_page_base_ptr + data_end_ptr - page_end_ptr;
+// dsize_avail = ??;
+// if(data_ptr folded)
+// else
+// *data = data_ptr;
+// }
+// break;
+// case RHM_JDAT_DEQ_MAGIC:
+// consume_deq();
+// break;
+// case RHM_JDAT_EMPTY_MAGIC:
+// consume_filler();
+// break;
+// default:
+// std::stringstream ss;
+// ss << std::hex << std::setfill('0');
+// ss << "Magic=0x" << std::setw(8) << _hdr._magic << std::dec;
+// throw jexception(jerrno::JERR_RMGR_UNKNOWNMAGIC, ss.str(), "rmgr", "read");
+// } // switch(_hdr._magic)
+// } // while
+}
+
+const iores
+rmgr::discard(data_tok* dtokp) throw (jexception)
+{
+//std::cout << " rmgr::get()" << std::flush;
+ iores res = pre_read_check(dtokp);
+ if (res != RHM_IORES_SUCCESS)
+ return res;
+
+ return RHM_IORES_NOTIMPL;
+
+// TODO - untangle this...
+// _hdr.reset();
+// // Read header, determine next record type
+// while (true)
+// {
+// if(dblks_rem() == 0 && _rrfc.is_compl() && !_rrfc.is_wr_aio_outstanding())
+// {
+// aio_cycle(); // check if any AIOs have returned
+// return RHM_IORES_EMPTY;
+// }
+// if (_page_cb_arr[_pg_index]._state != AIO_COMPLETE)
+// {
+// aio_cycle();
+// return RHM_IORES_AIO_WAIT;
+// }
+// void* rptr = (void*)((char*)_page_ptr_arr[_pg_index] +
+// (_pg_offset_dblks * JRNL_DBLK_SIZE));
+// ::memcpy(&_hdr, rptr, sizeof(hdr));
+// switch (_hdr._magic)
+// {
+// case RHM_JDAT_ENQ_MAGIC:
+// {
+// }
+// break;
+// case RHM_JDAT_DEQ_MAGIC:
+// consume_deq();
+// break;
+// case RHM_JDAT_EMPTY_MAGIC:
+// consume_filler();
+// break;
+// default:
+// std::stringstream ss;
+// ss << std::hex << std::setfill('0');
+// ss << "Magic=0x" << std::setw(8) << _hdr._magic << std::dec;
+// throw jexception(jerrno::JERR_RMGR_UNKNOWNMAGIC, ss.str(), "rmgr", "read");
+// } // switch
+// } // while
+}
+
+const iores
rmgr::read(void* const mbuf, const size_t mbsize, data_tok* dtokp) throw (jexception)
{
//std::cout << " rmgr::read()" << std::flush;
- if (_aio_evt_rem)
- get_events();
-//std::string s;
-//std::cout << " [a pi=" << _pg_index << " d=" << dblks_rem() << " c=" << (_rrfc.is_compl()?"T":"F") << " wo=" << (_rrfc.is_wr_aio_outstanding()?"T":"F") << " status:" << _rrfc.file_handle()->status_str(s) << "]" << std::flush;
- if(dblks_rem() == 0 && _rrfc.is_compl() && !_rrfc.is_wr_aio_outstanding())
- {
- aio_cycle(); // check if any AIOs have returned
- return RHM_IORES_EMPTY;
- }
-//std::cout << " b" << std::flush;
- // Check write state of this token is ENQ - required for read
- if (!dtokp->is_readable())
- {
- std::stringstream ss;
- ss << std::hex << std::setfill('0');
- ss << "dtok_id=0x" << std::setw(8) << dtokp->id();
- ss << "; dtok_rid=0x" << std::setw(16) << dtokp->rid();
- ss << "; dtok_wstate=" << dtokp->wstate_str();
- throw jexception(jerrno::JERR_RMGR_ENQSTATE, ss.str(), "rmgr", "read");
- }
+ iores res = pre_read_check(dtokp);
+ if (res != RHM_IORES_SUCCESS)
+ return res;
//std::cout << " c" << std::flush;
if (dtokp->rstate() == data_tok::SKIP_PART)
@@ -285,6 +412,38 @@
}
const iores
+rmgr::pre_read_check(data_tok* dtokp) throw (jexception)
+{
+ if (_aio_evt_rem)
+ get_events();
+
+//std::string s;
+//std::cout << " [a pi=" << _pg_index << " d=" << dblks_rem() << " c=" << (_rrfc.is_compl()?"T":"F") << " wo=" << (_rrfc.is_wr_aio_outstanding()?"T":"F") << " status:" << _rrfc.file_handle()->status_str(s) << "]" << std::flush;
+ if(dblks_rem() == 0 && _rrfc.is_compl() && !_rrfc.is_wr_aio_outstanding())
+ {
+ aio_cycle(); // check if any AIOs have returned
+ return RHM_IORES_EMPTY;
+ }
+
+//std::cout << " b" << std::flush;
+ // Check write state of this token is ENQ - required for read
+ if (dtokp)
+ {
+ if (!dtokp->is_readable())
+ {
+ std::stringstream ss;
+ ss << std::hex << std::setfill('0');
+ ss << "dtok_id=0x" << std::setw(8) << dtokp->id();
+ ss << "; dtok_rid=0x" << std::setw(16) << dtokp->rid();
+ ss << "; dtok_wstate=" << dtokp->wstate_str();
+ throw jexception(jerrno::JERR_RMGR_ENQSTATE, ss.str(), "rmgr", "read");
+ }
+ }
+
+ return RHM_IORES_SUCCESS;
+}
+
+const iores
rmgr::read_enq(hdr& h, void* rptr, data_tok* dtokp)
throw (jexception)
{
Modified: store/trunk/cpp/lib/jrnl/rmgr.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/rmgr.hpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/lib/jrnl/rmgr.hpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -68,14 +68,18 @@
~rmgr();
void initialize(std::deque<data_tok*>* const dtokl, const aio_cb rd_cb) throw (jexception);
+ const iores get(const u_int64_t& rid, const size_t& dsize, const size_t& dsize_avail,
+ const void** const data, bool auto_discard) throw (jexception);
+ const iores discard(data_tok* dtok) throw (jexception);
const iores read(void* const mbuf, const size_t mbsize, data_tok* dtok)
throw (jexception);
const u_int32_t get_events(page_state state = AIO_COMPLETE) throw (jexception);
private:
void initialize() throw (jexception);
- const iores read_enq(hdr& h, void* rptr, data_tok* dtok) throw (jexception);
- const iores read_deq(hdr& h, void* rptr, data_tok* dtok) throw (jexception);
+ const iores pre_read_check(data_tok* dtokp) throw (jexception);
+ const iores read_enq(hdr& h, void* rptr, data_tok* dtokp) throw (jexception);
+ const iores read_deq(hdr& h, void* rptr, data_tok* dtokp) throw (jexception);
void consume_deq() throw (jexception); // DEPRECATED, to be removed, use read_deq()
void consume_filler() throw (jexception);
const iores skip(data_tok* dtokp) throw (jexception);
Copied: store/trunk/cpp/lib/jrnl/txn_rec.cpp (from rev 959, store/trunk/cpp/lib/jrnl/dtx_rec.cpp)
===================================================================
--- store/trunk/cpp/lib/jrnl/txn_rec.cpp (rev 0)
+++ store/trunk/cpp/lib/jrnl/txn_rec.cpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -0,0 +1,361 @@
+/**
+* \file txn_rec.cpp
+*
+* Red Hat Messaging - Message Journal
+*
+* This file contains the code for the rhm::journal::txn_rec (journal dequeue
+* record) class. See comments in file txn_rec.hpp for details.
+*
+* \author Kim van der Riet
+*
+* Copyright 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 <jrnl/txn_rec.hpp>
+
+#include <assert.h>
+#include <iomanip>
+#include <sstream>
+#include <jrnl/jerrno.hpp>
+
+namespace rhm
+{
+namespace journal
+{
+
+txn_rec::txn_rec():
+ _txn_hdr(),
+ _xid(),
+ _dtx_tail()
+{}
+
+txn_rec::txn_rec(const u_int32_t magic, const u_int64_t rid):
+ _txn_hdr(magic, RHM_JDAT_VERSION, 0, rid, 0),
+ _xid(),
+ _dtx_tail(_txn_hdr._hdr)
+{}
+
+txn_rec::txn_rec(const u_int32_t magic, const u_int64_t rid, const std::string& xid):
+ _txn_hdr(magic, RHM_JDAT_VERSION, 0, rid, xid.size()),
+ _xid(xid),
+ _dtx_tail(_txn_hdr._hdr)
+{}
+
+txn_rec::~txn_rec()
+{}
+
+void
+txn_rec::reset(const u_int64_t rid)
+{
+ _txn_hdr._hdr._rid = rid;
+ _txn_hdr._xidsize = 0;
+ _dtx_tail._rid = rid;
+}
+
+void
+txn_rec::reset(const u_int64_t rid, const std::string& xid)
+{
+ _txn_hdr._hdr._rid = rid;
+ _txn_hdr._xidsize = xid.size();
+ _dtx_tail._rid = rid;
+}
+
+u_int32_t
+txn_rec::encode(void* wptr, u_int32_t rec_offs_dblks, u_int32_t max_size_dblks) throw (jexception)
+{
+ assert(wptr != NULL);
+ assert(max_size_dblks > 0);
+ assert(_xid.size() == _txn_hdr._xidsize);
+ assert(_txn_hdr._xidsize > 0);
+
+ size_t rec_offs = rec_offs_dblks * JRNL_DBLK_SIZE;
+ size_t rem = max_size_dblks * JRNL_DBLK_SIZE;
+ size_t wr_cnt = 0;
+ if (rec_offs_dblks) // Continuation of split dequeue record (over 2 or more pages)
+ {
+ if (size_dblks(rec_size()) - rec_offs_dblks > max_size_dblks) // Further split required
+ {
+ rec_offs -= sizeof(_txn_hdr);
+ size_t wsize = _txn_hdr._xidsize > rec_offs ? _txn_hdr._xidsize - rec_offs : 0;
+ size_t wsize2 = wsize;
+ if (wsize)
+ {
+ if (wsize > rem)
+ wsize = rem;
+ ::memcpy(wptr, (const char*)_xid.c_str() + rec_offs, wsize);
+ wr_cnt += wsize;
+ rem -= wsize;
+ }
+ rec_offs -= _txn_hdr._xidsize - wsize2;
+ if (rem)
+ {
+ wsize = sizeof(_dtx_tail) > rec_offs ? sizeof(_dtx_tail) - rec_offs : 0;
+ wsize2 = wsize;
+ if (wsize)
+ {
+ if (wsize > rem)
+ wsize = rem;
+ ::memcpy((char*)wptr + wr_cnt, (char*)&_dtx_tail + rec_offs, wsize);
+ wr_cnt += wsize;
+ rem -= wsize;
+ }
+ rec_offs -= sizeof(_dtx_tail) - wsize2;
+ }
+ assert(rem == 0);
+ assert(rec_offs == 0);
+ }
+ else // No further split required
+ {
+ rec_offs -= sizeof(_txn_hdr);
+ size_t wsize = _txn_hdr._xidsize > rec_offs ? _txn_hdr._xidsize - rec_offs : 0;
+ if (wsize)
+ {
+ ::memcpy(wptr, _xid.c_str() + rec_offs, wsize);
+ wr_cnt += wsize;
+ }
+ rec_offs -= _txn_hdr._xidsize - wsize;
+ wsize = sizeof(_dtx_tail) > rec_offs ? sizeof(_dtx_tail) - rec_offs : 0;
+ if (wsize)
+ {
+ ::memcpy((char*)wptr + wr_cnt, (char*)&_dtx_tail + rec_offs, wsize);
+ wr_cnt += wsize;
+#ifdef RHM_CLEAN
+ ::memset((char*)wptr + wr_cnt, RHM_CLEAN_CHAR,
+ (size_dblks(rec_size()) * JRNL_DBLK_SIZE) -
+ (rec_offs_dblks * JRNL_DBLK_SIZE) - wr_cnt);
+#endif
+ }
+ rec_offs -= sizeof(_dtx_tail) - wsize;
+ assert(rec_offs == 0);
+ }
+ }
+ else // Start at beginning of data record
+ {
+ // Assumption: the header will always fit into the first dblk
+ ::memcpy(wptr, (void*)&_txn_hdr, sizeof(_txn_hdr));
+ wr_cnt = sizeof(_txn_hdr);
+ if (size_dblks(rec_size()) > max_size_dblks) // Split required
+ {
+ size_t wsize;
+ rem -= sizeof(_txn_hdr);
+ if (rem)
+ {
+ wsize = rem >= _txn_hdr._xidsize ? _txn_hdr._xidsize : rem;
+ ::memcpy((char*)wptr + wr_cnt, _xid.c_str(), wsize);
+ wr_cnt += wsize;
+ rem -= wsize;
+ }
+ if (rem)
+ {
+ wsize = rem >= sizeof(_dtx_tail) ? sizeof(_dtx_tail) : rem;
+ ::memcpy((char*)wptr + wr_cnt, (void*)&_dtx_tail, wsize);
+ wr_cnt += wsize;
+ rem -= wsize;
+ }
+ assert(rem == 0);
+ }
+ else // No split required
+ {
+ if (_txn_hdr._xidsize)
+ {
+ ::memcpy((char*)wptr + wr_cnt, _xid.c_str(), _txn_hdr._xidsize);
+ wr_cnt += _txn_hdr._xidsize;
+ ::memcpy((char*)wptr + wr_cnt, (void*)&_dtx_tail, sizeof(_dtx_tail));
+ wr_cnt += sizeof(_dtx_tail);
+ }
+#ifdef RHM_CLEAN
+ ::memset((char*)wptr + wr_cnt, RHM_CLEAN_CHAR,
+ (size_dblks(rec_size()) * JRNL_DBLK_SIZE) - wr_cnt);
+#endif
+ }
+ }
+ return size_dblks(wr_cnt);
+}
+
+u_int32_t
+txn_rec::decode(hdr& h, void* rptr, u_int32_t rec_offs_dblks, u_int32_t max_size_dblks)
+ throw (jexception)
+{
+ assert(rptr != NULL);
+ assert(max_size_dblks > 0);
+
+ size_t rd_cnt = 0;
+ if (rec_offs_dblks) // Continuation of record on new page
+ {
+ const u_int32_t hdr_xid_dblks = size_dblks(deq_hdr::size() + _txn_hdr._xidsize);
+ const u_int32_t hdr_xid_tail_dblks = size_dblks(enq_hdr::size() + _txn_hdr._xidsize +
+ rec_tail::size());
+ const size_t rec_offs = rec_offs_dblks * JRNL_DBLK_SIZE;
+
+ if (hdr_xid_tail_dblks - rec_offs_dblks <= max_size_dblks)
+ {
+ // Remainder of xid fits within this page
+ if (rec_offs - deq_hdr::size() < _txn_hdr._xidsize)
+ {
+ // Part of xid still outstanding, copy remainder of xid and tail
+ const size_t xid_offs = rec_offs - deq_hdr::size();
+ const size_t xid_rem = _txn_hdr._xidsize - xid_offs;
+ _xid.append((char*)rptr, xid_rem);
+ rd_cnt = xid_rem;
+ ::memcpy((void*)&_dtx_tail, ((char*)rptr + rd_cnt), sizeof(_dtx_tail));
+ chk_tail();
+ rd_cnt += sizeof(_dtx_tail);
+ }
+ else
+ {
+ // Tail or part of tail only outstanding, complete tail
+ const size_t tail_offs = rec_offs - deq_hdr::size() - _txn_hdr._xidsize;
+ const size_t tail_rem = rec_tail::size() - tail_offs;
+ ::memcpy((char*)&_dtx_tail + tail_offs, rptr, tail_rem);
+ chk_tail();
+ rd_cnt = tail_rem;
+ }
+ }
+ else if (hdr_xid_dblks - rec_offs_dblks <= max_size_dblks)
+ {
+ // Remainder of xid fits within this page, tail split
+ const size_t xid_offs = rec_offs - deq_hdr::size();
+ const size_t xid_rem = _txn_hdr._xidsize - xid_offs;
+ _xid.append((char*)rptr, xid_rem);
+ rd_cnt += xid_rem;
+ const size_t tail_rem = (max_size_dblks * JRNL_DBLK_SIZE) - rd_cnt;
+ if (tail_rem)
+ {
+ ::memcpy((void*)&_dtx_tail, ((char*)rptr + xid_rem), tail_rem);
+ rd_cnt += tail_rem;
+ }
+ }
+ else
+ {
+ // Remainder of xid split
+ const size_t xid_cp_size = (max_size_dblks * JRNL_DBLK_SIZE);
+ _xid.append((char*)rptr, xid_cp_size);
+ rd_cnt += xid_cp_size;
+ }
+ }
+ else // Start of record
+ {
+ // Get and check header
+ _txn_hdr._hdr.copy(h);
+ rd_cnt = sizeof(hdr);
+#if defined(JRNL_BIG_ENDIAN) && defined(JRNL_32_BIT)
+ rd_cnt += sizeof(u_int32_t); // Filler 0
+#endif
+ _txn_hdr._xidsize = *(size_t*)((char*)rptr + rd_cnt);
+ rd_cnt = _txn_hdr.size();
+ chk_hdr();
+ const u_int32_t hdr_xid_dblks = size_dblks(deq_hdr::size() + _txn_hdr._xidsize);
+ const u_int32_t hdr_xid_tail_dblks = size_dblks(enq_hdr::size() + _txn_hdr._xidsize +
+ rec_tail::size());
+
+ // Check if record (header + xid + tail) fits within this page, we can check the
+ // tail before the expense of copying data to memory
+ if (hdr_xid_tail_dblks <= max_size_dblks)
+ {
+ // Entire header, xid and tail fits within this page
+ ::memcpy((void*)&_dtx_tail, (char*)rptr + rd_cnt + _txn_hdr._xidsize,
+ sizeof(_dtx_tail));
+ chk_tail();
+ _xid.assign((char*)rptr + rd_cnt, _txn_hdr._xidsize);
+ rd_cnt += _txn_hdr._xidsize + sizeof(_dtx_tail);
+ }
+ else if (hdr_xid_dblks <= max_size_dblks)
+ {
+ // Entire header and xid fit within this page, tail split
+ _xid.assign((char*)rptr + rd_cnt, _txn_hdr._xidsize);
+ rd_cnt += _txn_hdr._xidsize;
+ const size_t tail_rem = (max_size_dblks * JRNL_DBLK_SIZE) - rd_cnt;
+ if (tail_rem)
+ {
+ ::memcpy((void*)&_dtx_tail, (char*)rptr + rd_cnt, tail_rem);
+ rd_cnt += tail_rem;
+ }
+ }
+ else
+ {
+ // Header fits within this page, xid split
+ const size_t xid_cp_size = (max_size_dblks * JRNL_DBLK_SIZE) - rd_cnt;
+ _xid.assign((char*)rptr + rd_cnt, xid_cp_size);
+ rd_cnt += xid_cp_size;
+ }
+ }
+ return size_dblks(rd_cnt);
+}
+
+std::string&
+txn_rec::str(std::string& str) const
+{
+ std::stringstream ss;
+ if (_txn_hdr._hdr._magic == RHM_JDAT_DTXA_MAGIC)
+ ss << "dtxa_rec: m=" << _txn_hdr._hdr._magic;
+ else
+ ss << "dtxc_rec: m=" << _txn_hdr._hdr._magic;
+ ss << " v=" << (int)_txn_hdr._hdr._version;
+ ss << " rid=" << _txn_hdr._hdr._rid;
+ ss << " xid=\"" << _xid << "\"";
+ str.append(ss.str());
+ return str;
+}
+
+const size_t
+txn_rec::xid_size() const
+{
+ return _txn_hdr._xidsize;
+}
+
+const size_t
+txn_rec::rec_size() const
+{
+ return deq_hdr::size() + _txn_hdr._xidsize + rec_tail::size();
+}
+
+void
+txn_rec::chk_hdr() const throw (jexception)
+{
+ jrec::chk_hdr(_txn_hdr._hdr);
+ if (_txn_hdr._hdr._magic != RHM_JDAT_DTXA_MAGIC && _txn_hdr._hdr._magic != RHM_JDAT_DTXC_MAGIC)
+ {
+ std::stringstream ss;
+ ss << std::hex << std::setfill('0');
+ ss << "dtx magic: rid=0x" << std::setw(16) << _txn_hdr._hdr._rid;
+ ss << ": expected=(0x" << std::setw(8) << RHM_JDAT_DTXA_MAGIC;
+ ss << " or 0x" << RHM_JDAT_DTXC_MAGIC;
+ ss << ") read=0x" << std::setw(2) << (int)_txn_hdr._hdr._magic;
+ throw jexception(jerrno::JERR_DREC_INVRHDR, ss.str(), "txn_rec", "chk_hdr");
+ }
+}
+
+void
+txn_rec::chk_hdr(u_int64_t rid) const throw (jexception)
+{
+ chk_hdr();
+ jrec::chk_rid(_txn_hdr._hdr, rid);
+}
+
+void
+txn_rec::chk_tail() const throw (jexception)
+{
+ jrec::chk_tail(_dtx_tail, _txn_hdr._hdr);
+}
+
+} // namespace journal
+} // namespace rhm
Copied: store/trunk/cpp/lib/jrnl/txn_rec.hpp (from rev 959, store/trunk/cpp/lib/jrnl/dtx_rec.hpp)
===================================================================
--- store/trunk/cpp/lib/jrnl/txn_rec.hpp (rev 0)
+++ store/trunk/cpp/lib/jrnl/txn_rec.hpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -0,0 +1,88 @@
+/**
+* \file txn_rec.hpp
+*
+* Red Hat Messaging - Message Journal
+*
+* This file contains the code for the rhm::journal::txn_rec (journal data
+* record) class. See class documentation for details.
+*
+* \author Kim van der Riet
+*
+* Copyright 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 rhm_journal_txn_rec_hpp
+#define rhm_journal_txn_rec_hpp
+
+namespace rhm
+{
+namespace journal
+{
+class txn_rec;
+}
+}
+
+#include <jrnl/jrec.hpp>
+
+namespace rhm
+{
+namespace journal
+{
+
+ /**
+ * \class txn_rec
+ * \brief Class to handle a single journal DTX commit or abort record.
+ */
+ class txn_rec : public jrec
+ {
+ private:
+ txn_hdr _txn_hdr; ///< transaction header
+ std::string _xid; ///< XID
+ rec_tail _dtx_tail; ///< Record tail
+
+ public:
+ txn_rec();
+ txn_rec(const u_int32_t magic, const u_int64_t rid);
+ txn_rec(const u_int32_t magic, const u_int64_t rid, const std::string& xid);
+ ~txn_rec();
+
+ void reset(const u_int64_t rid);
+ void reset(const u_int64_t rid, const std::string& xid);
+ u_int32_t encode(void* wptr, u_int32_t rec_offs_dblks, u_int32_t max_size_dblks)
+ throw (jexception);
+ u_int32_t decode(hdr& h, void* rptr, u_int32_t rec_offs_dblks, u_int32_t max_size_dblks)
+ throw (jexception);
+ std::string& str(std::string& str) const;
+ inline const size_t data_size() const { return 0; } // This record never carries data
+ const size_t xid_size() const;
+ const size_t rec_size() const;
+
+ private:
+ void chk_hdr() const throw (jexception);
+ void chk_hdr(u_int64_t rid) const throw (jexception);
+ void chk_tail() const throw (jexception);
+ }; // class txn_rec
+
+} // namespace journal
+} // namespace rhm
+
+#endif // ifndef rhm_journal_txn_rec_hpp
Modified: store/trunk/cpp/lib/jrnl/wmgr.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/wmgr.cpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/lib/jrnl/wmgr.cpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -86,11 +86,14 @@
}
const iores
-wmgr::enqueue(const void* const data_buff, const size_t tot_data_len,
- const size_t /*this_data_len*/, data_tok* dtokp, const bool transient)
+wmgr::enqueue(const void* const data_buff, const size_t tot_data_len, const size_t this_data_len,
+ data_tok* dtokp, const void* const xid_ptr, const size_t xid_len, const bool transient)
throw (jexception)
{
- if (transient)
+ if (xid_len)
+ assert(xid_ptr != NULL);
+
+ if (this_data_len != tot_data_len)
return RHM_IORES_NOTIMPL;
if (_deq_busy)
@@ -124,7 +127,7 @@
else
rid = cont ? _wrfc.rid() - 1 : _wrfc.get_incr_rid();
- _enq_rec.reset(rid, data_buff, tot_data_len);
+ _enq_rec.reset(rid, data_buff, tot_data_len, xid_ptr, xid_len, transient);
if (!cont)
dtokp->set_rid(rid);
bool done = false;
@@ -216,16 +219,11 @@
}
const iores
-wmgr::enqueue_tx(const void* const /*data_buff*/, const size_t /*tot_data_len*/,
- const size_t /*this_data_len*/, data_tok* /*dtokp*/, const std::string& /*xid*/,
- const bool /*transient*/) throw (jexception)
+wmgr::dequeue(data_tok* dtokp, const void* const xid_ptr, const size_t xid_len) throw (jexception)
{
- return RHM_IORES_NOTIMPL;
-}
+ if (xid_len)
+ assert(xid_ptr != NULL);
-const iores
-wmgr::dequeue(data_tok* dtokp) throw (jexception)
-{
if (_enq_busy)
return RHM_IORES_BUSY;
@@ -342,57 +340,10 @@
if (dtokp->wstate() >= data_tok::DEQ_SUBM)
_deq_busy = false;
-// iores res = pre_write_check(false, dtokp);
-// if (res != RHM_IORES_SUCCESS)
-// return res;
-//
-// u_int64_t rid;
-//
-// if (dtokp->getSourceMessage())
-// {
-// rid = dtokp->dequeue_rid();
-// assert(rid != 0);
-// }
-// else
-// rid = _wrfc.get_incr_rid();
-//
-// //***
-// // NOTE: ASSUMPTION: sizeof(deq_hdr) <= JRNL_DBLK_SIZE
-// // This encoding is a simplification: it assumes deq_hdr (currently 20 bytes) fits inside
-// // one dblk. The dblk is a tunable parameter, but is unlikely to go lower than deq_hdr
-// // (currently dblk = 128 bytes). JRNL_DBLK_SIZE must be a power of 2.
-// // IF JRNL_DBLK_SIZE IS SET TO < 32 (i.e. 16 OR LESS) BYTES, THIS ENCODING WILL FAIL!
-// //***
-// deq_hdr dhdr(RHM_JDAT_DEQ_MAGIC, rid, dtokp->rid(), 0, RHM_JDAT_VERSION);
-// void* wptr = (void*)((char*)_page_ptr_arr[_pg_index] + _pg_offset_dblks * JRNL_DBLK_SIZE);
-// ::memcpy(wptr, &dhdr, sizeof(dhdr));
-// #ifdef RHM_CLEAN
-// ::memset((char*)wptr + sizeof(dhdr), RHM_CLEAN_CHAR, JRNL_DBLK_SIZE - sizeof(dhdr));
-// #endif
-// #if !(defined RHM_WRONLY || defined RHM_RDONLY)
-// u_int16_t fid = _emap.get_remove_fid(dtokp->rid());
-// _wrfc.decr_enqcnt(fid);
-// #endif
-// _pg_offset_dblks++;
-// _cached_offset_dblks++;
-// // TODO: Incorrect - must set state to DEQ_CACHED; DEQ_SUBM is set when AIO returns.
-// dtokp->set_wstate(data_tok::DEQ_SUBM);
-// _page_cb_arr[_pg_index]._pdtokl->push_back(dtokp);
-// if (_wrfc.empty()) // Has the file_hdr been written?
-// write_fhdr(rid, _wrfc.index(), JRNL_SBLK_SIZE * JRNL_DBLK_SIZE);
-// if (_pg_offset_dblks >= JRNL_WMGR_PAGE_SIZE * JRNL_SBLK_SIZE)
-// res = flush();
-
return res;
}
const iores
-wmgr::dequeue_tx(data_tok* /*dtokp*/, const std::string& /*xid*/) throw (jexception)
-{
- return RHM_IORES_NOTIMPL;
-}
-
-const iores
wmgr::flush()
{
iores res = write_flush();
@@ -626,7 +577,7 @@
void
wmgr::write_fhdr(u_int64_t rid, u_int32_t fid, size_t fro) throw (jexception)
{
- file_hdr fhdr(RHM_JDAT_FILE_MAGIC, rid, fid, fro, true, RHM_JDAT_VERSION);
+ file_hdr fhdr(RHM_JDAT_FILE_MAGIC, RHM_JDAT_VERSION, 0, rid, fid, fro, true);
::memcpy(_fhdr_buff, &fhdr, sizeof(fhdr));
#ifdef RHM_CLEAN
::memset((char*)_fhdr_buff + sizeof(fhdr), RHM_CLEAN_CHAR, _sblksize - sizeof(fhdr));
Modified: store/trunk/cpp/lib/jrnl/wmgr.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/wmgr.hpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/lib/jrnl/wmgr.hpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -88,13 +88,10 @@
void initialize(std::deque<data_tok*>* const dtokl, aio_cb wr_cb,
const u_int32_t max_dtokpp, const u_int32_t max_iowait_us) throw (jexception);
const iores enqueue(const void* const data_buff, const size_t tot_data_len,
- const size_t this_data_len, data_tok* dtokp, const bool transient)
+ const size_t this_data_len, data_tok* dtokp, const void* const xid_ptr,
+ const size_t xid_len, const bool transient) throw (jexception);
+ const iores dequeue(data_tok* dtokp, const void* const xid_ptr, const size_t xid_len)
throw (jexception);
- const iores enqueue_tx(const void* const data_buff, const size_t tot_data_len,
- const size_t this_data_len, data_tok* dtokp, const std::string& xid,
- const bool transient) throw (jexception);
- const iores dequeue(data_tok* dtokp) throw (jexception);
- const iores dequeue_tx(data_tok* dtokp, const std::string& xid) throw (jexception);
const iores flush();
const u_int32_t get_events(page_state state) throw (jexception);
Modified: store/trunk/cpp/tests/jrnl/JournalSystemTests.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/JournalSystemTests.cpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/tests/jrnl/JournalSystemTests.cpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -573,151 +573,153 @@
void EncodeTest_000()
{
- runEncodeTest(0, 0, 0, false, 2, "Empty journal");
+ runEncodeTest(0, 0, 0, false, 0, 0, false, 2, "Empty journal");
}
void EncodeTest_001()
{
- runEncodeTest(1, 10, 10, false, 2, "1*(10 bytes)");
+ runEncodeTest(1, 10, 10, false, 0, 0, false, 2, "1*(10 bytes)");
}
void EncodeTest_002()
{
- runEncodeTest(1, 10, 10, true, 2, "1*(10 bytes), auto-deq");
+ runEncodeTest(1, 10, 10, true, 0, 0, false, 2, "1*(10 bytes), auto-deq");
}
void EncodeTest_003()
{
- runEncodeTest(10, 10, 10, false, 2, "10*(10 bytes)");
+ runEncodeTest(10, 10, 10, false, 0, 0, false, 2, "10*(10 bytes)");
}
void EncodeTest_004()
{
- runEncodeTest(10, 10, 10, true, 2, "10*(10 bytes), auto-deq");
+ runEncodeTest(10, 10, 10, true, 0, 0, false, 2, "10*(10 bytes), auto-deq");
}
void EncodeTest_005()
{
- runEncodeTest(10, 92, 92, false, 2, "10*(1 dblk exact fit)");
+ runEncodeTest(10, 92, 92, false, 0, 0, false, 2, "10*(1 dblk exact fit)");
}
void EncodeTest_006()
{
- runEncodeTest(10, 92, 92, true, 2, "10*(1 dblk exact fit), auto-deq");
+ runEncodeTest(10, 92, 92, true, 0, 0, false, 2, "10*(1 dblk exact fit), auto-deq");
}
void EncodeTest_007()
{
- runEncodeTest(10, 93, 93, false, 2, "10*(1 dblk + 1 byte)");
+ runEncodeTest(10, 93, 93, false, 0, 0, false, 2, "10*(1 dblk + 1 byte)");
}
void EncodeTest_008()
{
- runEncodeTest(10, 93, 93, true, 2, "10*(1 dblk + 1 byte), auto-deq");
+ runEncodeTest(10, 93, 93, true, 0, 0, false, 2, "10*(1 dblk + 1 byte), auto-deq");
}
void EncodeTest_009()
{
- runEncodeTest(10, 476, 476, false, 2, "10*(1 sblk exact fit)");
+ runEncodeTest(10, 476, 476, false, 0, 0, false, 2, "10*(1 sblk exact fit)");
}
void EncodeTest_010()
{
- runEncodeTest(10, 476, 476, true, 2, "10*(1 sblk exact fit), auto-deq");
+ runEncodeTest(10, 476, 476, true, 0, 0, false, 2, "10*(1 sblk exact fit), auto-deq");
}
void EncodeTest_011()
{
- runEncodeTest(10, 477, 477, false, 2, "10*(1 sblk + 1 byte)");
+ runEncodeTest(10, 477, 477, false, 0, 0, false, 2, "10*(1 sblk + 1 byte)");
}
void EncodeTest_012()
{
- runEncodeTest(10, 477, 477, true, 2, "10*(1 sblk + 1 byte), auto-deq");
+ runEncodeTest(10, 477, 477, true, 0, 0, false, 2, "10*(1 sblk + 1 byte), auto-deq");
}
void EncodeTest_013()
{
- runEncodeTest(8, 4060, 4060, false, 2, "8*(1/8 page)");
+ runEncodeTest(8, 4060, 4060, false, 0, 0, false, 2, "8*(1/8 page)");
}
void EncodeTest_014()
{
- runEncodeTest(9, 4060, 4060, false, 2, "9*(1/8 page)");
+ runEncodeTest(9, 4060, 4060, false, 0, 0, false, 2, "9*(1/8 page)");
}
void EncodeTest_015()
{
- runEncodeTest(8, 4061, 4061, false, 2, "8*(1/8 page + 1 byte)");
+ runEncodeTest(8, 4061, 4061, false, 0, 0, false, 2, "8*(1/8 page + 1 byte)");
}
void EncodeTest_016()
{
- runEncodeTest(8, 3932, 3932, true, 2, "8*(1/8 page - 1 dblk for deq record), auto-deq");
+ runEncodeTest(8, 3932, 3932, true, 0, 0, false, 2,
+ "8*(1/8 page - 1 dblk for deq record), auto-deq");
}
void EncodeTest_017()
{
- runEncodeTest(9, 3932, 3932, true, 2, "9*(1/8 page - 1 dblk for deq record), auto-deq");
+ runEncodeTest(9, 3932, 3932, true, 0, 0, false, 2,
+ "9*(1/8 page - 1 dblk for deq record), auto-deq");
}
void EncodeTest_018()
{
- runEncodeTest(8, 3933, 3933, true, 2,
+ runEncodeTest(8, 3933, 3933, true, 0, 0, false, 2,
"8*(1/8 page - 1 dblk for deq record + 1 byte), auto-deq");
}
void EncodeTest_019()
{
- runEncodeTest(32, 32732, 32732, false, 2, "32*(1 page exact fit)");
+ runEncodeTest(32, 32732, 32732, false, 0, 0, false, 2, "32*(1 page exact fit)");
}
void EncodeTest_020()
{
- runEncodeTest(33, 32732, 32732, false, 2, "33*(1 page exact fit)");
+ runEncodeTest(33, 32732, 32732, false, 0, 0, false, 2, "33*(1 page exact fit)");
}
void EncodeTest_021()
{
- runEncodeTest(22, 49116, 49116, false, 2, "22*(1.5 pages)");
+ runEncodeTest(22, 49116, 49116, false, 0, 0, false, 2, "22*(1.5 pages)");
}
void EncodeTest_022()
{
- runEncodeTest(22, 48988, 48988, true, 2,
+ runEncodeTest(22, 48988, 48988, true, 0, 0, false, 2,
"22*(1.5 pages - 1 dblk for deq record), auto-deq");
}
void EncodeTest_023()
{
- runEncodeTest(48, 32732, 32732, false, 2, "48*(1 page exact fit)");
+ runEncodeTest(48, 32732, 32732, false, 0, 0, false, 2, "48*(1 page exact fit)");
}
void EncodeTest_024()
{
- runEncodeTest(49, 32732, 32732, false, 2, "49*(1 page exact fit)");
+ runEncodeTest(49, 32732, 32732, false, 0, 0, false, 2, "49*(1 page exact fit)");
}
void EncodeTest_025()
{
- runEncodeTest(20, 81884, 81884, false, 2, "20*(2.5 pages)");
+ runEncodeTest(20, 81884, 81884, false, 0, 0, false, 2, "20*(2.5 pages)");
}
void EncodeTest_026()
{
- runEncodeTest(20, 81756, 81756, true, 2,
+ runEncodeTest(20, 81756, 81756, true, 0, 0, false, 2,
"20*(2.5 pages - 1 dblk for deq record), auto-deq");
}
void EncodeTest_027()
{
- runEncodeTest(16, 786268, 786268, true, 2,
+ runEncodeTest(16, 786268, 786268, true, 0, 0, false, 2,
"16*(24 pages = 1/2 file); Total = 8 files exactly (full journal filespace)");
}
void EncodeTest_028()
{
- runEncodeTest(17, 786268, 786268, true, 2,
+ runEncodeTest(17, 786268, 786268, true, 0, 0, false, 2,
"17*(24 pages = 1/2 file); Total = 8 files + file 0 overwritten by 1/2 file");
}
@@ -807,11 +809,13 @@
}
void runEncodeTest(const unsigned num_msgs, const unsigned min_msg_size,
- const unsigned max_msg_szie, const bool auto_deq, const unsigned iterations,
+ const unsigned max_msg_szie, const bool auto_deq, const unsigned min_xid_size,
+ const unsigned max_xid_size, const bool transient, const unsigned iterations,
const char* test_descr)
{
std::cout << " [" << test_descr << "] " << std::flush;
- jtest::targs ta(num_msgs, min_msg_size, max_msg_szie, auto_deq, test_descr);
+ jtest::targs ta(num_msgs, min_msg_size, max_msg_szie, auto_deq, min_xid_size,
+ max_xid_size, transient, test_descr);
for (unsigned i=0; i<iterations; i++)
{
std::cout << "." << std::flush;
Modified: store/trunk/cpp/tests/jrnl/Makefile.rtest
===================================================================
--- store/trunk/cpp/tests/jrnl/Makefile.rtest 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/tests/jrnl/Makefile.rtest 2007-10-02 20:45:10 UTC (rev 960)
@@ -58,7 +58,7 @@
jrec.o \
enq_rec.o \
deq_rec.o \
- dtx_rec.o \
+ txn_rec.o \
nlfh.o \
lfh.o \
rrfc.o \
Modified: store/trunk/cpp/tests/jrnl/janalyze.py
===================================================================
--- store/trunk/cpp/tests/jrnl/janalyze.py 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/tests/jrnl/janalyze.py 2007-10-02 20:45:10 UTC (rev 960)
@@ -31,6 +31,8 @@
num_files = 8
hdr_ver = 1
+transient_mask = 0x1
+
def load(f, klass):
args = load_args(f, klass)
subclass = klass.descriminate(args)
@@ -347,6 +349,7 @@
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))
@@ -356,10 +359,18 @@
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']
else:
+ self.tnum = None
self.num_msgs = 0
self.msg_len = 0
self.auto_deq = False
+ self.xid_len = 0
+ self.transient = False
self.file_start = 0
self.file_num = 0
self.fro = 0x200
@@ -407,7 +418,15 @@
break
hdr.load(self.f)
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))
+ 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:
+ if hdr.flags & transient_mask == 0:
+ raise Exception('Expected transient record, found persistent')
+ else:
+ if hdr.flags & transient_mask != 0:
+ raise Exception('Expected persistent record, found transient')
stop = not self.check_rid(hdr)
if stop:
warn = ' (WARNING: rid out of order, last rid = %d - could be overwrite boundary.)' % hdr.rid
@@ -424,7 +443,7 @@
stop = not self.check_rid(hdr)
if stop:
warn = ' (WARNING: rid out of order, last rid = %d - could be overwrite boundary.)' % hdr.rid
- else:
+ elif self.tnum != None:
warn = 'WARNING: Dequeue record rid=%d found in non-dequeue test - ignoring.' % hdr.rid
print ' > %s%s' % (hdr, warn)
if not stop:
@@ -487,7 +506,10 @@
return { 'num_msgs':int(sl[1]),
'min_size':int(sl[2]),
'max_size':int(sl[3]),
- 'auto_deq':sl[4] != 'FALSE' }
+ 'auto_deq':sl[4] != 'FALSE',
+ 'xid_min_size':int(sl[5]),
+ 'xid_max_size':int(sl[6]),
+ 'transient':sl[7] != 'FALSE' }
except Exception:
pass
return None
Modified: store/trunk/cpp/tests/jrnl/jtest.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/jtest.cpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/tests/jrnl/jtest.cpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -76,15 +76,22 @@
_min_msg_size(0),
_max_msg_size(0),
_auto_deq(false),
+ _min_xid_size(0),
+ _max_xid_size(0),
+ _transient(false),
_comment(NULL)
{}
-jtest::targs::targs(const u_int32_t num_msgs, const size_t min_msg_size, const size_t max_msg_size, const bool auto_deq,
- const char* comment):
+jtest::targs::targs(const u_int32_t num_msgs, const size_t min_msg_size, const size_t max_msg_size,
+ const bool auto_deq, const size_t min_xid_size, const size_t max_xid_size,
+ const bool transient, const 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),
_comment(comment)
{}
@@ -126,8 +133,9 @@
#endif
p_args = new msg_producer::_p_args(_jc, ta._num_msgs, ta._min_msg_size, ta._max_msg_size,
- ta._auto_deq);
- c_args = new msg_consumer::_c_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);
+ 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);
#ifndef RHM_RDONLY
_mp.initialize(p_args);
@@ -371,8 +379,11 @@
tap->_min_msg_size = atol(toks[2]);
tap->_max_msg_size = atol(toks[3]);
tap->_auto_deq = strcmp(toks[4], "FALSE") != 0;
- if (toks.size() > 5)
- tap->_comment = toks[5];
+ tap->_min_xid_size = atol(toks[5]);
+ tap->_max_xid_size = atol(toks[6]);
+ tap->_transient = strcmp(toks[7], "FALSE") != 0;
+ if (toks.size() > 8)
+ tap->_comment = toks[8];
else
tap->_comment = NULL;
std::cout << "Test " << tnum << ": Messages=" << tap->_num_msgs << " Size=" <<
@@ -382,6 +393,15 @@
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;
Modified: store/trunk/cpp/tests/jrnl/jtest.hpp
===================================================================
--- store/trunk/cpp/tests/jrnl/jtest.hpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/tests/jrnl/jtest.hpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -53,10 +53,14 @@
size_t _min_msg_size;
size_t _max_msg_size;
bool _auto_deq;
+ size_t _min_xid_size;
+ size_t _max_xid_size;
+ bool _transient;
const char* _comment;
targs();
- targs(const u_int32_t num_msgs, const size_t min_msg_size, const size_t max_msg_size, const bool auto_deq = false,
- const char* comment = NULL);
+ targs(const u_int32_t num_msgs, const size_t min_msg_size, const size_t max_msg_size,
+ const bool auto_deq, const size_t min_xid_size, const size_t max_xid_size,
+ const bool transient, const char* comment = NULL);
};
private:
Modified: store/trunk/cpp/tests/jrnl/msg_consumer.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/msg_consumer.cpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/tests/jrnl/msg_consumer.cpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -37,12 +37,16 @@
#define EXCEPTION_BASE 0x40
-msg_consumer::_c_args::_c_args(rhm::journal::jcntl& jc, u_int32_t num_msgs, size_t min_msg_size,
- size_t max_msg_size):
+msg_consumer::_c_args::_c_args(rhm::journal::jcntl& jc, const u_int32_t num_msgs,
+ const size_t min_msg_size, const size_t max_msg_size, const size_t min_xid_size,
+ const size_t max_xid_size, const bool transient):
_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),
_err(0)
{}
@@ -90,7 +94,8 @@
u_int32_t
msg_consumer::consume(rhm::journal::jcntl& _jcntl, const u_int32_t num_msgs,
- const size_t min_msg_size, const size_t max_msg_size) throw (rhm::journal::jexception)
+ const size_t min_msg_size, const size_t max_msg_size, const size_t /*min_xid_size*/,
+ const size_t /*max_xid_size*/, const bool /*transient*/) throw (rhm::journal::jexception)
{
//std::cout << "msg_consumer::consume() num_msgs=" << num_msgs << std::endl;
size_t data_size;
@@ -181,7 +186,8 @@
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);
+ 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);
}
void
Modified: store/trunk/cpp/tests/jrnl/msg_consumer.hpp
===================================================================
--- store/trunk/cpp/tests/jrnl/msg_consumer.hpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/tests/jrnl/msg_consumer.hpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -49,9 +49,13 @@
u_int32_t _num_msgs;
size_t _min_msg_size;
size_t _max_msg_size;
+ size_t _min_xid_size;
+ size_t _max_xid_size;
+ bool _transient;
u_int32_t _err;
- _c_args(rhm::journal::jcntl& jc, u_int32_t num_msgs, size_t min_msg_size,
- size_t max_msg_size);
+ _c_args(rhm::journal::jcntl& jc, const u_int32_t num_msgs, const size_t min_msg_size,
+ const size_t max_msg_size, const size_t min_xid_size, const size_t max_xid_size,
+ const bool transient);
};
static const char* iores_str[];
@@ -76,7 +80,8 @@
void finalize();
u_int32_t consume(rhm::journal::jcntl& _jcntl, const u_int32_t numMsgs,
- const size_t min_msg_size, const size_t max_msg_size) throw (rhm::journal::jexception);
+ const size_t min_msg_size, const size_t max_msg_size, const size_t min_xid_size,
+ const size_t max_xid_size, const bool transient) throw (rhm::journal::jexception);
u_int32_t consume(_c_args* args) throw (rhm::journal::jexception);
void aio_callback(rhm::journal::jcntl* jc, u_int32_t num_dtoks);
Modified: store/trunk/cpp/tests/jrnl/msg_producer.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/msg_producer.cpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/tests/jrnl/msg_producer.cpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -36,12 +36,16 @@
#define EXCEPTION_BASE 0x50
msg_producer::_p_args::_p_args(rhm::journal::jcntl& jc, u_int32_t num_msgs,
- size_t min_msg_size, size_t max_msg_size, bool auto_dequeue):
+ size_t min_msg_size, size_t max_msg_size, bool auto_dequeue, size_t min_xid_size,
+ size_t max_xid_size, bool transient):
_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),
_err(0)
{}
@@ -58,6 +62,7 @@
{
instance_cnt++;
init_msg_buff();
+ init_xid_buff();
_aio_cmpl_dtok_list.clear();
_dd_dtok_list.clear();
}
@@ -104,8 +109,9 @@
}
u_int32_t
-msg_producer::produce(rhm::journal::jcntl& jc, const size_t minMsgSize,
- const size_t maxMsgSize) throw (rhm::journal::jexception)
+msg_producer::produce(rhm::journal::jcntl& jc, const size_t minMsgSize, const size_t maxMsgSize,
+ const size_t minXidSize, const size_t maxXidSize, const bool transient)
+ throw (rhm::journal::jexception)
{
_jcptr = &jc;
if (!_num_msgs)
@@ -113,25 +119,40 @@
if (maxMsgSize > _msg_buff_size)
throw rhm::journal::jexception(EXCEPTION_BASE+0,
"Message size exceeds internal buffer limit", "msg_producer", "produce");
+ if (maxXidSize > _xid_buff_size)
+ throw rhm::journal::jexception(EXCEPTION_BASE+1,
+ "XID 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;
+ size_t xid_size = maxXidSize;
+ if (minXidSize < maxXidSize)
+ {
+ size_t sizeRange = maxXidSize - minXidSize + 1;
+ xid_size = minXidSize + (int)(1.0*rand()*sizeRange/(RAND_MAX + 1.0));
+ }
+ const std::string xid((char*)_xid_buff + (msgCntr%26), xid_size);
size_t size = maxMsgSize;
if (minMsgSize < maxMsgSize)
{
size_t sizeRange = maxMsgSize - minMsgSize + 1;
size = minMsgSize + (int)(1.0*rand()*sizeRange/(RAND_MAX + 1.0));
}
+ const void* const msg = (char*)_msg_buff + (msgCntr%10);
rhm::journal::data_tok* dtokp = _dtok_master_list[msgCntr];
- const void* const msg = (char*)_msg_buff + (msgCntr%10);
//std::cout << " E" << dtokp->id() << /*"-" << dtokp->wstate_str() <<*/ " " << std::flush;
bool written = false;
while (!written)
{
- rhm::journal::iores eres = jc.enqueue_data_record(msg, size, size, dtokp, false);
+ rhm::journal::iores eres;
+ if (maxXidSize)
+ eres = jc.enqueue_txn_data_record(msg, size, size, dtokp, xid, 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)
@@ -154,7 +175,7 @@
dtokp->id() << " ws=" << wsstr << " eres=" << iores_str[eres] <<
std::flush;
if (aio_sleep_cnt >= MAX_AIO_SLEEPS)
- throw rhm::journal::jexception(EXCEPTION_BASE+1,
+ throw rhm::journal::jexception(EXCEPTION_BASE+2,
"Page cache full (AIO events outstanding for all pages); "
"exceeced wait time for pages to free.", "msg_producer",
"produce");
@@ -172,7 +193,7 @@
std::cout << "WARNING: Journal full." << std::flush;
}
if (jfull_sleep_cnt >= MAX_FULL_SLEEPS)
- throw rhm::journal::jexception(EXCEPTION_BASE+2,
+ 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");
@@ -184,6 +205,9 @@
std::cout << "msg_producer::produce() Unexpected msg state: id=" <<
dtokp->id() << " ws=" << wsstr << " eres=" << iores_str[eres] <<
std::flush;
+ throw rhm::journal::jexception(EXCEPTION_BASE+4,
+ "Unknown return from enqueue() or enqueue_tx()", "msg_producer",
+ "produce");
}
//print_dbug(msgCntr, size, (char*)msg, true);
@@ -199,7 +223,7 @@
while (!_dd_dtok_list.empty() && !_interrupt_flag)
{
if (++cnt > 10000)
- throw rhm::journal::jexception(EXCEPTION_BASE+3,
+ throw rhm::journal::jexception(EXCEPTION_BASE+5,
"Timeout waiting for all messages to be read.", "msg_producer",
"produce");
usleep(1000);
@@ -223,7 +247,8 @@
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);
+ return produce(args->_jc, args->_min_msg_size, args->_max_msg_size, args->_min_xid_size,
+ args->_max_xid_size, args->_transient);
}
void
@@ -263,6 +288,13 @@
}
void
+msg_producer::init_xid_buff()
+{
+ for (unsigned int i=0; i<_xid_buff_size; i++)
+ _xid_buff[i] = 'a' + i%26;
+}
+
+void
msg_producer::send_deferred_dequeues(rhm::journal::jcntl& jc)
{
std::deque<rhm::journal::data_tok*>::iterator ditr = _dd_dtok_list.begin();
@@ -290,7 +322,7 @@
break;
case rhm::journal::RHM_IORES_AIO_WAIT:
if (aio_sleep_cnt >= MAX_AIO_SLEEPS)
- throw rhm::journal::jexception(EXCEPTION_BASE+4,
+ throw rhm::journal::jexception(EXCEPTION_BASE+6,
"Page cache full (AIO events outstanding for all pages); "
"exceeced wait time for pages to free.", "msg_producer",
"send_deferred_dequeues");
@@ -329,7 +361,7 @@
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+5, ss.str(), "msg_producer",
+ throw rhm::journal::jexception(EXCEPTION_BASE+7, ss.str(), "msg_producer",
"jrnl_flush");
}
//std::cout << "+" << std::flush;
@@ -348,7 +380,7 @@
while (!_dd_dtok_list.empty() && !_interrupt_flag)
{
if (++cnt > 10000)
- throw rhm::journal::jexception(EXCEPTION_BASE+6,
+ throw rhm::journal::jexception(EXCEPTION_BASE+8,
"Timeout waiting for all messages to be read.", "msg_producer",
"jrnl_flush");
usleep(1000);
@@ -368,7 +400,7 @@
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+7, ss.str(), "msg_producer",
+ throw rhm::journal::jexception(EXCEPTION_BASE+9, ss.str(), "msg_producer",
"jrnl_flush");
}
//std::cout << "*" << std::flush;
@@ -417,11 +449,15 @@
"RHM_IORES_AIO_WAIT",
"RHM_IORES_EMPTY",
"RHM_IORES_FULL",
- "RHM_IORES_BUSY"
+ "RHM_IORES_BUSY",
+ "RHM_IORES_TXPENDING",
+ "RHM_IORES_NOTIMPL"
};
u_int16_t msg_producer::instance_cnt = 0;
const size_t msg_producer::_msg_buff_size = JRNL_DBLK_SIZE * JRNL_SBLK_SIZE * JRNL_FILE_SIZE * JRNL_NUM_FILES;
+const size_t msg_producer::_xid_buff_size = JRNL_DBLK_SIZE * JRNL_SBLK_SIZE * JRNL_FILE_SIZE * JRNL_NUM_FILES;
char msg_producer::_msg_buff[msg_producer::_msg_buff_size];
+char msg_producer::_xid_buff[msg_producer::_xid_buff_size];
bool msg_producer::_interrupt_flag = false;
Modified: store/trunk/cpp/tests/jrnl/msg_producer.hpp
===================================================================
--- store/trunk/cpp/tests/jrnl/msg_producer.hpp 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/tests/jrnl/msg_producer.hpp 2007-10-02 20:45:10 UTC (rev 960)
@@ -50,9 +50,13 @@
size_t _min_msg_size;
size_t _max_msg_size;
bool _auto_dequeue;
+ size_t _min_xid_size;
+ size_t _max_xid_size;
+ bool _transient;
u_int32_t _err;
_p_args(rhm::journal::jcntl& jc, u_int32_t num_msgs, size_t min_msg_size,
- size_t max_msg_size, bool auto_dequeue);
+ size_t max_msg_size, bool auto_dequeue, size_t min_xid_size,
+ size_t max_xid_size, bool transient);
};
static const char* iores_str[];
@@ -61,6 +65,8 @@
static u_int16_t instance_cnt;
static const size_t _msg_buff_size;
static char _msg_buff[];
+ static const size_t _xid_buff_size;
+ static char _xid_buff[];
static bool _interrupt_flag;
rhm::journal::jcntl* _jcptr;
u_int32_t _num_msgs;
@@ -83,7 +89,8 @@
void initialize(_p_args* args);
void finalize();
- u_int32_t produce(rhm::journal::jcntl& jc, const size_t minMsgSize, const size_t maxMsgSize)
+ u_int32_t produce(rhm::journal::jcntl& jc, const size_t minMsgSize, const size_t maxMsgSize,
+ const size_t minXidSize, const size_t maxXidSize, const bool transient)
throw (rhm::journal::jexception);
u_int32_t produce(_p_args* args) throw (rhm::journal::jexception);
void aio_callback(rhm::journal::jcntl* jc, u_int32_t num_dtoks);
@@ -95,6 +102,7 @@
private:
void init_msg_buff();
+ void init_xid_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, size_t msg_size, char* _msg_buff, bool show_msg = false) const;
Modified: store/trunk/cpp/tests/jrnl/rtest
===================================================================
--- store/trunk/cpp/tests/jrnl/rtest 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/tests/jrnl/rtest 2007-10-02 20:45:10 UTC (rev 960)
@@ -36,7 +36,7 @@
W_DO_TEST=T
W_TEST_FILE=wtests.csv
W_TEST_START=0
-W_TEST_STOP=67
+W_TEST_STOP=99
W_NITER=5
# Read test
Modified: store/trunk/cpp/tests/jrnl/rtests.csv
===================================================================
--- store/trunk/cpp/tests/jrnl/rtests.csv 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/tests/jrnl/rtests.csv 2007-10-02 20:45:10 UTC (rev 960)
@@ -1,72 +1,72 @@
-"Initialize only",,,,,,
-0,0,0,0,FALSE,,"No messages"
-,,,,,,
-"Within first block, page, file",,,,,,
-1,1,10,10,FALSE,,"10-byte message"
-2,10,10,10,FALSE,,"10-byte message"
-3,1,10,10,TRUE,,"10-byte message"
-4,10,10,10,TRUE,,"10-byte message"
-,,,,,,
-"Transition from one d-block to two per message",,,,,,
-5,10,84,84,FALSE,,"1 dblk exact fit"
-6,10,85,85,FALSE,,"1 dblk + 1 byte"
-7,10,84,84,TRUE,,"1 dblk exact fit"
-8,10,85,85,TRUE,,"1 dblk + 1 byte"
-,,,,,,
-"Transition from one s-block to two per message",,,,,,
-9,10,468,468,FALSE,,"1 sblk exact fit"
-10,10,469,469,FALSE,,"1 sblk + 1 byte"
-11,10,468,468,TRUE,,"1 sblk exact fit"
-12,10,469,469,TRUE,,"1 sblk + 1 byte"
-,,,,,,
-"Transition from first page to second",,,,,,
-13,8,8148,8148,FALSE,,"8 * 1/8 page; Total = 1 page exact fit"
-14,9,8148,8148,FALSE,,"9 * 1/8 page"
-15,8,8149,8149,FALSE,,"8 * (1/8 page + 1 byte)"
-16,8,8020,8020,TRUE,,"8 * (1/8 page – 1 dblk for deq record); Total = 1 page exact fit with deqs"
-17,9,8020,8020,TRUE,,"9 * (1/8 page – 1 dblk for deq record)"
-18,8,8021,8021,TRUE,,"8 * (1/8 page – 1 dblk for deq record + 1 byte)"
-,,,,,,
-"Page cache rollover (from last page back to page 0) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,
-19,16,65492,65492,FALSE,,"16 * (1 page exact fit); Total = entire cache exactly"
-20,17,65492,65492,FALSE,,"17 * (1 page exact fit); Total = entire cache + reuse of 1 page"
-21,11,98260,98260,FALSE,,"11 * 1.5 pages"
-22,11,98132,98132,TRUE,,"11 * (1.5 pages including 1 sblk for deq record)"
-,,,,,,
-"File transition (from file 0000 to 0001) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,
-23,24,65492,65492,FALSE,,"24 * (1 page exact fit); Total = entire file exactly"
-24,25,65492,65492,FALSE,,"25 * (1 page exact fit); Total = entire file + 1 page"
-25,10,163796,163796,FALSE,,"10 * (2.5 pages); Total = entire file + 2 pages"
-26,10,163668,163668,TRUE,,"10 * (2.5 pages including 1 sblk for deq record); Total = entire file + 2 pages"
-,,,,,,
-"File rollover (from file 0007 to 0000) - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,
-27,16,786388,786388,FALSE,,"16 * (12 pages = ½ file); Total = 8 files exactly"
-,,,,,,
-"Multi-page messages (large messages) - tests various paths in encoder; no dequeues required to test this functionality.",,,,,,
-28,16,65492,65492,FALSE,,"16 * (1 page exact fit)"
-29,16,65493,65493,FALSE,,"16 * (1 page + 1 byte): tail split"
-30,16,65503,65503,FALSE,,"16 * (1 page + 11 bytes): tail split"
-31,16,65504,65504,FALSE,,"16 * (1 page + 12 bytes): tail separated exactly"
-32,16,65505,65505,FALSE,,"16 * (1 page + 13 bytes): data split"
-33,16,131028,131028,FALSE,,"16 * (2 pages exact fit)"
-34,16,131029,131029,FALSE,,"16 * (2 pages + 1 byte): tail split"
-35,16,131039,131039,FALSE,,"16 * (2 pages + 11 bytes): tail split"
-36,16,131040,131040,FALSE,,"16 * (2 pages + 12 bytes): tail separated exactly"
-37,16,131041,131041,FALSE,,"16 * (2 pages + 13 bytes) data split"
-38,16,262100,262100,FALSE,,"16 * (4 pages exact fit)"
-39,16,262101,262101,FALSE,,"16 * (4 pages + 1 byte: tail split)"
-40,16,262111,262111,FALSE,,"16 * (4 pages + 1 byte: tail split)"
-41,16,262112,262112,FALSE,,"16 * (4 pages + 12 bytes: tail separated)"
-42,16,262113,262113,FALSE,,"16 * (4 pages + 13 bytes: data split)"
-43,16,229332,229332,FALSE,,"16 * (3.5 pages)"
-44,16,229333,229333,FALSE,,"16 * (3.5 pages + 1 byte)"
-,,,,,,
-"These set up journals for circular tests (repeatedly reading same journal) Make sure value testing is off!",,,,,,
-45,98304,0,84,FALSE,,"1 dblk no dequeues"
-46,49152,0,84,TRUE,,"1 dblk with dequeues"
-47,49152,0,212,FALSE,,"2 dblk no dequeues"
-48,24576,0,212,TRUE,,"2 dblk with dequeues"
-49,32768,212,212,TRUE,,"2 dblk fixed with dequeues"
-,,,,,,
-"Circular tests",,,,,,
-50,10000000,0,0,FALSE,,"Read 10,000,000 messages from one of the circular test journals above"
+"Initialize only",,,,,,,,,
+0,0,0,0,FALSE,0,0,FALSE,,"No messages"
+,,,,,,,,,
+"Within first block, page, file",,,,,,,,,
+1,1,10,10,FALSE,0,0,FALSE,,"10-byte message"
+2,10,10,10,FALSE,0,0,FALSE,,"10-byte message"
+3,1,10,10,TRUE,0,0,FALSE,,"10-byte message"
+4,10,10,10,TRUE,0,0,FALSE,,"10-byte message"
+,,,,,,,,,
+"Transition from one d-block to two per message",,,,,,,,,
+5,10,84,84,FALSE,0,0,FALSE,,"1 dblk exact fit"
+6,10,85,85,FALSE,0,0,FALSE,,"1 dblk + 1 byte"
+7,10,84,84,TRUE,0,0,FALSE,,"1 dblk exact fit"
+8,10,85,85,TRUE,0,0,FALSE,,"1 dblk + 1 byte"
+,,,,,,,,,
+"Transition from one s-block to two per message",,,,,,,,,
+9,10,468,468,FALSE,0,0,FALSE,,"1 sblk exact fit"
+10,10,469,469,FALSE,0,0,FALSE,,"1 sblk + 1 byte"
+11,10,468,468,TRUE,0,0,FALSE,,"1 sblk exact fit"
+12,10,469,469,TRUE,0,0,FALSE,,"1 sblk + 1 byte"
+,,,,,,,,,
+"Transition from first page to second",,,,,,,,,
+13,8,8148,8148,FALSE,0,0,FALSE,,"8 * 1/8 page; Total = 1 page exact fit"
+14,9,8148,8148,FALSE,0,0,FALSE,,"9 * 1/8 page"
+15,8,8149,8149,FALSE,0,0,FALSE,,"8 * (1/8 page + 1 byte)"
+16,8,8020,8020,TRUE,0,0,FALSE,,"8 * (1/8 page – 1 dblk for deq record); Total = 1 page exact fit with deqs"
+17,9,8020,8020,TRUE,0,0,FALSE,,"9 * (1/8 page – 1 dblk for deq record)"
+18,8,8021,8021,TRUE,0,0,FALSE,,"8 * (1/8 page – 1 dblk for deq record + 1 byte)"
+,,,,,,,,,
+"Page cache rollover (from last page back to page 0) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,,,,
+19,16,65492,65492,FALSE,0,0,FALSE,,"16 * (1 page exact fit); Total = entire cache exactly"
+20,17,65492,65492,FALSE,0,0,FALSE,,"17 * (1 page exact fit); Total = entire cache + reuse of 1 page"
+21,11,98260,98260,FALSE,0,0,FALSE,,"11 * 1.5 pages"
+22,11,98132,98132,TRUE,0,0,FALSE,,"11 * (1.5 pages including 1 sblk for deq record)"
+,,,,,,,,,
+"File transition (from file 0000 to 0001) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,,,,
+23,24,65492,65492,FALSE,0,0,FALSE,,"24 * (1 page exact fit); Total = entire file exactly"
+24,25,65492,65492,FALSE,0,0,FALSE,,"25 * (1 page exact fit); Total = entire file + 1 page"
+25,10,163796,163796,FALSE,0,0,FALSE,,"10 * (2.5 pages); Total = entire file + 2 pages"
+26,10,163668,163668,TRUE,0,0,FALSE,,"10 * (2.5 pages including 1 sblk for deq record); Total = entire file + 2 pages"
+,,,,,,,,,
+"File rollover (from file 0007 to 0000) - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,,,,
+27,16,786388,786388,FALSE,0,0,FALSE,,"16 * (12 pages = ½ file); Total = 8 files exactly"
+,,,,,,,,,
+"Multi-page messages (large messages) - tests various paths in encoder; no dequeues required to test this functionality.",,,,,,,,,
+28,16,65492,65492,FALSE,0,0,FALSE,,"16 * (1 page exact fit)"
+29,16,65493,65493,FALSE,0,0,FALSE,,"16 * (1 page + 1 byte): tail split"
+30,16,65503,65503,FALSE,0,0,FALSE,,"16 * (1 page + 11 bytes): tail split"
+31,16,65504,65504,FALSE,0,0,FALSE,,"16 * (1 page + 12 bytes): tail separated exactly"
+32,16,65505,65505,FALSE,0,0,FALSE,,"16 * (1 page + 13 bytes): data split"
+33,16,131028,131028,FALSE,0,0,FALSE,,"16 * (2 pages exact fit)"
+34,16,131029,131029,FALSE,0,0,FALSE,,"16 * (2 pages + 1 byte): tail split"
+35,16,131039,131039,FALSE,0,0,FALSE,,"16 * (2 pages + 11 bytes): tail split"
+36,16,131040,131040,FALSE,0,0,FALSE,,"16 * (2 pages + 12 bytes): tail separated exactly"
+37,16,131041,131041,FALSE,0,0,FALSE,,"16 * (2 pages + 13 bytes) data split"
+38,16,262100,262100,FALSE,0,0,FALSE,,"16 * (4 pages exact fit)"
+39,16,262101,262101,FALSE,0,0,FALSE,,"16 * (4 pages + 1 byte: tail split)"
+40,16,262111,262111,FALSE,0,0,FALSE,,"16 * (4 pages + 1 byte: tail split)"
+41,16,262112,262112,FALSE,0,0,FALSE,,"16 * (4 pages + 12 bytes: tail separated)"
+42,16,262113,262113,FALSE,0,0,FALSE,,"16 * (4 pages + 13 bytes: data split)"
+43,16,229332,229332,FALSE,0,0,FALSE,,"16 * (3.5 pages)"
+44,16,229333,229333,FALSE,0,0,FALSE,,"16 * (3.5 pages + 1 byte)"
+,,,,,,,,,
+"These set up journals for circular tests (repeatedly reading same journal) Make sure value testing is off!",,,,,,,,,
+45,98304,0,84,FALSE,0,0,FALSE,,"1 dblk no dequeues"
+46,49152,0,84,TRUE,0,0,FALSE,,"1 dblk with dequeues"
+47,49152,0,212,FALSE,0,0,FALSE,,"2 dblk no dequeues"
+48,24576,0,212,TRUE,0,0,FALSE,,"2 dblk with dequeues"
+49,32768,212,212,TRUE,0,0,FALSE,,"2 dblk fixed with dequeues"
+,,,,,,,,,
+"Circular tests",,,,,,,,,
+50,10000000,0,0,FALSE,0,0,FALSE,,"Read 10,000,000 messages from one of the circular test journals above"
Modified: store/trunk/cpp/tests/jrnl/rwtests.csv
===================================================================
--- store/trunk/cpp/tests/jrnl/rwtests.csv 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/tests/jrnl/rwtests.csv 2007-10-02 20:45:10 UTC (rev 960)
@@ -1,68 +1,68 @@
-"Initialize only",,,,,,
-0,0,0,0,FALSE,,"No messages"
-,,,,,,
-"Within first block, page, file",,,,,,
-1,1,10,10,FALSE,,"10-byte message"
-2,10,10,10,FALSE,,"10-byte message"
-3,1,10,10,TRUE,,"10-byte message"
-4,10,10,10,TRUE,,"10-byte message"
-,,,,,,
-"Transition from one d-block to two per message",,,,,,
-5,10,84,84,FALSE,,"1 dblk exact fit"
-6,10,85,85,FALSE,,"1 dblk + 1 byte"
-7,10,84,84,TRUE,,"1 dblk exact fit"
-8,10,85,85,TRUE,,"1 dblk + 1 byte"
-,,,,,,
-"Transition from one s-block to two per message",,,,,,
-9,10,468,468,FALSE,,"1 sblk exact fit"
-10,10,469,469,FALSE,,"1 sblk + 1 byte"
-11,10,468,468,TRUE,,"1 sblk exact fit"
-12,10,469,469,TRUE,,"1 sblk + 1 byte"
-,,,,,,
-"Transition from first page to second",,,,,,
-13,8,4052,4052,FALSE,,"8 * 1/8 page; Total = 1 page exact fit"
-14,9,4052,4052,FALSE,,"9 * 1/8 page"
-15,8,4053,4053,FALSE,,"8 * (1/8 page + 1 byte)"
-16,8,3924,3924,TRUE,,"8 * (1/8 page - 1 dblk for deq record); Total = 1 page exact fit with deqs"
-17,9,3924,3924,TRUE,,"9 * (1/8 page - 1 dblk for deq record)"
-18,8,3925,3925,TRUE,,"8 * (1/8 page - 1 dblk for deq record + 1 byte)"
-,,,,,,
-"Page cache rollover (from page 32 back to page 0) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,
-19,32,32724,32724,FALSE,,"32 * (1 page exact fit); Total = entire cache exactly"
-20,33,32724,32724,FALSE,,"33 * (1 page exact fit); Total = entire cache + reuse of 1 page"
-21,22,49108,49108,FALSE,,"22 * 1.5 pages"
-22,22,48980,48980,TRUE,,"22 * (1.5 pages including 1 sblk for deq record)"
-,,,,,,
-"File transition (from file 0000 to 0001) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,
-23,48,32724,32724,FALSE,,"48 * (1 page exact fit); Total = entire file exactly"
-24,49,32724,32724,FALSE,,"49 * (1 page exact fit); Total = entire file + 1 page"
-25,20,81876,81876,FALSE,,"20 * (2.5 pages); Total = entire file + 2 pages"
-26,20,81748,81748,TRUE,,"20 * (2.5 pages including 1 sblk for deq record); Total = entire file + 2 pages"
-,,,,,,
-"File rollover (from file 0007 to 0000) - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,
-27,16,786388,786388,FALSE,,"16 * (24 pages = ½ file); Total = 8 files exactly"
-28,16,786260,786260,TRUE,,"16 * (24 pages = ½ file); Total = 8 files exactly"
-29,17,786260,786260,TRUE,,"17 * (24 pages = ½ file); Total = 8 files + file 0 overwritten by ½ file"
-30,16,786261,786261,TRUE,,"16 * (24 pages + 1 byte); Total = 8 files + file 0 overwritten by 16 sblks"
-31,32,786260,786260,TRUE,,"32 * (24 pages = ½ file); Total = 16 files exactly, all files overwritten once"
-32,33,786260,786260,TRUE,,"33 * (24 pages = ½ file); Total = 16 ½ files, all files overwritten once + file 0 overwritten again by ½ file"
-33,32,786261,786261,TRUE,,"32 * (24 pages + 1 byte); All files overwritten once + file 0 overwritten again by 32 sblks"
-,,,,,,
-"Multi-page messages (large messages) - tests various paths in encoder; no dequeues required to test this functionality.",,,,,,
-34,16,32724,32724,FALSE,,"16 * (1 page exact fit)"
-35,16,32725,32725,FALSE,,"16 * (1 page + 1 byte): tail split"
-36,16,32735,32735,FALSE,,"16 * (1 page + 11 bytes): tail split"
-37,16,32736,32736,FALSE,,"16 * (1 page + 12 bytes): tail separated exactly"
-38,16,32737,32737,FALSE,,"16 * (1 page + 13 bytes): data split"
-39,16,65492,65492,FALSE,,"16 * (2 pages exact fit)"
-40,16,65493,65493,FALSE,,"16 * (2 pages + 1 byte): tail split"
-41,16,65503,65503,FALSE,,"16 * (2 pages + 11 bytes): tail split"
-42,16,65504,65504,FALSE,,"16 * (2 pages + 12 bytes): tail separated exactly"
-43,16,65505,65505,FALSE,,"16 * (2 pages + 13 bytes) data split"
-44,16,131028,131028,FALSE,,"16 * (4 pages exact fit)"
-45,16,131029,131029,FALSE,,"16 * (4 pages + 1 byte: tail split)"
-46,16,131039,131039,FALSE,,"16 * (4 pages + 1 byte: tail split)"
-47,16,131040,131040,FALSE,,"16 * (4 pages + 12 bytes: tail separated)"
-48,16,131041,131041,FALSE,,"16 * (4 pages + 13 bytes: data split)"
-49,16,114644,114644,FALSE,,"16 * (3.5 pages)"
-50,16,114645,114645,FALSE,,"16 * (3.5 pages + 1 byte)"
+"Initialize only",,,,,,,,,
+0,0,0,0,FALSE,0,0,FALSE,,"No messages"
+,,,,,,,,,
+"Within first block, page, file",,,,,,,,,
+1,1,10,10,FALSE,0,0,FALSE,,"10-byte message"
+2,10,10,10,FALSE,0,0,FALSE,,"10-byte message"
+3,1,10,10,TRUE,0,0,FALSE,,"10-byte message"
+4,10,10,10,TRUE,0,0,FALSE,,"10-byte message"
+,,,,,,,,,
+"Transition from one d-block to two per message",,,,,,,,,
+5,10,84,84,FALSE,0,0,FALSE,,"1 dblk exact fit"
+6,10,85,85,FALSE,0,0,FALSE,,"1 dblk + 1 byte"
+7,10,84,84,TRUE,0,0,FALSE,,"1 dblk exact fit"
+8,10,85,85,TRUE,0,0,FALSE,,"1 dblk + 1 byte"
+,,,,,,,,,
+"Transition from one s-block to two per message",,,,,,,,,
+9,10,468,468,FALSE,0,0,FALSE,,"1 sblk exact fit"
+10,10,469,469,FALSE,0,0,FALSE,,"1 sblk + 1 byte"
+11,10,468,468,TRUE,0,0,FALSE,,"1 sblk exact fit"
+12,10,469,469,TRUE,0,0,FALSE,,"1 sblk + 1 byte"
+,,,,,,,,,
+"Transition from first page to second",,,,,,,,,
+13,8,4052,4052,FALSE,0,0,FALSE,,"8 * 1/8 page; Total = 1 page exact fit"
+14,9,4052,4052,FALSE,0,0,FALSE,,"9 * 1/8 page"
+15,8,4053,4053,FALSE,0,0,FALSE,,"8 * (1/8 page + 1 byte)"
+16,8,3924,3924,TRUE,0,0,FALSE,,"8 * (1/8 page - 1 dblk for deq record); Total = 1 page exact fit with deqs"
+17,9,3924,3924,TRUE,0,0,FALSE,,"9 * (1/8 page - 1 dblk for deq record)"
+18,8,3925,3925,TRUE,0,0,FALSE,,"8 * (1/8 page - 1 dblk for deq record + 1 byte)"
+,,,,,,,,,
+"Page cache rollover (from page 32 back to page 0) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,,,,
+19,32,32724,32724,FALSE,0,0,FALSE,,"32 * (1 page exact fit); Total = entire cache exactly"
+20,33,32724,32724,FALSE,0,0,FALSE,,"33 * (1 page exact fit); Total = entire cache + reuse of 1 page"
+21,22,49108,49108,FALSE,0,0,FALSE,,"22 * 1.5 pages"
+22,22,48980,48980,TRUE,0,0,FALSE,,"22 * (1.5 pages including 1 sblk for deq record)"
+,,,,,,,,,
+"File transition (from file 0000 to 0001) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,,,,
+23,48,32724,32724,FALSE,0,0,FALSE,,"48 * (1 page exact fit); Total = entire file exactly"
+24,49,32724,32724,FALSE,0,0,FALSE,,"49 * (1 page exact fit); Total = entire file + 1 page"
+25,20,81876,81876,FALSE,0,0,FALSE,,"20 * (2.5 pages); Total = entire file + 2 pages"
+26,20,81748,81748,TRUE,0,0,FALSE,,"20 * (2.5 pages including 1 sblk for deq record); Total = entire file + 2 pages"
+,,,,,,,,,
+"File rollover (from file 0007 to 0000) - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,,,,
+27,16,786388,786388,FALSE,FALSE,FALSE,FALSE,,"16 * (24 pages = ½ file); Total = 8 files exactly"
+28,16,786260,786260,TRUE,0,0,FALSE,,"16 * (24 pages = ½ file); Total = 8 files exactly"
+29,17,786260,786260,TRUE,0,0,FALSE,,"17 * (24 pages = ½ file); Total = 8 files + file 0 overwritten by ½ file"
+30,16,786261,786261,TRUE,0,0,FALSE,,"16 * (24 pages + 1 byte); Total = 8 files + file 0 overwritten by 16 sblks"
+31,32,786260,786260,TRUE,0,0,FALSE,,"32 * (24 pages = ½ file); Total = 16 files exactly, all files overwritten once"
+32,33,786260,786260,TRUE,0,0,FALSE,,"33 * (24 pages = ½ file); Total = 16 ½ files, all files overwritten once + file 0 overwritten again by ½ file"
+33,32,786261,786261,TRUE,0,0,FALSE,,"32 * (24 pages + 1 byte); All files overwritten once + file 0 overwritten again by 32 sblks"
+,,,,,,,,,
+"Multi-page messages (large messages) - tests various paths in encoder; no dequeues required to test this functionality.",,,,,,,,,
+34,16,32724,32724,FALSE,0,0,FALSE,,"16 * (1 page exact fit)"
+35,16,32725,32725,FALSE,0,0,FALSE,,"16 * (1 page + 1 byte): tail split"
+36,16,32735,32735,FALSE,0,0,FALSE,,"16 * (1 page + 11 bytes): tail split"
+37,16,32736,32736,FALSE,0,0,FALSE,,"16 * (1 page + 12 bytes): tail separated exactly"
+38,16,32737,32737,FALSE,0,0,FALSE,,"16 * (1 page + 13 bytes): data split"
+39,16,65492,65492,FALSE,0,0,FALSE,,"16 * (2 pages exact fit)"
+40,16,65493,65493,FALSE,0,0,FALSE,,"16 * (2 pages + 1 byte): tail split"
+41,16,65503,65503,FALSE,0,0,FALSE,,"16 * (2 pages + 11 bytes): tail split"
+42,16,65504,65504,FALSE,0,0,FALSE,,"16 * (2 pages + 12 bytes): tail separated exactly"
+43,16,65505,65505,FALSE,0,0,FALSE,,"16 * (2 pages + 13 bytes) data split"
+44,16,131028,131028,FALSE,0,0,FALSE,,"16 * (4 pages exact fit)"
+45,16,131029,131029,FALSE,0,0,FALSE,,"16 * (4 pages + 1 byte: tail split)"
+46,16,131039,131039,FALSE,0,0,FALSE,,"16 * (4 pages + 1 byte: tail split)"
+47,16,131040,131040,FALSE,0,0,FALSE,,"16 * (4 pages + 12 bytes: tail separated)"
+48,16,131041,131041,FALSE,0,0,FALSE,,"16 * (4 pages + 13 bytes: data split)"
+49,16,114644,114644,FALSE,0,0,FALSE,,"16 * (3.5 pages)"
+50,16,114645,114645,FALSE,0,0,FALSE,,"16 * (3.5 pages + 1 byte)"
Modified: store/trunk/cpp/tests/jrnl/tests.ods
===================================================================
(Binary files differ)
Modified: store/trunk/cpp/tests/jrnl/wtests.csv
===================================================================
--- store/trunk/cpp/tests/jrnl/wtests.csv 2007-10-02 12:35:40 UTC (rev 959)
+++ store/trunk/cpp/tests/jrnl/wtests.csv 2007-10-02 20:45:10 UTC (rev 960)
@@ -1,107 +1,139 @@
-"Initialize only",,,,,,
-0,0,0,0,FALSE,,"No messages"
-,,,,,,
-"Within first block, page, file",,,,,,
-1,1,10,10,FALSE,,"10-byte message"
-2,10,10,10,FALSE,,"10-byte message"
-3,1,10,10,TRUE,,"10-byte message"
-4,10,10,10,TRUE,,"10-byte message"
-,,,,,,
-"Transition from one d-block to two per message",,,,,,
-5,10,84,84,FALSE,,"1 dblk exact fit"
-6,10,85,85,FALSE,,"1 dblk + 1 byte"
-7,10,84,84,TRUE,,"1 dblk exact fit"
-8,10,85,85,TRUE,,"1 dblk + 1 byte"
-,,,,,,
-"Transition from one s-block to two per message",,,,,,
-9,10,468,468,FALSE,,"1 sblk exact fit"
-10,10,469,469,FALSE,,"1 sblk + 1 byte"
-11,10,468,468,TRUE,,"1 sblk exact fit"
-12,10,469,469,TRUE,,"1 sblk + 1 byte"
-,,,,,,
-"Transition from first page to second",,,,,,
-13,8,4052,4052,FALSE,,"8 * 1/8 page; Total = 1 page exact fit"
-14,9,4052,4052,FALSE,,"9 * 1/8 page"
-15,8,4053,4053,FALSE,,"8 * (1/8 page + 1 byte)"
-16,8,3924,3924,TRUE,,"8 * (1/8 page - 1 dblk for deq record); Total = 1 page exact fit with deqs"
-17,9,3924,3924,TRUE,,"9 * (1/8 page - 1 dblk for deq record)"
-18,8,3925,3925,TRUE,,"8 * (1/8 page - 1 dblk for deq record + 1 byte)"
-,,,,,,
-"Page cache rollover (from page 32 back to page 0) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,
-19,32,32724,32724,FALSE,,"32 * (1 page exact fit); Total = entire cache exactly"
-20,33,32724,32724,FALSE,,"33 * (1 page exact fit); Total = entire cache + reuse of 1 page"
-21,22,49108,49108,FALSE,,"22 * 1.5 pages"
-22,22,48980,48980,TRUE,,"22 * (1.5 pages including 1 sblk for deq record)"
-,,,,,,
-"File transition (from file 0000 to 0001) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,
-23,48,32724,32724,FALSE,,"48 * (1 page exact fit); Total = entire file exactly"
-24,49,32724,32724,FALSE,,"49 * (1 page exact fit); Total = entire file + 1 page"
-25,20,81876,81876,FALSE,,"20 * (2.5 pages); Total = entire file + 2 pages"
-26,20,81748,81748,TRUE,,"20 * (2.5 pages including 1 sblk for deq record); Total = entire file + 2 pages"
-,,,,,,
-"File rollover (from file 0007 to 0000) - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,
-27,16,786388,786388,FALSE,,"16 * (24 pages = ½ file); Total = 8 files exactly"
-28,17,786388,786388,FALSE,,"17 * (24 pages = ½ file); Total = 8 files + file 0 overwritten by ½ file"
-29,16,786389,786389,FALSE,,"16 * (24 pages + 1 byte); Total = 8 files + file 0 overwritten by 16 sblks"
-30,32,786388,786388,FALSE,,"32 * (24 pages = ½ file); Total = 16 files exactly, all files overwritten once"
-31,33,786388,786388,FALSE,,"33 * (24 pages = ½ file); Total = 16 ½ files, all files overwritten once + file 0 overwritten again by ½ file"
-32,32,786389,786389,FALSE,,"32 * (24 pages + 1 byte); All files overwritten once + file 0 overwritten again by 32 sblks"
-,,,,,,
-"Multi-page messages (large messages) - tests various paths in encoder; no dequeues required to test this functionality.",,,,,,
-33,16,32724,32724,FALSE,,"16 * (1 page exact fit)"
-34,16,32725,32725,FALSE,,"16 * (1 page + 1 byte): tail split"
-35,16,32735,32735,FALSE,,"16 * (1 page + 11 bytes): tail split"
-36,16,32736,32736,FALSE,,"16 * (1 page + 12 bytes): tail separated exactly"
-37,16,32737,32737,FALSE,,"16 * (1 page + 13 bytes): data split"
-38,16,65492,65492,FALSE,,"16 * (2 pages exact fit)"
-39,16,65493,65493,FALSE,,"16 * (2 pages + 1 byte): tail split"
-40,16,65503,65503,FALSE,,"16 * (2 pages + 11 bytes): tail split"
-41,16,65504,65504,FALSE,,"16 * (2 pages + 12 bytes): tail separated exactly"
-42,16,65505,65505,FALSE,,"16 * (2 pages + 13 bytes) data split"
-43,16,131028,131028,FALSE,,"16 * (4 pages exact fit)"
-44,16,131029,131029,FALSE,,"16 * (4 pages + 1 byte: tail split)"
-45,16,131039,131039,FALSE,,"16 * (4 pages + 1 byte: tail split)"
-46,16,131040,131040,FALSE,,"16 * (4 pages + 12 bytes: tail separated)"
-47,16,131041,131041,FALSE,,"16 * (4 pages + 13 bytes: data split)"
-48,16,114644,114644,FALSE,,"16 * (3.5 pages)"
-49,16,114645,114645,FALSE,,"16 * (3.5 pages + 1 byte)"
-,,,,,,
-"Large (multi-megabyte) messages - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,
-50,32,1572820,1572820,FALSE,,"32 * (48 pages = 1 file exactly)"
-51,32,1572821,1572821,FALSE,,"32 * (48 pages + 1 byte)"
-52,32,1605588,1605588,FALSE,,"32 * (49 pages = 1 file + 1 page)"
-53,16,3145684,3145684,FALSE,,"16 * (96 pages = 2 files exactly)"
-54,16,3145685,3145685,FALSE,,"16 * (96 pages + 1 byte)"
-55,16,3178452,3178452,FALSE,,"16 * (97 pages = 2 files + 1 page"
-56,8,6291412,6291412,FALSE,,"8 * (192 pages = 4 files exactly)"
-57,8,6291413,6291413,FALSE,,"8 * (192 pages + 1 byte)"
-58,8,6324180,6324180,FALSE,,"8 * (193 pages = 4 files + 1 page)"
-59,32,1572692,1572692,TRUE,,"32 * (48 pages including 1 sblk for deq record = 1 file exactly)"
-60,32,1572693,1572693,TRUE,,"32 * (48 pages including 1 sblk for deq record + 1 byte)"
-61,32,1605460,1605460,TRUE,,"32 * (49 pages including 1 sblk for deq record = 1 file + 1 page)"
-62,16,3145556,3145556,TRUE,,"16 * (96 pages including 1 sblk for deq record = 2 files exactly)"
-63,16,3145557,3145557,TRUE,,"16 * (96 pages including 1 sblk for deq record + 1 byte)"
-64,16,3178324,3178324,TRUE,,"16 * (97 pages including 1 sblk for deq record = 2 files + 1 page"
-65,8,6291284,6291284,TRUE,,"8 * (192 pages including 1 sblk for deq record = 4 files exactly)"
-66,8,6291285,6291285,TRUE,,"8 * (192 pages including 1 sblk for deq record + 1 byte)"
-67,8,6324052,6324052,TRUE,,"8 * (193 pages including 1 sblk for deq record = 4 files + 1 page)"
-,,,,,,
-"High volume tests of random message lengths - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,
-68,5000000,0,84,FALSE,,"1 dblk max"
-69,3000000,0,340,FALSE,,"3 dblks max"
-70,1600000,0,1236,FALSE,,"10 dblks max"
-71,600000,0,3796,FALSE,,"30 dblks max"
-72,200000,0,12756,FALSE,,"100 dblks max"
-73,60000,0,38356,FALSE,,"300 dblks max"
-74,20000,0,127956,FALSE,,"1000 dblks max"
-75,2500000,0,84,TRUE,,"1 dblk max"
-76,1500000,0,340,TRUE,,"3 dblks max"
-77,800000,0,1236,TRUE,,"10 dblks max"
-78,300000,0,3796,TRUE,,"30 dblks max"
-79,100000,0,12756,TRUE,,"100 dblks max"
-80,30000,0,38356,TRUE,,"300 dblks max"
-81,10000,0,127956,TRUE,,"1000 dblks max"
-,,,,,,
-"STANDARD PERFORMANCE BENCHMARK: 10,000,000 writes, data=212b (2 dblks)",,,,,,
-82,10000000,212,212,FALSE,,"2 dblks"
-83,10000000,212,212,TRUE,,"2 dblks"
+"Initialize only",,,,,,,,,
+0,0,0,0,FALSE,0,0,FALSE,,"No messages"
+,,,,,,,,,
+"Within first block, page, file",,,,,,,,,
+1,1,10,10,FALSE,0,0,FALSE,,"1 * 10-byte message"
+2,10,10,10,FALSE,0,0,FALSE,,"10 * 10-byte message"
+3,1,10,10,FALSE,0,0,TRUE,,"1 * 10-byte message, transient"
+4,10,10,10,FALSE,0,0,TRUE,,"10 * 10-byte message, transient"
+5,1,10,10,FALSE,10,10,FALSE,,"1 * 10-byte message, txn"
+6,10,10,10,FALSE,10,10,FALSE,,"10 * 10-byte message, txn"
+7,1,10,10,FALSE,10,10,TRUE,,"1 * 10-byte message, txn, transient"
+8,10,10,10,FALSE,10,10,TRUE,,"10 * 10-byte message, txn, transient"
+9,1,10,10,TRUE,0,0,FALSE,,"1 * 10-byte message, deq"
+10,10,10,10,TRUE,0,0,FALSE,,"10 * 10-byte message, deq"
+11,1,10,10,TRUE,0,0,TRUE,,"1 * 10-byte message, transient, deq"
+12,10,10,10,TRUE,0,0,TRUE,,"10 * 10-byte message, transient, deq"
+13,1,10,10,TRUE,10,10,FALSE,,"1 * 10-byte message, txn, deq"
+14,10,10,10,TRUE,10,10,FALSE,,"10 * 10-byte message, txn, deq"
+15,1,10,10,TRUE,10,10,TRUE,,"1 * 10-byte message, txn, transient, deq"
+16,10,10,10,TRUE,10,10,TRUE,,"10 * 10-byte message, txn, transient, deq"
+,,,,,,,,,
+"Transition from one d-block to two per message",,,,,,,,,
+17,10,84,84,FALSE,0,0,FALSE,,"1 dblk exact fit"
+18,10,85,85,FALSE,0,0,FALSE,,"1 dblk + 1 byte"
+19,10,58,58,FALSE,26,26,FALSE,,"1 dblk exact fit, txn"
+20,10,59,59,FALSE,26,26,FALSE,,"1 dblk + 1 byte, txn"
+,,,,,,,,,
+"Transition from one s-block to two per message",,,,,,,,,
+21,10,468,468,FALSE,0,0,FALSE,,"1 sblk exact fit"
+22,10,469,469,FALSE,0,0,FALSE,,"1 sblk + 1 byte"
+23,10,442,442,FALSE,26,26,FALSE,,"1 sblk exact fit, txn"
+24,10,443,443,FALSE,26,26,FALSE,,"1 sblk + 1 byte, txn"
+,,,,,,,,,
+"Transition from first page to second",,,,,,,,,
+25,8,4052,4052,FALSE,0,0,FALSE,,"8 * 1/8 page; Total = 1 page exact fit"
+26,9,4052,4052,FALSE,0,0,FALSE,,"9 * 1/8 page"
+27,8,4053,4053,FALSE,0,0,FALSE,,"8 * (1/8 page + 1 byte)"
+28,8,3796,3796,FALSE,256,256,FALSE,,"8 * 1/8 page; Total = 1 page exact fit, txn"
+29,9,3796,3796,FALSE,256,256,FALSE,,"9 * 1/8 page, txn"
+30,8,3797,3797,FALSE,256,256,FALSE,,"8 * (1/8 page + 1 byte), txn"
+,,,,,,,,,
+"Page cache rollover (from page 32 back to page 0) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,,,,
+31,32,32724,32724,FALSE,0,0,FALSE,,"32 * (1 page exact fit); Total = entire cache exactly"
+32,33,32724,32724,FALSE,0,0,FALSE,,"33 * (1 page exact fit); Total = entire cache + reuse of 1 page"
+33,22,49108,49108,FALSE,0,0,FALSE,,"22 * 1.5 pages"
+34,32,32468,32468,FALSE,256,256,FALSE,,"32 * (1 page exact fit); Total = entire cache exactly, txn"
+35,33,32468,32468,FALSE,256,256,FALSE,,"33 * (1 page exact fit); Total = entire cache + reuse of 1 page, txn"
+36,22,48852,48852,FALSE,256,256,FALSE,,"22 * 1.5 pages, txn"
+,,,,,,,,,
+"File transition (from file 0000 to 0001) - no dequeues as exact sizes are needed and dequeues are non-deterministic",,,,,,,,,
+37,48,32724,32724,FALSE,0,0,FALSE,,"48 * (1 page exact fit); Total = entire file exactly"
+38,49,32724,32724,FALSE,0,0,FALSE,,"49 * (1 page exact fit); Total = entire file + 1 page"
+39,20,81876,81876,FALSE,0,0,FALSE,,"20 * (2.5 pages); Total = entire file + 2 pages"
+40,48,32468,32468,FALSE,256,256,FALSE,,"48 * (1 page exact fit); Total = entire file exactly, txn"
+41,49,32468,32468,FALSE,256,256,FALSE,,"49 * (1 page exact fit); Total = entire file + 1 page, txn"
+42,20,81620,81620,FALSE,256,256,FALSE,,"20 * (2.5 pages); Total = entire file + 2 pages, txn"
+,,,,,,,,,
+"File rollover (from file 0007 to 0000) - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,,,,
+43,16,786388,786388,FALSE,0,0,FALSE,,"16 * (24 pages = ½ file); Total = 8 files exactly"
+44,17,786388,786388,FALSE,0,0,FALSE,,"17 * (24 pages = ½ file); Total = 8 files + file 0 overwritten by ½ file"
+45,16,786389,786389,FALSE,0,0,FALSE,,"16 * (24 pages + 1 byte); Total = 8 files + file 0 overwritten by 16 sblks"
+46,32,786388,786388,FALSE,0,0,FALSE,,"32 * (24 pages = ½ file); Total = 16 files exactly, all files overwritten once"
+47,33,786388,786388,FALSE,0,0,FALSE,,"33 * (24 pages = ½ file); Total = 16 ½ files, all files overwritten once + file 0 overwritten again by ½ file"
+48,32,786389,786389,FALSE,0,0,FALSE,,"32 * (24 pages + 1 byte); All files overwritten once + file 0 overwritten again by 32 sblks"
+49,16,786132,786132,FALSE,256,256,FALSE,,"16 * (24 pages = ½ file); Total = 8 files exactly, txn"
+50,17,786132,786132,FALSE,256,256,FALSE,,"17 * (24 pages = ½ file); Total = 8 files + file 0 overwritten by ½ file, txn"
+51,16,786133,786133,FALSE,256,256,FALSE,,"16 * (24 pages + 1 byte); Total = 8 files + file 0 overwritten by 16 sblks, txn"
+52,32,786132,786132,FALSE,256,256,FALSE,,"32 * (24 pages = ½ file); Total = 16 files exactly, all files overwritten once, txn"
+53,33,786132,786132,FALSE,256,256,FALSE,,"33 * (24 pages = ½ file); Total = 16 ½ files, all files overwritten once + file 0 overwritten again by ½ file, txn"
+54,32,786133,786133,FALSE,256,256,FALSE,,"32 * (24 pages + 1 byte); All files overwritten once + file 0 overwritten again by 32 sblks, txn"
+,,,,,,,,,
+"Multi-page messages (large messages) - tests various paths in encoder; no dequeues required to test this functionality.",,,,,,,,,
+55,16,10,10,FALSE,32724,32724,FALSE,,"16 * (xid 1 page exact fit)"
+56,16,10,10,FALSE,32725,32725,FALSE,,"16 * (xid 1 page + 1 byte): tail split"
+57,16,10,10,FALSE,32735,32735,FALSE,,"16 * (xid 1 page + 11 bytes): tail split"
+58,16,10,10,FALSE,32736,32736,FALSE,,"16 * (xid 1 page + 12 bytes): tail separated exactly"
+59,16,10,10,FALSE,32737,32737,FALSE,,"16 * (xid 1 page + 13 bytes): data split"
+60,16,10,10,FALSE,65492,65492,FALSE,,"16 * (xid 2 pages exact fit)"
+61,16,10,10,FALSE,65493,65493,FALSE,,"16 * (xid 2 pages + 1 byte): tail split"
+62,16,10,10,FALSE,65503,65503,FALSE,,"16 * (xid 2 pages + 11 bytes): tail split"
+63,16,10,10,FALSE,65504,65504,FALSE,,"16 * (xid 2 pages + 12 bytes): tail separated exactly"
+64,16,10,10,FALSE,65505,65505,FALSE,,"16 * (xid 2 pages + 13 bytes) data split"
+65,16,32724,32724,FALSE,0,0,FALSE,,"16 * (1 page exact fit)"
+66,16,32725,32725,FALSE,0,0,FALSE,,"16 * (1 page + 1 byte): tail split"
+67,16,32735,32735,FALSE,0,0,FALSE,,"16 * (1 page + 11 bytes): tail split"
+68,16,32736,32736,FALSE,0,0,FALSE,,"16 * (1 page + 12 bytes): tail separated exactly"
+69,16,32737,32737,FALSE,0,0,FALSE,,"16 * (1 page + 13 bytes): data split"
+70,16,65492,65492,FALSE,0,0,FALSE,,"16 * (2 pages exact fit)"
+71,16,65493,65493,FALSE,0,0,FALSE,,"16 * (2 pages + 1 byte): tail split"
+72,16,65503,65503,FALSE,0,0,FALSE,,"16 * (2 pages + 11 bytes): tail split"
+73,16,65504,65504,FALSE,0,0,FALSE,,"16 * (2 pages + 12 bytes): tail separated exactly"
+74,16,65505,65505,FALSE,0,0,FALSE,,"16 * (2 pages + 13 bytes) data split"
+75,16,131028,131028,FALSE,0,0,FALSE,,"16 * (4 pages exact fit)"
+76,16,131029,131029,FALSE,0,0,FALSE,,"16 * (4 pages + 1 byte: tail split)"
+77,16,131039,131039,FALSE,0,0,FALSE,,"16 * (4 pages + 1 byte: tail split)"
+78,16,131040,131040,FALSE,0,0,FALSE,,"16 * (4 pages + 12 bytes: tail separated)"
+79,16,131041,131041,FALSE,0,0,FALSE,,"16 * (4 pages + 13 bytes: data split)"
+80,16,114644,114644,FALSE,0,0,FALSE,,"16 * (3.5 pages)"
+81,16,114645,114645,FALSE,0,0,FALSE,,"16 * (3.5 pages + 1 byte)"
+,,,,,,,,,
+"Large (multi-megabyte) messages - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,,,,
+82,32,1572820,1572820,FALSE,0,0,FALSE,,"32 * (48 pages = 1 file exactly)"
+83,32,1572821,1572821,FALSE,0,0,FALSE,,"32 * (48 pages + 1 byte)"
+84,32,1605588,1605588,FALSE,0,0,FALSE,,"32 * (49 pages = 1 file + 1 page)"
+85,16,3145684,3145684,FALSE,0,0,FALSE,,"16 * (96 pages = 2 files exactly)"
+86,16,3145685,3145685,FALSE,0,0,FALSE,,"16 * (96 pages + 1 byte)"
+87,16,3178452,3178452,FALSE,0,0,FALSE,,"16 * (97 pages = 2 files + 1 page"
+88,8,6291412,6291412,FALSE,0,0,FALSE,,"8 * (192 pages = 4 files exactly)"
+89,8,6291413,6291413,FALSE,0,0,FALSE,,"8 * (192 pages + 1 byte)"
+90,8,6324180,6324180,FALSE,0,0,FALSE,,"8 * (193 pages = 4 files + 1 page)"
+91,32,1572692,1572692,TRUE,0,0,FALSE,,"32 * (48 pages including 1 sblk for deq record = 1 file exactly)"
+92,32,1572693,1572693,TRUE,0,0,FALSE,,"32 * (48 pages including 1 sblk for deq record + 1 byte)"
+93,32,1605460,1605460,TRUE,0,0,FALSE,,"32 * (49 pages including 1 sblk for deq record = 1 file + 1 page)"
+94,16,3145556,3145556,TRUE,0,0,FALSE,,"16 * (96 pages including 1 sblk for deq record = 2 files exactly)"
+95,16,3145557,3145557,TRUE,0,0,FALSE,,"16 * (96 pages including 1 sblk for deq record + 1 byte)"
+96,16,3178324,3178324,TRUE,0,0,FALSE,,"16 * (97 pages including 1 sblk for deq record = 2 files + 1 page"
+97,8,6291284,6291284,TRUE,0,0,FALSE,,"8 * (192 pages including 1 sblk for deq record = 4 files exactly)"
+98,8,6291285,6291285,TRUE,0,0,FALSE,,"8 * (192 pages including 1 sblk for deq record + 1 byte)"
+99,8,6324052,6324052,TRUE,0,0,FALSE,,"8 * (193 pages including 1 sblk for deq record = 4 files + 1 page)"
+,,,,,,,,,
+"High volume tests of random message lengths - RHM_WRONLY req'd for auto-dequeue == FALSE",,,,,,,,,
+100,5000000,0,84,FALSE,0,0,FALSE,,"1 dblk max"
+101,3000000,0,340,FALSE,0,0,FALSE,,"3 dblks max"
+102,1600000,0,1236,FALSE,0,0,FALSE,,"10 dblks max"
+103,600000,0,3796,FALSE,0,0,FALSE,,"30 dblks max"
+104,200000,0,12756,FALSE,0,0,FALSE,,"100 dblks max"
+105,60000,0,38356,FALSE,0,0,FALSE,,"300 dblks max"
+106,20000,0,127956,FALSE,0,0,FALSE,,"1000 dblks max"
+107,2500000,0,84,TRUE,0,0,FALSE,,"1 dblk max"
+108,1500000,0,340,TRUE,0,0,FALSE,,"3 dblks max"
+109,800000,0,1236,TRUE,0,0,FALSE,,"10 dblks max"
+110,300000,0,3796,TRUE,0,0,FALSE,,"30 dblks max"
+111,100000,0,12756,TRUE,0,0,FALSE,,"100 dblks max"
+112,30000,0,38356,TRUE,0,0,FALSE,,"300 dblks max"
+113,10000,0,127956,TRUE,0,0,FALSE,,"1000 dblks max"
+,,,,,,,,,
+"STANDARD PERFORMANCE BENCHMARK: 10,000,000 writes, data=212b (2 dblks)",,,,,,,,,
+114,10000000,212,212,FALSE,0,0,FALSE,,"2 dblks"
+115,10000000,212,212,TRUE,0,0,FALSE,,"2 dblks"
[View Less]
17 years, 3 months
rhmessaging commits: r959 - store/trunk/cpp/lib.
by rhmessaging-commits@lists.jboss.org
Author: gordonsim
Date: 2007-10-02 08:35:40 -0400 (Tue, 02 Oct 2007)
New Revision: 959
Modified:
store/trunk/cpp/lib/BdbMessageStore.cpp
store/trunk/cpp/lib/BdbMessageStore.h
Log:
Make message arg const in append- and load- Content
Modified: store/trunk/cpp/lib/BdbMessageStore.cpp
===================================================================
--- store/trunk/cpp/lib/BdbMessageStore.cpp 2007-10-01 15:16:57 UTC (rev 958)
+++ store/trunk/cpp/lib/BdbMessageStore.cpp 2007-10-02 12:35:…
[View More]40 UTC (rev 959)
@@ -663,7 +663,7 @@
return peek.get_size();
}
-void BdbMessageStore::appendContent(PersistableMessage& msg, const std::string& data)
+void BdbMessageStore::appendContent(const PersistableMessage& msg, const std::string& data)
{
u_int64_t messageId (msg.getPersistenceId());
if (messageId != 0) {
@@ -690,7 +690,7 @@
THROW_STORE_EXCEPTION("Cannot append content. Message not known to store!");
}
}
-void BdbMessageStore::loadContent(PersistableMessage& msg, std::string& data, u_int64_t offset, u_int32_t length)
+void BdbMessageStore::loadContent(const PersistableMessage& msg, std::string& data, u_int64_t offset, u_int32_t length)
{
u_int64_t realOffset = offset + sizeof(u_int32_t)/*header length*/+ msg.encodedHeaderSize();
u_int64_t messageId (msg.getPersistenceId());
Modified: store/trunk/cpp/lib/BdbMessageStore.h
===================================================================
--- store/trunk/cpp/lib/BdbMessageStore.h 2007-10-01 15:16:57 UTC (rev 958)
+++ store/trunk/cpp/lib/BdbMessageStore.h 2007-10-02 12:35:40 UTC (rev 959)
@@ -139,8 +139,8 @@
void stage(qpid::broker::PersistableMessage& msg);
void destroy(qpid::broker::PersistableMessage& msg);
- void appendContent(qpid::broker::PersistableMessage& msg, const std::string& data);
- void loadContent(qpid::broker::PersistableMessage& msg, std::string& data, u_int64_t offset, u_int32_t length);
+ void appendContent(const qpid::broker::PersistableMessage& msg, const std::string& data);
+ void loadContent(const qpid::broker::PersistableMessage& msg, std::string& data, u_int64_t offset, u_int32_t length);
void enqueue(qpid::broker::TransactionContext* ctxt,
qpid::broker::PersistableMessage& msg,
[View Less]
17 years, 3 months
rhmessaging commits: r958 - store/trunk/cpp/lib.
by rhmessaging-commits@lists.jboss.org
Author: cctrieloff
Date: 2007-10-01 11:16:57 -0400 (Mon, 01 Oct 2007)
New Revision: 958
Modified:
store/trunk/cpp/lib/BdbMessageStore.cpp
Log:
skip reading db for m-id log when using journal
Modified: store/trunk/cpp/lib/BdbMessageStore.cpp
===================================================================
--- store/trunk/cpp/lib/BdbMessageStore.cpp 2007-10-01 14:46:01 UTC (rev 957)
+++ store/trunk/cpp/lib/BdbMessageStore.cpp 2007-10-01 15:16:57 UTC (rev 958)
@@ -547,6 +547,9 @@
std::…
[View More]set<string> prepared;
collectPreparedXids(prepared);
+ txn_lock_map enqueues;
+ txn_lock_map dequeues;
+ //when using the async journal, it will abort unprepaired xids and populate the locked maps
if (!usingJrnl()){
std::set<string> known;
readXids(enqueueXidDb, known);
@@ -559,17 +562,14 @@
completed(txn, dequeueXidDb, enqueueXidDb);
}
}
+ readLockedMappings(enqueueXidDb, enqueues);
+ readLockedMappings(dequeueXidDb, dequeues);
}
- txn_lock_map enqueues;
- txn_lock_map dequeues;
+
+ for (std::set<string>::iterator i = prepared.begin(); i != prepared.end(); i++) {
+ txns.push_back(new PreparedTransaction(*i, enqueues[*i], dequeues[*i]));
+ }
- //this will be empty when using the journal -- TODO to get from journal.
- readLockedMappings(enqueueXidDb, enqueues);
- readLockedMappings(dequeueXidDb, dequeues);
-
- for (std::set<string>::iterator i = prepared.begin(); i != prepared.end(); i++) {
- txns.push_back(new PreparedTransaction(*i, enqueues[*i], dequeues[*i]));
- }
}
void BdbMessageStore::readXids(Db& db, std::set<string>& xids)
[View Less]
17 years, 3 months